File size: 5,934 Bytes
cb71624
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fe613b2
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import os
import json
import requests
import gradio as gr

BACKEND_PUBLIC_URL = os.getenv("BACKEND_PUBLIC_URL", "http://134.199.203.136:8080").rstrip("/")
AMD_LLM_MODEL = os.getenv("AMD_LLM_MODEL", "Qwen/Qwen2.5-7B-Instruct")
DEMO_MODE = os.getenv("DEMO_MODE", "true")


def backend_get(path: str):
    url = f"{BACKEND_PUBLIC_URL}{path}"
    try:
        response = requests.get(url, timeout=25)
        response.raise_for_status()
        try:
            return response.json()
        except Exception:
            return {"raw": response.text[:3000]}
    except Exception as exc:
        return {
            "error": str(exc),
            "url": url,
            "hint": "Check that the AMD backend is running and reachable."
        }


def backend_post(path: str, payload: dict):
    url = f"{BACKEND_PUBLIC_URL}{path}"
    try:
        response = requests.post(url, json=payload, timeout=90)
        response.raise_for_status()
        try:
            return response.json()
        except Exception:
            return {"raw": response.text[:5000]}
    except Exception as exc:
        return {
            "error": str(exc),
            "url": url,
            "hint": "Check the backend route in /docs. If this route does not exist, use the fallback demo."
        }


def check_backend():
    health = backend_get("/health")
    amd = backend_get("/api/amd/performance")

    return json.dumps(
        {
            "backend_url": BACKEND_PUBLIC_URL,
            "health": health,
            "amd_performance": amd,
            "model": AMD_LLM_MODEL,
            "demo_mode": DEMO_MODE,
        },
        indent=2,
        ensure_ascii=False,
    )


def run_santa_ana_demo():
    payload = {
        "scenario": "santa_ana",
        "demo_mode": True,
        "model": AMD_LLM_MODEL,
    }

    result = backend_post("/api/demo/run", payload)
    return json.dumps(result, indent=2, ensure_ascii=False)


def run_fallback_demo():
    result = {
        "status": "fallback_demo",
        "message": "Synthetic fallback demo. AMD backend may be offline or demo route may be unavailable.",
        "scenario": "Santa Ana wildfire synthetic demo",
        "signals": [
            {
                "type": "text",
                "content": "Smoke visible near hillside. Two families requesting evacuation assistance.",
                "priority_hint": "high"
            },
            {
                "type": "image_report",
                "content": "Simulated image evidence: smoke plume near residential area.",
                "priority_hint": "medium"
            },
            {
                "type": "csv_location",
                "content": "Lat/lon cluster indicates repeated alerts from the same area.",
                "priority_hint": "high"
            }
        ],
        "consolidated_incident": {
            "incident_type": "wildfire",
            "priority": "P1",
            "location": "Santa Ana synthetic demo area",
            "evidence_count": 3
        },
        "recommended_resources": [
            "evacuation support",
            "medical triage unit",
            "fire response team",
            "public alert message"
        ],
        "dispatch_message": "P1 wildfire risk near residential area. Dispatch evacuation support and fire response. Monitor wind direction and confirm affected households.",
        "amd_note": "Full backend is expected to run on AMD Developer Cloud. This fallback does not claim live GPU inference."
    }

    return json.dumps(result, indent=2, ensure_ascii=False)


with gr.Blocks(title="ReliefLens AI") as demo:
    gr.Markdown(
        """
        # 🚨 ReliefLens AI

        **Agentic disaster-response triage powered by AMD Developer Cloud.**

        ReliefLens AI turns chaotic multimodal field reports into structured incidents,
        priority labels, evidence links, resource recommendations, and dispatch-ready messages.

        This public Space calls a FastAPI backend deployed on AMD Developer Cloud.
        """
    )

    with gr.Row():
        gr.Textbox(value=BACKEND_PUBLIC_URL, label="AMD Backend URL", interactive=False)
        gr.Textbox(value=AMD_LLM_MODEL, label="Target model", interactive=False)

    with gr.Tab("1. AMD Backend Status"):
        gr.Markdown("Check whether the AMD Cloud backend is reachable.")
        status_btn = gr.Button("Check Backend")
        status_output = gr.Code(label="Backend status", language="json")
        status_btn.click(fn=check_backend, outputs=status_output)

    with gr.Tab("2. Santa Ana Demo"):
        gr.Markdown(
            """
            Runs the synthetic Santa Ana crisis-response scenario through the AMD backend.

            If the backend endpoint is not available yet, use the fallback tab.
            """
        )
        run_btn = gr.Button("Run Santa Ana Demo via AMD Backend")
        run_output = gr.Code(label="Demo output", language="json")
        run_btn.click(fn=run_santa_ana_demo, outputs=run_output)

    with gr.Tab("3. Offline Fallback Demo"):
        gr.Markdown("Safe local fallback for judges if the AMD VM is offline.")
        fallback_btn = gr.Button("Run Fallback Demo")
        fallback_output = gr.Code(label="Fallback output", language="json")
        fallback_btn.click(fn=run_fallback_demo, outputs=fallback_output)

    with gr.Tab("4. Safety / Limitations"):
        gr.Markdown(
            """
            ## Safety and limitations

            - This demo uses synthetic disaster-response data.
            - It is not connected to emergency services.
            - It should not be used for real-world emergency dispatch.
            - AMD Cloud validation should be shown with `rocm-smi`, backend status, and performance telemetry.
            - If the AMD VM is destroyed to save credits, the fallback demo remains available.
            """
        )


if __name__ == "__main__":
    demo.launch(ssr_mode=False)