Spaces:
Running
Running
| import os, requests, json, time | |
| from utils.constants import ROUTER_TEXTGEN_URL, REQUEST_TIMEOUT_SECONDS_DEFAULT, RETRIES_DEFAULT, BACKOFF_SECONDS_DEFAULT | |
| from utils.persona import AI_GYNO_PERSONA_V4 | |
| def _headers(): | |
| tok = os.getenv("HF_API_TOKEN") or os.getenv("HF_TOKEN") | |
| return {"Authorization": f"Bearer {tok}", "Content-Type": "application/json"} if tok else {} | |
| def chat(user_message: str, mode: str = "patient") -> str: | |
| url = os.getenv("HF_CHAT_ENDPOINT") or ROUTER_TEXTGEN_URL | |
| headers = _headers() | |
| if not headers: | |
| return "β Set HF_API_TOKEN (or HF_TOKEN) in Secrets." | |
| style = "Explain simply and reassure." if mode=="patient" else "Use clinical phrasing, list differentials and next steps." | |
| prompt = f"""{AI_GYNO_PERSONA_V4} | |
| Patient message: | |
| {user_message} | |
| Mode: {mode} | |
| Instructions: | |
| - {style} | |
| - Provide likely causes, initial tests, red-flags (2-5), and 2-3 next steps. | |
| - If missing key info, ask 2 follow-up questions. | |
| - Keep response concise (<= 250 words). | |
| """ | |
| payload = { | |
| "inputs": prompt, | |
| "parameters": {"max_new_tokens": 400, "temperature": 0.2, "return_full_text": False} | |
| } | |
| for attempt in range(1, RETRIES_DEFAULT+1): | |
| try: | |
| r = requests.post(url, headers=headers, json=payload, timeout=REQUEST_TIMEOUT_SECONDS_DEFAULT) | |
| txt = r.text | |
| # detect HTML / loading | |
| if "<html" in txt.lower(): | |
| if "loading" in txt.lower(): | |
| time.sleep(BACKOFF_SECONDS_DEFAULT * attempt); continue | |
| return f"β Non-JSON HTML response: {txt[:500]}" | |
| try: | |
| data = r.json() | |
| except Exception: | |
| return txt[:2000] | |
| # Text generation style | |
| if isinstance(data, list) and data and "generated_text" in data[0]: | |
| return data[0]["generated_text"] | |
| if isinstance(data, dict) and "generated_text" in data: | |
| return data["generated_text"] | |
| # Some routers return {'text': '...'} or similar | |
| if isinstance(data, dict) and "text" in data: | |
| return data["text"] | |
| return "β Unexpected response: " + json.dumps(data)[:1200] | |
| except Exception as e: | |
| time.sleep(BACKOFF_SECONDS_DEFAULT * attempt) | |
| return "β Endpoint unreachable after retries." | |