Offline-first medical triage and diagnostic translation at the edge β zero cloud, zero network, zero excuses
When disasters strike, communication grids collapse first. Rural health workers are stranded without access to cloud AI tools, unable to match colloquial symptom descriptions ("running stomach", "fire in the chest") to formal clinical protocols ("gastroenteritis", "GERD").
SomaPulse brings clinical intelligence to the edge. It transcribes spoken symptoms using local Whisper.cpp, maps colloquial terms to medical ontologies via SapBERT embeddings, and retrieves matching protocols from a local sqlite-vec database β all in under 120ms with zero internet.
Key Features:
- π€ Edge Speech Ingestion: HTML5 audio β local Whisper.cpp transcription (38ms p50)
- 𧬠SapBERT Semantic Mapping: Aligns colloquial dialect terms to UMLS clinical concepts
- π Protocol Retrieval: Cosine similarity search against pre-seeded medical guidelines
β οΈ Drug Contraindication Warnings: Critical interaction alerts rendered instantly- π 100% Offline: No network, no cloud API, no subscriptions β runs on a $300 laptop
Click to expand all dashboard screenshots
Edge system fully operational: Whisper 16-bit GGML loaded, SapBERT ONNX v1.2 ready, 142 protocols indexed, 1180 MB RAM on i5-8250U. Voice waveform visualizer idle. Quick-access demo queries for Diarrhea, Fever, and Breathing visible below the recorder.
Transcript: "having severe watery stool and cramping for two days". Matched Acute Diarrhea & Dehydration Protocol (Gastroenteritis) at 91.2% similarity in 118ms. Action steps include ORS administration and zinc dosage.
β οΈ Contraindications: Do NOT administer antimotility drugs if bloody stool observed.
Transcript: "tight breathing heavy lung chest whistle sound for three hours". Matched Acute Bronchial Constriction Protocol (Asthma/Bronchospasm) at 85.6% similarity in 102ms. Action steps: sit upright, salbutamol inhaler, monitor respiratory rate.
β οΈ Do NOT use sedatives.
Transcript: "my child has a hot body shaking skin and cannot swallow water we are at a high elevation camp". Matched Severe Hyperpyrexia & Acute Tonsillitis/Meningitis Protocol at 88.7% similarity in 94ms. 5 action steps including HIGH ELEVATION WARNING.
β οΈ Three contraindications including meningitis rule-out and immediate transport.
graph TD
Responder([Field Responder]) <-->|Audio Recording / Web UI| UI[Next.js 16 / React 19 Frontend]
UI <-->|Local API calls| API[Python FastAPI Backend]
API <-->|Speech Stream| Whisper[Whisper.cpp <br/> GGML 16-bit Quantized]
API <-->|Extract Symptoms| ONNX[SapBERT ONNX Runtime <br/> 384-dim Biomedical Embeddings]
API <-->|Vector Distance Query| SQLite[SQLite + sqlite-vec <br/> Cosine Similarity Search]
| Layer | Technology |
|---|---|
| Frontend | Next.js 16 (App Router), React 19, Tailwind CSS v4 |
| Backend | Python 3.12, FastAPI |
| Transcription | Whisper.cpp (16-bit GGML, CPU-optimized) |
| NLP Embeddings | SapBERT (ONNX-runtime, 384-dim biomedical vectors) |
| Vector Search | SQLite + sqlite-vec (cosine similarity) |
Data is persisted in Supabase (PostgreSQL) with Row-Level Security enabled. All tables use the sp_ prefix to namespace within the shared Supabase instance.
erDiagram
sp_triage_results ||--o{ sp_protocol_matches : "produces"
sp_triage_results {
serial id PK
int latency_ms
text transcript
timestamptz created_at
}
sp_protocol_matches {
serial id PK
int triage_result_id FK
int protocol_id
text title
text clinical_term
numeric similarity
jsonb steps
jsonb warnings
}
sp_system_health {
serial id PK
varchar status
varchar network
boolean whisper_loaded
boolean sapbert_loaded
int db_records
int ram_usage_mb
text cpu_model
}
sp_vocabulary_gaps {
serial id PK
text colloquial
text clinical
text umls
}
| Table | Purpose | Rows |
|---|---|---|
sp_triage_results |
Voice triage sessions β transcript text and pipeline latency | 3 |
sp_protocol_matches |
Matched clinical protocols β title, similarity score, action steps, contraindication warnings | 3 |
sp_system_health |
Edge system status β model load state, RAM, CPU, network mode | 1 |
sp_vocabulary_gaps |
SapBERT colloquialβclinical vocabulary mappings with UMLS codes | 5 |
RLS Policy: Anonymous read access enabled on all tables. Write operations require
service_rolekey.
- Node.js β₯ 20
- npm
- Python 3.12 (for backend + benchmark scripts)
git clone https://github.com/edycutjong/somapulse.git
cd somapulse
npm install
cp .env.example .env.local
npm run devpython seed.py # Creates protocols.db with 142 pre-compiled SapBERT protocol vectorspython bench.py # Validates full pipeline meets <200ms target (p50: ~58ms, p95: ~71ms)48 passing tests across 4 test suites β covering mock data integrity, component rendering, interactive triage selection, voice recording state, vocabulary mapping validation, UMLS code format checks, and edge/offline system health branching.
npm test # Run all 48 tests
npm run test:coverage # Coverage report
npm run lint # ESLint
npm run typecheck # TypeScript check
npm run build # Production build
npm run ci # Full CI pipeline (lint + typecheck + test + build)CI runs on Node.js 20, 22, and 24 via GitHub Actions on every push.
devpost-uoe-somapulse/
βββ docs/ # README assets
βββ src/
β βββ app/ # Next.js pages + __tests__/
β βββ lib/ # Mock data & utilities + __tests__/
βββ .github/ # CI workflows
βββ bench.py # Pipeline latency benchmark script
βββ seed.py # Deterministic protocol database seeder
βββ .env.example # Environment template
βββ LICENSE # MIT
βββ README.md # You are here
Pre-Seeded Knowledge: The model runs entirely offline. It cannot answer open-ended medical inquiries outside the pre-seeded protocol indexes. Novel conditions require a new offline sync to expand the local database.
- Next.js 16 β App Router, React Server Components
- React 19 β UI framework
- TypeScript β Type-safe JavaScript
- Tailwind CSS v4 β Utility-first styling
- Python 3.12 β Backend runtime
- FastAPI β Async REST API server
- Whisper.cpp β Offline speech-to-text (GGML)
- SapBERT β Biomedical entity embeddings (ONNX)
- sqlite-vec β Vector similarity search
- SQLite β Embedded local database
- Jest β Testing framework (48 passing tests)
- GitHub Actions β CI/CD pipeline
- Vercel β Frontend deployment
MIT Β© 2026 Edy Cu
Built for UOE Summer of Code 2026. Thank you to the organizers and judges for the opportunity.