dikheng's picture
feat: Anatomical Region Selector — body map + dropdown inject region into prompt
4a34d56
import json
import re
from src.model_loader import generate_response
# Supported language codes: en, vn, zh, es, fr, ja
_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