Project Info
Inspiration
Millions of older adults live alone, and the scariest moments — a fall, a stroke, choking, wandering at night — often happen with no one around to notice. Existing medical-alert devices rely on the person pressing a button, which fails exactly when they can't. But the opposite extreme — a camera feed or an app that pings family every time grandpa drops a spoon — gets muted within a week. We wanted a companion that quietly watches for trouble, checks in like a caring human would, and reaches a real person only when it actually matters — without turning someone's home into a 24/7 surveillance feed.
What it does
QuietCare is an always-on elderly-safety companion built around one idea: stay silent through the noise of daily life, and speak up only in a real emergency. "Your phone doesn't blow up every time grandpa drops a spoon — only when something's actually wrong." A phone on a lanyard runs cheap on-device sensing (accelerometer + a rolling audio buffer) and, when something looks wrong, streams a short event to the cloud over a WebSocket. Two cooperating Claude agents take over: elder-agent reasons about the event, runs a gentle spoken check-in ("Margaret, are you okay?"), and fuses the signals — trigger type, what it hears back, whether they responded at all, and non-speech sounds like a thud or a scream — into a decision to resolve or escalate. caretaker-agent picks up escalations over a message bus and alerts the human caretaker via SMS or a voice call, and can even handle everyday errands like a prescription refill, or answer a casual "how's mom today?" text. The experience is deliberately lopsided: the elder is asked nothing and the caretaker hears nothing — until the one moment that counts. It handles falls, inactivity (a possible silent emergency like a stroke), and geofence breaches (wandering), with higher urgency at night.
How we built it
Client: Expo / React Native (TypeScript) with expo-sensors for fall detection, a rolling on-device audio buffer, a single front-camera snapshot on trigger, and a resilient auto-reconnecting WebSocket. Backend: Python + FastAPI exposing a WebSocket (/ws) and /health. Two Claude agents run a provider-agnostic tool-use loop. Services: Claude (reasoning, via the PaleBlueDot router), Deepgram (STT/TTS), Twilio (SMS/voice), BAND (agent message bus), Browserbase (cloud browser for errands), Redis (memory), Sentry (monitoring). Safety core: an explicit escalation state machine enforces invariants — the LLM decides what to do, but the code decides what's allowed. Mock-by-default: every provider falls back to a deterministic mock when its API key is absent, so the whole loop runs end-to-end with zero credentials.
Challenges we ran into
Avoiding both false alarms and missed emergencies. An unanswered check-in could mean "they're fine and walked away" or "they're unconscious." We solved this by fusing multiple signals — trigger source, transcript, silence, and acoustic distress tags — rather than trusting any one. Silence after a fall became one of our strongest signals, since the worst emergencies are exactly the ones where the person can't speak. Letting an AI act without letting it act dangerously. We separated decision-making (the LLM) from enforcement (a deterministic state machine), and hard-gated 911 behind explicit human confirmation. Always-on without being invasive. We buffer audio on-device and only send the seconds before a trigger, never a continuous stream. Demoability. Building real telephony, STT, and agents that also run fully mocked with no keys took careful interface design.
Accomplishments we're proud of
A genuine two-agent system that cooperates over a real message bus — one agent that knows the elder, one that represents the family. 911 is unreachable without a human — a safety guarantee enforced in code, not just a prompt. Dignity-first design: a gentle check-in before any alarm, privacy by architecture, and a device that asks the elder to learn nothing. Runs end-to-end with zero credentials thanks to mock fallbacks.
What we learned
For high-stakes AI, the most important code is the part that constrains the model, not the part that prompts it. Multi-signal fusion beats any single sensor for safety decisions. Privacy is an architecture choice — buffer vs. upload, keys server-side, no raw media in telemetry — not a checkbox.
What's next
for QuietCare Real on-device fall-detection ML (CNN-LSTM on SisFall) to replace the threshold heuristic. A richer caretaker dashboard with wellness trends and incident history. Medication reminders and adherence tracking to make it useful every day, not just in emergencies. Native Apple Watch fall-API integration and on-device speech to cut cloud dependence further.
Quietcare
An ambient AI safety companion for elderly care. Cal Hacks 2026 · June 20–21
"Your phone doesn't blow up every time grandpa drops a spoon — only when something is actually wrong."
Elderly people living alone face a dangerous gap: when something goes wrong — a fall, a stroke, choking, sudden confusion — help often arrives far too late. Quietcare watches ambiently, runs a calm spoken check-in when something looks off, and loops in the right person fast, without false alarms.
How it works
A phone app watches motion + audio cheaply on-device. It continuously streams
short audio segments as audio_probe frames — the backend tags the YAMNet
audio scene and watches for a wake signal — and the elder can hold to talk
to send a voice_conversation clip that the backend transcribes, answers with
the conversation agent, and speaks back. When something looks wrong it streams a
trigger event over the same WebSocket. The backend then runs two cooperating
Claude agents:
- elder-agent — reasons about the event, runs a spoken voice check-in, fuses the signals (trigger source + transcript + whether the elder responded + any non-speech acoustic distress), and decides to resolve or escalate.
- caretaker-agent — triages an escalation off the message bus and alerts the human caretaker via SMS / voice call, and can request human-authorized 911.
phone (client) cloud (server) humans
┌──────────────┐ WS /ws ┌───────────────┐ BAND bus ┌────────────────┐
│ fall detect │ ───────► │ elder-agent │ ──@mention─►│ caretaker-agent│
│ audio buffer │ trigger │ (Claude) │ │ (Claude) │
│ check-in I/O │ ◄─────── │ voice + ML │ │ Twilio SMS/call│
└──────────────┘ speak/ └───────────────┘ └───────┬────────┘
listen │ gated
▼
human-authorized 911
Everything runs end-to-end with zero credentials — every external provider sits behind an interface with an automatic mock fallback.
Repository layout
| Path | What's there |
|---|---|
server/ | FastAPI backend, the two Claude agents, all providers, escalation FSM. |
client/ | Expo (React Native) device app: on-device fall detection, rolling audio buffer, check-in I/O, camera snapshot. |
server/app/band_mesh/ | Standalone BAND agent daemons (elder + caretaker) for the full @mention mesh. |
shared/protocol.md | The WebSocket protocol v1 contract shared by client + server. |
PROJECT.md | Full project brief, pitch notes, and sponsor rationale. |
design-videos/ | UI mocks + walkthrough recordings. |
Quickstart
Backend (all-mock, no keys)
cd server
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # all keys may stay blank
# terminal 1 — run the server
uvicorn app.main:app --host 0.0.0.0 --port 8080
# terminal 2 — drive the full loop
python mock/send_trigger.py --scenario emergency # -> escalation + caretaker alert
python mock/send_trigger.py --scenario fine # -> resolves silently
GET http://localhost:8080/health reports which provider impls are active
(mock vs real).
Client (device app)
See client/README.md for the Expo dev-build + Android
install steps. The client holds no API keys and talks to the backend purely
over the WebSocket contract.
Safety model
The LLM decides transitions (via which tools it calls); the code enforces them and the hard invariants:
- 911 is never reachable without explicit human confirmation.
escalate_911is gated instate_machine.gate_911(human_confirmed=…), re-sanctioned by a policy gate, and dispatch only fires on a token-verified human approval. - Every escalation passes through a check-in first, unless the trigger is an unambiguous hard fall.
- Agents never autonomously dial emergency services — they can only request human authorization.
idle -> triggered -> checking_in -> (resolved | escalating)
\-> escalating (only if hard_fall)
escalating -> caretaker_notified -> (human_ack | 911_gated)
Sponsor / integration stack
Every integration is wired behind an interface with an automatic mock fallback.
| Provider | Layer | Role |
|---|---|---|
| PaleBlueDot (TokenRouter) | Inference | Anthropic-compatible gateway serving Claude; direct Anthropic is the fallback. |
| BAND | Inter-agent bus | Carries escalations between the elder- and caretaker-agents; powers the full @mention mesh. |
| Deepgram | Voice I/O | Real STT (nova-2) + TTS (aura-asteria-en) for the spoken check-in. |
| YAMNet (TFLite) | Audio-scene ML | Non-speech distress tagging (thud / scream / glass) fused into the decision. |
| Redis | Memory | Elder profile, meds, history, recent events. |
| Twilio | Emergency channel | Real SMS / voice calls to the caretaker + gated 911 dispatch + inbound "how's mom?" recap. |
| Browserbase | Everyday-care | Off-critical-path automation (e.g. medication refill) via a cloud browser. |
| Arize AX | Evals / tracing | OpenTelemetry tracing of the agent tool-use loop and every Claude call. |
| ArmorIQ | Security posture | MCP-endpoint vulnerability scanning (SAFE-MCP). |
| Sentry | Monitoring | Error/perf monitoring on backend + client. |
Secrets live only in
server/.env/client/.env(gitignored) and the BAND daemonagent_config.yaml. Never commit keys. Seeserver/.env.examplefor the full list.
Verification scripts
The backend ships live diagnostics under server/scripts/:
check_keys.py/check_remaining_sponsors.py— live connectivity for every provider.verify_audio.py/verify_yamnet.py— Deepgram STT↔TTS round-trip + YAMNet classification.verify_app_hook.py/mesh_demo_kickoff.py— drive the app→elder→caretaker BAND mesh end-to-end.verify_emergency_call.py— places a real gated emergency-dispatch call (to a number you control).verify_observability.py/probe_armoriq.py— Arize tracing + ArmorIQ security-scan checks.fake_phone.py— simulates the phone over the WebSocket, sending a real spoken clip through thevoice_conversationSTT→agent→TTS loop.fetch_yamnet.py— downloads the YAMNet model intoserver/models/.
Run the test suite with python -m unittest discover -s tests from server/.
Analysis
View
Metric
- 43
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
- FastAPIIn code
- JavaScriptIn code
- PythonIn code
- ReactIn code
- TypeScriptIn code
- AnthropicClaimed
5 of 6 appear in the indexed code. 1 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
No AI coding agent signals were found in this repository.
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
604 KB
Source files
123
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
SashaSkind/Quietcare
190 files · 20.3 MB · @ 71d178d
Structure
Interface
8 files · 4%Screens, components and styles rendered to the user.
API & routing
38 files · 20%Request entry points: routes, handlers and controllers.
Application logic
30 files · 16%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
- Python52%
- TypeScript35%
- Markdown11%
- JavaScript2%
- YAML0%
- Shell0%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
client/package.json
npm · 26- @sentry/react-native
- babel-preset-expo
- expo
- expo-asset
- expo-av
- expo-camera
- expo-dev-client
- expo-file-system
- expo-location
- expo-sensors
- expo-speech
- expo-status-bar
- react
- react-dom
- react-native
- react-native-fast-tflite
- react-native-web
- +9 more
server/requirements.txt
pypi · 6- fastapi
- pydantic
- pydantic-settings
- python-dotenv
- python-multipart
- uvicorn[standard]
client/mock/package.json
npm · 1- ws
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.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.