Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -162,14 +162,9 @@ with tab1:
|
|
162 |
with tab2:
|
163 |
ASSISTANT_ID = "asst_9v09zgizdcuuhNdcFQpRo9RO"
|
164 |
|
165 |
-
|
166 |
-
st.session_state
|
167 |
-
|
168 |
-
st.session_state.image_response = None
|
169 |
-
if "image_results" not in st.session_state:
|
170 |
-
st.session_state.image_results = []
|
171 |
-
if "image_lightbox" not in st.session_state:
|
172 |
-
st.session_state.image_lightbox = None
|
173 |
|
174 |
image_input = st.chat_input("Ask for histology visual references (e.g. ovary histology, mitosis)")
|
175 |
if image_input:
|
@@ -178,9 +173,8 @@ with tab2:
|
|
178 |
st.session_state.image_lightbox = None
|
179 |
|
180 |
try:
|
181 |
-
if st.session_state.image_thread_id
|
182 |
-
|
183 |
-
st.session_state.image_thread_id = thread.id
|
184 |
|
185 |
client.beta.threads.messages.create(
|
186 |
thread_id=st.session_state.image_thread_id,
|
@@ -210,34 +204,33 @@ with tab2:
|
|
210 |
response_text = msg.content[0].text.value
|
211 |
st.session_state.image_response = response_text
|
212 |
|
213 |
-
# ✅
|
214 |
lines = response_text.splitlines()
|
215 |
-
|
216 |
-
|
217 |
|
218 |
for line in lines:
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
if
|
234 |
-
st.session_state.image_lightbox =
|
235 |
break
|
236 |
except Exception as e:
|
237 |
st.error(f"❌ Visual Assistant Error: {e}")
|
238 |
|
239 |
text_col, image_col = st.columns([2, 1])
|
240 |
-
|
241 |
with text_col:
|
242 |
if st.session_state.image_response:
|
243 |
st.markdown("### 🧠 Assistant Response")
|
@@ -246,30 +239,30 @@ with tab2:
|
|
246 |
with image_col:
|
247 |
if st.session_state.image_results:
|
248 |
st.markdown("### 🖼️ Image Preview(s)")
|
249 |
-
|
250 |
-
|
251 |
-
|
|
|
252 |
try:
|
253 |
-
r = requests.get(
|
254 |
r.raise_for_status()
|
255 |
img = Image.open(BytesIO(r.content))
|
256 |
-
st.image(img, caption=
|
257 |
-
|
258 |
-
|
|
|
259 |
except Exception as e:
|
260 |
-
st.warning(f"⚠️ Could not load: {
|
261 |
-
st.error(f"{e}")
|
262 |
else:
|
263 |
st.info("ℹ️ No image references found yet.")
|
264 |
|
265 |
if st.session_state.image_lightbox:
|
266 |
st.markdown("### 🔬 Full Image View")
|
267 |
try:
|
268 |
-
|
269 |
-
r = requests.get(img_url, timeout=10)
|
270 |
r.raise_for_status()
|
271 |
full_img = Image.open(BytesIO(r.content))
|
272 |
-
st.image(full_img, caption=
|
273 |
except Exception as e:
|
274 |
st.warning("⚠️ Could not load full image.")
|
275 |
st.error(str(e))
|
|
|
162 |
with tab2:
|
163 |
ASSISTANT_ID = "asst_9v09zgizdcuuhNdcFQpRo9RO"
|
164 |
|
165 |
+
for key in ["image_thread_id", "image_response", "image_results", "image_lightbox"]:
|
166 |
+
if key not in st.session_state:
|
167 |
+
st.session_state[key] = None if "id" in key or "lightbox" in key else []
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
image_input = st.chat_input("Ask for histology visual references (e.g. ovary histology, mitosis)")
|
170 |
if image_input:
|
|
|
173 |
st.session_state.image_lightbox = None
|
174 |
|
175 |
try:
|
176 |
+
if not st.session_state.image_thread_id:
|
177 |
+
st.session_state.image_thread_id = client.beta.threads.create().id
|
|
|
178 |
|
179 |
client.beta.threads.messages.create(
|
180 |
thread_id=st.session_state.image_thread_id,
|
|
|
204 |
response_text = msg.content[0].text.value
|
205 |
st.session_state.image_response = response_text
|
206 |
|
207 |
+
# ✅ Image metadata parser
|
208 |
lines = response_text.splitlines()
|
209 |
+
image_entries = []
|
210 |
+
current = {"title": "", "description": "", "url": ""}
|
211 |
|
212 |
for line in lines:
|
213 |
+
if line.startswith("### 🖼️"):
|
214 |
+
current = {"title": line.replace("### 🖼️", "").strip(), "description": "", "url": ""}
|
215 |
+
elif line.strip().startswith("- **Description:**"):
|
216 |
+
current["description"] = line.split("**Description:**")[-1].strip()
|
217 |
+
elif "Image URL:" in line:
|
218 |
+
match = re.search(r'(https://[^\s]+)', line)
|
219 |
+
if match:
|
220 |
+
current["url"] = match.group(1)
|
221 |
+
image_entries.append(current)
|
222 |
+
elif line.strip().startswith("https://") and current["url"] == "":
|
223 |
+
current["url"] = line.strip()
|
224 |
+
image_entries.append(current)
|
225 |
+
|
226 |
+
st.session_state.image_results = image_entries
|
227 |
+
if image_entries and not st.session_state.image_lightbox:
|
228 |
+
st.session_state.image_lightbox = image_entries[0]["url"]
|
229 |
break
|
230 |
except Exception as e:
|
231 |
st.error(f"❌ Visual Assistant Error: {e}")
|
232 |
|
233 |
text_col, image_col = st.columns([2, 1])
|
|
|
234 |
with text_col:
|
235 |
if st.session_state.image_response:
|
236 |
st.markdown("### 🧠 Assistant Response")
|
|
|
239 |
with image_col:
|
240 |
if st.session_state.image_results:
|
241 |
st.markdown("### 🖼️ Image Preview(s)")
|
242 |
+
cols = st.columns(4)
|
243 |
+
for idx, entry in enumerate(st.session_state.image_results):
|
244 |
+
col = cols[idx % 4]
|
245 |
+
with col:
|
246 |
try:
|
247 |
+
r = requests.get(entry["url"], timeout=10)
|
248 |
r.raise_for_status()
|
249 |
img = Image.open(BytesIO(r.content))
|
250 |
+
st.image(img, caption=entry["title"], use_container_width=True)
|
251 |
+
st.caption(entry["description"][:100] + "...")
|
252 |
+
if st.button("🔍 View", key=f"view_{idx}"):
|
253 |
+
st.session_state.image_lightbox = entry["url"]
|
254 |
except Exception as e:
|
255 |
+
st.warning(f"⚠️ Could not load image: {entry['url']}")
|
|
|
256 |
else:
|
257 |
st.info("ℹ️ No image references found yet.")
|
258 |
|
259 |
if st.session_state.image_lightbox:
|
260 |
st.markdown("### 🔬 Full Image View")
|
261 |
try:
|
262 |
+
r = requests.get(st.session_state.image_lightbox, timeout=10)
|
|
|
263 |
r.raise_for_status()
|
264 |
full_img = Image.open(BytesIO(r.content))
|
265 |
+
st.image(full_img, caption=st.session_state.image_lightbox.split('/')[-1], use_container_width=True)
|
266 |
except Exception as e:
|
267 |
st.warning("⚠️ Could not load full image.")
|
268 |
st.error(str(e))
|