Spaces:
Sleeping
Sleeping
import gradio as gr | |
import os | |
import json | |
from openai import OpenAI | |
# ========== Config ========== | |
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") | |
ASSISTANT_ID = os.environ.get("ASSISTANT_ID") | |
client = OpenAI(api_key=OPENAI_API_KEY) | |
# ========== Functions ========== | |
def query_assistant(message): | |
try: | |
thread = client.beta.threads.create() | |
client.beta.threads.messages.create( | |
thread_id=thread.id, | |
role="user", | |
content=message | |
) | |
run = client.beta.threads.runs.create( | |
thread_id=thread.id, | |
assistant_id=ASSISTANT_ID | |
) | |
# Poll run status | |
while True: | |
run_status = client.beta.threads.runs.retrieve( | |
thread_id=thread.id, | |
run_id=run.id | |
) | |
if run_status.status in ("completed", "failed", "cancelled"): | |
break | |
if run_status.status != "completed": | |
return f"β Assistant failed: {run_status.status}", [] | |
messages = client.beta.threads.messages.list(thread_id=thread.id) | |
for m in reversed(messages.data): | |
if m.role == "assistant": | |
try: | |
parsed = json.loads(m.content[0].text.value) | |
return None, parsed.get("results", []) | |
except Exception as e: | |
return f"β οΈ Failed to parse assistant response: {e}", [] | |
return "β οΈ No assistant response found", [] | |
except Exception as e: | |
return f"β Error: {e}", [] | |
def render_cards(results): | |
cards = [] | |
for r in results: | |
title = r.get("drawing_title", "Untitled") | |
summary = r.get("summary", "") | |
pages = r.get("pages", []) | |
image_elems = [] | |
for page in pages: | |
url = page.get("public_image_url") | |
label = f"{title} β Page {page.get('page_number')}" | |
if url: | |
image_elems.append(gr.Image(value=url, label=label, show_label=True)) | |
with gr.Column(scale=1): | |
cards.append( | |
gr.Group( | |
[ | |
gr.Markdown(f"**{title}**\n\n**Summary:** {summary}"), | |
gr.Accordion("π View Drawing Pages", open=False, children=image_elems) | |
] | |
) | |
) | |
return cards | |
def on_query_submit(prompt): | |
status, results = query_assistant(prompt) | |
if status: | |
return status, [] | |
return "β Found matching drawings", render_cards(results) | |
# ========== Interface ========== | |
with gr.Blocks(theme=gr.themes.Base(), title="Forrestdale Technical Drawing Assistant") as app: | |
gr.Markdown(""" | |
# ποΈ Forrestdale Technical Drawing Assistant | |
Ask about plans, drawings or components (e.g. _Show me all electrical plans_) | |
""") | |
with gr.Row(): | |
query_input = gr.Textbox(placeholder="e.g. Show me all civil drainage plans", scale=5) | |
query_button = gr.Button("π Search", scale=1) | |
status_output = gr.Markdown("", visible=True) | |
result_display = gr.Column() | |
query_button.click(fn=on_query_submit, inputs=query_input, outputs=[status_output, result_display]) | |
# ========== Launch ========== | |
if __name__ == "__main__": | |
app.launch() | |