witspathologyv2 / app.py
IAMTFRMZA's picture
Update app.py
1ba534e verified
raw
history blame
5.37 kB
import streamlit as st
import os
import time
import re
import requests
from PIL import Image
from io import BytesIO
from openai import OpenAI
# ------------------ App Configuration ------------------
st.set_page_config(page_title="Schlaeger Forrestdale DocAIA", layout="wide")
st.title("πŸ“„ Document AI Assistant")
st.caption("Chat with an AI Assistant on your construction documents")
# ------------------ Load API Key and Assistant ID ------------------
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
ASSISTANT_ID = os.environ.get("ASSISTANT_ID")
if not OPENAI_API_KEY or not ASSISTANT_ID:
st.error("❌ Missing secrets. Please set both OPENAI_API_KEY and ASSISTANT_ID in Hugging Face Space secrets.")
st.stop()
client = OpenAI(api_key=OPENAI_API_KEY)
# ------------------ Session State Initialization ------------------
if "messages" not in st.session_state:
st.session_state.messages = []
if "thread_id" not in st.session_state:
st.session_state.thread_id = None
if "image_url" not in st.session_state:
st.session_state.image_url = None
if "image_updated" not in st.session_state:
st.session_state.image_updated = False
# ------------------ Sidebar Controls ------------------
st.sidebar.header("πŸ”§ Settings")
if st.sidebar.button("πŸ”„ Clear Chat"):
st.session_state.messages = []
st.session_state.thread_id = None
st.session_state.image_url = None
st.session_state.image_updated = False
st.rerun()
show_image = st.sidebar.checkbox("πŸ“– Show Document Image", value=True)
# ------------------ Layout: Image + Chat ------------------
col1, col2 = st.columns([1, 2])
# ------------------ Left Panel: Image ------------------
with col1:
if show_image and st.session_state.image_url:
with st.spinner("πŸ–ΌοΈ Loading image preview..."):
try:
response = requests.get(st.session_state.image_url)
response.raise_for_status()
img = Image.open(BytesIO(response.content))
st.image(img, caption="πŸ“‘ Extracted Page", use_container_width=True)
st.session_state.image_updated = False
except Exception as e:
st.warning(f"⚠️ Failed to load image from URL:\n{st.session_state.image_url}\n\nError: {e}")
# ------------------ Right Panel: Chat ------------------
with col2:
prompt = st.chat_input("Type your question about the document or choose from FAQs below...")
# Display chat history in a cleaner bubble layout
paired_messages = []
buffer = []
for msg in st.session_state.messages:
buffer.append(msg)
if msg["role"] == "assistant" and len(buffer) == 2:
paired_messages.append(buffer.copy())
buffer.clear()
if buffer:
paired_messages.append(buffer.copy())
for pair in reversed(paired_messages):
for msg in pair:
with st.chat_message(msg["role"]):
st.markdown(f"{msg['content']}", unsafe_allow_html=True)
if prompt:
st.session_state.messages.append({"role": "user", "content": prompt})
try:
if st.session_state.thread_id is None:
thread = client.beta.threads.create()
st.session_state.thread_id = thread.id
client.beta.threads.messages.create(
thread_id=st.session_state.thread_id,
role="user",
content=prompt
)
run = client.beta.threads.runs.create(
thread_id=st.session_state.thread_id,
assistant_id=ASSISTANT_ID
)
with st.spinner("πŸ€– Assistant is thinking..."):
while True:
run_status = client.beta.threads.runs.retrieve(
thread_id=st.session_state.thread_id,
run_id=run.id
)
if run_status.status == "completed":
break
time.sleep(1)
messages = client.beta.threads.messages.list(thread_id=st.session_state.thread_id)
assistant_message = None
for message in reversed(messages.data):
if message.role == "assistant":
assistant_message = message.content[0].text.value
break
st.session_state.messages.append({"role": "assistant", "content": assistant_message})
match = re.search(r'Document Reference:\s+(.+?),\s+Page\s+(\d+)', assistant_message)
if match:
doc_name = match.group(1).strip()
page = int(match.group(2))
page_str = f"{page:04d}"
corrected_url = (
f"https://raw.githubusercontent.com/AndrewLORTech/c2ozschlaegerforrestdale/main/"
f"{doc_name}/{doc_name}_page_{page_str}.png"
)
st.session_state.image_url = corrected_url
st.session_state.image_updated = True
st.rerun()
except Exception as e:
st.error(f"❌ Error: {str(e)}")
# ------------------ Suggested FAQs Section ------------------
st.markdown("""
<hr>
<b>🧠 Suggested FAQs:</b>
- What are the mechanical services on page 3?
- Summarize the demolition schedule.
- List the safety compliance steps.
""")