Skip to content

achref-soua/pulse

Repository files navigation

Pulse

Aortic & endovascular surgery intelligence — from referral to recovery

Latest release License Stack Synthetic data

⚠️ Educational demonstration on fully synthetic patient data — not for clinical use; not medical advice.


What is Pulse?

Pulse is a full-stack clinical decision-support demo for aortic and endovascular surgery. It reimagines the original CardioSurg-AI-Assistant (Streamlit + ChromaDB) on a modern production-grade stack: a Next.js 15 dashboard, a FastAPI intelligence service, a RAG pipeline over Quiver (the author's own vector DB), and a LangGraph multi-agent copilot powered by Groq.

The project exists to show what a senior-level, full-stack, AI-native clinical tool looks like when built with the right foundations — not as a clinical product.

📖 Pulse, Explained — the field guide (PDF) — a designed, plain-English tour of what Pulse is and how it's built, for clinicians and engineers alike.

Before (prototype) Pulse v2.0
Streamlit chat Next.js 15 dashboard — full clinical UI, light + dark
ChromaDB Quiver — author's own vector DB
Minimal LangGraph stub Tool-calling agent — router, tools, memory, streaming
Single-shot RAG Agent grounds every claim; never invents a score
Random synthetic patients 200 clinically-correlated synthetic patients
No clinical calculators 7 validated calculators + IFU-fit engine
No auth JWT + role-based access (4 roles), fail-closed queries
No PDF Medical-grade PDF report + a designed field-guide PDF
No streaming Token + tool-step SSE streaming copilot
⌘K palette · cohort analytics · NL→cohort · MCP server

Screenshots

Generated by task screenshots against the running seeded stack — every screen is captured in both light and dark (-dark suffix).

Landing page

Landing

Agentic AI copilot — watch it call tools and cite its work

The copilot doesn't just chat: it routes, calls the deterministic clinical engine, and streams each step as a tool chip before answering — grounded, never guessed.

Copilot (light) Copilot (dark)
Copilot Copilot dark

Cohort analytics

Analytics (light) Analytics (dark)
Analytics Analytics dark

⌘K command palette

Command palette

Dashboard — light & dark

Light Dark
Dashboard Dashboard dark

Patient roster — 200 synthetic patients

Patients list

Patient detail — Overview tab (Patient 1)

Patient overview

Patient detail — multiple patients, multiple tabs

Overview Risk & Suitability Notes AI Summary
P1 overview P1 risk P1 notes P1 AI
P2 overview P2 risk
P3 overview P3 AI

Risk calculators — RCRI, NEWS2, GAS

RCRI form RCRI result NEWS2 result GAS result
RCRI form RCRI result NEWS2 result GAS result

Monitoring & Devices

Monitoring Devices
Monitoring Devices

Knowledge Base — guidelines and literature

Knowledge Base

Medical-grade PDF report

(generated on demand per patient — download via the AI Summary tab)

AI Copilot — streaming chat

AI Copilot

Admin — user management and audit log

Users Audit Log
Admin users Audit log

Features

Patient Roster & CDP

200 synthetic aortic-surgery patients with: full anatomy (aortic dimensions, morphology), comorbidities, medications, labs, vitals timelines, clinical notes, attending physician, and current clinical phase (pre-op / intra-op / post-op).

Clinical Calculators

All calculators are deterministic, unit-tested, and never approximated by the LLM:

Calculator Domain
RCRI Cardiac risk for non-cardiac surgery
CHA₂DS₂-VASc Stroke risk in atrial fibrillation
HAS-BLED Bleeding risk in anticoagulation
NEWS2 Early warning score — post-op deterioration
GAS Glasgow Aneurysm Score — AAA operative risk
EuroSCORE II Cardiac surgery operative mortality
IFU-fit engine Device suitability for EVAR/TEVAR

Agentic AI Copilot

A real tool-calling agent on LangGraph — not a single-shot RAG call (ADR-0010):

  • Router → agent ⇄ tools — an 8B router triages the request; a 70B agent binds eight grounded tools and loops through a ToolNode until it has an answer
  • Grounded, never guessed — every clinical score comes from the deterministic engine via score_patient/calculate_risk_score; the model orchestrates but cannot invent a number
  • Streamed reasoning — SSE emits router → tool_call → tool_result → sources → token → done, rendered as a live agent-step timeline
  • Multi-turn memory — prior turns persist to Conversation/Message and replay, so the graph stays stateless
  • RAG over Quiversearch_guidelines embeds, searches, and cross-encoder-reranks; every citation is a real source

MCP Server

Pulse's clinical tools are exposed over the Model Context Protocol so external agents can drive it — score_patient, match_devices, get_patient, search_guidelines, query_cohort (docs, ADR-0009). It reuses the in-app tool layer, so an external agent gets byte-identical, grounded behaviour. Run with task mcp.

Cohort Analytics & Natural-Language Search

  • /analytics — cohort distributions (phase, intervention, aneurysm type, sex, age, diameter bands) as tokenized Recharts, correct in light and dark
  • NL→cohort — "post-op patients with large aneurysms over 75" becomes schema-validated roster filters (ADR-0012); fails closed rather than matching everyone

⌘K Command Palette

Global fuzzy search over patients (live), devices, navigation, and quick actions — opened with ⌘K or the TopBar search.

Patient AI Summary & PDF Report

Triggered per-patient, the LangGraph pipeline builds a structured clinical narrative from the patient record and knowledge base, rendered as:

  • An inline summary card in the dashboard
  • A downloadable medical-grade PDF: indigo header band with Pulse logo, patient info table, AI narrative, colour-coded risk scores, cited sources, and confidentiality footer

Post-op Monitoring

Vitals time-series charts with NEWS2 colour bands, alert thresholds, and AI-generated deterioration flags.

Knowledge Base Explorer

Browse and filter all 13 guidelines and literature entries indexed in Quiver. Filterable by type, section, and title.

Device Catalog

EVAR/TEVAR device specifications with IFU fit assessment per patient anatomy.

Admin

User management (CRUD, role assignment), audit log viewer.


Architecture

flowchart LR
  U[Clinician] -->|HTTPS| W["web · Next.js 15\nApp Router · TypeScript\nTailwind · shadcn/ui"]
  W -->|REST + SSE| A["api · FastAPI · Python 3.12\nSQLAlchemy 2 async · Alembic"]
  A -->|SQL| P[(Postgres 16)]
  A -->|vector search| Q[("Quiver\nvector DB")]
  A -->|cache · checkpoints| R[(Redis)]
  A -->|LLM inference| G["Groq\nllama-3.3-70b-versatile"]
  subgraph AI ["FastAPI · AI plane"]
    LG["LangGraph StateGraph\nretrieve → generate"]
    RAG["Quiver hybrid search\n+ cross-encoder rerank"]
    CALC["Clinical calculators\n(deterministic)"]
    PDF["ReportLab PDF\ngenerator"]
  end
  A --- AI
  LG --> RAG --> Q
Loading

Five services in docker-compose.yml:

  • web — Next.js 15 (App Router, RSC, Server Actions)
  • api — FastAPI, async SQLAlchemy, LangGraph, Quiver client
  • db — Postgres 16
  • quiverQuiver vector DB (author's own project)
  • redis — session checkpoints, rate-limit counters

See docs/architecture.md and the ADRs for decision rationale.


Quickstart

git clone https://github.com/achref-soua/pulse.git
cd pulse
cp .env.example .env

# Optional — add your Groq key for AI features (app runs without it, AI routes return 503):
# GROQ_API_KEY=gsk_...

task up       # docker compose up -d --build --wait
task migrate  # run Alembic migrations
task seed     # populate Postgres + Quiver (≈30 s)

Open http://localhost:3000 and sign in:

Role Email Password
Surgeon surgeon@demo.pulse demo-surgeon-2024
Anesthetist anesthetist@demo.pulse demo-anesthetist-2024
Nurse nurse@demo.pulse demo-nurse-2024
Admin admin@demo.pulse demo-admin-2024

Full build & run reference

# Install
pnpm install                          # web + monorepo packages
cd apps/api && uv sync && cd ../..    # Python deps

# Dev servers
pnpm --filter web dev                 # http://localhost:3000
cd apps/api && uv run uvicorn app.main:app --reload --port 8000

# Tests
task test           # all: vitest + pytest
task test:api       # pytest (apps/api)
task test:web       # vitest (apps/web)
task e2e            # Playwright E2E (requires running stack)

# Lint & type-check
task lint           # ruff + eslint
task type-check     # pyright + tsc

# Screenshots (requires running seeded stack)
BASE_URL=http://localhost:3000 task screenshots

# Wipe and reseed
task reset          # docker compose down -v && task up && task migrate && task seed

Configuration reference

Variable Default Required Description
DATABASE_URL postgresql+asyncpg://pulse:pulse@db:5432/pulse Yes Async SQLAlchemy DSN
QUIVER_URL http://quiver:8080 Yes Quiver server base URL
QUIVER_API_KEY dev-quiver-key-change-me Yes Quiver API key
REDIS_URL redis://redis:6379/0 Yes Redis connection URL
JWT_SECRET Yes JWT signing secret (≥ 32 chars)
GROQ_API_KEY AI features Groq API key — leave blank to disable AI routes
GROQ_MODEL llama-3.3-70b-versatile No Primary generation model
GROQ_ROUTER_MODEL llama-3.1-8b-instant No Fast router / intent model
EMBEDDING_MODEL BAAI/bge-small-en-v1.5 No Sentence-transformer embedding model
RERANK_ENABLED true No Enable cross-encoder reranking of RAG candidates
ENVIRONMENT development No development | production

Full list with comments in .env.example.


Clinical scores & references

All calculators are deterministic, unit-tested against published score definitions, and never delegated to the LLM. See docs/clinical/REFERENCES.md for every cited paper and guideline.


Architecture decisions

ADR Decision
0001 Next.js 15 + FastAPI + Quiver + LangGraph + Groq
0002 Quiver over ChromaDB / pgvector / Qdrant
0003 LangGraph StateGraph for patient summary
0004 AGPL-3.0
0005 Direct ChatGroq.astream() for SSE chat
0006 bge-small-en-v1.5 embeddings + cross-encoder rerank
0007 ReportLab for PDF report generation
0008 JWT via Authorization: Bearer header only

Deployment

docker compose up -d --build is the primary deployment target. The compose file includes named volumes for Postgres data and the Quiver index. See docs/architecture.md for service boundaries, health-check configuration, and resource guidance.


License

AGPL-3.0 — © 2024–2026 Achref Soua

Pulse is an educational demonstration on fully synthetic patient data. It is not a medical device, does not constitute medical advice, and must not be used for clinical decision-making on real patients.

About

No description, website, or topics provided.

Resources

License

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors