Skip to content

Commit 860211b

Browse files
committed
Defer viewer auto-open to after PDF write in run_evaluation_and_report
When the one-shot run_evaluation_and_report tool ran the eval, the sub-call to handle_run_evaluation auto-opened the viewer immediately after the eval finished. The viewer loaded the /results page before generate_report had a chance to write the PDF, so the page showed "no report has been generated yet" — and the user had to manually refresh. - handle_run_evaluation now honors an optional openViewer arg (default True for backwards compat). When False it skips the auto-open and omits viewResults from the response so the caller owns it. - run_evaluation_and_report passes openViewer=False, then opens the viewer itself only after generate_report returns. Same ensure_viewer _running plumbing, same error fallback.
1 parent 895fbe2 commit 860211b

2 files changed

Lines changed: 53 additions & 18 deletions

File tree

eval_mcp/server.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,9 +809,13 @@ async def run_evaluation_and_report(
809809

810810
config_name = create_data["configName"]
811811

812+
# Suppress the eval's auto-open: the viewer would load before the PDF
813+
# is written and show "no report has been generated yet". We open it
814+
# ourselves once the report is on disk.
812815
eval_result = await handle_run_evaluation({
813816
"configName": config_name,
814817
"user_id": uid,
818+
"openViewer": False,
815819
})
816820
eval_data = json.loads(eval_result[0].text)
817821
eval_data["configName"] = config_name
@@ -835,6 +839,29 @@ async def run_evaluation_and_report(
835839
report_data = json.loads(report_result[0].text)
836840

837841
eval_data["report"] = report_data
842+
843+
viewer_path = f"/results?group={run_id}"
844+
try:
845+
from eval_mcp.viewer import ensure_viewer_running
846+
info = ensure_viewer_running(port=4001, open_path=viewer_path)
847+
eval_data["viewerUrl"] = info["url"]
848+
if info.get("browserOpened"):
849+
eval_data["viewResults"] = (
850+
f"Viewer already running; opened {info['url']}"
851+
if info.get("alreadyRunning")
852+
else f"Started viewer and opened {info['url']}"
853+
)
854+
elif info.get("error"):
855+
eval_data["viewResults"] = (
856+
f"Could not auto-start viewer ({info['error']}). "
857+
f"Run `eval-mcp view` manually, then open {info['url']}"
858+
)
859+
except Exception as e:
860+
eval_data["viewResults"] = (
861+
f"Run `eval-mcp view` in your terminal, then open "
862+
f"http://localhost:4001{viewer_path} ({e})"
863+
)
864+
838865
return json.dumps(eval_data, indent=2)
839866

840867

eval_mcp/tools/run_eval.py

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -501,24 +501,31 @@ async def handle_run_evaluation(args: Dict[str, Any]) -> List[TextContent]:
501501
# Auto-open the viewer so the user doesn't have to run a separate
502502
# command. On any failure we fall back to a manual-instructions string
503503
# rather than lying that the browser opened successfully.
504+
# The one-shot `run_evaluation_and_report` path passes openViewer=False
505+
# so it can open the viewer after the PDF report is written; otherwise
506+
# the page loads before the report exists and shows "no report yet".
504507
view_results_msg = f"Run `eval-mcp view` in your terminal, then open {viewer_url}"
505-
try:
506-
from eval_mcp.viewer import ensure_viewer_running
507-
info = ensure_viewer_running(port=4001, open_path=viewer_path)
508-
viewer_url = info["url"]
509-
if info.get("browserOpened"):
510-
if info.get("alreadyRunning"):
511-
view_results_msg = f"Viewer already running; opened {viewer_url}"
512-
else:
513-
view_results_msg = f"Started viewer and opened {viewer_url}"
514-
elif info.get("error"):
515-
logger.warning(f"Viewer auto-start: {info['error']}")
516-
view_results_msg = (
517-
f"Could not auto-start viewer ({info['error']}). "
518-
f"Run `eval-mcp view` manually, then open {viewer_url}"
519-
)
520-
except Exception as e:
521-
logger.warning(f"Could not auto-start viewer: {e}")
508+
open_viewer = args.get("openViewer", True)
509+
if open_viewer:
510+
try:
511+
from eval_mcp.viewer import ensure_viewer_running
512+
info = ensure_viewer_running(port=4001, open_path=viewer_path)
513+
viewer_url = info["url"]
514+
if info.get("browserOpened"):
515+
if info.get("alreadyRunning"):
516+
view_results_msg = f"Viewer already running; opened {viewer_url}"
517+
else:
518+
view_results_msg = f"Started viewer and opened {viewer_url}"
519+
elif info.get("error"):
520+
logger.warning(f"Viewer auto-start: {info['error']}")
521+
view_results_msg = (
522+
f"Could not auto-start viewer ({info['error']}). "
523+
f"Run `eval-mcp view` manually, then open {viewer_url}"
524+
)
525+
except Exception as e:
526+
logger.warning(f"Could not auto-start viewer: {e}")
527+
else:
528+
view_results_msg = None
522529

523530
result = {
524531
"success": True,
@@ -529,13 +536,14 @@ async def handle_run_evaluation(args: Dict[str, Any]) -> List[TextContent]:
529536
"userDir": str(user_dir),
530537
"message": "Evaluation completed successfully",
531538
"summary": results_summary,
532-
"viewResults": view_results_msg,
533539
"nextStep": (
534540
f"Call generate_report(group_id=\"{run_id}\") to create a PDF "
535541
f"report for the user. Pass `context` describing what they "
536542
f"were evaluating so the narrative is tailored."
537543
) if run_id else None,
538544
}
545+
if view_results_msg is not None:
546+
result["viewResults"] = view_results_msg
539547

540548
return [TextContent(type="text", text=json.dumps(result, indent=2))]
541549

0 commit comments

Comments
 (0)