"""
G-MASS: Ghana Medical AI Safety Screen
Gradio interface for open evaluation and demo use.
This app is intentionally a thin UI over the production pipeline modules:
models.router, scorer.scorer, and core.metrics. It does not define separate
model or scorer behavior.
"""
from __future__ import annotations
import html
import json
import os
import re
import sys
import tempfile
import time
from contextlib import contextmanager
from pathlib import Path
import gradio as gr
import pandas as pd
import plotly.graph_objects as go
from dotenv import load_dotenv
try:
import spaces
except Exception: # pragma: no cover - spaces exists only on Hugging Face runtimes
spaces = None
APP_DIR = Path(__file__).resolve().parent
ROOT = APP_DIR if (APP_DIR / "configs").exists() else APP_DIR.parent
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
load_dotenv(ROOT / ".env")
try:
from core.config import DOMAINS, FAILURE_CATEGORIES
from core.metrics import full_model_profile
from core.utils import ensure_dirs, load_jsonl, save_jsonl_line, utc_now
from models.router import (
BIOMISTRAL_MODEL,
GEMINI_MODEL,
GPT4O_MODEL,
PHI3_MODEL,
build_prompt_with_language_instruction,
call_model,
)
from scorer.scorer import GMassScorer
GMASS_AVAILABLE = True
IMPORT_ERROR = ""
except Exception as exc: # pragma: no cover - displayed in UI during bad deploys
GMASS_AVAILABLE = False
IMPORT_ERROR = str(exc)
LANGUAGES = {
"English": "english",
"Ghanaian English": "ghanaian_en",
"Twi": "twi",
}
MODEL_OPTIONS = {
f"GPT-4o ({GPT4O_MODEL if GMASS_AVAILABLE else 'gpt-4o'})": "gpt4o",
f"Gemini Flash ({GEMINI_MODEL if GMASS_AVAILABLE else 'gemini-2.5-flash'})": "gemini",
f"Phi-3 Mini ({PHI3_MODEL if GMASS_AVAILABLE else 'microsoft/Phi-3-mini-4k-instruct'})": "phi3",
f"BioMistral ({BIOMISTRAL_MODEL if GMASS_AVAILABLE else 'BioMistral/BioMistral-7B-SLERP'})": "biomistral",
}
REQUIRED_ENV_BY_MODEL = {
"gpt4o": "OPENAI_API_KEY",
"gemini": "GEMINI_API_KEY",
"phi3": "HF_TOKEN",
"biomistral": "HF_TOKEN",
}
APP_VERSION = "1.1.1"
PUBLIC_METRICS_PATH = ROOT / "data" / "public_metrics" / "benchmark_summary.json"
DEFAULT_RESULTS_PATH = ROOT / "data" / "eval_outputs" / "combined" / "all_models_scored.jsonl"
COMMUNITY_FEEDBACK_PATH = ROOT / "data" / "community_feedback.jsonl"
PROMPT_COLUMNS_BY_LANGUAGE = {
"english": [
"prompt",
"english_prompt",
"prompt_en",
"source_standard_english",
"probe_en",
"question_en",
],
"twi": [
"prompt",
"twi_prompt",
"prompt_twi",
"prompt_twi_validated",
"final_approved_twi",
"prompt_twi_draft",
"probe_twi",
"question_twi",
],
"ghanaian_en": [
"prompt",
"ghanaian_en_prompt",
"gh_en_prompt",
"prompt_ghanaian_en",
"final_approved_ghanaian_english",
"probe_gh_en",
"question_gh_en",
],
}
LANGUAGE_ALIASES = {
"en": "english",
"eng": "english",
"english": "english",
"tw": "twi",
"twi": "twi",
"akan": "twi",
"gh-en": "ghanaian_en",
"gh_en": "ghanaian_en",
"ghanaian_en": "ghanaian_en",
"ghanaian english": "ghanaian_en",
"ghanaian-english": "ghanaian_en",
}
if spaces is not None:
@spaces.GPU
def zerogpu_compatibility_probe():
"""Satisfy ZeroGPU startup checks; G-MASS itself uses API/CPU calls."""
return "ready"
else:
def zerogpu_compatibility_probe():
return "ready"
def _format_error_content(message: str) -> str:
lines = [line.strip() for line in message.strip().split("\n")]
html_parts = []
in_ul = False
in_ol = False
def close_lists():
nonlocal in_ul, in_ol
if in_ul:
html_parts.append("")
in_ul = False
if in_ol:
html_parts.append("")
in_ol = False
def format_inline(text: str) -> str:
escaped = html.escape(text)
escaped = re.sub(r"`([^`]+)`", r"\1", escaped)
escaped = re.sub(r"\*\*([^*]+)\*\*", r"\1", escaped)
return escaped
for line in lines:
if not line:
close_lists()
continue
ol_match = re.match(r"^(\d+)\.\s+(.*)$", line)
ul_match = re.match(r"^[โข\-\*]\s+(.*)$", line)
if ol_match:
if in_ul:
html_parts.append("")
in_ul = False
if not in_ol:
html_parts.append("
{content}
") close_lists() return "".join(html_parts) def _error(message: str) -> str: body = _format_error_content(message) return ( "{response}
Open Cross-Lingual Clinical Safety Evaluation for Medical AI in Ghanaian Languages