# --- Imports --- import streamlit as st import PyPDF2 import requests import json from sentence_transformers import SentenceTransformer import numpy as np from sklearn.metrics.pairwise import cosine_similarity from datetime import datetime from groq import Groq # --- Page config --- st.set_page_config( page_title="🚨 First Aid Emergency Assistant", page_icon="🚨", layout="wide", initial_sidebar_state="expanded" ) # --- Enhanced Professional UI CSS --- st.markdown(""" """, unsafe_allow_html=True) # --- GROQ API setup --- @st.cache_resource def setup_groq(): try: return st.secrets["GROQ_API_KEY"] except: st.error("❌ Missing GROQ_API_KEY in `.streamlit/secrets.toml`") st.stop() client = Groq(api_key=setup_groq()) # --- PDF Processing --- @st.cache_resource def load_pdf(): try: with open("First-Aid.pdf", "rb") as f: reader = PyPDF2.PdfReader(f) text = "".join(page.extract_text() + "\n" for page in reader.pages) return text except: st.error("❌ Failed to load 'First-Aid.pdf'. Upload it to the app root.") st.stop() # --- Knowledge Base Setup --- @st.cache_resource def setup_knowledge_base(): text = load_pdf() chunks, current_chunk = [], "" for sentence in text.split('\n'): if len(current_chunk + sentence) < 1000: current_chunk += sentence + "\n" else: if current_chunk.strip(): chunks.append(current_chunk.strip()) current_chunk = sentence + "\n" if current_chunk.strip(): chunks.append(current_chunk.strip()) model = SentenceTransformer('all-MiniLM-L6-v2') embeddings = model.encode(chunks) return chunks, embeddings, model # --- Context Matching --- def find_relevant_context(query, chunks, embeddings, model, top_k=3): query_embedding = model.encode([query]) similarities = cosine_similarity(query_embedding, embeddings)[0] top_indices = np.argsort(similarities)[-top_k:][::-1] return "\n\n".join([chunks[i] for i in top_indices]) # --- Query GROQ --- def query_groq(prompt, api_key): url = "https://api.groq.com/openai/v1/chat/completions" headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"} data = { "model": "llama3-70b-8192", "messages": [ { "role": "system", "content": """You are a First Aid Emergency Assistant. Answer only first aid-related queries. Be clear, concise, and step-by-step. For serious emergencies, advise calling 911. If asked off-topic, respond with: "🚨 I'm specialized in First Aid emergencies only!".""" }, {"role": "user", "content": prompt} ], "temperature": 0.3, "max_tokens": 1000 } try: r = requests.post(url, headers=headers, json=data, timeout=30) r.raise_for_status() return r.json()["choices"][0]["message"]["content"] except Exception as e: return f"❌ GROQ API Error: {str(e)}" # --- Session State --- if "messages" not in st.session_state: st.session_state.messages = [{ "role": "assistant", "content": "🚨 **Hello! I'm your First Aid Emergency Assistant.**\n\nAsk me about CPR, bleeding, choking, burns, or any first aid emergency. I'm here to help you with step-by-step guidance!" }] if "knowledge_base" not in st.session_state: with st.spinner("🔄 Loading knowledge base..."): chunks, embeddings, model = setup_knowledge_base() st.session_state.knowledge_base = { "chunks": chunks, "embeddings": embeddings, "model": model } if "feedback_shown" not in st.session_state: st.session_state.feedback_shown = False if "response_count" not in st.session_state: st.session_state.response_count = 0 # --- Main App Layout --- # Compact Header st.markdown('''

🚨 First Aid Emergency Assistant

Your AI-powered emergency response guide

''', unsafe_allow_html=True) # Main content area col1, col2 = st.columns([3, 1]) with col1: # Create a container with fixed height for chat messages chat_container = st.container() with chat_container: # Create the scrollable chat area using st.container with height st.markdown('
', unsafe_allow_html=True) # Display chat messages for i, msg in enumerate(st.session_state.messages): if msg["role"] == "user": st.markdown(f'
{msg["content"]}
', unsafe_allow_html=True) else: st.markdown(f'
🤖 First Aid Assistant
{msg["content"]}
', unsafe_allow_html=True) st.markdown('
', unsafe_allow_html=True) # Show feedback request after first response if st.session_state.response_count >= 1 and not st.session_state.feedback_shown: st.markdown('''

💬 How was this assistance?

Your feedback helps us improve emergency response guidance.

''', unsafe_allow_html=True) feedback_col1, feedback_col2, feedback_col3 = st.columns(3) with feedback_col1: if st.button("👍 Helpful"): st.success("Thank you for your feedback!") st.session_state.feedback_shown = True st.rerun() with feedback_col2: if st.button("👎 Not helpful"): st.info("Thanks for letting us know. We'll work to improve!") st.session_state.feedback_shown = True st.rerun() with feedback_col3: if st.button("⏭️ Skip"): st.session_state.feedback_shown = True st.rerun() # Enhanced Input Container with better spacing st.markdown('
', unsafe_allow_html=True) # Form for Enter key support and auto-clear with st.form(key="chat_form", clear_on_submit=True): input_col1, input_col2 = st.columns([4, 1]) with input_col1: user_input = st.text_input( "", placeholder="What do to in case of heart pain?", key="user_input_form", label_visibility="collapsed" ) with input_col2: send = st.form_submit_button("Send 🚀") # Clear Chat Button if st.button("🗑️ Clear Chat", key="clear_chat", help="Clear all messages and start fresh"): st.session_state.messages = [{ "role": "assistant", "content": "🚨 **Hello! I'm your First Aid Emergency Assistant.**\n\nAsk me about CPR, bleeding, choking, burns, or any first aid emergency. I'm here to help you with step-by-step guidance!" }] st.session_state.feedback_shown = False st.session_state.response_count = 0 st.rerun() st.markdown('
', unsafe_allow_html=True) # Sidebar with medical disclaimer and info with col2: st.markdown("### 🩺 Medical Disclaimer") with st.expander("⚠️ Important - Click to read", expanded=False): st.markdown(""" **MEDICAL DISCLAIMER:** This tool provides general first aid guidance only. 🚨 **In real emergencies:** - Call emergency services immediately - This is NOT a substitute for professional medical care - Always seek professional help for serious injuries Use this tool for educational purposes and basic guidance only. """) st.markdown("### 🎯 What I Can Help With") st.markdown(''' ''', unsafe_allow_html=True) # Process Input (works with both Enter key and button click) if send and user_input and user_input.strip(): # Add user message st.session_state.messages.append({"role": "user", "content": user_input}) # Get AI response try: kb = st.session_state.knowledge_base context = find_relevant_context(user_input, kb["chunks"], kb["embeddings"], kb["model"]) full_prompt = f""" Based on this first aid manual content, answer the question: {user_input} Context: {context} Please provide clear, step-by-step guidance. Use bullet points or numbered lists when appropriate. """ response = query_groq(full_prompt, setup_groq()) # Add emergency warning for serious cases if any(x in user_input.lower() for x in ["heart attack", "stroke", "not breathing", "unconscious", "severe bleeding", "choking"]): response = f"🚨 **CALL EMERGENCY SERVICES IMMEDIATELY!**\n\n{response}" # Add bot response st.session_state.messages.append({"role": "assistant", "content": response}) st.session_state.response_count += 1 except Exception as e: st.session_state.messages.append({ "role": "assistant", "content": f"❌ Sorry, I encountered an error: {str(e)}. Please try again or rephrase your question." }) # Rerun to show updated chat st.rerun() # Footer st.markdown("---") st.markdown('''
🤖 First Aid Emergency Assistant | Always consult medical professionals for serious emergencies
''', unsafe_allow_html=True)