Spaces:
Sleeping
Sleeping
| import os | |
| import uuid | |
| import asyncio.base_events as base_events | |
| import gradio as gr | |
| from PIL import Image | |
| from nivra_agent import nivra_chat, nivra_vision, log_call | |
| def _patch_asyncio_event_loop_del(): | |
| """ | |
| Suppress known event loop cleanup crashes seen on some HF Space runtimes. | |
| """ | |
| original_del = getattr(base_events.BaseEventLoop, "__del__", None) | |
| if original_del is None: | |
| return | |
| def patched_del(self): | |
| try: | |
| original_del(self) | |
| except ValueError as exc: | |
| if "Invalid file descriptor" not in str(exc): | |
| raise | |
| base_events.BaseEventLoop.__del__ = patched_del | |
| _patch_asyncio_event_loop_del() | |
| # ================================================== | |
| # Constants | |
| # ================================================== | |
| UPLOAD_DIR = "/tmp/uploads" | |
| os.makedirs(UPLOAD_DIR, exist_ok=True) | |
| SPACE_HOST = os.environ.get( | |
| "SPACE_HOST", | |
| "https://datdevsteve-nivra-ai-agent.hf.space" | |
| ) | |
| # ================================================== | |
| # CHAT ENDPOINT | |
| # ================================================== | |
| def chat_fn(message, history): | |
| history = history or [] | |
| history.append({"role": "user", "content": message}) | |
| response = nivra_chat(message, history) | |
| history.append({"role": "assistant", "content": response}) | |
| # 🔥 LOG CHAT CALL | |
| log_call( | |
| input_type="TEXT", | |
| input_value=message, | |
| output_value=response | |
| ) | |
| return history, "" | |
| # ================================================== | |
| # 🆕 VISION ENDPOINT (URL-BASED) | |
| # ================================================== | |
| def vision_fn(image_url: str, hint_text: str): | |
| response = nivra_vision(image_url, hint_text) | |
| # 🔥 LOG IMAGE CALL AT API ENTRY LEVEL | |
| log_call( | |
| input_type="IMAGE", | |
| input_value=image_url, | |
| output_value=response | |
| ) | |
| return response | |
| # ================================================== | |
| # UI + API | |
| # ================================================== | |
| with gr.Blocks(title="🩺 Nivra AI Agent") as demo: | |
| gr.Markdown( | |
| "# 🩺 Nivra AI Agent\n" | |
| "_AI-powered healthcare assistant for preliminary guidance._" | |
| ) | |
| # ------------------------------- | |
| # Chat UI | |
| # ------------------------------- | |
| chatbot = gr.Chatbot(show_label=False, type="messages") # type: ignore | |
| txt = gr.Textbox( | |
| placeholder="Describe your symptoms (e.g. fever, headache, rash)..." | |
| ) | |
| send = gr.Button("Send") | |
| send.click(chat_fn, inputs=[txt, chatbot], outputs=[chatbot, txt]) | |
| txt.submit(chat_fn, inputs=[txt, chatbot], outputs=[chatbot, txt]) | |
| # ------------------------------- | |
| # 🔒 Hidden Vision API (Flutter) | |
| # ------------------------------- | |
| gr.Button(visible=False).click( | |
| vision_fn, | |
| inputs=[ | |
| gr.Textbox(label="image_url"), | |
| gr.Textbox(label="hint_text"), | |
| ], | |
| outputs=[gr.Textbox()], | |
| api_name="vision_fn", | |
| ) | |
| # ================================================== | |
| # Launch (HF-safe) | |
| # ================================================== | |
| launch_kwargs = { | |
| "server_name": "0.0.0.0", | |
| "ssr_mode": False, | |
| "show_error": True, | |
| } | |
| configured_port = os.environ.get("GRADIO_SERVER_PORT") or os.environ.get("PORT") | |
| if configured_port: | |
| launch_kwargs["server_port"] = int(configured_port) | |
| demo.launch(**launch_kwargs) | |