(run: RunState)
| 444 | |
| 445 | |
| 446 | def _run_agent_background(run: RunState) -> None: |
| 447 | env = os.environ.copy() |
| 448 | env["CS_DASHBOARD_NO_BROWSER"] = "1" |
| 449 | src_dir = str(PROJECT_ROOT / "src") |
| 450 | env["PYTHONPATH"] = src_dir + os.pathsep + env.get("PYTHONPATH", "") |
| 451 | |
| 452 | agent_cmd = f"bash {RUN_AGENT_SH} {run.yaml_path} --no_dashboard" |
| 453 | if _CONDA_ENV: |
| 454 | shell_cmd = f"conda run -n {_CONDA_ENV} --no-capture-output {agent_cmd}" |
| 455 | else: |
| 456 | shell_cmd = agent_cmd |
| 457 | |
| 458 | try: |
| 459 | proc = subprocess.Popen( |
| 460 | shell_cmd, shell=True, cwd=str(PROJECT_ROOT), env=env, |
| 461 | stdout=subprocess.PIPE, stderr=subprocess.STDOUT, |
| 462 | ) |
| 463 | run.process = proc |
| 464 | |
| 465 | host_log_dir = HOST_OUTPUTS_DIR / run.task_name |
| 466 | run.event_log_path = str(host_log_dir / "agent_events.log") |
| 467 | run.workspace_output_dir = str(WORKSPACE_OUTPUTS_DIR / run.task_name) |
| 468 | run.status = "running" |
| 469 | |
| 470 | stdout_lines: list[str] = [] |
| 471 | if proc.stdout: |
| 472 | for raw_line in proc.stdout: |
| 473 | stdout_lines.append(raw_line.decode("utf-8", errors="replace")) |
| 474 | |
| 475 | proc.wait() |
| 476 | final_status, _ = _parse_events(run.event_log_path) |
| 477 | |
| 478 | if final_status == "completed": |
| 479 | # Keep status as "running" while post-processing so the frontend |
| 480 | # does not fetch results before artefacts are ready. |
| 481 | run.status = "post_processing" |
| 482 | try: |
| 483 | _post_process(run) |
| 484 | except Exception as post_exc: |
| 485 | import traceback |
| 486 | traceback.print_exc() |
| 487 | print(f"[POST] Post-processing error: {post_exc}") |
| 488 | # Mark completed only AFTER zip/pdf are built |
| 489 | run.status = "completed" |
| 490 | elif proc.returncode != 0: |
| 491 | run.status = "failed" |
| 492 | tail = "".join(stdout_lines[-20:]).strip() |
| 493 | run.error = f"Agent exited with code {proc.returncode}.\n{tail}" |
| 494 | else: |
| 495 | if final_status == "running": |
| 496 | run.status = "failed" |
| 497 | run.error = "Agent exited without completing the workflow." |
| 498 | else: |
| 499 | run.status = "failed" |
| 500 | tail = "".join(stdout_lines[-20:]).strip() |
| 501 | run.error = f"Agent produced no output.\n{tail}" if tail else "Agent produced no output." |
| 502 | |
| 503 | except Exception as exc: |
nothing calls this directly
no test coverage detected