Spaces:
Running
Running
updated gradio ui
Browse files- gradio-ui.py +121 -23
gradio-ui.py
CHANGED
|
@@ -223,45 +223,133 @@ def call_bidsifier_step(
|
|
| 223 |
def confirm_commands(
|
| 224 |
last_state: Optional[Dict[str, Any]],
|
| 225 |
progress_value: int,
|
| 226 |
-
) -> Tuple[str, int]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
"""
|
| 228 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
|
| 230 |
Parameters
|
| 231 |
----------
|
| 232 |
last_state : dict or None
|
| 233 |
-
State
|
| 234 |
-
list of `commands`. If None, nothing can be executed.
|
| 235 |
progress_value : int
|
| 236 |
-
Current progress
|
| 237 |
|
| 238 |
Returns
|
| 239 |
-------
|
| 240 |
-
|
| 241 |
-
|
| 242 |
new_progress : int
|
| 243 |
-
Updated progress value.
|
|
|
|
|
|
|
| 244 |
"""
|
| 245 |
if not last_state:
|
| 246 |
-
return "⚠️ No previous BIDSifier step to
|
| 247 |
|
| 248 |
output_root = last_state.get("output_root", "").strip()
|
| 249 |
commands: List[str] = last_state.get("commands", [])
|
|
|
|
| 250 |
|
| 251 |
if not output_root:
|
| 252 |
-
return "⚠️ Output root is empty; cannot execute commands.", progress_value
|
| 253 |
-
|
| 254 |
if not commands:
|
| 255 |
-
return "⚠️ No commands detected
|
| 256 |
|
| 257 |
root = Path(output_root)
|
| 258 |
root.mkdir(parents=True, exist_ok=True)
|
| 259 |
|
| 260 |
all_details: List[str] = []
|
| 261 |
-
|
| 262 |
for raw_cmd in commands:
|
| 263 |
-
# Support multi-line shell with backslash continuations *within* a line,
|
| 264 |
-
# but commands already come one-per-line from `parse_commands_from_markdown`.
|
| 265 |
for cmd in split_shell_commands(raw_cmd):
|
| 266 |
proc = subprocess.run(
|
| 267 |
cmd,
|
|
@@ -279,16 +367,20 @@ def confirm_commands(
|
|
| 279 |
|
| 280 |
status = "### Command execution log\n\n" + "\n\n".join(all_details)
|
| 281 |
|
| 282 |
-
# Heuristic: if we executed commands for this step, bump progress to max
|
| 283 |
-
# of current and the step index.
|
| 284 |
-
step_label = last_state.get("step_label")
|
| 285 |
try:
|
| 286 |
idx = STEP_LABELS.index(step_label)
|
| 287 |
-
new_progress = max(progress_value, idx + 1)
|
| 288 |
except (ValueError, TypeError):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 289 |
new_progress = progress_value
|
| 290 |
|
| 291 |
-
return status, new_progress
|
| 292 |
|
| 293 |
|
| 294 |
def run_bids_validation(output_root: str) -> Tuple[str, str]:
|
|
@@ -394,9 +486,14 @@ with gr.Blocks(
|
|
| 394 |
lines=1,
|
| 395 |
type="password",
|
| 396 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 397 |
dataset_xml_input = gr.Textbox(
|
| 398 |
-
label="Dataset XML",
|
| 399 |
-
placeholder="Paste dataset_structure.xml content here
|
| 400 |
lines=8,
|
| 401 |
)
|
| 402 |
readme_input = gr.Textbox(
|
|
@@ -468,7 +565,8 @@ with gr.Blocks(
|
|
| 468 |
interactive=True,
|
| 469 |
)
|
| 470 |
|
| 471 |
-
confirm_button = gr.Button("Confirm
|
|
|
|
| 472 |
bids_validator_button = gr.Button("Run BIDS Validator", variant="primary")
|
| 473 |
|
| 474 |
status_msg = gr.Markdown(label="Status / execution log")
|
|
|
|
| 223 |
def confirm_commands(
|
| 224 |
last_state: Optional[Dict[str, Any]],
|
| 225 |
progress_value: int,
|
| 226 |
+
) -> Tuple[str, str, Dict[str, Any], int, str, str]:
|
| 227 |
+
"""Advance to the next BIDSifier step and call the agent for it.
|
| 228 |
+
|
| 229 |
+
Parameters
|
| 230 |
+
----------
|
| 231 |
+
last_state : dict or None
|
| 232 |
+
State from the previous `call_bidsifier_step`.
|
| 233 |
+
progress_value : int
|
| 234 |
+
Current progress value.
|
| 235 |
+
|
| 236 |
+
Returns
|
| 237 |
+
-------
|
| 238 |
+
llm_output : str
|
| 239 |
+
Raw output from the agent for the next step.
|
| 240 |
+
commands_str : str
|
| 241 |
+
Parsed commands from that output.
|
| 242 |
+
new_state : dict
|
| 243 |
+
Updated state reflecting the new step.
|
| 244 |
+
new_progress : int
|
| 245 |
+
Updated progress value (1-based index of new step).
|
| 246 |
+
new_step_label : str
|
| 247 |
+
UI label of the advanced step (or unchanged if already at last step).
|
| 248 |
+
status_msg : str
|
| 249 |
+
Short status / info message.
|
| 250 |
"""
|
| 251 |
+
if not last_state:
|
| 252 |
+
return (
|
| 253 |
+
"⚠️ No previous BIDSifier step to advance from.",
|
| 254 |
+
"",
|
| 255 |
+
{},
|
| 256 |
+
progress_value,
|
| 257 |
+
STEP_LABELS[0],
|
| 258 |
+
"No state available to confirm.",
|
| 259 |
+
)
|
| 260 |
+
|
| 261 |
+
current_label = last_state.get("step_label")
|
| 262 |
+
try:
|
| 263 |
+
idx = STEP_LABELS.index(current_label)
|
| 264 |
+
except (ValueError, TypeError):
|
| 265 |
+
idx = 0
|
| 266 |
+
|
| 267 |
+
# If already at last step, do not advance further.
|
| 268 |
+
if idx >= len(STEP_LABELS) - 1:
|
| 269 |
+
return (
|
| 270 |
+
"⚠️ Already at final step; cannot advance.",
|
| 271 |
+
"",
|
| 272 |
+
last_state,
|
| 273 |
+
progress_value,
|
| 274 |
+
current_label,
|
| 275 |
+
"Final step reached.",
|
| 276 |
+
)
|
| 277 |
+
|
| 278 |
+
next_label = STEP_LABELS[idx + 1]
|
| 279 |
+
next_id = BIDSIFIER_STEPS[next_label]
|
| 280 |
+
|
| 281 |
+
# Rebuild context from last_state.
|
| 282 |
+
context = build_context(
|
| 283 |
+
last_state.get("dataset_xml", "") or "",
|
| 284 |
+
last_state.get("readme_text", "") or "",
|
| 285 |
+
last_state.get("publication_text", "") or "",
|
| 286 |
+
last_state.get("output_root", "") or "",
|
| 287 |
+
)
|
| 288 |
+
|
| 289 |
+
agent = BIDSifierAgent(
|
| 290 |
+
provider=last_state.get("provider", "openai"),
|
| 291 |
+
model=last_state.get("model", "gpt-4o-mini"),
|
| 292 |
+
)
|
| 293 |
+
|
| 294 |
+
llm_output = agent.run_step(next_id, context)
|
| 295 |
+
commands = parse_commands_from_markdown(llm_output)
|
| 296 |
+
commands_str = "\n".join(commands) if commands else ""
|
| 297 |
+
|
| 298 |
+
new_state = dict(last_state)
|
| 299 |
+
new_state.update(
|
| 300 |
+
{
|
| 301 |
+
"step_label": next_label,
|
| 302 |
+
"step_id": next_id,
|
| 303 |
+
"llm_output": llm_output,
|
| 304 |
+
"commands": commands,
|
| 305 |
+
}
|
| 306 |
+
)
|
| 307 |
+
|
| 308 |
+
new_progress = max(progress_value, idx + 2) # idx is 0-based; progress is 1-based
|
| 309 |
+
status_msg = f"Advanced to step '{next_label}'. Parsed {len(commands)} command(s)."
|
| 310 |
+
|
| 311 |
+
return llm_output, commands_str, new_state, new_progress, next_label, status_msg
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
def run_commands(
|
| 315 |
+
last_state: Optional[Dict[str, Any]],
|
| 316 |
+
progress_value: int,
|
| 317 |
+
) -> Tuple[str, int, str]:
|
| 318 |
+
"""Execute parsed shell commands for the current step, then advance step pointer.
|
| 319 |
|
| 320 |
Parameters
|
| 321 |
----------
|
| 322 |
last_state : dict or None
|
| 323 |
+
State containing commands to execute.
|
|
|
|
| 324 |
progress_value : int
|
| 325 |
+
Current progress value.
|
| 326 |
|
| 327 |
Returns
|
| 328 |
-------
|
| 329 |
+
execution_log : str
|
| 330 |
+
Markdown log of command execution results.
|
| 331 |
new_progress : int
|
| 332 |
+
Updated progress value after execution.
|
| 333 |
+
new_step_label : str
|
| 334 |
+
Updated dropdown label pointing to next step (or unchanged if final).
|
| 335 |
"""
|
| 336 |
if not last_state:
|
| 337 |
+
return "⚠️ No previous BIDSifier step to run.", progress_value, STEP_LABELS[0]
|
| 338 |
|
| 339 |
output_root = last_state.get("output_root", "").strip()
|
| 340 |
commands: List[str] = last_state.get("commands", [])
|
| 341 |
+
step_label = last_state.get("step_label")
|
| 342 |
|
| 343 |
if not output_root:
|
| 344 |
+
return "⚠️ Output root is empty; cannot execute commands.", progress_value, step_label or STEP_LABELS[0]
|
|
|
|
| 345 |
if not commands:
|
| 346 |
+
return "⚠️ No commands detected to execute.", progress_value, step_label or STEP_LABELS[0]
|
| 347 |
|
| 348 |
root = Path(output_root)
|
| 349 |
root.mkdir(parents=True, exist_ok=True)
|
| 350 |
|
| 351 |
all_details: List[str] = []
|
|
|
|
| 352 |
for raw_cmd in commands:
|
|
|
|
|
|
|
| 353 |
for cmd in split_shell_commands(raw_cmd):
|
| 354 |
proc = subprocess.run(
|
| 355 |
cmd,
|
|
|
|
| 367 |
|
| 368 |
status = "### Command execution log\n\n" + "\n\n".join(all_details)
|
| 369 |
|
|
|
|
|
|
|
|
|
|
| 370 |
try:
|
| 371 |
idx = STEP_LABELS.index(step_label)
|
|
|
|
| 372 |
except (ValueError, TypeError):
|
| 373 |
+
idx = 0
|
| 374 |
+
|
| 375 |
+
# Advance pointer (without auto-calling agent) if not at final step.
|
| 376 |
+
if idx < len(STEP_LABELS) - 1:
|
| 377 |
+
new_step_label = STEP_LABELS[idx + 1]
|
| 378 |
+
new_progress = max(progress_value, idx + 2)
|
| 379 |
+
else:
|
| 380 |
+
new_step_label = STEP_LABELS[idx]
|
| 381 |
new_progress = progress_value
|
| 382 |
|
| 383 |
+
return status, new_progress, new_step_label
|
| 384 |
|
| 385 |
|
| 386 |
def run_bids_validation(output_root: str) -> Tuple[str, str]:
|
|
|
|
| 486 |
lines=1,
|
| 487 |
type="password",
|
| 488 |
)
|
| 489 |
+
dataset_xml_file = gr.File(
|
| 490 |
+
label="Upload dataset_structure.xml (optional)",
|
| 491 |
+
file_types=[".xml", ".txt"],
|
| 492 |
+
type="filepath",
|
| 493 |
+
)
|
| 494 |
dataset_xml_input = gr.Textbox(
|
| 495 |
+
label="Dataset XML (editable)",
|
| 496 |
+
placeholder="Paste or upload dataset_structure.xml content here",
|
| 497 |
lines=8,
|
| 498 |
)
|
| 499 |
readme_input = gr.Textbox(
|
|
|
|
| 565 |
interactive=True,
|
| 566 |
)
|
| 567 |
|
| 568 |
+
confirm_button = gr.Button("Confirm (advance & call next step)", variant="primary")
|
| 569 |
+
run_commands_button = gr.Button("Run Commands", variant="secondary")
|
| 570 |
bids_validator_button = gr.Button("Run BIDS Validator", variant="primary")
|
| 571 |
|
| 572 |
status_msg = gr.Markdown(label="Status / execution log")
|