Add a local web viewer for experiment runs#122
Open
merlerm wants to merge 10 commits into
Open
Conversation
Inspecting a sweep meant opening results.json by hand and hunting for the matching GIFs and sandbox git history across output directories. experiments/results_viewer.py serves a browsable index of every run found under --root: metrics, per-episode success/failure GIFs, and the sandbox git history of the generated approach.py with per-commit diffs and the agent's reasoning pulled from stream.jsonl. It can also re-render a GIF for any episode on the current or a past approach version. Browsing needs only the Python stdlib; hydra, numpy, and the robocode packages are imported lazily on the first render, so a downloaded outputs/ folder can be inspected on a machine without the full environment.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a stdlib-only local HTTP results viewer to make it easier to browse experiment run outputs (metrics, per-episode GIFs, and sandbox approach.py git history) without manually navigating results.json and run directories.
Changes:
- Introduces
experiments/results_viewer.py, a small HTTP server + embedded frontend for indexing runs and rendering/serving per-episode GIFs and approach history. - Documents how to launch the viewer from the README.
- Adds
viewer_runs/to.gitignoreas a conventional curated runs collection directory.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
README.md |
Documents launching the new results viewer. |
experiments/results_viewer.py |
New local web UI + API for browsing runs and (optionally) re-rendering GIFs and viewing sandbox history. |
.gitignore |
Ignores viewer_runs/ as a curated run collection directory. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Three fixes from review: - The render worker composed its replay config with `primitives=[]`. A generated approach.py indexes the exact primitives it was written against, so re-rendering any run that used primitives raised KeyError. Resolve the run's own set from its .hydra directory instead, preferring the recorded override and falling back to the resolved list in config.yaml. - `_safe` compared resolved paths with a string prefix, which admits a sibling directory sharing the prefix (/runs/ab passes a /runs/a check). Use Path.is_relative_to. - The server bound 0.0.0.0, exposing run logs and files to anyone who could reach the port. Bind 127.0.0.1 by default, with --host to opt back out.
tomsilver
approved these changes
Jul 21, 2026
tomsilver
left a comment
Owner
There was a problem hiding this comment.
not checking this carefully but seems useful :)
merlerm
enabled auto-merge (squash)
July 22, 2026 08:03
merlerm
disabled auto-merge
July 22, 2026 08:05
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Inspecting a sweep meant opening
results.jsonby hand and hunting for the matching GIFs and sandbox git history across output directories. This puts the viewer I have been using locally into the repo.experiments/results_viewer.pyis a stdlib-only HTTP server that serves a browsable index of every run found under--root:gen_*generation metricsapproach.py, with per-commit diffs and the agent's reasoning matched fromstream.jsonlBrowsing needs only the Python stdlib. hydra, numpy, and the robocode packages are imported lazily on the first render, so a downloaded
outputs/folder can be inspected on a machine without the full environment.python experiments/results_viewer.py --root . --port 8000The scan walks
--rootrecursively and picks up runs wherever they live (outputs/,multirun/, or a curated collection), skipping re-eval passes.viewer_runs/is gitignored as the conventional spot for a curated collection.Checks: pylint 10.00/10, mypy clean. Smoke-tested against 19 local runs: index, static assets,
/api/runs,/api/stamp, and run detail all return 200 with correct metrics, 100 episodes, and history detected.