witspathology / app.py
IAMTFRMZA's picture
Update app.py
d4f41a3 verified
raw
history blame
4.53 kB
import streamlit as st
import os
import time
import json
import re
from openai import OpenAI
# Configuration
st.set_page_config(page_title="Forrestdale Drawing Viewer", layout="wide")
st.title("πŸ“ Forrestdale Technical Drawing Assistant")
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
ASSISTANT_ID = "asst_DjvuWBc7tCvMbAhY7n1em4BZ"
if not OPENAI_API_KEY:
st.error("❌ Missing OPENAI_API_KEY.")
st.stop()
client = OpenAI(api_key=OPENAI_API_KEY)
if "tech_thread_id" not in st.session_state:
thread = client.beta.threads.create()
st.session_state.tech_thread_id = thread.id
if "tech_messages" not in st.session_state:
st.session_state.tech_messages = []
# Prompt input
prompt = st.chat_input("Ask about plans, drawings or components (e.g. Show me all electrical plans)")
if prompt:
st.session_state.tech_messages.append({"role": "user", "content": prompt})
# Display assistant messages
for msg in st.session_state.tech_messages:
with st.chat_message(msg["role"]):
st.markdown(msg["content"])
# Trigger assistant
if st.session_state.tech_messages and st.session_state.tech_messages[-1]["role"] == "user":
with st.spinner("⏳ Fetching results from assistant..."):
try:
client.beta.threads.messages.create(
thread_id=st.session_state.tech_thread_id,
role="user",
content=st.session_state.tech_messages[-1]["content"]
)
run = client.beta.threads.runs.create(
thread_id=st.session_state.tech_thread_id,
assistant_id=ASSISTANT_ID
)
while True:
run_status = client.beta.threads.runs.retrieve(
thread_id=st.session_state.tech_thread_id,
run_id=run.id
)
if run_status.status in ["completed", "failed", "cancelled"]:
break
time.sleep(1)
if run_status.status != "completed":
st.error("⚠️ Assistant run failed.")
else:
messages = client.beta.threads.messages.list(thread_id=st.session_state.tech_thread_id)
for message in reversed(messages.data):
if message.role == "assistant":
reply_content = message.content[0].text.value.strip()
st.session_state.tech_messages.append({"role": "assistant", "content": reply_content})
# Try to parse response as JSON block (```json ... ```)
try:
match = re.search(r"```json\s*(.*?)```", reply_content, re.DOTALL)
json_str = match.group(1) if match else reply_content
results = json.loads(json_str)
if isinstance(results, list):
for item in results:
drawing_number = item.get("drawing_number")
discipline = item.get("discipline")
summary = item.get("summary")
images = item.get("images", [])
single_image = item.get("image")
question = item.get("question", None)
with st.container(border=True):
st.markdown(f"### πŸ—‚οΈ {drawing_number} ({discipline})")
st.markdown(f"**Summary:** {summary}")
with st.expander("πŸ“‚ View Drawing Details"):
if question:
st.markdown(f"**Question Match:** {question}")
if single_image:
st.image(single_image, caption=drawing_number)
elif images:
for i, img in enumerate(images, start=1):
st.image(img, caption=f"{drawing_number} – Page {i}")
except Exception as parse_error:
st.warning("🟑 Could not parse assistant response as JSON.")
break
except Exception as e:
st.error(f"❌ Error occurred: {e}")