Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -164,9 +164,11 @@ with tab2:
|
|
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 "
|
|
|
|
|
|
|
168 |
|
169 |
-
image_input = st.chat_input("Ask for histology visual references (e.g. ovary histology, mitosis)")
|
170 |
if image_input:
|
171 |
st.session_state.image_response = None
|
172 |
st.session_state.image_results = []
|
@@ -187,85 +189,68 @@ with tab2:
|
|
187 |
assistant_id=ASSISTANT_ID
|
188 |
)
|
189 |
|
190 |
-
with st.spinner("
|
191 |
while True:
|
192 |
-
|
193 |
thread_id=st.session_state.image_thread_id,
|
194 |
run_id=run.id
|
195 |
)
|
196 |
-
if
|
197 |
break
|
198 |
time.sleep(1)
|
199 |
|
200 |
-
if
|
201 |
messages = client.beta.threads.messages.list(thread_id=st.session_state.image_thread_id)
|
202 |
for msg in reversed(messages.data):
|
203 |
if msg.role == "assistant":
|
204 |
response_text = msg.content[0].text.value
|
205 |
st.session_state.image_response = response_text
|
206 |
|
207 |
-
#
|
208 |
lines = response_text.splitlines()
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
for line in lines:
|
213 |
-
if line.startswith("### ๐ผ๏ธ"):
|
214 |
-
|
215 |
-
|
216 |
-
|
|
|
|
|
|
|
217 |
elif "Image URL:" in line:
|
218 |
-
|
219 |
-
|
220 |
-
|
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")
|
237 |
-
st.markdown(st.session_state.image_response, unsafe_allow_html=True)
|
238 |
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
|
259 |
if st.session_state.image_lightbox:
|
260 |
st.markdown("### ๐ฌ Full Image View")
|
261 |
try:
|
262 |
-
|
263 |
-
|
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.
|
268 |
-
|
269 |
-
if st.button("โ Close Preview"):
|
270 |
st.session_state.image_lightbox = None
|
271 |
st.rerun()
|
|
|
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 "response" in key else []
|
168 |
+
|
169 |
+
st.markdown("### ๐ Search Histology Visual References")
|
170 |
+
image_input = st.chat_input("e.g. mitosis, seminiferous tubule, cell cycle")
|
171 |
|
|
|
172 |
if image_input:
|
173 |
st.session_state.image_response = None
|
174 |
st.session_state.image_results = []
|
|
|
189 |
assistant_id=ASSISTANT_ID
|
190 |
)
|
191 |
|
192 |
+
with st.spinner("๐งฌ Retrieving images..."):
|
193 |
while True:
|
194 |
+
status = client.beta.threads.runs.retrieve(
|
195 |
thread_id=st.session_state.image_thread_id,
|
196 |
run_id=run.id
|
197 |
)
|
198 |
+
if status.status in ("completed", "failed", "cancelled"):
|
199 |
break
|
200 |
time.sleep(1)
|
201 |
|
202 |
+
if status.status == "completed":
|
203 |
messages = client.beta.threads.messages.list(thread_id=st.session_state.image_thread_id)
|
204 |
for msg in reversed(messages.data):
|
205 |
if msg.role == "assistant":
|
206 |
response_text = msg.content[0].text.value
|
207 |
st.session_state.image_response = response_text
|
208 |
|
209 |
+
# Extract URLs and details for grid card display
|
210 |
lines = response_text.splitlines()
|
211 |
+
block = {}
|
212 |
+
all_cards = []
|
|
|
213 |
for line in lines:
|
214 |
+
if line.strip().startswith("### ๐ผ๏ธ"):
|
215 |
+
if block: all_cards.append(block)
|
216 |
+
block = {"title": line.replace("### ๐ผ๏ธ", "").strip()}
|
217 |
+
elif "Page:" in line:
|
218 |
+
block["page"] = line.split("Page:")[1].strip()
|
219 |
+
elif "Description:" in line:
|
220 |
+
block["desc"] = line.split("Description:")[1].strip()
|
221 |
elif "Image URL:" in line:
|
222 |
+
block["url"] = line.split("Image URL:")[1].strip()
|
223 |
+
if block: all_cards.append(block)
|
224 |
+
st.session_state.image_results = all_cards
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
|
227 |
+
except Exception as e:
|
228 |
+
st.error(f"โ Assistant Error: {e}")
|
229 |
+
|
230 |
+
# ๐ Display Image Cards
|
231 |
+
if st.session_state.image_results:
|
232 |
+
st.markdown("### ๐ผ๏ธ Image Results")
|
233 |
+
cols = st.columns(4)
|
234 |
+
for idx, item in enumerate(st.session_state.image_results):
|
235 |
+
with cols[idx % 4]:
|
236 |
+
try:
|
237 |
+
img = Image.open(BytesIO(requests.get(item["url"]).content))
|
238 |
+
st.image(img, use_container_width=True)
|
239 |
+
except:
|
240 |
+
st.image("https://via.placeholder.com/150?text=Error", use_container_width=True)
|
241 |
+
|
242 |
+
st.markdown(f"**{item['title']}**", unsafe_allow_html=True)
|
243 |
+
st.caption(item.get("desc", "")[:150] + "...")
|
244 |
+
if st.button("๐ View", key=f"img_{idx}"):
|
245 |
+
st.session_state.image_lightbox = item["url"]
|
246 |
|
247 |
if st.session_state.image_lightbox:
|
248 |
st.markdown("### ๐ฌ Full Image View")
|
249 |
try:
|
250 |
+
full_img = Image.open(BytesIO(requests.get(st.session_state.image_lightbox).content))
|
251 |
+
st.image(full_img, use_container_width=True)
|
|
|
|
|
252 |
except Exception as e:
|
253 |
+
st.error(f"โ ๏ธ Could not load full image: {e}")
|
254 |
+
if st.button("โ Close Image View"):
|
|
|
255 |
st.session_state.image_lightbox = None
|
256 |
st.rerun()
|