| import json |
| import re |
| from src.model_loader import generate_response |
|
|
| |
|
|
| _LANG_INSTRUCTIONS = { |
| "en": "Respond in English.", |
| "vn": "Respond in Vietnamese (Tiếng Việt).", |
| "zh": "Respond in Simplified Chinese (简体中文).", |
| "es": "Respond in Spanish (Español).", |
| "fr": "Respond in French (Français).", |
| "ja": "Respond in Japanese (日本語).", |
| } |
|
|
|
|
| def _build_prompt(image_path: str | None, text_description: str, lang: str, region: str = "") -> str: |
| lang_instruction = _LANG_INSTRUCTIONS.get(lang, _LANG_INSTRUCTIONS["en"]) |
| has_image = bool(image_path) |
| region_line = f"Affected body region: {region}\n" if region else "" |
| return ( |
| "You are MediVision, a professional dermatology and wound-care assistant.\n" |
| f"{lang_instruction}\n" |
| "The user has provided" |
| + (" an image of a skin condition and" if has_image else "") |
| + " the following clinical information:\n\n" |
| + region_line |
| + f"Symptom description: {text_description}\n\n" |
| "Analyze the above and respond with a single JSON object using these exact keys:\n" |
| " \"diagnosis\": the standard clinical/medical condition name (e.g. contact dermatitis, " |
| "superficial laceration, cellulitis, tinea corporis) — NOT a restatement or summary of the " |
| "patient's symptom text. You MUST translate this medical term into the language specified above.\n" |
| " \"severity\": MUST be exactly one of these English words (do not translate): " |
| "Low | Medium | High | Urgent\n" |
| " \"recommended_actions\": list of 3-5 actionable clinical recommendations, " |
| "written in the language specified above\n" |
| " \"confidence_score\": integer 0-100\n" |
| "CRITICAL: \"diagnosis\" and all items in \"recommended_actions\" MUST be written in " |
| "the language specified above. \"severity\" MUST stay as one English word.\n" |
| "Return only the JSON object, no extra text." |
| ) |
|
|
|
|
| def _parse_response(raw: str) -> dict: |
| match = re.search(r'\{.*\}', raw, re.DOTALL) |
| if match: |
| try: |
| data = json.loads(match.group()) |
| return { |
| "diagnosis": data.get("diagnosis", "Unknown"), |
| "severity": data.get("severity", "Low"), |
| "recommended_actions": data.get("recommended_actions", []), |
| "confidence_score": int(data.get("confidence_score", 70)), |
| } |
| except (json.JSONDecodeError, ValueError): |
| pass |
| raise ValueError(f"Could not parse model response as JSON: {raw[:200]}") |
|
|
|
|
| def analyze_image_and_text( |
| image_path: str | None, |
| text_description: str, |
| language: str = "en", |
| region: str = "", |
| ) -> dict: |
| """ |
| Run analysis via AMD Cloud backend. |
| Raises RuntimeError if the backend is unreachable. |
| Raises ValueError if the model response cannot be parsed. |
| |
| Returns dict with keys: diagnosis, severity, recommended_actions, |
| confidence_score, _metrics (latency_ms, total_tokens, tokens_per_sec). |
| """ |
| lang = language.lower() |
| prompt = _build_prompt(image_path, text_description, lang, region=region) |
| raw, metrics = generate_response(prompt, image_path=image_path) |
| result = _parse_response(raw) |
| result["_metrics"] = metrics |
| return result |
|
|