< return to vault
DETAILS·PROJ.SAHAY / 05·experimental
> source: github.com/advay-sinha/SAHAY-AI

SAHAY-AI

Lets a language model phrase a distressed caller's intake without ever letting it decide what to ask, what to score, or whether to escalate.

project overview

SAHAY-AI receives a victim's first contact by voice or text, runs a strictly bounded intake conversation, and builds a structured case profile with a Stress Vulnerability Index (SVI) and per-claim evidence for a human helpline executive. The victim gets a status timeline and never has to retell their account at the next stage. It is an intake instrument, not a chatbot or counsellor: a deterministic state machine picks the intent, a language model may only phrase it, a validator checks the sentence before it is spoken, and pre-written text is used if validation fails. It is a prototype — no clinical validity is claimed and SVI weights are provisional pending expert calibration.

architecture

The Expo victim app and the React + Vite executive console both connect to a FastAPI gateway over WebSockets and REST, behind a consent gate, JWT auth with roles, and server-side role-filtered fan-out. Each turn splits into two paths. The reply path, budgeted under 3 s, runs the crisis pre-check → dialogue state machine (S0–S9, with an unconditional crisis interrupt SX and human handoff SH) → optional LLM phrasing → output validator → text-to-speech. A parallel assessment path that never blocks a reply runs detectors, classifiers and acoustics → svi.compute → alerts → recommendations, and only executive clients receive its events. Speech runs on a loopback-only Whisper Small service behind Silero VAD, so victim audio never leaves the deployment. The safety-critical modules — dialogue.next, guardrails.validate and svi.compute — are pure standard-library functions with no I/O, and every provider (ASR, TTS, LLM, storage, retrieval, assessment runner) sits behind an adapter with a working mock. State lives in Supabase PostgreSQL through SQLAlchemy and Alembic, and AI recommendations and human decisions are stored in separate tables so no record can read as though a machine decided.

VOICE · CHATCRISIS CHECKSTATE MACHINEVALIDATORHUMAN EXECparallel path: detectors → svi → alerts

constraints

  • the assistant never speaks freely — every sentence is an approved intent, validated before synthesis, with written fallbacks in Hindi and English so the dialogue runs with the LLM disabled
  • assessment data never reaches the victim — no score, band, emotion or alert in the victim app, enforced server-side and asserted by tests on both ends
  • a human decides everything — every recommended action needs explicit executive confirmation
  • privacy — speech, acoustics and classifiers are self-hosted; victim audio stays on the machine
  • latency — victim stops speaking to assistant starts must stay under 3 s

tradeoffs

  • a deterministic, weighted 9-dimension SVI over a learned severity model: fully explainable and testable, with hard overrides (confirmed danger or crisis forces Critical) beating the weighted sum
  • abstention as a valid output: aggregate confidence below 0.45, poor audio or low language confidence returns needs_human and no score at all
  • trained models in shadow over in the loop: MuRIL text affect, speech-emotion heads and a MuRIL safety detector are shown beside the rules but never route, score or speak
  • a small MVP profile — local background runner instead of Redis/RQ, local keyword retrieval instead of pgvector — with FastAPI as the only database gateway

failure notes

  • the shadow MuRIL detector reaches 0.99 AUROC on Reddit crisis text but only 0.56–0.62 micro F1 on SAHAY's own fixtures against the rules' 0.93 / 0.88, and fires on harmless absence wording — so it is rejected for product integration
  • all safety numbers are development-fixture regression evidence: the locked evaluation set has 0 samples, so nothing is claimed as generalisation
  • the fixed S0, S9, SX and SH scripts must be human-written, reviewed and recorded; until then the code fails closed rather than generating them
  • Hindi word error rate and latency on a real phone over Wi-Fi are still unmeasured — stated, not hidden

infrastructure

fastapi · websockets · postgresql (supabase) · sqlalchemy · react + vite console · expo mobile app · whisper small · silero vad · pytorch · muril (shadow)

engineering reasoning

Safety is architectural rather than procedural: the crisis interrupt is a synchronous pre-check that runs before dialogue policy, no model decides whether to escalate, and a contract-mirror test fails the build if the event allowlists, SVI weights, band thresholds or abstention floor drift between the spec, backend, ML code and console. On development fixtures the rules miss 0 of 17 critical events, the crisis pre-check finds 9 of 9 cases, red-team prompts are blocked 39 of 39 before synthesis, and a server-side voice turn takes 581 ms at p95.

future work

  • > an independent locked evaluation set and blind corpus
  • > expert calibration of the SVI weights
  • > speech-emotion gating on team recordings in Hindi and English
< return to vaultEND OF RECORD · PROJ.SAHAY / 05