File size: 3,820 Bytes
80e3a1e
4a71975
1d2d6d2
4a71975
1d2d6d2
4a71975
1d2d6d2
 
 
 
80e3a1e
1d2d6d2
 
 
 
4a71975
 
1d2d6d2
4a71975
 
1d2d6d2
 
 
 
 
4a71975
1d2d6d2
 
 
 
80e3a1e
1d2d6d2
 
 
 
 
80e3a1e
1d2d6d2
 
 
 
 
 
 
 
 
4a71975
1d2d6d2
 
 
 
 
 
4a71975
1d2d6d2
 
 
 
 
 
 
 
 
 
 
 
 
 
4a71975
1d2d6d2
4a71975
1d2d6d2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import os
import time
import json
from openai import OpenAI

# App config
st.set_page_config(page_title="๐Ÿ—๏ธ Forrestdale Technical Drawing Assistant", layout="wide")
st.title("๐Ÿ—๏ธ Forrestdale Technical Drawing Assistant")
st.caption("Ask about plans, drawings or components")

# Load secrets
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
ASSISTANT_ID = os.environ.get("ASSISTANT_ID")
client = OpenAI(api_key=OPENAI_API_KEY)

if not OPENAI_API_KEY or not ASSISTANT_ID:
    st.error("Missing secrets: OPENAI_API_KEY or ASSISTANT_ID")
    st.stop()

# Session setup
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

# Prompt input
prompt = st.chat_input("Ask something like 'Show me all civil drawings' or 'Where are the switchboards?'")
if prompt:
    st.session_state.messages.append({"role": "user", "content": prompt})

# Chat + assistant processing
if st.session_state.messages and st.session_state.messages[-1]["role"] == "user":
    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("๐Ÿ”Ž Querying assistant..."):
        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":
                    try:
                        raw = message.content[0].text.value.strip()
                        if raw.startswith("```json"):
                            raw = raw.removeprefix("```json").removesuffix("```").strip()
                        data = json.loads(raw)
                        st.session_state.messages.append({"role": "assistant", "content": data})
                    except Exception as e:
                        st.error(f"โš ๏ธ Could not parse assistant response as JSON.\n{e}")
                    break
    st.rerun()

# Card view rendering
for msg in st.session_state.messages:
    if msg["role"] == "assistant":
        data = msg["content"]
        if isinstance(data, list) and len(data) > 0:
            st.markdown("### ๐Ÿ“‹ Results")
            cols = st.columns(4)
            for i, item in enumerate(data):
                with cols[i % 4]:
                    st.image(item.get("images", [item.get("image")])[0], caption=item["drawing_number"], use_column_width=True)
                    with st.expander("Details"):
                        st.write(f"**Discipline:** {item['discipline']}")
                        st.write(f"**Summary:** {item['summary']}")
                        if "question" in item:
                            st.write(f"**Question:** {item['question']}")
                        for idx, img in enumerate(item.get("images", [])):
                            st.image(img, caption=f"Page {idx+1}", use_column_width=True)
        else:
            st.warning("Assistant returned no matching drawings.")
    elif msg["role"] == "user":
        with st.chat_message("user"):
            st.markdown(msg["content"])