Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Update src/streamlit_app.py
Browse files- src/streamlit_app.py +116 -96
src/streamlit_app.py
CHANGED
|
@@ -358,13 +358,23 @@ st.markdown("""
|
|
| 358 |
border-color: rgba(255, 255, 255, 0.1);
|
| 359 |
}
|
| 360 |
}
|
| 361 |
-
/* Model display checkboxes:
|
| 362 |
.st-key-narrow_model_display [data-testid="stHorizontalBlock"] {
|
| 363 |
flex-wrap: nowrap !important;
|
| 364 |
}
|
| 365 |
.st-key-narrow_model_display [data-testid="column"] {
|
| 366 |
min-width: 0 !important;
|
| 367 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
/* Mobile: stack image comparison columns vertically */
|
| 369 |
@media (max-width: 768px) {
|
| 370 |
.st-key-image_comparison [data-testid="stHorizontalBlock"] {
|
|
@@ -387,8 +397,17 @@ def _parse_success(value):
|
|
| 387 |
return False
|
| 388 |
|
| 389 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
@st.cache_data
|
| 391 |
-
def load_data():
|
| 392 |
"""Load and clean data. Tries repo root (HF Space: /app/data/) then script dir."""
|
| 393 |
csv_path = None
|
| 394 |
for base in (_repo_root, _script_dir):
|
|
@@ -823,8 +842,11 @@ FAILURE_MODE_OPTIONS = [
|
|
| 823 |
"Click Region Error",
|
| 824 |
"Visual Confusion",
|
| 825 |
"Spatial Reasoning Error",
|
| 826 |
-
"
|
| 827 |
-
"
|
|
|
|
|
|
|
|
|
|
| 828 |
]
|
| 829 |
|
| 830 |
|
|
@@ -857,11 +879,7 @@ def _build_available_samples(df_filtered, selected_variant, failure_mode="All"):
|
|
| 857 |
if failure_mode != "All":
|
| 858 |
# Get one row per sample to check failure mode (use original variant)
|
| 859 |
df_orig = df_rel[df_rel["variant"] == "original"].drop_duplicates(subset=["task_id", "step_index"])
|
| 860 |
-
|
| 861 |
-
# These are sub-categories of "Invalid" stored in the description column
|
| 862 |
-
match_mask = df_orig["description"].str.lower() == failure_mode.lower()
|
| 863 |
-
else:
|
| 864 |
-
match_mask = df_orig["interesting_cases"] == failure_mode
|
| 865 |
match_pairs = set(zip(df_orig.loc[match_mask, "task_id"], df_orig.loc[match_mask, "step_index"]))
|
| 866 |
filtered_pairs &= match_pairs
|
| 867 |
|
|
@@ -919,7 +937,7 @@ def _render_compact_header():
|
|
| 919 |
html = f"""
|
| 920 |
<div class="gui-viewer-compact-header">
|
| 921 |
<h2 style="margin:0;color:var(--gui-viewer-heading);font-size:1.3rem;font-weight:700;">GUI-Perturbed Baseline Result Viewer</h2>
|
| 922 |
-
<p style="margin:0.25rem 0 0.4rem;color:var(--gui-viewer-muted);font-size:0.85rem;line-height:1.4;">
|
| 923 |
<div class="header-row">
|
| 924 |
{fig_logo_html}
|
| 925 |
{manifold_logo_html}
|
|
@@ -1110,7 +1128,7 @@ def main():
|
|
| 1110 |
|
| 1111 |
# --- Load data ---
|
| 1112 |
with st.spinner("Loading results..."):
|
| 1113 |
-
df = load_data()
|
| 1114 |
_t = _lap("load_data", _t)
|
| 1115 |
if df.empty:
|
| 1116 |
st.error("No data found")
|
|
@@ -1125,7 +1143,10 @@ def main():
|
|
| 1125 |
# --- Compute state from session defaults (widgets rendered later read from previous rerun) ---
|
| 1126 |
query_types = sorted(df['query_type'].unique().tolist())
|
| 1127 |
use_reasoning_options = sorted(df['use_reasoning'].unique().tolist())
|
| 1128 |
-
|
|
|
|
|
|
|
|
|
|
| 1129 |
selected_use_reasoning = st.session_state.get("use_reasoning_filter", use_reasoning_options[0] if use_reasoning_options else None)
|
| 1130 |
if selected_query_type not in query_types:
|
| 1131 |
selected_query_type = query_types[0] if query_types else None
|
|
@@ -1155,8 +1176,8 @@ def main():
|
|
| 1155 |
# to avoid 1-rerun lag vs the manually maintained selected_models dict
|
| 1156 |
selected_models = [m for m in all_models if st.session_state.get(f"model_{m}", True)]
|
| 1157 |
|
| 1158 |
-
if '
|
| 1159 |
-
st.session_state.
|
| 1160 |
|
| 1161 |
# Initialize navigation state
|
| 1162 |
if 'current_sample_index' not in st.session_state:
|
|
@@ -1171,16 +1192,20 @@ def main():
|
|
| 1171 |
st.session_state.sample_nav_input = st.session_state.current_sample_index + 1
|
| 1172 |
|
| 1173 |
# Build available samples
|
|
|
|
|
|
|
|
|
|
| 1174 |
available_samples, available_samples_all, full_list_index_by_sample = _build_available_samples(
|
| 1175 |
df_filtered,
|
| 1176 |
st.session_state.selected_variant,
|
| 1177 |
-
|
| 1178 |
)
|
| 1179 |
_t = _lap("_build_available_samples", _t)
|
| 1180 |
|
| 1181 |
if not available_samples:
|
| 1182 |
st.error(
|
| 1183 |
-
f"No samples found with both original and {st.session_state.selected_variant} perturbation"
|
|
|
|
| 1184 |
)
|
| 1185 |
return
|
| 1186 |
|
|
@@ -1189,7 +1214,7 @@ def main():
|
|
| 1189 |
selected_query_type,
|
| 1190 |
selected_use_reasoning,
|
| 1191 |
st.session_state.selected_variant,
|
| 1192 |
-
|
| 1193 |
)
|
| 1194 |
filters_changed = st.session_state.get("_filter_signature") != current_filter_signature
|
| 1195 |
if filters_changed:
|
|
@@ -1231,7 +1256,7 @@ def main():
|
|
| 1231 |
_t = _lap("build rows by model", _t)
|
| 1232 |
|
| 1233 |
# ==========================================
|
| 1234 |
-
# RENDER: Images
|
| 1235 |
# ==========================================
|
| 1236 |
_render_images(
|
| 1237 |
original_rows_by_model,
|
|
@@ -1243,19 +1268,44 @@ def main():
|
|
| 1243 |
_t = _lap("render images", _t)
|
| 1244 |
|
| 1245 |
# ==========================================
|
| 1246 |
-
# RENDER:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1247 |
# ==========================================
|
| 1248 |
with st.container(key="narrow_model_display"):
|
| 1249 |
-
st.
|
| 1250 |
-
|
| 1251 |
-
|
| 1252 |
-
|
| 1253 |
-
|
| 1254 |
-
|
| 1255 |
-
|
| 1256 |
-
|
| 1257 |
-
|
| 1258 |
-
|
| 1259 |
|
| 1260 |
# Recompute selected_models from current checkbox widget state
|
| 1261 |
selected_models = [m for m in all_models if st.session_state.get(f"model_{m}", True)]
|
|
@@ -1272,61 +1322,21 @@ def main():
|
|
| 1272 |
_t = _lap("render model results", _t)
|
| 1273 |
|
| 1274 |
# ==========================================
|
| 1275 |
-
# RENDER:
|
| 1276 |
# ==========================================
|
| 1277 |
with st.container(key="narrow_controls"):
|
| 1278 |
st.markdown("---")
|
| 1279 |
-
st.markdown("####
|
| 1280 |
-
|
| 1281 |
-
# Navigation callbacks (use -/+ on number input for prev/next)
|
| 1282 |
-
def on_sample_change():
|
| 1283 |
-
new_val = st.session_state.sample_nav_input
|
| 1284 |
-
if new_val - 1 != st.session_state.current_sample_index:
|
| 1285 |
-
st.session_state.current_sample_index = new_val - 1
|
| 1286 |
-
|
| 1287 |
-
def on_search():
|
| 1288 |
-
query = st.session_state.get("instruction_search", "").strip().lower()
|
| 1289 |
-
if not query:
|
| 1290 |
-
return
|
| 1291 |
-
# Search from current position + 1, wrapping around
|
| 1292 |
-
n = len(available_samples)
|
| 1293 |
-
start = (st.session_state.current_sample_index + 1) % n
|
| 1294 |
-
for offset in range(n):
|
| 1295 |
-
idx = (start + offset) % n
|
| 1296 |
-
instr = available_samples[idx].get("instruction", "").lower()
|
| 1297 |
-
if query in instr:
|
| 1298 |
-
st.session_state.current_sample_index = idx
|
| 1299 |
-
st.session_state.sample_nav_input = idx + 1
|
| 1300 |
-
return
|
| 1301 |
|
| 1302 |
-
#
|
| 1303 |
-
|
| 1304 |
-
|
| 1305 |
-
|
| 1306 |
-
|
| 1307 |
-
|
| 1308 |
-
total_in_full_list = len(available_samples_all)
|
| 1309 |
-
nav_label = f"Sample ({st.session_state.current_sample_index + 1} of {len(available_samples)}"
|
| 1310 |
-
if position_in_full_list is not None and total_in_full_list != len(available_samples):
|
| 1311 |
-
nav_label += f" | {position_in_full_list} of {total_in_full_list} total"
|
| 1312 |
-
nav_label += ")"
|
| 1313 |
-
st.number_input(
|
| 1314 |
-
nav_label,
|
| 1315 |
-
min_value=1,
|
| 1316 |
-
max_value=len(available_samples),
|
| 1317 |
-
key="sample_nav_input",
|
| 1318 |
-
on_change=on_sample_change,
|
| 1319 |
-
)
|
| 1320 |
-
with search_col:
|
| 1321 |
-
st.text_input(
|
| 1322 |
-
"Search instructions",
|
| 1323 |
-
key="instruction_search",
|
| 1324 |
-
on_change=on_search,
|
| 1325 |
-
placeholder="Type to search task instructions...",
|
| 1326 |
-
)
|
| 1327 |
|
| 1328 |
-
#
|
| 1329 |
-
f = st.columns(
|
| 1330 |
with f[0]:
|
| 1331 |
new_variant = st.selectbox(
|
| 1332 |
"Visual Variant",
|
|
@@ -1337,7 +1347,7 @@ def main():
|
|
| 1337 |
help="Precision: viewport zoom. Style: visual randomization. Text Shrink: font size reduced.",
|
| 1338 |
)
|
| 1339 |
with f[1]:
|
| 1340 |
-
|
| 1341 |
"Instruction Variant",
|
| 1342 |
query_types,
|
| 1343 |
key="query_type_filter",
|
|
@@ -1345,33 +1355,43 @@ def main():
|
|
| 1345 |
help="Direct Instruction vs Relational Instruction",
|
| 1346 |
)
|
| 1347 |
with f[2]:
|
| 1348 |
-
|
| 1349 |
"Reasoning",
|
| 1350 |
use_reasoning_options,
|
| 1351 |
key="use_reasoning_filter",
|
| 1352 |
format_func=lambda x: "Yes" if x else "No",
|
| 1353 |
help="Whether chain-of-thought reasoning was used",
|
| 1354 |
)
|
| 1355 |
-
|
| 1356 |
-
|
| 1357 |
-
|
| 1358 |
-
|
| 1359 |
-
|
| 1360 |
-
|
| 1361 |
-
|
| 1362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1363 |
|
| 1364 |
_t = _lap("control panel widgets", _t)
|
| 1365 |
|
| 1366 |
-
# Handle variant
|
| 1367 |
-
needs_rerun = False
|
| 1368 |
if new_variant != st.session_state.selected_variant:
|
| 1369 |
st.session_state.selected_variant = new_variant
|
| 1370 |
-
needs_rerun = True
|
| 1371 |
-
if new_failure_mode != st.session_state.failure_mode_filter:
|
| 1372 |
-
st.session_state.failure_mode_filter = new_failure_mode
|
| 1373 |
-
needs_rerun = True
|
| 1374 |
-
if needs_rerun:
|
| 1375 |
st.rerun()
|
| 1376 |
|
| 1377 |
_lap("main() total", _t0)
|
|
|
|
| 358 |
border-color: rgba(255, 255, 255, 0.1);
|
| 359 |
}
|
| 360 |
}
|
| 361 |
+
/* Model display checkboxes: compact row */
|
| 362 |
.st-key-narrow_model_display [data-testid="stHorizontalBlock"] {
|
| 363 |
flex-wrap: nowrap !important;
|
| 364 |
}
|
| 365 |
.st-key-narrow_model_display [data-testid="column"] {
|
| 366 |
min-width: 0 !important;
|
| 367 |
}
|
| 368 |
+
/* Mobile: allow wrapping so checkboxes don't overflow */
|
| 369 |
+
@media (max-width: 768px) {
|
| 370 |
+
.st-key-narrow_model_display [data-testid="stHorizontalBlock"] {
|
| 371 |
+
flex-wrap: wrap !important;
|
| 372 |
+
}
|
| 373 |
+
}
|
| 374 |
+
/* Failure mode pills: no word breaking */
|
| 375 |
+
.st-key-failure_mode_pills button {
|
| 376 |
+
white-space: nowrap !important;
|
| 377 |
+
}
|
| 378 |
/* Mobile: stack image comparison columns vertically */
|
| 379 |
@media (max-width: 768px) {
|
| 380 |
.st-key-image_comparison [data-testid="stHorizontalBlock"] {
|
|
|
|
| 397 |
return False
|
| 398 |
|
| 399 |
|
| 400 |
+
def _csv_mtime():
|
| 401 |
+
"""Return CSV modification time so cache invalidates when file changes."""
|
| 402 |
+
for base in (_repo_root, _script_dir):
|
| 403 |
+
candidate = base / "data" / "baseline_results_full_new.csv"
|
| 404 |
+
if candidate.exists():
|
| 405 |
+
return candidate.stat().st_mtime
|
| 406 |
+
return None
|
| 407 |
+
|
| 408 |
+
|
| 409 |
@st.cache_data
|
| 410 |
+
def load_data(_mtime=None):
|
| 411 |
"""Load and clean data. Tries repo root (HF Space: /app/data/) then script dir."""
|
| 412 |
csv_path = None
|
| 413 |
for base in (_repo_root, _script_dir):
|
|
|
|
| 842 |
"Click Region Error",
|
| 843 |
"Visual Confusion",
|
| 844 |
"Spatial Reasoning Error",
|
| 845 |
+
"Text Matching Bias",
|
| 846 |
+
"Instruction Misinterpretation",
|
| 847 |
+
"Goal Hallucination",
|
| 848 |
+
"Location Hallucination",
|
| 849 |
+
"Reasoning Drift",
|
| 850 |
]
|
| 851 |
|
| 852 |
|
|
|
|
| 879 |
if failure_mode != "All":
|
| 880 |
# Get one row per sample to check failure mode (use original variant)
|
| 881 |
df_orig = df_rel[df_rel["variant"] == "original"].drop_duplicates(subset=["task_id", "step_index"])
|
| 882 |
+
match_mask = df_orig["interesting_cases"] == failure_mode
|
|
|
|
|
|
|
|
|
|
|
|
|
| 883 |
match_pairs = set(zip(df_orig.loc[match_mask, "task_id"], df_orig.loc[match_mask, "step_index"]))
|
| 884 |
filtered_pairs &= match_pairs
|
| 885 |
|
|
|
|
| 937 |
html = f"""
|
| 938 |
<div class="gui-viewer-compact-header">
|
| 939 |
<h2 style="margin:0;color:var(--gui-viewer-heading);font-size:1.3rem;font-weight:700;">GUI-Perturbed Baseline Result Viewer</h2>
|
| 940 |
+
<p style="margin:0.25rem 0 0.4rem;color:var(--gui-viewer-muted);font-size:0.85rem;line-height:1.4;">Explore how 7B GUI grounding models perform on original vs. perturbed screenshots from GUI-Perturbed</p>
|
| 941 |
<div class="header-row">
|
| 942 |
{fig_logo_html}
|
| 943 |
{manifold_logo_html}
|
|
|
|
| 1128 |
|
| 1129 |
# --- Load data ---
|
| 1130 |
with st.spinner("Loading results..."):
|
| 1131 |
+
df = load_data(_mtime=_csv_mtime())
|
| 1132 |
_t = _lap("load_data", _t)
|
| 1133 |
if df.empty:
|
| 1134 |
st.error("No data found")
|
|
|
|
| 1143 |
# --- Compute state from session defaults (widgets rendered later read from previous rerun) ---
|
| 1144 |
query_types = sorted(df['query_type'].unique().tolist())
|
| 1145 |
use_reasoning_options = sorted(df['use_reasoning'].unique().tolist())
|
| 1146 |
+
_default_query_type = "relational_query" if "relational_query" in query_types else (query_types[0] if query_types else None)
|
| 1147 |
+
if "query_type_filter" not in st.session_state and _default_query_type is not None:
|
| 1148 |
+
st.session_state.query_type_filter = _default_query_type
|
| 1149 |
+
selected_query_type = st.session_state.get("query_type_filter", _default_query_type)
|
| 1150 |
selected_use_reasoning = st.session_state.get("use_reasoning_filter", use_reasoning_options[0] if use_reasoning_options else None)
|
| 1151 |
if selected_query_type not in query_types:
|
| 1152 |
selected_query_type = query_types[0] if query_types else None
|
|
|
|
| 1176 |
# to avoid 1-rerun lag vs the manually maintained selected_models dict
|
| 1177 |
selected_models = [m for m in all_models if st.session_state.get(f"model_{m}", True)]
|
| 1178 |
|
| 1179 |
+
if 'failure_mode_pills' not in st.session_state:
|
| 1180 |
+
st.session_state.failure_mode_pills = "Spatial Reasoning Error"
|
| 1181 |
|
| 1182 |
# Initialize navigation state
|
| 1183 |
if 'current_sample_index' not in st.session_state:
|
|
|
|
| 1192 |
st.session_state.sample_nav_input = st.session_state.current_sample_index + 1
|
| 1193 |
|
| 1194 |
# Build available samples
|
| 1195 |
+
_active_failure_mode = st.session_state.get("failure_mode_pills", "All")
|
| 1196 |
+
if _active_failure_mode is None:
|
| 1197 |
+
_active_failure_mode = "All"
|
| 1198 |
available_samples, available_samples_all, full_list_index_by_sample = _build_available_samples(
|
| 1199 |
df_filtered,
|
| 1200 |
st.session_state.selected_variant,
|
| 1201 |
+
_active_failure_mode,
|
| 1202 |
)
|
| 1203 |
_t = _lap("_build_available_samples", _t)
|
| 1204 |
|
| 1205 |
if not available_samples:
|
| 1206 |
st.error(
|
| 1207 |
+
f"No samples found with both original and {st.session_state.selected_variant} perturbation "
|
| 1208 |
+
f"for failure mode \"{_active_failure_mode}\""
|
| 1209 |
)
|
| 1210 |
return
|
| 1211 |
|
|
|
|
| 1214 |
selected_query_type,
|
| 1215 |
selected_use_reasoning,
|
| 1216 |
st.session_state.selected_variant,
|
| 1217 |
+
_active_failure_mode,
|
| 1218 |
)
|
| 1219 |
filters_changed = st.session_state.get("_filter_signature") != current_filter_signature
|
| 1220 |
if filters_changed:
|
|
|
|
| 1256 |
_t = _lap("build rows by model", _t)
|
| 1257 |
|
| 1258 |
# ==========================================
|
| 1259 |
+
# RENDER: Images (hero content)
|
| 1260 |
# ==========================================
|
| 1261 |
_render_images(
|
| 1262 |
original_rows_by_model,
|
|
|
|
| 1268 |
_t = _lap("render images", _t)
|
| 1269 |
|
| 1270 |
# ==========================================
|
| 1271 |
+
# RENDER: Sample navigation (right under images)
|
| 1272 |
+
# ==========================================
|
| 1273 |
+
def on_sample_change():
|
| 1274 |
+
new_val = st.session_state.sample_nav_input
|
| 1275 |
+
if new_val - 1 != st.session_state.current_sample_index:
|
| 1276 |
+
st.session_state.current_sample_index = new_val - 1
|
| 1277 |
+
|
| 1278 |
+
with st.container(key="narrow_sample_nav"):
|
| 1279 |
+
position_in_full_list = full_list_index_by_sample.get(
|
| 1280 |
+
(current_sample['task_id'], current_sample['step_index'])
|
| 1281 |
+
)
|
| 1282 |
+
total_in_full_list = len(available_samples_all)
|
| 1283 |
+
nav_label = f"Sample ({st.session_state.current_sample_index + 1} of {len(available_samples)}"
|
| 1284 |
+
if position_in_full_list is not None and total_in_full_list != len(available_samples):
|
| 1285 |
+
nav_label += f" | {position_in_full_list} of {total_in_full_list} total"
|
| 1286 |
+
nav_label += ")"
|
| 1287 |
+
st.number_input(
|
| 1288 |
+
nav_label,
|
| 1289 |
+
min_value=1,
|
| 1290 |
+
max_value=len(available_samples),
|
| 1291 |
+
key="sample_nav_input",
|
| 1292 |
+
on_change=on_sample_change,
|
| 1293 |
+
)
|
| 1294 |
+
|
| 1295 |
+
# ==========================================
|
| 1296 |
+
# RENDER: Model display checkboxes (collapsible, default collapsed)
|
| 1297 |
# ==========================================
|
| 1298 |
with st.container(key="narrow_model_display"):
|
| 1299 |
+
with st.expander("Model Display", expanded=False):
|
| 1300 |
+
model_display_cols = st.columns(len(all_models)) if all_models else []
|
| 1301 |
+
for i, model in enumerate(all_models):
|
| 1302 |
+
with model_display_cols[i]:
|
| 1303 |
+
checked = st.checkbox(
|
| 1304 |
+
_model_label(model),
|
| 1305 |
+
value=st.session_state.selected_models.get(model, True),
|
| 1306 |
+
key=f"model_{model}",
|
| 1307 |
+
)
|
| 1308 |
+
st.session_state.selected_models[model] = checked
|
| 1309 |
|
| 1310 |
# Recompute selected_models from current checkbox widget state
|
| 1311 |
selected_models = [m for m in all_models if st.session_state.get(f"model_{m}", True)]
|
|
|
|
| 1322 |
_t = _lap("render model results", _t)
|
| 1323 |
|
| 1324 |
# ==========================================
|
| 1325 |
+
# RENDER: Filters & Search
|
| 1326 |
# ==========================================
|
| 1327 |
with st.container(key="narrow_controls"):
|
| 1328 |
st.markdown("---")
|
| 1329 |
+
st.markdown("#### Filters & Search")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1330 |
|
| 1331 |
+
# Failure mode pills (key pre-initialized in session state)
|
| 1332 |
+
st.pills(
|
| 1333 |
+
"Failure Mode",
|
| 1334 |
+
FAILURE_MODE_OPTIONS,
|
| 1335 |
+
key="failure_mode_pills",
|
| 1336 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1337 |
|
| 1338 |
+
# Filter dropdowns
|
| 1339 |
+
f = st.columns(3)
|
| 1340 |
with f[0]:
|
| 1341 |
new_variant = st.selectbox(
|
| 1342 |
"Visual Variant",
|
|
|
|
| 1347 |
help="Precision: viewport zoom. Style: visual randomization. Text Shrink: font size reduced.",
|
| 1348 |
)
|
| 1349 |
with f[1]:
|
| 1350 |
+
st.selectbox(
|
| 1351 |
"Instruction Variant",
|
| 1352 |
query_types,
|
| 1353 |
key="query_type_filter",
|
|
|
|
| 1355 |
help="Direct Instruction vs Relational Instruction",
|
| 1356 |
)
|
| 1357 |
with f[2]:
|
| 1358 |
+
st.selectbox(
|
| 1359 |
"Reasoning",
|
| 1360 |
use_reasoning_options,
|
| 1361 |
key="use_reasoning_filter",
|
| 1362 |
format_func=lambda x: "Yes" if x else "No",
|
| 1363 |
help="Whether chain-of-thought reasoning was used",
|
| 1364 |
)
|
| 1365 |
+
|
| 1366 |
+
# Search instructions
|
| 1367 |
+
def on_search():
|
| 1368 |
+
query = st.session_state.get("instruction_search", "").strip().lower()
|
| 1369 |
+
if not query:
|
| 1370 |
+
return
|
| 1371 |
+
n = len(available_samples)
|
| 1372 |
+
if n == 0:
|
| 1373 |
+
return
|
| 1374 |
+
start = (st.session_state.current_sample_index + 1) % n
|
| 1375 |
+
for offset in range(n):
|
| 1376 |
+
idx = (start + offset) % n
|
| 1377 |
+
instr = available_samples[idx].get("instruction", "").lower()
|
| 1378 |
+
if query in instr:
|
| 1379 |
+
st.session_state.current_sample_index = idx
|
| 1380 |
+
st.session_state.sample_nav_input = idx + 1
|
| 1381 |
+
return
|
| 1382 |
+
|
| 1383 |
+
st.text_input(
|
| 1384 |
+
"Search instructions",
|
| 1385 |
+
key="instruction_search",
|
| 1386 |
+
on_change=on_search,
|
| 1387 |
+
placeholder="Type to search task instructions...",
|
| 1388 |
+
)
|
| 1389 |
|
| 1390 |
_t = _lap("control panel widgets", _t)
|
| 1391 |
|
| 1392 |
+
# Handle variant change
|
|
|
|
| 1393 |
if new_variant != st.session_state.selected_variant:
|
| 1394 |
st.session_state.selected_variant = new_variant
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1395 |
st.rerun()
|
| 1396 |
|
| 1397 |
_lap("main() total", _t0)
|