File size: 3,374 Bytes
a1ea7b4 229fc53 a1ea7b4 229fc53 a1ea7b4 229fc53 4a34d56 a1ea7b4 229fc53 4a34d56 229fc53 4a34d56 58e50ff 2a98f28 58e50ff 2a98f28 58e50ff 229fc53 a1ea7b4 229fc53 a1ea7b4 229fc53 4a34d56 229fc53 a1ea7b4 c19c1f8 229fc53 4a34d56 c19c1f8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | 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
|