Project Info
Inspiration
Daily life now runs on phone trees and web portals. If you're homebound, low-vision, low-literacy, or elderly, that quietly locks you out of basic dignity-level tasks: refilling a prescription, renewing a registration, paying a bill. Existing tools assume you can see a screen and supervise an agent the whole way. The people who most need help are the ones those tools were never built for. Open Door is our swing at that gap: an agent that talks to you, works the web for you, and stops to ask out loud before it ever spends your money or does something it can't undo.
What it does
You say what you need ("I need to refill my metformin, I can't get to the pharmacy") Open Door: Plans it out loud: One Claude call turns your spoken goal into a visible, ordered plan. Each step labeled with which "body" handles it and why Works the portal for you: A real browser navigates the pharmacy site, finds the prescription, and reads the actual out-of-pocket cost off the page Stops at the gate: Before the one irreversible step — submitting the refill — it speaks the cost aloud ("This will charge you $14 and submit your refill. Should I go ahead?") and waits. You answer by voice -> "yes" or "no" Only then acts: On "yes," it submits and reads back the confirmation. On "no," it stops cold and tells you nothing was charged The plan is the hero of the screen: steps light up as they run, the gated step pauses red, and the question is spoken, so a person who can't see or touch the screen can complete a real, costly action entirely by voice.
How we built it
The architecture is built around seams — every external service is swappable, so the whole thing runs offline against mocks and flips to live with one env var. Planner (Anthropic, Claude Opus 4.8) - The centerpiece: A strict-JSON planner with adaptive thinking, defensive parsing, and a content-guard that retries if the spoken wording reads like a stage direction instead of real speech. It generalizes: give it a DMV renewal or a utility bill and it produces a correct, gated plan Browse leg (Browserbase + Playwright) - Drives a real Chromium through the portal: Local by default (free), Browserbase cloud with one env flag — same Playwright code over CDP. Self-healing navigation so the run survives messy pages. Stop-before-submit is structural: the effector never decides to submit; it only clicks the button when dispatch hands it the gated step, which only happens after a human "yes" Speak leg (Deepgram) - Both directions: TTS (Aura) voices the gate question and every spoken line; STT (Nova) hears your goal at intake and your yes/no at the gate. The spoken confirmation is load-bearing, not decoration Dispatch + the human gate - A pausable state machine: it physically parks the browser on the irreversible button and refuses to proceed until a human decides. Negative answers win on ambiguity. It never proceeds unless it clearly heard "yes." Declining skips the rest of the plan so it can never falsely report success Observability (Sentry) - Every effector is instrumented: every gate leaves a breadcrumb of exactly what the human approved. We exercised it for real (killed the portal mid-browse and watched the capture land), because un-triggered observability doesn't count Frontend - A single-page hero: UI streaming live state over Server-Sent Events (push on change, not polling), plus a connected-services landing that frames Open Door as a platform for all of daily life's errands 22 regression tests, an 8/8 live health check, and an offline-first build kept it honest.
Challenges we ran into
Making spoken output sound human: The planner kept reading step descriptions aloud ("Confirm which pharmacy holds their prescription"). We fixed it with a sharper prompt plus a deterministic guard that detects stage-direction phrasing and retries for real second-person speech Generalist planner vs. scripted hands: The planner imagines portal features (home delivery) the mock fixture doesn't have. We made the browse leg self-heal and tolerant so any goal completes rather than timing out A "no" that still said yes: Early on, declining the gate still ran the downstream "all done" steps. We made declining halt the plan — the bug that most violated our own thesis, and the one we're proudest to have caught
Accomplishments we're proud of
The spoken safety gate. The agent parks on the irreversible button and asks aloud, and you answer aloud. It's a small thing that makes a powerful agent safe to hand to someone who can't supervise it. That's the whole point.
What we learned
Building a careful agent is mostly about designing where it stops, not where it acts. The seams and the gate were more engineering than the "doing," and that's the right ratio for something that spends a vulnerable person's money.
What's next
Generalize the browse leg to natural-language web navigation so it handles any real portal (the planner already generalizes); add real account connections per service; a pending-errands queue and an in-app action history.
Open Door
An AI agent that does the bureaucratic errands of daily life for people who can't — and never spends their money or does anything irreversible without asking first, out loud.
Daily life now runs on phone trees and web portals. If you're homebound, low-vision, low-literacy, or elderly, that quietly locks you out of basic, dignity-level tasks: refilling a prescription, renewing a registration, paying a bill. Tools built for general users assume you can see a screen and supervise an agent the whole way — the people who most need help are the ones they were never built for.
Open Door takes a spoken goal, decomposes it into a visible plan, works the web on your behalf, and stops to ask — by voice — before anything costly or irreversible. Care made legible: powerful enough to act, careful enough to ask first.
Flagship demo: a homebound patient refills a prescription by voice. The agent confirms details aloud, navigates the pharmacy portal, reads the real out-of-pocket cost off the page, and pauses for a spoken "yes" before submitting.
How it works
A single Claude planner turns a spoken goal into a structured Plan. Each step is dispatched to an effector — a swappable "body" — and the run pauses at a human gate before any costly or irreversible action.
| Leg | What it does | Powered by |
|---|---|---|
| Plan | Decomposes the goal into a visible, ordered plan; tags each step's risk; writes the spoken lines | Claude (Anthropic) |
| Browse | Drives a real browser through the portal: read the page, find the item, surface the real cost, submit | Playwright (local) / Browserbase (cloud) |
| Speak | Voices the gate question and reads results aloud (TTS); hears the goal and the yes/no answer (STT) | Deepgram (Aura + Nova) |
| Gate | Pauses at any costly/irreversible step and refuses to proceed without an explicit human "yes" | dispatch state machine |
| Observe | Captures every effector failure and records what the human approved at each gate | Sentry |
Two design rules hold the whole thing together:
- The Plan is a first-class, serializable object — the frontend renders it directly, so you watch the agent's reasoning as live data.
- Effectors share one Protocol and are resolved by a registry lookup (never an
if/else), so mock and live backends are interchangeable and a new leg is oneregister()call. Going live is configuration, not a refactor.
The gate is structural, not cosmetic: the browse effector never decides to submit — it only clicks the irreversible button when dispatch hands it the gated step, which dispatch does only after a human yes. Declining halts the rest of the plan, so it can never falsely report success.
Try it out
Prerequisites
- Python 3.11 (conda recommended)
1. Set up the environment
conda env create -f environment.yml
conda activate opendoor
python -m playwright install chromium # for the real browse leg
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python -m playwright install chromium
2. Run it — no API keys needed
python -m frontend.server
Open http://127.0.0.1:8000 and click Plan & run. Out of the box it runs fully offline: a deterministic golden plan, mock effectors, and the browser's built-in voice. To use a real local browser against the bundled mock pharmacy portal (still no key required), set OPENDOOR_BROWSE=real.
3. Go live (optional)
Copy the template and fill in whichever keys you have:
cp .env.example .env
ANTHROPIC_API_KEY=... # live planner (real goal -> real plan)
DEEPGRAM_API_KEY=... # real voice in + out
OPENDOOR_SPEAK=real
BROWSERBASE_API_KEY=... # cloud browser (optional; local needs no key)
BROWSERBASE_PROJECT_ID=...
OPENDOOR_SENTRY=1 # observability (optional)
SENTRY_DSN=...
Restart the server. .env is loaded automatically and is gitignored — keys never get committed. Each leg degrades gracefully: with no key, it falls back to the offline path for that leg.
4. Verify
pytest # 26 offline tests (no keys, no network)
python scripts/healthcheck.py # live end-to-end probe of every leg (needs keys)
Configuration
All optional; set in .env or the environment.
| Variable | Effect |
|---|---|
OPENDOOR_BROWSE | real = local Chromium · cloud = Browserbase · unset = offline mock |
OPENDOOR_HEADED=1 | Show the Chromium window during a run (default headless) |
OPENDOOR_SPEAK=real | Use Deepgram voice (TTS+STT); otherwise the browser's Web Speech |
OPENDOOR_SENTRY=1 | Enable Sentry (requires SENTRY_DSN) |
OPENDOOR_PLANNER_MODEL | Override the planner model (default claude-opus-4-8) |
Project structure
agent/
contracts.py Plan / Step / Risk / Effector / EffectorBackend
planner.py the Claude planner: prompt, defensive JSON parsing, retries
dispatch.py execution loop + the pausable human gate
observability.py Sentry seam (instrument effectors + record gate decisions)
store.py JSON-backed persistence (services, errands, history)
demo.py the golden plan + env-selected effector registry
effectors/
base.py the effector registry (the open seam, in code)
browse.py Playwright/Browserbase web navigation
speak.py Deepgram TTS + STT
mock.py offline mock backends
frontend/
server.py FastAPI host: drives runs, streams state over SSE
index.html the hero UI: live plan, spoken gate, errands, history
portal/
mock_pharmacy.html deterministic test fixture for the browse leg
tests/ 26 tests, all offline
scripts/healthcheck.py
Status & what's next
All four legs are live and verified, with persistence, an urgency-ordered errands queue, a connected-services view, and an in-app action history. The planner already generalizes to new errands (e.g. a DMV renewal); the browse leg is scripted to the demo portal today. The clear next steps are generalizing the browse leg to natural-language navigation of arbitrary real portals, real per-service account connections, and an interactive "clarify" step that collects missing details mid-plan.
Built for the AI Hackathon 2026 with Claude, Deepgram, Browserbase, and Sentry.
Analysis
View
Metric
- 5
- 1
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- AnthropicIn code
- FastAPIIn code
- HTMLIn code
- PythonIn code
4 of 4 appear in the indexed code.
AI coding agents
- Claude CodeCommits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
157 KB
Source files
26
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
Jeffrey-Le/open-door
31 files · 217 KB · @ e1e2b02
Structure
Interface
2 files · 6%Screens, components and styles rendered to the user.
Application logic
13 files · 42%Domain rules, services and shared utilities.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- Python59%
- HTML27%
- Markdown12%
- YAML1%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
requirements.txt
pypi · 11- anthropic
- browserbase
- deepgram-sdk
- fastapi
- httpx
- jinja2
- playwright
- pytest
- python-multipart
- sentry-sdk
- uvicorn[standard]
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.