Local-first voice AI for OpenMRS encounters.
OpenMRS LiveKit is a hackathon prototype for privacy-preserving clinical translation and encounter draft generation. It runs beside OpenMRS on clinic hardware, routes audio through LiveKit, transcribes each turn locally, redacts PHI-like values, translates clinician-patient speech, and builds clinician-reviewed OpenMRS draft observations.
It is not a medical device, not a diagnosis engine, and not an autonomous scribe. The system never writes clinical data to OpenMRS without clinician review.
- Captures a clinical conversation through a local LiveKit room.
- Supports local or provider-backed STT, translation, LLM extraction, and TTS.
- Redacts PHI-like values before transcript persistence or cloud AI calls.
- Translates clinical speech while preserving negation, uncertainty, medications, dosages, and redaction placeholders.
- Extracts candidate OpenMRS facts with evidence, confidence, speaker, timestamp, and review status.
- Generates OpenMRS-style draft encounter payloads from approved facts only.
- Keeps incomplete or low-confidence items in a review queue.
Many OpenMRS deployments operate in clinics with unreliable internet, limited staffing, and language or health-literacy barriers between clinicians and patients. Cloud-only AI is a poor fit when PHI cannot leave the facility or when connectivity is unreliable.
This project focuses on a narrow, reusable pattern:
LiveKit voice capture
-> local STT
-> PHI redaction
-> clinical translation
-> evidence-backed facts
-> clinician review
-> OpenMRS draft payload
This repo contains the LiveKit voice agent and OpenMRS-safe clinical processing primitives.
The companion OpenMRS O3 frontend lives at:
https://github.com/sihsalus/openmrs-esm-livekit
Together they provide the full demo flow: OpenMRS patient chart, LiveKit room launch, local AI workflow, privacy status, and clinician-reviewed draft UI.
Clinician / patient audio
|
v
Local LiveKit room
|
v
Local or provider STT
faster-whisper / OpenAI / Deepgram
|
v
De-identification gateway
|
+------------------------------+
| |
v v
Patient-facing translation Clinical fact extraction
configured LLM / rules configured LLM + tools
| |
v v
Local or provider TTS EncounterDraft
Piper / OpenAI / other providers review queue
| |
v v
Patient hears response OpenMRS draft payload
after clinician approval
The intended deployment is a standalone local service or container running next to OpenMRS.
OpenMRS interaction is through REST or FHIR endpoints:
- read patient, visit, encounter type, location, provider, form, and concept metadata;
- build local draft encounter and obs payloads;
- submit only clinician-approved observations;
- keep the demo path synthetic and read-only by default.
The current prototype includes an OpenMRS-style payload builder that only emits approved facts and keeps the rest in a review bundle.
The project is designed to be offline-capable, but model providers are configuration-driven.
Default development configuration:
- LLM provider:
openai - Foundation model:
gpt-4.1-minithroughOPENAI_MODEL - STT provider:
deepgramby default, oropenai/whisper - TTS provider:
openaiby default, orpiper/ other configured providers
Recommended local-first demo configuration:
- Audio routing: local LiveKit server.
- STT:
whisperprovider, backed byfaster-whisper, with language-specific clinical prompts and VAD filtering. - TTS:
piperfor local CPU voice output, selecting a configured English or Spanish voice from room metadata. - LLM / structured extraction:
ollamaprovider, defaulting toqwen3:8bthroughOLLAMA_MODEL. A site can switch to another local model, such as a clinically tuned model, by changingOLLAMA_MODEL. - Structured output: tool calls, schema-shaped draft objects, and local OpenMRS payload generation.
Minimum reliable clinic target:
- modern 8-core CPU;
- 16 GB RAM recommended;
- 20 GB free disk for models and runtime artifacts;
- no GPU required.
A lighter profile can run on an Intel i5-class mini PC or laptop with 8 GB RAM using Vosk, Piper, and a small quantized parser model.
- LiveKit agent foundation for OpenMRS encounter workflows.
- Cloud-safe clinical translation prompt with deterministic PHI placeholders.
- Local de-identification for emails, phone numbers, document IDs, dates, UUIDs, and known entities.
- Reviewable clinical facts with confidence, evidence, speaker, and status.
- OpenMRS-style encounter draft payloads generated only from approved facts.
- Transcript persistence disabled by default, with redaction before any optional save.
- Hackathon submission materials in
docs/.
- Human-in-the-loop by default.
- No automatic diagnosis.
- No autonomous prescribing or ordering.
- No automatic OpenMRS writes.
- No production PHI in demos.
- Transcript persistence disabled by default.
- Raw transcript storage requires explicit configuration.
- External AI services should receive only synthetic, redacted, or contractually protected data. The target deployment avoids external AI APIs entirely.
See docs/security-model.md for the detailed privacy and production-hardening model.
src/
agent.py LiveKit agent entrypoint
session.py AgentSession lifecycle and prompt setup
clinical_translation.py Cloud-safe/local-safe translation prompt helpers
deidentification.py Deterministic PHI-like redaction helpers
clinical_facts.py Reviewable clinical fact primitives
openmrs_payload.py OpenMRS-style draft payload builder
transcript.py Optional transcript persistence with redaction
docs/
assets/
hackathon-dossier.md
submission-form-fields.md
demo-script.md
security-model.md
proposal-positioning.md
tests/
test_backend_client.py
test_clinical_facts.py
test_config.py
test_deidentification.py
test_inworld_integration.py
test_local_providers.py
test_openmrs_payload.py
test_openmrs_tools.py
test_providers_mistral.py
test_session.py
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env
pytestUseful checks before opening a PR:
ruff check src/ tests/
ruff format --check src/ tests/
mypy src/ --ignore-missing-imports
pytest --tb=short -q --cov=src --cov-report=term-missingUse demo or test credentials only.
LIVEKIT_URL=ws://localhost:7880
LIVEKIT_API_KEY=devkey
LIVEKIT_API_SECRET=secret
STT_PROVIDER=whisper
TTS_PROVIDER=piper
LLM_PROVIDER=ollama
ENABLE_TRANSCRIPT_SAVE=false
TRANSCRIPT_REDACTION_ENABLED=true
TRANSCRIPT_RAW_STORAGE_ALLOWED=falseThe local provider path uses faster-whisper, Piper TTS, and an Ollama-hosted
OpenAI-compatible LLM. The model is not hardcoded into the application; it is
selected through LLM_PROVIDER and provider-specific model variables.
The agent does not require one fixed foundation model.
Current defaults:
LLM_PROVIDER=openai
OPENAI_MODEL=gpt-4.1-miniFor the local/offline hackathon path:
LLM_PROVIDER=ollama
OLLAMA_MODEL=qwen3:8bThe base system prompt is written in Spanish because the current target demo needs Spanish clinical robustness in a Latin American OpenMRS setting. Runtime language defaults are still English unless the room metadata says OpenMRS is using Spanish. Each LiveKit room can carry normalized language metadata:
{
"doctorLanguage": "es",
"patientLanguage": "en",
"agentVoiceLanguage": "es",
"speakerAttributionMode": "source-role",
"defaultHumanRole": "doctor",
"languageMode": "bilingual",
"agentProviderOverrides": {
"sttProvider": "deepgram",
"ttsProvider": "inworld",
"deepgramModel": "nova-3",
"deepgramEnableDiarization": true,
"deepgramUseFlux": false,
"inworldModel": "inworld-tts-2"
}
}The agent uses doctorLanguage for STT language hints and clinician-facing
input, patientLanguage for patient-facing translation context, and
agentVoiceLanguage for the initial greeting, assistant transcript labels, TTS
language hints, and Piper model selection. Local Whisper uses a clinical initial
prompt aligned with the configured STT language.
If room metadata is missing, the agent falls back to English for clinician,
patient, and agent voice language. A Spanish OpenMRS locale should send
doctorLanguage=es, patientLanguage=es, and usually agentVoiceLanguage=es.
Room metadata can also override the STT/TTS provider before a new
AgentSession is created. Supported room-scoped overrides are
sttProvider=whisper|deepgram, ttsProvider=piper|inworld, deepgramModel,
deepgramEnableDiarization, deepgramUseFlux, and inworldModel. Secrets are
never read from room metadata; sttProvider=deepgram is ignored unless
DEEPGRAM_API_KEY is configured, and ttsProvider=inworld is ignored unless
INWORLD_API_KEY and INWORLD_VOICE_ID are configured.
Speaker attribution is explicit. When the STT provider emits speaker_id
(for example Deepgram Nova with DEEPGRAM_ENABLE_DIARIZATION=true), the agent
maps that speaker id to doctor or patient using speakerRoleMap when
provided, or a conservative dynamic map where the first speaker is
defaultHumanRole and the second distinct speaker is the other human role. If
no speaker_id is present, the transcript payload remains honest and marks
attributionSource=missing-speaker-id; it does not claim acoustic diarization.
Piper TTS is model-file driven. The agent can select a Piper model per room before the LiveKit session is created:
PIPER_MODEL_PATH_ES=/srv/piper/voices/es_MX-claude-high.onnx
PIPER_MODEL_PATH_EN=/srv/piper/voices/en_US-lessac-medium.onnx
PIPER_SPEAKER_ID_EN=
PIPER_SPEAKER_ID_ES=PIPER_MODEL_PATH is still supported as a legacy language-agnostic fallback,
but new deployments should prefer PIPER_MODEL_PATH_EN and
PIPER_MODEL_PATH_ES. If the requested language-specific model is missing, the
agent logs the actual fallback source, for example
piper_voice_source=piper_model_path_es_fallback. The CPU deployment image is
expected to include both the Spanish and English Piper models and should set
PIPER_MODEL_PATH_EN to the English model path.
A site can override the full session instructions through LiveKit room metadata
(agent_prompt) or future site configuration. Code, comments, tests, and public
PR descriptions remain in English.
Recommended short description:
OpenMRS LiveKit is a fully local clinical interpreter and encounter compiler. It runs voice capture, transcription, translation, and structured extraction on clinic hardware, de-identifies text before model inference, and produces clinician-reviewed OpenMRS draft observations without sending PHI to cloud AI services.
Target track: Clinical Track.
Distribution model: fully open source.
License: MIT.
Working prototype for the OpenMRS AI Hackathon 2026. The repository contains the LiveKit agent foundation and the first OpenMRS-specific safety primitives. It still needs production hardening, a review UI, site-specific concept mapping, and validated local model packaging before clinical use.
MIT.