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],
|