Project Info
Inspiration
When I was FaceTiming my friend who's working as an E.M.T., he mentioned how chaotic a paramedic's job can get. When he told me this, the first thing that came to mind was not 'AI assistant in a hackathon,' but when brainstorming for this event, I quickly realized how AI could be helpful in such medical situations where every second is critical and every piece of information needs to be perfect. This is why we created Nos.
What it does
Nos listens to the paramedic and to the patient when they can speak. It builds a live, structured picture of the case as it happens. It tracks what's been said and done, automatically identifies medications / other objects from vials or labels held up to the camera, and runs a safety check in the background that catches what would otherwise slip through: a symptom mentioned once and never followed up on, a medication about to be given that interacts with something the patient's already on. It works even when the patient is unconscious or can't speak for themselves, since it never depends on them as the only source of truth. The moment the doors open at the ER, it generates a structured handoff report from everything captured along the way.
How we built it
We split the system into three coordinated layers connected through an event bus, so each piece could be built in parallel without blocking the others. A voice layer transcribes the paramedic-patient conversation in real time. An agent layer extracts structured medical facts, looks for relevant information on the internet, builds the timeline, and runs continuous safety checks, including flagging unfollowed-up symptoms and known medication interactions. A vision layer runs Claude's vision API against a live camera feed, using motion-and-stillness detection to capture frames automatically when something, e.g. a vial or a medical bracelet, is held steady in view, without requiring the paramedic to do anything by hand. Identified items are cross-referenced against the patient's known medications before anything is administered. Everything converges into a single handoff report at the moment of arrival. We treated privacy as a principal design constraint: raw audio and video are processed in memory and never written to disk or persistent storage. The only data retained is the structured visit record itself (timeline, medications, flags), which is what the handoff report is built from, kept to the minimum necessary for continuity of care. A database of past handoffs is kept for a first responder or medical care provider to access later, with options to delete any handoff and automatically deleting after two weeks. While we've taken steps to address privacy, we believe persistent visit data would possibly need encryption at rest and role-based access controls before real deployment in order to respect a patient's privacy as much as possible.
Challenges we ran into
Tuning the vision pipeline's capture trigger so it fires reliably on a held-up vial without flooding the system with redundant calls on every frame. We allow the user to capture whenever they think is relevant. Keeping the safety agent anchored to real, verifiable gaps (a stated symptom with no follow-up, a known drug interaction) instead of drifting into vague or unfounded clinical judgment. Previously, Nos would alert the user if a patient stated that they were "old," which is something to keep note of but not necessarily a "concern" immediately. Figuring out how to account for unconscious or unresponsive patients. Thankfully, we designed a system where the transcription can recognize different speakers, but this doesn't affect the information that gets passed to the handoff. Building privacy into the architecture itself. We had difficulty deciding what never gets persisted and what gets shown. This is probably the challenge that we were least expecting to deal with, but arguably it's the most interesting problem for us.
Accomplishments we're proud of
A multimodal pipeline that includes voice, vision, and structured reasoning. These all feed into one coherent report rather than three disconnected demos. We designed a safety agent that catches real, demonstrable gaps live, anchored to actual transcript and vision content rather than vague heuristics. We've created a privacy policy we can actually defend: by design, no persistent raw audio or video and a push for confidentiality when handling patient data in databases or third party apps.
What we learned
Specialized agents beat one big prompt. Splitting extraction, timeline-building, safety-checking, and handoff generation into separate agents made each one easier to reason about and debug, even though it meant more coordination overhead through the event bus. Multimodal inputs need to actually align with each other. The vision and transcript pipelines only became useful once we cross-referenced them. A vial identified by the camera matters because it's checked against what was said, not as a standalone fact. Privacy is a policy that has to be decided before building. Choices like never writing raw audio/video to disk only work if they're baked into the pipeline from the start. Realizing this after the architecture is set is much harder than designing for it from the first hour. The line between "assisting a first responder" and "replacing their judgment" is surprisingly thin. We had to actively rework early ideas (like flagging based on a patient's age alone) that sounded helpful but were really the system making a clinical call it had no real basis for.
What's next
for Nos: Ambulance Assistant Our primary goal is to move more of the pipeline to fully local, on-device models so nothing leaves the vehicle at all. We experimented with this during the hackathon by hosting some of our agents locally and see it as the clear production direction, particularly for the vision component, which currently uses Claude's hosted VLM API for accuracy. For any remaining third-party model usage, production deployment would require formal data agreements, including but not limited to a signed BAA and a no-training guarantee, which is a real legal commitment we haven't pursued at hackathon scale, but is non-negotiable before Nos could be used with real patient data. We'd also want tighter integration with real EHR systems, and more rigorous validation of the safety agent's flagging accuracy against real EMS protocols rather than our own judgment and what we thought was accurate.
ER Copilot
Real-time AI clinical operations assistant — Berkeley AI Hackathon.
Quick start
Option 1 — Docker Compose (recommended)
Start all services with a single command:
cp .env.example .env # add API keys (all optional — heuristics work offline)
docker compose up --build
This launches:
| Service | Port |
|---|---|
| Next.js frontend | 3000 |
| FastAPI backend | 8000 |
| Redis | 6379 |
Open http://localhost:3000 → click Demo → watch all agents work → Generate Handoff Report.
Option 2 — Manual setup
Two terminals required — Python backend + Next.js frontend.
Terminal 1 — Python backend:
cd backend
pip install -r requirements.txt
cp ../.env.example ../.env # add API keys (all optional — heuristics work offline)
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
Terminal 2 — Next.js frontend:
npm install
npm run dev
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Browser (Next.js frontend — TypeScript/React, port 3000) │
└──────────────────────┬──────────────────────────────────────┘
│ /api/* (proxied via next.config.ts)
┌──────────────────────▼──────────────────────────────────────┐
│ Python FastAPI backend (port 8000) │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ Event Bus │ │ 6 Agents │ │ SSE Hub │ │
│ │ (Redis or │───▶│ extraction │───▶│ /api/events │ │
│ │ in-memory) │ │ timeline │ └───────────────┘ │
│ └─────────────┘ │ safety │ │
│ │ docs │ ┌───────────────┐ │
│ ┌─────────────┐ │ research │ │ State Store │ │
│ │ Claude │───▶│ handoff │───▶│ (Redis or │ │
│ │ (optional) │ └──────────────┘ │ in-memory) │ │
│ └─────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────────┘
- Backend: Python 3.11+ · FastAPI · asyncio
- Event bus: Redis pub/sub (in-memory fallback)
- Real-time UI: Server-Sent Events (
/api/events) - 6 agents: extraction, timeline, safety, documentation, research, handoff
- Demo Mode: replays
scripts/demo-scenario.json - Live Mode: browser mic via Web Speech API →
/api/transcript
Project structure
backend/ # Python FastAPI backend (replaces lib/ + app/api/)
main.py # FastAPI app entry point
events.py # Shared event dataclasses
bus.py # Event bus (Redis or in-memory)
claude.py # Anthropic Claude wrapper
debounce.py # Async debounce utility
redis_layer/ # Redis client, keys, state persistence
sse/ # SSE fan-out hub
agents/ # 6 async agents
prompts/ # Claude prompts + heuristic fallbacks
demo/ # Demo scenario replay
routes/ # FastAPI route handlers
Dockerfile # Backend container image
app/ # Next.js frontend (UI only)
page.tsx # Main dashboard
layout.tsx
components/ # React UI panels
hooks/ # useEncounterEvents (SSE client)
scripts/
demo-scenario.json # Demo encounter dialogue script
Dockerfile # Frontend container image
docker-compose.yml # Orchestrate frontend, backend & Redis
Scripts
| Command | Description |
|---|---|
docker compose up --build | Start all services (frontend dev, backend, Redis) |
docker compose -f docker-compose.prod.yml up --build | Production images + external Redis from .env |
docker compose down | Stop all services |
npm run dev | Start Next.js frontend (port 3000) |
npm run typecheck | TypeScript check |
uvicorn main:app --reload | Start Python backend (run from backend/) |
API keys
All optional for demo. Without keys, heuristic fallbacks produce a working demo.
| Key | Enables |
|---|---|
ANTHROPIC_API_KEY | Claude-powered extraction, SOAP, handoff |
DEEPGRAM_API_KEY | Deepgram STT (Live mode uses Web Speech API without it) |
REDIS_URL | Persistent state + multi-instance pub/sub |
BROWSERBASE_API_KEY | Live web research (mock citations without it) |
Docs
- Deployment guide — Railway, Docker production, env vars
- Backend README
- Teammate 1 — Platform & Pipeline
- Teammate 2 — Agents, UI & Demo
- Product plan
Analysis
View
Metric
- 28
- 13
- 6
- 6
- 4
- 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
- CSSIn code
- FastAPIIn code
- Next.jsIn code
- PythonIn code
- ReactIn code
- Tailwind CSSIn code
- TypeScriptIn code
- DockerClaimed
- RedisClaimed
8 of 10 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- Claude CodeConfig · Commits
- CursorCommits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
451 KB
Source files
84
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
JacobChan182/Berkeley-AI-Hackathon
99 files · 708 KB · @ 7f9e28a
Structure
Interface
19 files · 19%Screens, components and styles rendered to the user.
API & routing
3 files · 3%Request entry points: routes, handlers and controllers.
Application logic
42 files · 42%Domain rules, services and shared utilities.
+5 more
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
- Python43%
- Markdown29%
- TypeScript27%
- CSS1%
- Shell0%
- YAML0%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
package.json
npm · 18- @anthropic-ai/sdk
- @deepgram/sdk
- ioredis
- next
- react
- react-dom
- ws
- +11 more
backend/requirements.txt
pypi · 7- anthropic
- fastapi
- httpx
- playwright
- python-dotenv
- redis[asyncio]
- 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.