Skip to content

Commit 1e3055a

Browse files
author
waynetoh
committed
added clinical-assistant
1 parent 1c30de2 commit 1e3055a

21 files changed

+1531
-2
lines changed

clinical-assistant/.env.example

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Langfuse Configuration for Clinical Assistant Tracing
2+
# Get these keys from your Langfuse project settings: https://cloud.langfuse.com
3+
4+
# Required for Langfuse tracing
5+
LANGFUSE_PUBLIC_KEY=pk-lf-your-public-key-here
6+
LANGFUSE_SECRET_KEY=sk-lf-your-secret-key-here
7+
8+
# Langfuse host (choose your region)
9+
LANGFUSE_HOST=https://cloud.langfuse.com # EU region (default)
10+
# LANGFUSE_HOST=https://us.cloud.langfuse.com # US region
11+
12+
# Optional: Clinical session and provider identification for better tracing
13+
CLINICAL_SESSION_ID=clinical-session-001
14+
HEALTHCARE_PROVIDER_ID=[email protected]
15+
16+
# Note: Copy this file to .env and fill in your actual values
17+
# The application will work without these variables but tracing will be disabled

clinical-assistant/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# clinical-assistant
2+
3+
Healthcare professionals face increasing challenges in managing complex patient data and making timely, accurate decisions. This lab demonstrates how to build a clinical assistant using AWS technologies that can assist providers by integrating multiple data sources and AI capabilities.
4+
As a healthcare provider, we want an AI agent that analyzes a patient’s current symptoms, medical history, and existing documentation to recommend an accurate and personalized course of action. The agent shall help with the following:
5+
6+
- Ingest and understand the patient’s current symptoms and complaints.
7+
- Retrieve relevant historical medical records and documentation through MCP servers.
8+
- Utilize AWS Strands SDK to orchestrate the AI agent’s reasoning, planning, and tool invocation, enabling dynamic and flexible decision-making workflows.
9+
- Run Agents, LiteLLM and MCP servers on EC2 instances powered by Amazon EKS, optimizing cost and performance.

clinical-assistant/app.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: MIT-0
3+
4+
# Adapted from https://github.com/kyopark2014/strands-agent
5+
# SPDX-License-Identifier: MIT
6+
7+
import logging
8+
import sys
9+
10+
import streamlit as st
11+
12+
import health_agent_async
13+
14+
logging.basicConfig(
15+
level=logging.INFO, # Default to INFO level
16+
format="%(filename)s:%(lineno)d | %(message)s",
17+
handlers=[logging.StreamHandler(sys.stderr)],
18+
)
19+
logger = logging.getLogger("streamlit")
20+
21+
# title
22+
st.set_page_config(
23+
page_title="Clinical Decision Support AI Assistant",
24+
page_icon="🏥",
25+
layout="centered",
26+
initial_sidebar_state="auto",
27+
menu_items=None,
28+
)
29+
30+
with st.sidebar:
31+
st.title("Clinical Assistant Menu")
32+
33+
st.markdown(
34+
"**Clinical Decision Support AI Assistant** with access to patient data through MCP healthcare server. "
35+
"This assistant helps healthcare professionals with diagnostic reasoning and clinical decision-making. "
36+
)
37+
38+
39+
# Healthcare-specific information
40+
st.markdown("### Available Patient Data")
41+
st.markdown("""
42+
**Sample Patient IDs:**
43+
- PAT001, PAT002, PAT003
44+
45+
**Available Tools:**
46+
- Patient Demographics
47+
- Medical History
48+
- Lab Results
49+
- Patient Search
50+
- Risk Assessment
51+
""")
52+
53+
st.markdown("---")
54+
55+
st.markdown("### ⚠️ Important Notice")
56+
st.markdown("""
57+
This is a **clinical decision support tool** for healthcare professionals only.
58+
59+
- Not a replacement for clinical judgment
60+
- Final decisions must be made by qualified healthcare professionals
61+
- Maintains HIPAA compliance principles
62+
""")
63+
64+
clear_button = st.button("Reset Conversation", key="clear")
65+
66+
st.title("🏥 Clinical Decision Support AI Assistant")
67+
68+
# Initialize chat history
69+
if "messages" not in st.session_state:
70+
st.session_state.messages = []
71+
st.session_state.greetings = False
72+
73+
# Display chat messages from history on app rerun
74+
def display_chat_messages():
75+
"""Print message history
76+
@returns None
77+
"""
78+
for message in st.session_state.messages:
79+
with st.chat_message(message["role"]):
80+
if "images" in message:
81+
for url in message["images"]:
82+
logger.info(f"url: {url}")
83+
file_name = url[url.rfind("/") + 1 :]
84+
st.image(url, caption=file_name, use_container_width=True)
85+
st.markdown(message["content"])
86+
87+
display_chat_messages()
88+
89+
# Greet user
90+
if not st.session_state.greetings:
91+
with st.chat_message("assistant"):
92+
intro = """👋 Welcome to the Clinical Decision Support AI Assistant!
93+
94+
I'm here to help healthcare professionals with:
95+
- **Diagnostic reasoning** and differential diagnoses
96+
- **Patient data analysis** using our MCP healthcare server
97+
- **Clinical insights** based on medical guidelines
98+
- **Treatment recommendations** considering patient history
99+
- **Lab result interpretation** and clinical findings
100+
101+
I have access to patient data for sample patients (PAT001, PAT002, PAT003) and can help with clinical decision-making.
102+
103+
**Important:** I'm a support tool for healthcare professionals, not a replacement for clinical judgment. All recommendations are for clinical decision support only.
104+
105+
How can I assist you with your clinical analysis today?"""
106+
107+
st.markdown(intro)
108+
# Add assistant response to chat history
109+
st.session_state.messages.append({"role": "assistant", "content": intro})
110+
st.session_state.greetings = True
111+
112+
if clear_button or "messages" not in st.session_state:
113+
st.session_state.messages = []
114+
st.session_state.greetings = False
115+
st.rerun()
116+
117+
# Always show the chat input
118+
if prompt := st.chat_input("Enter your clinical question or patient case..."):
119+
with st.chat_message("user"): # display user message in chat message container
120+
st.markdown(prompt)
121+
122+
st.session_state.messages.append(
123+
{"role": "user", "content": prompt}
124+
) # add user message to chat history
125+
prompt = prompt.replace('"', "").replace("'", "")
126+
logger.info(f"Clinical prompt: {prompt}")
127+
128+
with st.chat_message("assistant"):
129+
response = health_agent_async.run_health_agent(prompt, st)
130+
131+
st.session_state.messages.append({"role": "assistant", "content": response})
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
3+
# Script to clean up Langfuse deployment
4+
5+
set -e
6+
7+
# Color codes for better readability
8+
GREEN='\033[0;32m'
9+
BLUE='\033[0;34m'
10+
RED='\033[0;31m'
11+
YELLOW='\033[0;33m'
12+
NC='\033[0m' # No Color
13+
14+
# Function to display messages with timestamp
15+
log() {
16+
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
17+
}
18+
19+
warn() {
20+
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
21+
}
22+
23+
success() {
24+
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS:${NC} $1"
25+
}
26+
27+
log "Uninstalling Langfuse Helm release..."
28+
helm uninstall langfuse || warn "Failed to uninstall Langfuse Helm release, it may not exist"
29+
30+
log "Deleting Langfuse PVCs..."
31+
kubectl delete pvc data-langfuse-clickhouse-shard0-0 data-langfuse-clickhouse-shard0-1 data-langfuse-clickhouse-shard0-2 data-langfuse-postgresql-0 data-langfuse-zookeeper-0 data-langfuse-zookeeper-1 data-langfuse-zookeeper-2 langfuse-s3 valkey-data-langfuse-redis-primary-0 || warn "Failed to delete some PVCs, they may not exist"
32+
33+
log "Waiting for resources to be cleaned up (30 seconds)..."
34+
sleep 30
35+
36+
success "Langfuse cleanup completed!"
37+
log "You can now run setup.sh to reinstall Langfuse with the auto-ebs-sc storage class"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
apiVersion: karpenter.sh/v1
2+
kind: NodePool
3+
metadata:
4+
name: custom
5+
spec:
6+
template:
7+
spec:
8+
expireAfter: 168h
9+
nodeClassRef:
10+
group: eks.amazonaws.com
11+
kind: NodeClass
12+
name: default
13+
requirements:
14+
- key: karpenter.sh/capacity-type
15+
operator: In
16+
values: ["spot", "on-demand"]
17+
- key: "eks.amazonaws.com/instance-category"
18+
operator: In
19+
values: ["c", "m", "r"]
20+
- key: "eks.amazonaws.com/instance-generation"
21+
operator: Gt
22+
values: ["5"]
23+
- key: kubernetes.io/arch
24+
operator: In
25+
values: ["amd64", "arm64"]
26+
limits:
27+
cpu: 1000
28+
memory: 1000Gi
29+
disruption:
30+
consolidationPolicy: WhenEmptyOrUnderutilized
31+
consolidateAfter: 1m
32+
33+

0 commit comments

Comments
 (0)