""" Professional Nurse Advocate Assistant Powered by Claude claude-opus-4-6 | A-EQUIP Model | NHS OGL v3.0 BYOK — bring your own Anthropic API key. Free forever on Hugging Face. """ import streamlit as st from datetime import date from pna.rag import PNAKnowledgeBase from pna.claude_client import stream_response, generate_supervision_note from pna.export import build_supervision_docx, build_cpd_docx, HAS_DOCX # ─── Page config ───────────────────────────────────────────────────────────── st.set_page_config( page_title="PNA Assistant | Professional Nurse Advocate", page_icon="👨🏾⚕️", layout="wide", initial_sidebar_state="expanded", ) # ─── Custom CSS ────────────────────────────────────────────────────────────── st.markdown(""" """, unsafe_allow_html=True) # ─── Session state ──────────────────────────────────────────────────────────── defaults = { "messages": [], "api_key": "", "nurse_name": "", "session_started": None, } for k, v in defaults.items(): if k not in st.session_state: st.session_state[k] = v # ─── Load RAG knowledge base ────────────────────────────────────────────────── @st.cache_resource(show_spinner="Loading A-EQUIP knowledge base…") def load_knowledge_base(): return PNAKnowledgeBase() kb = load_knowledge_base() # ─── Sidebar ───────────────────────────────────────────────────────────────── with st.sidebar: st.markdown("### 👨🏾⚕️ PNA Assistant") st.caption("A-EQUIP Model · Restorative Supervision") st.divider() # ── API Key (BYOK) ──────────────────────────────────────────────────────── st.markdown("#### 🔑 Your Anthropic API Key") api_key_input = st.text_input( "Enter key to start chatting", type="password", value=st.session_state.api_key, placeholder="sk-ant-api03-...", help="Used only for this session and never stored.", ) if api_key_input: st.session_state.api_key = api_key_input st.success("✅ Key entered") st.caption( "[Get a free API key →](https://console.anthropic.com) " "· Costs ~£0.01 per conversation" ) st.divider() # ── Your details ────────────────────────────────────────────────────────── st.markdown("#### 📋 Your Details") st.caption("Optional — used in supervision note exports.") st.session_state.nurse_name = st.text_input( "Your name", value=st.session_state.nurse_name, placeholder="e.g. Nurse Jane Smith", ) cpd_hours = st.number_input( "Session length (hours)", min_value=0.5, max_value=8.0, value=1.0, step=0.5, ) st.divider() # ── Session controls ────────────────────────────────────────────────────── st.markdown("#### 🔄 Session") col1, col2 = st.columns(2) with col1: if st.button("🗑️ Clear", use_container_width=True): st.session_state.messages = [] st.session_state.session_started = None st.rerun() with col2: if st.button("🆕 New", use_container_width=True): st.session_state.messages = [] st.session_state.session_started = date.today().isoformat() st.rerun() # ── Exports ─────────────────────────────────────────────────────────────── if st.session_state.messages: st.divider() st.markdown("#### 📥 Export") if st.button("📄 Generate supervision note", use_container_width=True): if not st.session_state.api_key: st.error("Please enter your API key first.") else: with st.spinner("Generating note with Claude…"): note = generate_supervision_note( st.session_state.api_key, st.session_state.messages, ) st.session_state["last_note"] = note if "last_note" in st.session_state: note = st.session_state["last_note"] st.text_area("Preview", note, height=200) if HAS_DOCX: docx_bytes = build_supervision_docx(note, st.session_state.nurse_name) if docx_bytes: st.download_button( "⬇️ Supervision note (.docx)", data=docx_bytes, file_name=f"PNA_Supervision_{date.today()}.docx", mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document", use_container_width=True, ) cpd_bytes = build_cpd_docx(note, st.session_state.nurse_name, cpd_hours) if cpd_bytes: st.download_button( "⬇️ NMC CPD Record (.docx)", data=cpd_bytes, file_name=f"NMC_CPD_{date.today()}.docx", mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document", use_container_width=True, ) else: st.download_button( "⬇️ Download as .txt", data=note, file_name=f"PNA_Supervision_{date.today()}.txt", mime="text/plain", use_container_width=True, ) st.divider() st.markdown( '
Contains public sector information licensed under the ' 'Open Government Licence v3.0 — NHS England.
', unsafe_allow_html=True, ) # ─── Main content ───────────────────────────────────────────────────────────── st.markdown("""Your AI guide to the A-EQUIP model, restorative supervision, and quality improvement
🇬🇧 NHS England · A-EQUIP Model NMC Standards OGL v3.0