Overview
In a crisis, people don't fill in forms. They talk, fast and often scared, and responders need a location and an urgency, not a transcript.
So the reporter's side is a conversation and the responder's side is structured data. The model sits in between and turns one into the other while the person is still talking.

How it works
The server owns the conversation
Raw 16 kHz microphone audio goes from a React AudioWorklet over a WebSocket to FastAPI, which holds the Gemini Live session. The API key and conversation state never touch the browser.
You can cut it off mid-sentence
Voice activity detection runs on the server; when the caller interrupts, the browser immediately drops queued playback.
A retried call can't file an emergency twice
Gemini calls a
submit_responder_reporttool that's idempotent within a session and writes through the same SQLite pipeline as typed reports.It never pretends to be an emergency service
The prompt follows psychological-first-aid priorities, and the assistant doesn't confirm a handoff until the report tool has actually succeeded.
It degrades instead of breaking
Without a Gemini key, typed reports fall back to deterministic triage so the app still works.