File size: 7,394 Bytes
d10de1b
134b798
 
d10de1b
134b798
 
d10de1b
cbca53c
d10de1b
 
134b798
 
 
d10de1b
 
134b798
 
 
d10de1b
134b798
d10de1b
 
134b798
 
 
 
d10de1b
134b798
d10de1b
 
134b798
d10de1b
cbca53c
134b798
 
d10de1b
 
 
 
 
 
 
 
 
 
 
134b798
 
 
 
 
 
 
 
d10de1b
134b798
 
 
d10de1b
 
134b798
 
d10de1b
134b798
 
 
d10de1b
 
 
134b798
 
d10de1b
134b798
 
 
 
d10de1b
 
 
134b798
d10de1b
 
134b798
 
d10de1b
 
134b798
d10de1b
134b798
d10de1b
 
134b798
d10de1b
 
 
 
 
 
 
 
134b798
 
d10de1b
134b798
d10de1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134b798
d10de1b
 
134b798
d10de1b
 
134b798
 
 
 
 
 
d10de1b
 
 
 
 
134b798
 
d10de1b
134b798
 
d10de1b
134b798
d10de1b
 
 
134b798
d10de1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134b798
 
d10de1b
 
 
 
134b798
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
172
"""
app.py โ€” NLP4ASD Gradio interface.
Entry point for both local use and Hugging Face Spaces deployment.

On first startup the knowledge base is built automatically if missing.
"""

import spaces
import gradio as gr

from config       import PROFILES, LANGUAGES, VECTOR_INDEX_PATH
from utils        import file_exists
from rag_pipeline import answer, build_knowledge_base


# โ”€โ”€ Auto-build index on startup โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

def _ensure_index():
    if not file_exists(VECTOR_INDEX_PATH):
        print("[app] Index not found โ€” building knowledge base on first startup...")
        try:
            build_knowledge_base()
            print("[app] Knowledge base ready.")
        except Exception as e:
            print(f"[app] โš ๏ธ  Could not build index automatically: {e}")
            print("[app]    Run manually: python build_knowledge_base.py")

_ensure_index()


# โ”€โ”€ Query handler โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

@spaces.GPU
def query_handler(question: str, profile: str, language: str):
    """Called by Gradio on each submission. Returns (answer, sources, disclaimer)."""
    if not question.strip():
        return "Please enter a question.", "", ""

    result = answer(question, profile, language)

    if result["error"]:
        return f"โš ๏ธ {result['error']}", "", ""

    return result["answer"], result["sources"], result["disclaimer"]


def rebuild_handler():
    """Called by the Rebuild button in the Advanced accordion."""
    try:
        build_knowledge_base()
        return "โœ… Knowledge base rebuilt successfully."
    except Exception as e:
        return f"โŒ {e}"


# โ”€โ”€ Gradio UI โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

_DESCRIPTION = """
## ๐Ÿงฉ NLP4ASD โ€” Autism Spectrum Disorder Assistant

Answers questions about ASD using **retrieved scientific sources**.  
Response style adapts automatically to your selected profile.

1. Choose your **profile** and **language**
2. Type your **question**
3. The system retrieves relevant passages and generates a grounded answer
"""

with gr.Blocks(
    theme=gr.themes.Soft(primary_hue="indigo", secondary_hue="blue", neutral_hue="slate"),
    title="NLP4ASD",
    css="""
        .answer-box textarea  { font-size:15px; line-height:1.7; }
        .source-box textarea  { font-size:13px; color:#555; }
        .disclaimer textarea  { font-size:12px; color:#888; font-style:italic; }
        footer { display:none !important; }
    """,
) as demo:

    gr.Markdown(_DESCRIPTION)

    with gr.Row():

        # โ”€โ”€ Left column: inputs โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        with gr.Column(scale=1):
            profile_input = gr.Dropdown(
                choices=PROFILES, value=PROFILES[0],
                label="๐Ÿ‘ค Your Profile",
                info="The answer style will adapt to your background.",
            )
            language_input = gr.Dropdown(
                choices=LANGUAGES, value=LANGUAGES[0],
                label="๐ŸŒ Language",
            )
            question_input = gr.Textbox(
                label="โ“ Your Question",
                placeholder="e.g. What are the early signs of autism in toddlers?",
                lines=4,
            )
            with gr.Row():
                submit_btn = gr.Button("๐Ÿ” Ask",   variant="primary", scale=3)
                clear_btn  = gr.Button("๐Ÿ—‘ Clear",  scale=1)

        # โ”€โ”€ Right column: outputs โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
        with gr.Column(scale=2):
            answer_output = gr.Textbox(
                label="๐Ÿ’ฌ Answer",
                lines=10,
                interactive=False,
                elem_classes=["answer-box"],
            )
            sources_output = gr.Textbox(
                label="๐Ÿ“š Sources",
                lines=4,
                interactive=False,
                elem_classes=["source-box"],
            )
            disclaimer_output = gr.Textbox(
                label="โš ๏ธ Disclaimer",
                lines=2,
                interactive=False,
                elem_classes=["disclaimer"],
            )

    # โ”€โ”€ Example questions โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    gr.Examples(
        examples=[
            ["What are the early signs of autism in toddlers?",                          "Parent",                   "English"],
            ["How does sensory overload affect autistic people day to day?",              "Patient / Autistic person", "English"],
            ["What pharmacological treatments are evidence-based for ASD?",              "Healthcare Professional",   "English"],
            ["What classroom accommodations help autistic students the most?",           "Teacher / Educator",        "English"],
            ["What does the genetic heritability research say about ASD?",               "Researcher",                "English"],
            ["Qu'est-ce que le burnout autistique et comment le reconnaรฎtre ?",          "Patient / Autistic person", "French"],
        ],
        inputs=[question_input, profile_input, language_input],
        label="Example Questions",
    )

    # โ”€โ”€ Advanced: rebuild index โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    with gr.Accordion("๐Ÿ”ง Advanced โ€” Rebuild Knowledge Base", open=False):
        gr.Markdown(
            "Use this after adding new `.txt` files to `data/raw/`. "
            "Rebuilds the FAISS index from scratch."
        )
        rebuild_btn    = gr.Button("โ™ป๏ธ Rebuild Index", variant="secondary")
        rebuild_status = gr.Textbox(label="Status", interactive=False, lines=2)
        rebuild_btn.click(rebuild_handler, outputs=rebuild_status)

    # โ”€โ”€ Wire up events โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    submit_btn.click(
        query_handler,
        inputs=[question_input, profile_input, language_input],
        outputs=[answer_output, sources_output, disclaimer_output],
    )
    question_input.submit(
        query_handler,
        inputs=[question_input, profile_input, language_input],
        outputs=[answer_output, sources_output, disclaimer_output],
    )
    clear_btn.click(
        lambda: ("", "", "", ""),
        outputs=[question_input, answer_output, sources_output, disclaimer_output],
    )

    gr.Markdown(
        "---\n*NLP4ASD is a research prototype. "
        "Always consult a qualified professional for medical decisions.*"
    )


if __name__ == "__main__":
    demo.launch(show_error=True)