Spaces:
Sleeping
Sleeping
File size: 5,066 Bytes
3d9fd27 4a71975 3d9fd27 d09f114 9910527 4a71975 d09f114 8c7ee14 d09f114 8c7ee14 3d9fd27 8c7ee14 9910527 8c7ee14 3d9fd27 209a87c 3d9fd27 209a87c 8c7ee14 1fecdb8 8c7ee14 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
import streamlit as st
import os
import time
import re
import requests
import json
from PIL import Image
from io import BytesIO
from urllib.parse import quote
from openai import OpenAI
# ------------------ App Configuration ------------------
st.set_page_config(page_title="Schlaeger Forrestdale TechDocAIA", layout="wide", initial_sidebar_state="collapsed")
st.title("π Schlaeger Forrestdale Document Assistant")
st.caption("Explore City of Armadale construction documents using AI + OCR π§")
# ------------------ 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 "pending_prompt" not in st.session_state:
st.session_state.pending_prompt = None
if "results" not in st.session_state:
st.session_state.results = []
if "lightbox_url" not in st.session_state:
st.session_state.lightbox_url = None
# ------------------ Sidebar ------------------
st.sidebar.header("βΉοΈ Information")
if st.sidebar.button("π§Ή Clear Chat"):
st.session_state.messages = []
st.session_state.thread_id = None
st.session_state.pending_prompt = None
st.session_state.results = []
st.session_state.lightbox_url = None
st.rerun()
# ------------------ Chat Input ------------------
user_prompt = st.chat_input("Ask about plans, drawings or components")
if user_prompt:
st.session_state.messages.append({"role": "user", "content": user_prompt})
# ------------------ Assistant Query ------------------
if st.session_state.messages and st.session_state.messages[-1]["role"] == "user":
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=st.session_state.messages[-1]["content"]
)
run = client.beta.threads.runs.create(
thread_id=st.session_state.thread_id,
assistant_id=ASSISTANT_ID
)
with st.spinner("π€ Parsing and responding..."):
while True:
run_status = client.beta.threads.runs.retrieve(
thread_id=st.session_state.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(f"β οΈ Assistant failed: {run_status.status}")
else:
messages = client.beta.threads.messages.list(thread_id=st.session_state.thread_id)
for message in reversed(messages.data):
if message.role == "assistant":
assistant_reply = message.content[0].text.value
st.session_state.messages.append({"role": "assistant", "content": assistant_reply})
try:
json_data = json.loads(assistant_reply.strip("`json "))
st.session_state.results = json_data
except:
st.session_state.results = []
break
st.rerun()
except Exception as e:
st.error(f"β Error: {e}")
# ------------------ Sorting and Filters ------------------
if st.session_state.results:
with st.expander("π§ Options (Filter + Pagination)", expanded=False):
disciplines = sorted(set(d.get("discipline", "") for d in st.session_state.results))
selected_discipline = st.selectbox("π Filter by discipline", ["All"] + disciplines)
page_size = 8
page_num = st.number_input("Page", min_value=1, step=1, value=1)
filtered_results = [r for r in st.session_state.results if selected_discipline == "All" or r.get("discipline") == selected_discipline]
paged = filtered_results[(page_num - 1) * page_size : page_num * page_size]
st.markdown("---")
st.subheader("π Drawing Results")
cols = st.columns(4)
for i, item in enumerate(paged):
with cols[i % 4]:
st.markdown(f"**{item['drawing_number']}**")
st.markdown(f"_Discipline: {item['discipline']}_")
st.caption(item.get("summary", ""))
for url in item.get("images", [])[:1]:
st.image(url, caption=item['drawing_number'], use_container_width=True)
else:
for msg in st.session_state.messages:
with st.chat_message(msg["role"]):
st.markdown(msg["content"], unsafe_allow_html=True)
|