Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AgentCare — Maven Specialty Clinic

An agentic AI system for non-clinical patient administration and care coordination: registration → intent detection → department routing → appointment booking → document coordination → confirmation & reminders → follow-up — with a human sitting on every decision and medical decisions kept out of the AI.

Built for the AgentCare Build Challenge 2026. This is not a diagnosis or treatment system. The AI performs administrative routing only; it never diagnoses, prescribes, or replaces a clinician (RULE-5).

Architecture at a glance

Layer Choice
Backend Python + FastAPI
UI Server-rendered Jinja2 templates
Persistence SQLite via SQLAlchemy (on disk — survives restart)
Orchestration LangGraph (Coordinator + specialist nodes)
LLM Groq (llama-3.3-70b-versatile) via langchain-groq

Agents (≥3 genuinely distinct)

  1. Coordinator — plans the request path, delegates, assembles the confirmation from persisted data.
  2. Intake & Routing (conversational) — drives a live chat; on entry it reads the patient's real record and detects one of four scenarios (new / follow-up / reschedule / cancel), maps the stated purpose to a valid department, asks when unclear, flags emergencies. The LLM does the NLU; a deterministic phase machine + DB tools decide the truth (never a fabricated doctor or slot).
  3. Appointment — pulls doctors/slots, checks conflicts, books/reschedules/cancels (always starts PENDING).
  4. Document — classifies uploads into a controlled vocabulary, SHA-256 de-duplicates, maps to patient, routes each report to the department that reads it (ECG → Cardiology, MRI/X-Ray → Orthopaedics) so staff see only reports relevant to their specialty, flags missing required docs.
  5. Safety & Escalation — blocks diagnosis/prescription language; screens every chat turn (self-harm → halt + crisis helplines + staff escalation; abuse/off-topic → redirect; emergency → urge 108 but still offer booking).
  6. Follow-up — reminders, follow-up scheduling, pre-visit lab alerts, notifications.

The LLM is advisory: every appointment is PENDING until dept-scoped staff confirm / redirect / escalate / cancel / reschedule it (the human-approval gate).

State for each run persists in a WorkflowRun row (never an in-memory-only store — RULE-4). Every action appends an AuditEvent.

Full architecture reference: docs/architecture.html — agent roster, the workflow mapped to agents, the data model, and how the build clears every §6 mandatory requirement and §10 disqualifier.

Local setup

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

cp .env.example .env         # then add your GROQ_API_KEY (free: console.groq.com)
python -m app.seed           # load synthetic Bengaluru-clinic data
uvicorn app.main:app --reload

Open http://127.0.0.1:8000. Every login uses OTP 123456. The header has a split Patient Login / Staff Login — and because the two sessions live in separate cookie slots, you can be signed in as a patient and a staff member in the same browser at once.

Demo patients (OTP 123456) — each exercises a different chat scenario:

Patient Phone Scenario
Krishnan +916364842536 Cardiology follow-up; ECG already on file → books straight through
Priya +919000100001 General-medicine follow-up; no prep needed → straight to doctors
Arjun +919000100002 Gastro follow-up; blood test (LFT) missing → agent gates on upload first
Ravi +919000100003 Booked cardiology follow-up, ECG missing → drives the staff pre-visit reminder
Sana +919000100004 Pending new cardiology request → drives the staff confirm queue

Demo staff (OTP 123456, phone +9190000000NN, NN = department index): Cardiology 01 is the richest demo (Sana pending + Ravi pre-visit + Krishnan history); General-Medicine 00, Gastro 06 also have appointments. Admin +919900000099 sees all departments.

No key? The app still boots; agent calls fall back to a deterministic stub (LLM_STUB=1), so the UI and database work offline.

Try the workflow

As the patient:

  1. Open Appointments → a chat starts. Describe your visit in natural language (e.g. "persistent cough and mild fever") → the Intake agent routes you to a department and offers real doctor cards + slot chips. Try "sudden chest pain and can't breathe" to see the emergency flag.
  2. Pick a doctor + slot in the chat → the visit is created PENDING (awaiting staff).
  3. When a follow-up needs a report you don't have (e.g. Arjun's LFT), Lab Results shows a "please upload" prompt. Pick any PDF/PNG named like resting_ecg.pdf → it auto-submits; the Document agent classifies, de-duplicates, and routes it to the reading department.

As the staff (Cardiology — you only see your department): 4. The queue shows new requests to review; the doctor calendar shows free and booked slots (green = confirmed, yellow = pending). 5. Open a request → confirm / reschedule / cancel / redirect to emergency, or schedule a follow-up. The patient is notified (the bell). The appointment view also shows a pre-visit documents panel (on file vs. missing) and any lab reminders raised for the visit.

Every step writes an AuditEvent; the agent reasoning trace is visible to staff only (never on the patient's screen).

Tests

pytest            # 37 tests, all green

The suite (in tests/) covers each layer end-to-end — auth/RBAC, the agent routing + conversational booking, the staff lifecycle, and document handling:

File Tests What it locks down
test_smoke.py 3 health check, home renders, seed populates departments
test_auth.py 6 register→login flow, T&C required, wrong OTP rejected, unauthenticated portal redirects, a patient cannot reach the staff console, staff login is department-scoped
test_portal.py 2 seeded portal sections render, profile edits persist
test_agents.py 8 symptom→department routing, emergency language flagged, advice-seeking flagged but still routed, out-of-scope declined, vague purpose asks to clarify, cancel intent handled, chat→booking creates a PENDING appointment, emergency chat booking opens an escalation
test_staff.py 7 queue is department-scoped, out-of-department staff cannot act, confirm sets status + notifies, cancel frees the slot, reschedule moves the slot, emergency redirect, follow-up creates a parent-linked appointment
test_documents.py 11 classify from filename, explicit-type hint wins, route report to department, upload persists routed dept, staff see only their department's docs, upload de-dupes, unsupported type rejected, required-doc status + upload satisfies it, pre-visit reminder is idempotent, confirming a follow-up raises the reminder, seed ships the demo reminder

Tests run fully offline against a throwaway SQLite DB with the LLM stub — no GROQ_API_KEY needed.

Data model

See app/models.py. Core entities follow the challenge §9 schema (User, PatientProfile, Department, Doctor, AppointmentSlot, Appointment, PatientDocument, WorkflowRun, Reminder, Escalation, AuditEvent) plus extensions the clinic workflow needs (InsuranceInfo, MedicalHistoryEntry, Notification, RequiredDocument, and follow-up links on Appointment).

Safety & privacy

  • All sample data is synthetic; no real patient information (RULE-6).
  • Secrets live only in a gitignored .env; .env.example documents the shape.
  • The assistant maps symptoms to a department, never to a diagnosis, and emergencies are routed to human staff.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages