File size: 4,337 Bytes
3d9fd27
4a71975
3d9fd27
209a87c
3d9fd27
9910527
4a71975
3d9fd27
 
 
 
9910527
3d9fd27
4a71975
3d9fd27
 
 
209a87c
3d9fd27
209a87c
3d9fd27
 
 
209a87c
3d9fd27
 
209a87c
3d9fd27
 
 
209a87c
3d9fd27
 
 
 
 
 
 
 
 
 
 
 
f1f3914
18e25a2
3d9fd27
 
 
 
717ae43
3d9fd27
 
 
 
 
 
 
 
f1f3914
3d9fd27
 
 
 
 
 
 
 
717ae43
3d9fd27
 
 
 
9910527
3d9fd27
 
 
 
 
 
 
717ae43
3d9fd27
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import os
import time
import json
import re
from openai import OpenAI

# Basic config
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 = 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})

for msg in st.session_state.tech_messages:
    with st.chat_message(msg["role"]):
        st.markdown(msg["content"])

# Fetch assistant reply
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:
                            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):
                                cols = st.columns(4)
                                for idx, item in enumerate(results):
                                    with cols[idx % 4]:
                                        with st.container(border=True):
                                            st.markdown(f"### πŸ“ {item.get('drawing_number')} ({item.get('discipline')})", help=item.get("summary"))
                                            st.caption(item.get("summary"))

                                            with st.expander("πŸ“‚ View Drawing Details"):
                                                if item.get("question"):
                                                    st.markdown(f"**Question Match:** {item.get('question')}")
                                                if item.get("image"):
                                                    st.image(item.get("image"), caption=item.get("drawing_number"))
                                                elif item.get("images"):
                                                    for i, img in enumerate(item["images"]):
                                                        if img.startswith("http"):
                                                            st.image(img, caption=f"{item['drawing_number']} – Page {i+1}")
                        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}")