Spaces:
Sleeping
Sleeping
Rafael Poyiadzi Claude Opus 4.6 commited on
Commit ·
6c9ed33
1
Parent(s): 425e3d7
Add toggleable research column with dict expansion
Browse filesResearch column is hidden by default. A "Show research details" checkbox
expands the raw research dict into separate columns (research.answer,
research.sources, etc). CSV download always contains the full raw data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
app.py
CHANGED
|
@@ -140,19 +140,6 @@ async def run_agent_map(api_key, file, query, effort_label, fields_list):
|
|
| 140 |
output_df = result.data
|
| 141 |
|
| 142 |
if "research" in output_df.columns:
|
| 143 |
-
def _extract_research(val):
|
| 144 |
-
if isinstance(val, dict):
|
| 145 |
-
return val.get("answer", str(val))
|
| 146 |
-
if isinstance(val, str):
|
| 147 |
-
try:
|
| 148 |
-
parsed = ast.literal_eval(val)
|
| 149 |
-
if isinstance(parsed, dict) and "answer" in parsed:
|
| 150 |
-
return parsed["answer"]
|
| 151 |
-
except (ValueError, SyntaxError):
|
| 152 |
-
pass
|
| 153 |
-
return val
|
| 154 |
-
|
| 155 |
-
output_df["research"] = output_df["research"].apply(_extract_research)
|
| 156 |
cols = [c for c in output_df.columns if c != "research"] + ["research"]
|
| 157 |
output_df = output_df[cols]
|
| 158 |
|
|
@@ -164,6 +151,56 @@ async def run_agent_map(api_key, file, query, effort_label, fields_list):
|
|
| 164 |
return output_df, gr.update(value=tmp.name, visible=True)
|
| 165 |
|
| 166 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
with gr.Blocks(
|
| 168 |
title="everyrow research",
|
| 169 |
css=".error-box { background: #fee; border: 1px solid #c00; border-radius: 8px; padding: 12px; color: #900; }",
|
|
@@ -379,10 +416,13 @@ with gr.Blocks(
|
|
| 379 |
result_df, download_update = await run_agent_map(
|
| 380 |
api_key_val, file_val, query_val, effort_val, fields_list
|
| 381 |
)
|
|
|
|
| 382 |
return (
|
| 383 |
gr.update(value="", visible=False),
|
| 384 |
result_df,
|
|
|
|
| 385 |
download_update,
|
|
|
|
| 386 |
)
|
| 387 |
except gr.Error:
|
| 388 |
raise
|
|
@@ -394,19 +434,40 @@ with gr.Blocks(
|
|
| 394 |
),
|
| 395 |
gr.update(),
|
| 396 |
gr.update(),
|
|
|
|
|
|
|
| 397 |
)
|
| 398 |
|
| 399 |
submit_btn.click(
|
| 400 |
fn=on_submit,
|
| 401 |
inputs=[api_key, file, query, effort] + all_text_inputs,
|
| 402 |
-
outputs=[error_box, output_table, download_btn],
|
| 403 |
)
|
| 404 |
|
| 405 |
gr.Markdown("### Results")
|
| 406 |
error_box = gr.Markdown(visible=False, elem_classes=["error-box"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 407 |
output_table = gr.Dataframe(label="Results")
|
| 408 |
download_btn = gr.File(label="Download CSV", visible=False)
|
| 409 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 410 |
def on_upload(file):
|
| 411 |
if file is None:
|
| 412 |
return gr.update(visible=False), gr.update(visible=False)
|
|
|
|
| 140 |
output_df = result.data
|
| 141 |
|
| 142 |
if "research" in output_df.columns:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
cols = [c for c in output_df.columns if c != "research"] + ["research"]
|
| 144 |
output_df = output_df[cols]
|
| 145 |
|
|
|
|
| 151 |
return output_df, gr.update(value=tmp.name, visible=True)
|
| 152 |
|
| 153 |
|
| 154 |
+
RESEARCH_TRUNCATE_LEN = 120
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def _parse_research_val(val):
|
| 158 |
+
"""Try to parse a research value into a dict."""
|
| 159 |
+
if isinstance(val, dict):
|
| 160 |
+
return val
|
| 161 |
+
if isinstance(val, str):
|
| 162 |
+
try:
|
| 163 |
+
parsed = ast.literal_eval(val)
|
| 164 |
+
if isinstance(parsed, dict):
|
| 165 |
+
return parsed
|
| 166 |
+
except (ValueError, SyntaxError):
|
| 167 |
+
pass
|
| 168 |
+
return None
|
| 169 |
+
|
| 170 |
+
|
| 171 |
+
def _extract_answer(val):
|
| 172 |
+
"""Extract the answer string from a research value."""
|
| 173 |
+
parsed = _parse_research_val(val)
|
| 174 |
+
if parsed is not None:
|
| 175 |
+
return parsed.get("answer", str(val))
|
| 176 |
+
return str(val)
|
| 177 |
+
|
| 178 |
+
|
| 179 |
+
def hide_research(df: pd.DataFrame) -> pd.DataFrame:
|
| 180 |
+
"""Default view: drop the research column."""
|
| 181 |
+
if "research" not in df.columns:
|
| 182 |
+
return df
|
| 183 |
+
return df.drop(columns=["research"])
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
def expand_research(df: pd.DataFrame) -> pd.DataFrame:
|
| 187 |
+
"""Expanded view: explode research dict into separate columns."""
|
| 188 |
+
if "research" not in df.columns:
|
| 189 |
+
return df
|
| 190 |
+
result = df.copy()
|
| 191 |
+
parsed_dicts = result["research"].apply(_parse_research_val)
|
| 192 |
+
has_dicts = parsed_dicts.notna().any()
|
| 193 |
+
if not has_dicts:
|
| 194 |
+
return result
|
| 195 |
+
expanded = pd.json_normalize(parsed_dicts.apply(lambda v: v if v is not None else {}))
|
| 196 |
+
expanded.index = result.index
|
| 197 |
+
# Prefix expanded columns with "research." to avoid clashes
|
| 198 |
+
expanded.columns = [f"research.{c}" for c in expanded.columns]
|
| 199 |
+
result = result.drop(columns=["research"])
|
| 200 |
+
result = pd.concat([result, expanded], axis=1)
|
| 201 |
+
return result
|
| 202 |
+
|
| 203 |
+
|
| 204 |
with gr.Blocks(
|
| 205 |
title="everyrow research",
|
| 206 |
css=".error-box { background: #fee; border: 1px solid #c00; border-radius: 8px; padding: 12px; color: #900; }",
|
|
|
|
| 416 |
result_df, download_update = await run_agent_map(
|
| 417 |
api_key_val, file_val, query_val, effort_val, fields_list
|
| 418 |
)
|
| 419 |
+
has_research = "research" in result_df.columns
|
| 420 |
return (
|
| 421 |
gr.update(value="", visible=False),
|
| 422 |
result_df,
|
| 423 |
+
hide_research(result_df) if has_research else result_df,
|
| 424 |
download_update,
|
| 425 |
+
gr.update(value=False, visible=has_research),
|
| 426 |
)
|
| 427 |
except gr.Error:
|
| 428 |
raise
|
|
|
|
| 434 |
),
|
| 435 |
gr.update(),
|
| 436 |
gr.update(),
|
| 437 |
+
gr.update(),
|
| 438 |
+
gr.update(),
|
| 439 |
)
|
| 440 |
|
| 441 |
submit_btn.click(
|
| 442 |
fn=on_submit,
|
| 443 |
inputs=[api_key, file, query, effort] + all_text_inputs,
|
| 444 |
+
outputs=[error_box, full_results_state, output_table, download_btn, research_toggle],
|
| 445 |
)
|
| 446 |
|
| 447 |
gr.Markdown("### Results")
|
| 448 |
error_box = gr.Markdown(visible=False, elem_classes=["error-box"])
|
| 449 |
+
full_results_state = gr.State(None)
|
| 450 |
+
research_toggle = gr.Checkbox(
|
| 451 |
+
label="Show research details",
|
| 452 |
+
value=False,
|
| 453 |
+
visible=False,
|
| 454 |
+
)
|
| 455 |
output_table = gr.Dataframe(label="Results")
|
| 456 |
download_btn = gr.File(label="Download CSV", visible=False)
|
| 457 |
|
| 458 |
+
def toggle_research(show_full, full_df):
|
| 459 |
+
if full_df is None:
|
| 460 |
+
return gr.update()
|
| 461 |
+
if show_full:
|
| 462 |
+
return expand_research(full_df)
|
| 463 |
+
return hide_research(full_df)
|
| 464 |
+
|
| 465 |
+
research_toggle.change(
|
| 466 |
+
toggle_research,
|
| 467 |
+
inputs=[research_toggle, full_results_state],
|
| 468 |
+
outputs=output_table,
|
| 469 |
+
)
|
| 470 |
+
|
| 471 |
def on_upload(file):
|
| 472 |
if file is None:
|
| 473 |
return gr.update(visible=False), gr.update(visible=False)
|