File size: 7,140 Bytes
f10a835
f064c62
f10a835
193db9d
 
973519b
 
55d797c
193db9d
f064c62
 
 
 
 
 
0bab47c
f064c62
193db9d
 
f10a835
55d797c
3b39b49
4b84911
193db9d
 
633b045
973519b
4b84911
 
 
7985347
973519b
 
4b84911
55d797c
bdbc03c
973519b
 
4b84911
973519b
 
54e2d5b
973519b
54e2d5b
5f3e7d5
 
f064c62
193db9d
973519b
 
f064c62
973519b
 
 
55d797c
193db9d
55d797c
193db9d
 
 
 
 
 
 
 
 
 
 
 
 
55d797c
 
 
 
 
 
f10a835
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22e8b31
 
54e2d5b
22e8b31
 
55d797c
 
193db9d
 
22e8b31
55d797c
 
193db9d
d43ec9f
22e8b31
f10a835
 
 
 
 
 
22e8b31
f10a835
 
f064c62
bdbc03c
 
f10a835
 
bdbc03c
f10a835
4b84911
 
f10a835
4b84911
7985347
4b84911
bdbc03c
 
f10a835
 
55d797c
 
f10a835
 
 
 
55d797c
f10a835
 
 
 
f064c62
 
9756440
 
 
 
 
 
193db9d
f10a835
 
f064c62
 
f10a835
 
 
 
 
 
 
 
 
 
 
 
 
 
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
173
174
175
176
import json
import sys

import datasets
import gradio as gr
from apscheduler.schedulers.background import BackgroundScheduler
from huggingface_hub import snapshot_download
from loguru import logger

from envs import LOG_LEVEL

# Set the log level to INFO
logger.remove()
logger.add(sys.stdout, level=LOG_LEVEL, diagnose=False)

from app_configs import DEFAULT_SELECTIONS, THEME
from components.hf_pipelines import create_hf_pipeline_submission_interface
from components.quizbowl.bonus import BonusInterface
from components.quizbowl.tossup import TossupInterface
from components.typed_dicts import PipelineInterfaceDefaults, TossupInterfaceDefaults
from display.css_html_js import fonts_header, js_head, leaderboard_css
from display.custom_css import css_bonus, css_pipeline, css_tossup
from display.guide import BUILDING_MARKDOWN, QUICKSTART_MARKDOWN

# Constants
from envs import (
    API,
    COMPETITION_URL,
    CONTACT_EMAIL,
    DISCORD_URL,
    DOCS_REPO_URL,
    EVAL_REQUESTS_PATH,
    EVAL_RESULTS_PATH,
    GITHUB_ISSUES_URL,
    LEADERBOARD_REFRESH_INTERVAL,
    LEADERBOARD_URL,
    PLAYGROUND_DATASET_NAMES,
    QUEUE_REPO,
    REGISTRATION_URL,
    REPO_ID,
    RESULTS_REPO,
    SERVER_RESTART_INTERVAL,
)
from hf_datasets_utils import download_dataset_snapshot
from shared.workflows import factory
from shared.workflows.configs import AVAILABLE_MODELS
from shared.workflows.llms import llm_cache


def restart_space():
    llm_cache.sync_to_hf()
    API.restart_space(repo_id=REPO_ID)


download_dataset_snapshot(QUEUE_REPO, EVAL_REQUESTS_PATH)


def load_dataset(mode: str):
    if mode == "tossup":
        ds = datasets.load_dataset(PLAYGROUND_DATASET_NAMES["tossup"], split="eval")
        ds = ds.filter(lambda x: x["qid"].split("-")[2] == "1" and int(x["qid"].split("-")[3]) <= 10)
    elif mode == "bonus":
        ds = datasets.load_dataset(PLAYGROUND_DATASET_NAMES["bonus"], split="eval")
        ds = ds.filter(lambda x: x["qid"].split("-")[2] == "1" and int(x["qid"].split("-")[3]) <= 10)
    else:
        raise ValueError(f"Invalid mode: {mode}")

    return ds


def get_default_tab_id(request: gr.Request):
    logger.info(f"Request: {request}")
    tab_key_value = request.query_params.get("tab", "tossup")
    return gr.update(selected=tab_key_value)


def presave_pipeline_state(
    login_btn,
    browser_state: dict,
    tossup_pipeline_state: dict,
    tossup_output_state: dict,
    bonus_pipeline_state: dict,
    bonus_output_state: dict,
):
    browser_state.setdefault("tossup", {})
    browser_state["tossup"]["pipeline_state"] = tossup_pipeline_state
    browser_state["tossup"]["output_state"] = tossup_output_state
    browser_state.setdefault("bonus", {})
    browser_state["bonus"]["pipeline_state"] = bonus_pipeline_state
    browser_state["bonus"]["output_state"] = bonus_output_state
    logger.debug(
        f"Pipeline state before login. Login button: {login_btn}, browser state: {json.dumps(browser_state, indent=4)}"
    )
    return login_btn, browser_state


if __name__ == "__main__":
    scheduler = BackgroundScheduler()
    scheduler.add_job(restart_space, "interval", seconds=SERVER_RESTART_INTERVAL)
    scheduler.start()

    css = css_pipeline + css_tossup + css_bonus + leaderboard_css
    head = fonts_header + js_head
    tossup_ds = load_dataset("tossup")
    bonus_ds = load_dataset("bonus")
    with gr.Blocks(
        css=css,
        head=head,
        theme=THEME,
        title="QANTA 2025 Quizbowl Competition",
    ) as demo:
        browser_state = gr.BrowserState(
            {
                "tossup": {"pipeline_state": None, "output_state": None},
                "bonus": {"pipeline_state": None, "output_state": None},
            }
        )
        with gr.Row():
            with gr.Column(scale=5):
                gr.Markdown(
                    f"## πŸ€– Welcome to QANTA 2025 Quizbowl Arena! &emsp;&emsp;&emsp; πŸ‘‰ πŸ† [Leaderboard]({LEADERBOARD_URL}) πŸ‘ˆ"
                    "\n### 🎲 Create, play around, and submit your quizbowl agents."
                    f"<br>πŸ“‹ [Register]({REGISTRATION_URL}) to participate in our [QANTA 2025 Human-AI Quizbowl Competition]({COMPETITION_URL}).",
                    elem_classes="welcome-text",
                )
            # leaderboard_btn = gr.Button("πŸ† Leaderboard", elem_id="leaderboard-btn", link=LEADERBOARD_URL)
            login_btn = gr.LoginButton(scale=1)

        accent_color = "#B00000"
        gr.Markdown(
            f"πŸ‘€ <span style='color:{accent_color};font-weight:bold;'>First time here?</span> Check out the [❓ Help](#help) tab for a quick introduction and "
            f"[QANTA25 Documentation]({DOCS_REPO_URL}) "
            "for detailed examples and tutorials on how to create and compete with your own QuizBowl agents. "
            f"<br>🀨 <span style='color:{accent_color};font-weight:bold;'>Facing any issues?</span> Please contact us at [{CONTACT_EMAIL}](mailto:{CONTACT_EMAIL}), or raise an issue on our [GitHub repository]({GITHUB_ISSUES_URL})."
            f" &nbsp; πŸ§‘πŸ»β€πŸ’» <span style='color:{accent_color};font-weight:bold;'>Engagements?</span> Join our [Discord server]({DISCORD_URL}) for discussions and getting help.",
            elem_classes="help-text",
        )
        with gr.Tabs() as gtab:
            with gr.Tab("πŸ›ŽοΈ Tossup Agents", id="tossup"):
                defaults = TossupInterfaceDefaults(
                    **DEFAULT_SELECTIONS["tossup"], init_workflow=factory.create_simple_qb_tossup_workflow()
                )
                tossup_interface = TossupInterface(demo, browser_state, tossup_ds, AVAILABLE_MODELS, defaults)
            with gr.Tab("πŸ™‹πŸ»β€β™‚οΈ Bonus Round Agents", id="bonus"):
                defaults = PipelineInterfaceDefaults(
                    **DEFAULT_SELECTIONS["bonus"], init_workflow=factory.create_simple_qb_bonus_workflow()
                )
                bonus_interface = BonusInterface(demo, browser_state, bonus_ds, AVAILABLE_MODELS, defaults)
            # with gr.Tab("πŸ€— HuggingFace Pipelines", elem_id="hf-pipeline-tab", id="hf-pipeline-tab"):
            #     hf_pipeline_interface = create_hf_pipeline_submission_interface(demo)
            with gr.Tab("❓ Help", id="help"):
                with gr.Row():
                    with gr.Column():
                        gr.Markdown(QUICKSTART_MARKDOWN)
                    with gr.Column():
                        gr.Markdown(BUILDING_MARKDOWN)

        # Event Listeners

        # This is used to retrieve the pipeline state user was working on before login.
        # makes things less annoying when progress is lost due to login.
        login_btn.click(
            fn=presave_pipeline_state,
            inputs=[
                login_btn,
                browser_state,
                tossup_interface.pipeline_state,
                tossup_interface.output_state,
                bonus_interface.pipeline_state,
                bonus_interface.output_state,
            ],
            outputs=[login_btn, browser_state],
        )

        demo.queue(default_concurrency_limit=40).launch()