Spaces:
Running
Running
Maharshi Gor
commited on
Commit
·
d15e788
1
Parent(s):
e00ec4e
Update: Pipeline selector.
Browse files* Pipeline selector component,
* methods to load past user submissions, for both bonus and tossup and change logging library to loguru.
* Currently commented out the pipeline loading triggers.
requirements.txt
CHANGED
@@ -25,4 +25,5 @@ langchain-community
|
|
25 |
langchain-anthropic
|
26 |
langchain-openai
|
27 |
langchain-cohere
|
28 |
-
json_repair
|
|
|
|
25 |
langchain-anthropic
|
26 |
langchain-openai
|
27 |
langchain-cohere
|
28 |
+
json_repair
|
29 |
+
loguru
|
src/components/model_pipeline/model_pipeline.py
CHANGED
@@ -2,6 +2,7 @@ import gradio as gr
|
|
2 |
import yaml
|
3 |
from loguru import logger
|
4 |
|
|
|
5 |
from components.model_pipeline.state_manager import (
|
6 |
ModelStepUIState,
|
7 |
PipelineState,
|
@@ -62,9 +63,11 @@ class PipelineInterface:
|
|
62 |
ui_state: PipelineUIState | None = None,
|
63 |
model_options: list[str] = None,
|
64 |
simple: bool = False,
|
|
|
65 |
):
|
66 |
self.model_options = model_options
|
67 |
self.simple = simple
|
|
|
68 |
if not ui_state:
|
69 |
ui_state = PipelineUIState.from_workflow(workflow)
|
70 |
self.ui_state = make_state(ui_state)
|
@@ -155,16 +158,13 @@ class PipelineInterface:
|
|
155 |
|
156 |
def _render_output_fields(self, available_variables: list[str], pipeline_state: PipelineState):
|
157 |
dropdowns = {}
|
158 |
-
|
159 |
-
variable_options = [UNSET_VALUE] + [v for v in available_variables if v not in self.input_variables]
|
160 |
with gr.Column(elem_classes="step-accordion"):
|
161 |
with gr.Row(elem_classes="output-fields-header"):
|
162 |
gr.Markdown("#### Final output variables mapping:")
|
163 |
with gr.Row(elem_classes="output-fields-row"):
|
164 |
for output_field in self.required_output_variables:
|
165 |
-
value = pipeline_state.workflow.outputs
|
166 |
-
if not value:
|
167 |
-
value = UNSET_VALUE
|
168 |
dropdown = gr.Dropdown(
|
169 |
label=output_field,
|
170 |
value=value,
|
@@ -234,7 +234,7 @@ class PipelineInterface:
|
|
234 |
self._render_pipeline_header()
|
235 |
|
236 |
# Function to render all steps
|
237 |
-
@gr.render(inputs=[self.pipeline_state, self.ui_state])
|
238 |
def render_steps(state: PipelineState, ui_state: PipelineUIState):
|
239 |
"""Render all steps in the pipeline"""
|
240 |
logger.info(f"\nRerender triggered! Current UI State:{ui_state.model_dump()}")
|
@@ -251,21 +251,24 @@ class PipelineInterface:
|
|
251 |
|
252 |
components.append(step_objects)
|
253 |
|
254 |
-
# Bottom buttons
|
255 |
if not self.simple:
|
256 |
self._render_add_step_button(-1)
|
257 |
|
258 |
-
@gr.render(
|
|
|
|
|
|
|
|
|
259 |
def render_output_fields(available_variables, pipeline_state):
|
260 |
-
|
261 |
|
262 |
export_btn = gr.Button("Export Pipeline", elem_classes="export-button")
|
263 |
# components.append(export_btn)
|
264 |
|
265 |
# Add a code box to display the workflow JSON
|
266 |
# with gr.Column(elem_classes="workflow-json-container"):
|
267 |
-
with gr.Accordion("Pipeline Preview", open=False, elem_classes="pipeline-preview") as config_accordion:
|
268 |
-
config_output = gr.Code(
|
269 |
label="Workflow Configuration",
|
270 |
language="yaml",
|
271 |
elem_classes="workflow-json",
|
@@ -274,21 +277,27 @@ class PipelineInterface:
|
|
274 |
)
|
275 |
# components.append(config_accordion)
|
276 |
|
277 |
-
config_output.blur(
|
278 |
fn=update_workflow_from_code,
|
279 |
-
inputs=[config_output, self.ui_state],
|
280 |
outputs=[self.pipeline_state],
|
281 |
)
|
282 |
|
283 |
# Connect the export button to show the workflow JSON
|
|
|
284 |
export_btn.click(self.validate_workflow, inputs=[self.pipeline_state], outputs=[self.pipeline_state]).success(
|
285 |
-
fn=lambda: gr.update(visible=True, open=True), outputs=[config_accordion]
|
286 |
)
|
287 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
fn=self.sm.get_formatted_config,
|
289 |
inputs=[self.pipeline_state, gr.State("yaml")],
|
290 |
-
outputs=[config_output],
|
291 |
js="() => {document.querySelector('.pipeline-preview').scrollIntoView({behavior: 'smooth'})}",
|
292 |
)
|
293 |
-
|
294 |
-
# self.all_components = components
|
|
|
2 |
import yaml
|
3 |
from loguru import logger
|
4 |
|
5 |
+
from app_configs import UNSELECTED_VAR_NAME
|
6 |
from components.model_pipeline.state_manager import (
|
7 |
ModelStepUIState,
|
8 |
PipelineState,
|
|
|
63 |
ui_state: PipelineUIState | None = None,
|
64 |
model_options: list[str] = None,
|
65 |
simple: bool = False,
|
66 |
+
show_pipeline_selector: bool = False,
|
67 |
):
|
68 |
self.model_options = model_options
|
69 |
self.simple = simple
|
70 |
+
self.show_pipeline_selector = show_pipeline_selector
|
71 |
if not ui_state:
|
72 |
ui_state = PipelineUIState.from_workflow(workflow)
|
73 |
self.ui_state = make_state(ui_state)
|
|
|
158 |
|
159 |
def _render_output_fields(self, available_variables: list[str], pipeline_state: PipelineState):
|
160 |
dropdowns = {}
|
161 |
+
variable_options = [UNSELECTED_VAR_NAME] + [v for v in available_variables if v not in self.input_variables]
|
|
|
162 |
with gr.Column(elem_classes="step-accordion"):
|
163 |
with gr.Row(elem_classes="output-fields-header"):
|
164 |
gr.Markdown("#### Final output variables mapping:")
|
165 |
with gr.Row(elem_classes="output-fields-row"):
|
166 |
for output_field in self.required_output_variables:
|
167 |
+
value = pipeline_state.workflow.outputs.get(output_field, UNSELECTED_VAR_NAME)
|
|
|
|
|
168 |
dropdown = gr.Dropdown(
|
169 |
label=output_field,
|
170 |
value=value,
|
|
|
234 |
self._render_pipeline_header()
|
235 |
|
236 |
# Function to render all steps
|
237 |
+
@gr.render(inputs=[self.pipeline_state, self.ui_state], concurrency_limit=1, concurrency_id="render_steps")
|
238 |
def render_steps(state: PipelineState, ui_state: PipelineUIState):
|
239 |
"""Render all steps in the pipeline"""
|
240 |
logger.info(f"\nRerender triggered! Current UI State:{ui_state.model_dump()}")
|
|
|
251 |
|
252 |
components.append(step_objects)
|
253 |
|
|
|
254 |
if not self.simple:
|
255 |
self._render_add_step_button(-1)
|
256 |
|
257 |
+
@gr.render(
|
258 |
+
inputs=[self.variables_state, self.pipeline_state],
|
259 |
+
concurrency_limit=1,
|
260 |
+
concurrency_id="render_output_fields",
|
261 |
+
)
|
262 |
def render_output_fields(available_variables, pipeline_state):
|
263 |
+
self._render_output_fields(available_variables, pipeline_state)
|
264 |
|
265 |
export_btn = gr.Button("Export Pipeline", elem_classes="export-button")
|
266 |
# components.append(export_btn)
|
267 |
|
268 |
# Add a code box to display the workflow JSON
|
269 |
# with gr.Column(elem_classes="workflow-json-container"):
|
270 |
+
with gr.Accordion("Pipeline Preview", open=False, elem_classes="pipeline-preview") as self.config_accordion:
|
271 |
+
self.config_output = gr.Code(
|
272 |
label="Workflow Configuration",
|
273 |
language="yaml",
|
274 |
elem_classes="workflow-json",
|
|
|
277 |
)
|
278 |
# components.append(config_accordion)
|
279 |
|
280 |
+
self.config_output.blur(
|
281 |
fn=update_workflow_from_code,
|
282 |
+
inputs=[self.config_output, self.ui_state],
|
283 |
outputs=[self.pipeline_state],
|
284 |
)
|
285 |
|
286 |
# Connect the export button to show the workflow JSON
|
287 |
+
self.add_triggers_for_pipeline_export([export_btn.click], self.pipeline_state)
|
288 |
export_btn.click(self.validate_workflow, inputs=[self.pipeline_state], outputs=[self.pipeline_state]).success(
|
289 |
+
fn=lambda: gr.update(visible=True, open=True), outputs=[self.config_accordion]
|
290 |
)
|
291 |
+
|
292 |
+
def add_triggers_for_pipeline_export(self, triggers: list, input_pipeline_state: gr.State):
|
293 |
+
gr.on(
|
294 |
+
triggers,
|
295 |
+
self.validate_workflow,
|
296 |
+
inputs=[input_pipeline_state],
|
297 |
+
outputs=[self.pipeline_state],
|
298 |
+
).success(
|
299 |
fn=self.sm.get_formatted_config,
|
300 |
inputs=[self.pipeline_state, gr.State("yaml")],
|
301 |
+
outputs=[self.config_output],
|
302 |
js="() => {document.querySelector('.pipeline-preview').scrollIntoView({behavior: 'smooth'})}",
|
303 |
)
|
|
|
|
src/components/quizbowl/bonus.py
CHANGED
@@ -1,18 +1,19 @@
|
|
1 |
import json
|
2 |
-
import logging
|
3 |
from typing import Any
|
4 |
|
5 |
import gradio as gr
|
6 |
import pandas as pd
|
7 |
from datasets import Dataset
|
|
|
8 |
|
9 |
-
from components.model_pipeline.model_pipeline import PipelineInterface, PipelineState
|
|
|
10 |
from submission import submit
|
11 |
from workflows.qb.multi_step_agent import MultiStepBonusAgent
|
12 |
from workflows.qb.simple_agent import SimpleBonusAgent
|
13 |
from workflows.structs import ModelStep, Workflow
|
14 |
|
15 |
-
from .
|
16 |
from .plotting import (
|
17 |
create_bonus_confidence_plot,
|
18 |
create_bonus_html,
|
@@ -51,7 +52,7 @@ def initialize_eval_interface(example: dict, model_outputs: list[dict]):
|
|
51 |
|
52 |
return html_content, plot_data, state
|
53 |
except Exception as e:
|
54 |
-
|
55 |
return f"<div>Error initializing interface: {str(e)}</div>", pd.DataFrame(), "{}"
|
56 |
|
57 |
|
@@ -112,7 +113,7 @@ class BonusInterface:
|
|
112 |
|
113 |
def __init__(self, app: gr.Blocks, dataset: Dataset, model_options: dict, defaults: dict):
|
114 |
"""Initialize the Bonus interface."""
|
115 |
-
|
116 |
self.ds = dataset
|
117 |
self.model_options = model_options
|
118 |
self.app = app
|
@@ -122,6 +123,8 @@ class BonusInterface:
|
|
122 |
|
123 |
def _render_model_interface(self, workflow: Workflow, simple: bool = True):
|
124 |
"""Render the model interface."""
|
|
|
|
|
125 |
self.pipeline_interface = PipelineInterface(
|
126 |
workflow,
|
127 |
simple=simple,
|
@@ -131,7 +134,7 @@ class BonusInterface:
|
|
131 |
def _render_qb_interface(self):
|
132 |
"""Render the quizbowl interface."""
|
133 |
with gr.Row(elem_classes="bonus-header-row form-inline"):
|
134 |
-
self.qid_selector = get_qid_selector(len(self.ds))
|
135 |
self.run_btn = gr.Button("Run on Bonus Question", variant="secondary")
|
136 |
|
137 |
self.question_display = gr.HTML(label="Question", elem_id="bonus-question-display")
|
@@ -176,7 +179,7 @@ class BonusInterface:
|
|
176 |
def get_new_question_html(self, question_id: int):
|
177 |
"""Get the HTML for a new question."""
|
178 |
if question_id is None:
|
179 |
-
|
180 |
question_id = 1
|
181 |
try:
|
182 |
question_id = int(question_id) - 1
|
@@ -190,6 +193,20 @@ class BonusInterface:
|
|
190 |
except Exception as e:
|
191 |
return f"Error loading question: {str(e)}"
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
def get_model_outputs(self, example: dict, pipeline_state: PipelineState):
|
194 |
"""Get the model outputs for a given question ID."""
|
195 |
outputs = []
|
@@ -281,10 +298,8 @@ class BonusInterface:
|
|
281 |
gr.update(value=df, label="Scores on Sample Set"),
|
282 |
gr.update(value=plot_data, label="Part Scores on Sample Set"),
|
283 |
)
|
284 |
-
except Exception:
|
285 |
-
|
286 |
-
|
287 |
-
logging.error(f"Error evaluating bonus: {traceback.format_exc()}")
|
288 |
return "Error evaluating bonus", None, None
|
289 |
|
290 |
def submit_model(
|
@@ -303,6 +318,22 @@ class BonusInterface:
|
|
303 |
outputs=[self.question_display],
|
304 |
)
|
305 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
self.run_btn.click(
|
307 |
self.pipeline_interface.validate_workflow,
|
308 |
inputs=[self.pipeline_interface.pipeline_state],
|
|
|
1 |
import json
|
|
|
2 |
from typing import Any
|
3 |
|
4 |
import gradio as gr
|
5 |
import pandas as pd
|
6 |
from datasets import Dataset
|
7 |
+
from loguru import logger
|
8 |
|
9 |
+
from components.model_pipeline.model_pipeline import PipelineInterface, PipelineState, PipelineUIState
|
10 |
+
from display.formatting import styled_error
|
11 |
from submission import submit
|
12 |
from workflows.qb.multi_step_agent import MultiStepBonusAgent
|
13 |
from workflows.qb.simple_agent import SimpleBonusAgent
|
14 |
from workflows.structs import ModelStep, Workflow
|
15 |
|
16 |
+
from . import commons
|
17 |
from .plotting import (
|
18 |
create_bonus_confidence_plot,
|
19 |
create_bonus_html,
|
|
|
52 |
|
53 |
return html_content, plot_data, state
|
54 |
except Exception as e:
|
55 |
+
logger.exception(f"Error initializing interface: {e.args}")
|
56 |
return f"<div>Error initializing interface: {str(e)}</div>", pd.DataFrame(), "{}"
|
57 |
|
58 |
|
|
|
113 |
|
114 |
def __init__(self, app: gr.Blocks, dataset: Dataset, model_options: dict, defaults: dict):
|
115 |
"""Initialize the Bonus interface."""
|
116 |
+
logger.info(f"Initializing Bonus interface with dataset size: {len(dataset)}")
|
117 |
self.ds = dataset
|
118 |
self.model_options = model_options
|
119 |
self.app = app
|
|
|
123 |
|
124 |
def _render_model_interface(self, workflow: Workflow, simple: bool = True):
|
125 |
"""Render the model interface."""
|
126 |
+
with gr.Row():
|
127 |
+
self.model_selector = commons.get_pipeline_selector([])
|
128 |
self.pipeline_interface = PipelineInterface(
|
129 |
workflow,
|
130 |
simple=simple,
|
|
|
134 |
def _render_qb_interface(self):
|
135 |
"""Render the quizbowl interface."""
|
136 |
with gr.Row(elem_classes="bonus-header-row form-inline"):
|
137 |
+
self.qid_selector = commons.get_qid_selector(len(self.ds))
|
138 |
self.run_btn = gr.Button("Run on Bonus Question", variant="secondary")
|
139 |
|
140 |
self.question_display = gr.HTML(label="Question", elem_id="bonus-question-display")
|
|
|
179 |
def get_new_question_html(self, question_id: int):
|
180 |
"""Get the HTML for a new question."""
|
181 |
if question_id is None:
|
182 |
+
logger.error("Question ID is None. Setting to 1")
|
183 |
question_id = 1
|
184 |
try:
|
185 |
question_id = int(question_id) - 1
|
|
|
193 |
except Exception as e:
|
194 |
return f"Error loading question: {str(e)}"
|
195 |
|
196 |
+
def get_user_submission_names(self, profile: gr.OAuthProfile | None) -> list[str]:
|
197 |
+
if profile is None:
|
198 |
+
logger.error("Authentication required. Please log in to view your submissions.")
|
199 |
+
return []
|
200 |
+
model_names = submit.get_user_submission_names("bonus", profile)
|
201 |
+
logger.info("Loaded model names: {model_names}")
|
202 |
+
return gr.update(choices=model_names, value=None)
|
203 |
+
|
204 |
+
def load_user_submission(self, model_name: str, profile: gr.OAuthProfile | None) -> PipelineState:
|
205 |
+
if profile is None:
|
206 |
+
return styled_error("Authentication required. Please log in to view your submissions.")
|
207 |
+
submission = submit.load_submission(model_name, "tossup", profile)
|
208 |
+
return PipelineState(workflow=submission.workflow, ui_state=PipelineUIState.from_workflow(submission.workflow))
|
209 |
+
|
210 |
def get_model_outputs(self, example: dict, pipeline_state: PipelineState):
|
211 |
"""Get the model outputs for a given question ID."""
|
212 |
outputs = []
|
|
|
298 |
gr.update(value=df, label="Scores on Sample Set"),
|
299 |
gr.update(value=plot_data, label="Part Scores on Sample Set"),
|
300 |
)
|
301 |
+
except Exception as e:
|
302 |
+
logger.exception(f"Error evaluating bonus: {e.args}")
|
|
|
|
|
303 |
return "Error evaluating bonus", None, None
|
304 |
|
305 |
def submit_model(
|
|
|
318 |
outputs=[self.question_display],
|
319 |
)
|
320 |
|
321 |
+
gr.on(
|
322 |
+
triggers=[self.app.load],
|
323 |
+
fn=self.get_user_submission_names,
|
324 |
+
outputs=[self.model_selector],
|
325 |
+
)
|
326 |
+
|
327 |
+
# self.new_loaded_pipeline_state = gr.State(value=None)
|
328 |
+
# self.model_selector.change(
|
329 |
+
# fn=self.load_user_submission,
|
330 |
+
# inputs=[self.model_selector],
|
331 |
+
# outputs=[self.new_loaded_pipeline_state],
|
332 |
+
# )
|
333 |
+
# self.pipeline_interface.add_triggers_for_pipeline_export(
|
334 |
+
# [self.new_loaded_pipeline_state.change], self.new_loaded_pipeline_state
|
335 |
+
# )
|
336 |
+
|
337 |
self.run_btn.click(
|
338 |
self.pipeline_interface.validate_workflow,
|
339 |
inputs=[self.pipeline_interface.pipeline_state],
|
src/components/quizbowl/commons.py
CHANGED
@@ -13,3 +13,12 @@ def get_qid_selector(dataset_size: int):
|
|
13 |
container=False,
|
14 |
elem_classes="qid-selector",
|
15 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
container=False,
|
14 |
elem_classes="qid-selector",
|
15 |
)
|
16 |
+
|
17 |
+
|
18 |
+
def get_pipeline_selector(model_options: list[str]):
|
19 |
+
return gr.Dropdown(
|
20 |
+
label="User Submissions and Examples",
|
21 |
+
choices=model_options,
|
22 |
+
value="",
|
23 |
+
interactive=True,
|
24 |
+
)
|
src/components/quizbowl/tossup.py
CHANGED
@@ -1,19 +1,20 @@
|
|
1 |
import json
|
2 |
-
import logging
|
3 |
from typing import Any
|
4 |
|
5 |
import gradio as gr
|
6 |
import numpy as np
|
7 |
import pandas as pd
|
8 |
from datasets import Dataset
|
|
|
9 |
|
10 |
-
from components.model_pipeline.model_pipeline import PipelineInterface, PipelineState
|
|
|
11 |
from submission import submit
|
12 |
from workflows.qb.multi_step_agent import MultiStepTossupAgent
|
13 |
from workflows.qb.simple_agent import SimpleTossupAgent
|
14 |
from workflows.structs import ModelStep, Workflow
|
15 |
|
16 |
-
from .
|
17 |
from .plotting import (
|
18 |
create_scatter_pyplot,
|
19 |
create_tossup_confidence_pyplot,
|
@@ -39,7 +40,7 @@ def prepare_buzz_evals(
|
|
39 |
) -> tuple[list[str], list[tuple[int, float, bool]]]:
|
40 |
"""Process text into tokens and assign random values for demonstration."""
|
41 |
if not run_indices:
|
42 |
-
|
43 |
return [], []
|
44 |
eval_points = []
|
45 |
for i, v in zip(run_indices, model_outputs):
|
@@ -68,7 +69,7 @@ def initialize_eval_interface(example, model_outputs: list[dict]):
|
|
68 |
|
69 |
return html_content, plot_data, state
|
70 |
except Exception as e:
|
71 |
-
|
72 |
return f"<div>Error initializing interface: {str(e)}</div>", pd.DataFrame(), "{}"
|
73 |
|
74 |
|
@@ -164,9 +165,15 @@ def validate_model_step(model_step: ModelStep):
|
|
164 |
class TossupInterface:
|
165 |
"""Gradio interface for the Tossup mode."""
|
166 |
|
167 |
-
def __init__(
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
"""Initialize the Tossup interface."""
|
169 |
-
|
170 |
self.ds = dataset
|
171 |
self.model_options = model_options
|
172 |
self.app = app
|
@@ -176,6 +183,8 @@ class TossupInterface:
|
|
176 |
|
177 |
def _render_model_interface(self, workflow: Workflow, simple: bool = True):
|
178 |
"""Render the model interface."""
|
|
|
|
|
179 |
self.pipeline_interface = PipelineInterface(
|
180 |
workflow,
|
181 |
simple=simple,
|
@@ -198,7 +207,7 @@ class TossupInterface:
|
|
198 |
def _render_qb_interface(self):
|
199 |
"""Render the quizbowl interface."""
|
200 |
with gr.Row(elem_classes="bonus-header-row form-inline"):
|
201 |
-
self.qid_selector = get_qid_selector(len(self.ds))
|
202 |
self.run_btn = gr.Button("Run on Tossup Question", variant="secondary")
|
203 |
self.question_display = gr.HTML(label="Question", elem_id="tossup-question-display")
|
204 |
with gr.Row():
|
@@ -249,7 +258,7 @@ class TossupInterface:
|
|
249 |
def get_new_question_html(self, question_id: int) -> str:
|
250 |
"""Get the HTML for a new question."""
|
251 |
if question_id is None:
|
252 |
-
|
253 |
question_id = 1
|
254 |
try:
|
255 |
example = self.ds[question_id - 1]
|
@@ -276,6 +285,20 @@ class TossupInterface:
|
|
276 |
outputs = add_model_scores(outputs, example["clean_answers"], example["run_indices"])
|
277 |
return outputs
|
278 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
def single_run(
|
280 |
self,
|
281 |
question_id: int,
|
@@ -341,10 +364,8 @@ class TossupInterface:
|
|
341 |
gr.update(value=df, label="Scores on Sample Set"),
|
342 |
gr.update(value=plot_data, label="Buzz Positions on Sample Set"),
|
343 |
)
|
344 |
-
except Exception:
|
345 |
-
|
346 |
-
|
347 |
-
logging.error(f"Error evaluating tossups: {traceback.format_exc()}")
|
348 |
return "Error evaluating tossups", None, None
|
349 |
|
350 |
def submit_model(
|
@@ -361,6 +382,22 @@ class TossupInterface:
|
|
361 |
outputs=[self.question_display],
|
362 |
)
|
363 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
364 |
self.run_btn.click(
|
365 |
self.pipeline_interface.validate_workflow,
|
366 |
inputs=[self.pipeline_interface.pipeline_state],
|
|
|
1 |
import json
|
|
|
2 |
from typing import Any
|
3 |
|
4 |
import gradio as gr
|
5 |
import numpy as np
|
6 |
import pandas as pd
|
7 |
from datasets import Dataset
|
8 |
+
from loguru import logger
|
9 |
|
10 |
+
from components.model_pipeline.model_pipeline import PipelineInterface, PipelineState, PipelineUIState
|
11 |
+
from display.formatting import styled_error
|
12 |
from submission import submit
|
13 |
from workflows.qb.multi_step_agent import MultiStepTossupAgent
|
14 |
from workflows.qb.simple_agent import SimpleTossupAgent
|
15 |
from workflows.structs import ModelStep, Workflow
|
16 |
|
17 |
+
from . import commons
|
18 |
from .plotting import (
|
19 |
create_scatter_pyplot,
|
20 |
create_tossup_confidence_pyplot,
|
|
|
40 |
) -> tuple[list[str], list[tuple[int, float, bool]]]:
|
41 |
"""Process text into tokens and assign random values for demonstration."""
|
42 |
if not run_indices:
|
43 |
+
logger.warning("No run indices provided, returning empty results")
|
44 |
return [], []
|
45 |
eval_points = []
|
46 |
for i, v in zip(run_indices, model_outputs):
|
|
|
69 |
|
70 |
return html_content, plot_data, state
|
71 |
except Exception as e:
|
72 |
+
logger.exception(f"Error initializing interface: {e.args}")
|
73 |
return f"<div>Error initializing interface: {str(e)}</div>", pd.DataFrame(), "{}"
|
74 |
|
75 |
|
|
|
165 |
class TossupInterface:
|
166 |
"""Gradio interface for the Tossup mode."""
|
167 |
|
168 |
+
def __init__(
|
169 |
+
self,
|
170 |
+
app: gr.Blocks,
|
171 |
+
dataset: Dataset,
|
172 |
+
model_options: dict,
|
173 |
+
defaults: dict,
|
174 |
+
):
|
175 |
"""Initialize the Tossup interface."""
|
176 |
+
logger.info(f"Initializing Tossup interface with dataset size: {len(dataset)}")
|
177 |
self.ds = dataset
|
178 |
self.model_options = model_options
|
179 |
self.app = app
|
|
|
183 |
|
184 |
def _render_model_interface(self, workflow: Workflow, simple: bool = True):
|
185 |
"""Render the model interface."""
|
186 |
+
with gr.Row():
|
187 |
+
self.model_selector = commons.get_pipeline_selector([])
|
188 |
self.pipeline_interface = PipelineInterface(
|
189 |
workflow,
|
190 |
simple=simple,
|
|
|
207 |
def _render_qb_interface(self):
|
208 |
"""Render the quizbowl interface."""
|
209 |
with gr.Row(elem_classes="bonus-header-row form-inline"):
|
210 |
+
self.qid_selector = commons.get_qid_selector(len(self.ds))
|
211 |
self.run_btn = gr.Button("Run on Tossup Question", variant="secondary")
|
212 |
self.question_display = gr.HTML(label="Question", elem_id="tossup-question-display")
|
213 |
with gr.Row():
|
|
|
258 |
def get_new_question_html(self, question_id: int) -> str:
|
259 |
"""Get the HTML for a new question."""
|
260 |
if question_id is None:
|
261 |
+
logger.error("Question ID is None. Setting to 1")
|
262 |
question_id = 1
|
263 |
try:
|
264 |
example = self.ds[question_id - 1]
|
|
|
285 |
outputs = add_model_scores(outputs, example["clean_answers"], example["run_indices"])
|
286 |
return outputs
|
287 |
|
288 |
+
def get_user_submission_names(self, profile: gr.OAuthProfile | None) -> list[str]:
|
289 |
+
if profile is None:
|
290 |
+
logger.error("Authentication required. Please log in to view your submissions.")
|
291 |
+
return []
|
292 |
+
model_names = submit.get_user_submission_names("tossup", profile)
|
293 |
+
logger.info("Loaded model names: {model_names}")
|
294 |
+
return gr.update(choices=model_names, value=None)
|
295 |
+
|
296 |
+
def load_user_submission(self, model_name: str, profile: gr.OAuthProfile | None) -> PipelineState:
|
297 |
+
if profile is None:
|
298 |
+
return styled_error("Authentication required. Please log in to view your submissions.")
|
299 |
+
submission = submit.load_submission(model_name, "tossup", profile)
|
300 |
+
return PipelineState(workflow=submission.workflow, ui_state=PipelineUIState.from_workflow(submission.workflow))
|
301 |
+
|
302 |
def single_run(
|
303 |
self,
|
304 |
question_id: int,
|
|
|
364 |
gr.update(value=df, label="Scores on Sample Set"),
|
365 |
gr.update(value=plot_data, label="Buzz Positions on Sample Set"),
|
366 |
)
|
367 |
+
except Exception as e:
|
368 |
+
logger.exception(f"Error evaluating tossups: {e.args}")
|
|
|
|
|
369 |
return "Error evaluating tossups", None, None
|
370 |
|
371 |
def submit_model(
|
|
|
382 |
outputs=[self.question_display],
|
383 |
)
|
384 |
|
385 |
+
gr.on(
|
386 |
+
triggers=[self.app.load],
|
387 |
+
fn=self.get_user_submission_names,
|
388 |
+
outputs=[self.model_selector],
|
389 |
+
)
|
390 |
+
|
391 |
+
# self.new_loaded_pipeline_state = gr.State(value=None)
|
392 |
+
# self.model_selector.change(
|
393 |
+
# fn=self.load_user_submission,
|
394 |
+
# inputs=[self.model_selector],
|
395 |
+
# outputs=[self.new_loaded_pipeline_state],
|
396 |
+
# )
|
397 |
+
# self.pipeline_interface.add_triggers_for_pipeline_export(
|
398 |
+
# [self.new_loaded_pipeline_state.change], self.new_loaded_pipeline_state
|
399 |
+
# )
|
400 |
+
|
401 |
self.run_btn.click(
|
402 |
self.pipeline_interface.validate_workflow,
|
403 |
inputs=[self.pipeline_interface.pipeline_state],
|