Skip to content

Expose uploaded OSMO report URLs#932

Open
cvolkcvolk wants to merge 1 commit into
cvolk/feature/osmo-parallel-exact-outputsfrom
cvolk/feature/osmo-report-url
Open

Expose uploaded OSMO report URLs#932
cvolkcvolk wants to merge 1 commit into
cvolk/feature/osmo-parallel-exact-outputsfrom
cvolk/feature/osmo-report-url

Conversation

@cvolkcvolk

Copy link
Copy Markdown
Collaborator

Summary

Print direct URLs for uploaded OSMO reports

Detailed description

  • Add a typed experiment_output.swift_path override for the final Experiment output.
  • Derive the upload destination and browser-ready index.html URL from the same path.
  • Print the report URL after successful submission while preserving the current Arena Swift default.
  • Stack this follow-up on Distribute Arena Experiment Runs with exact outputs #929.

Signed-off-by: Clemens Volk <cvolk@nvidia.com>
@arena-review-bot

Copy link
Copy Markdown
Contributor

🤖 Isaac Lab-Arena Review Bot

Summary

This PR adds a typed ExperimentOutputTaskCfg.swift_path override and derives both the OSMO Swift output destination and a browser-ready index.html report URL from that one path, then prints the report URL after a successful submission. The change is small, well-scoped to the osmo/ submission layer, and cleanly tested (URL derivation, the print path, config rejection, and composed defaults). I confirmed the default Swift output URL is unchanged (experiment_output_swift_url(DATASETS_PATH) reproduces the old DATASET_SWIFT_URL), so existing runs keep publishing to the same place.

No blocking issues found: URLs derive from a single swift_path source of truth, the report URL is only printed when a workflow ID is parsed (dry-run and parse failures skip it gracefully without affecting the submission), and the sole ExperimentOutputTask call site is updated for the new task_cfg argument.

Test Coverage

Good. New unit tests cover experiment_output_swift_url / experiment_report_https_url, the successful-submission print via a monkeypatched subprocess.run, Hydra rejection of unknown experiment_output.* fields, and the composed default. These are pure-Python OSMO tests, so the sim inner/outer pattern does not apply.

Verdict

Ship it

@greptile-apps

greptile-apps Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR exposes the direct browser URL for OSMO-uploaded experiment reports by adding a typed swift_path override to ExperimentOutputTaskCfg and deriving both the Swift upload destination and the https:// index URL from the same configured path. After a successful (non-dry-run) workflow submission the URL is printed to stdout.

  • ExperimentOutputTaskCfg.swift_path defaults to the existing DATASETS_PATH, preserving the previous upload behaviour with no breaking changes.
  • experiment_output_swift_url and experiment_report_https_url normalise the path (strip surrounding slashes, reject URL schemes) and percent-encode the workflow ID so special characters in workflow names produce a valid URL.
  • Tests cover URL derivation, the printed output after a mocked submission, Hydra override validation for the new field, and integration into the composed workflow task output.

Confidence Score: 4/5

Safe to merge — the change is additive and backwards-compatible; the only nit is a missing type annotation that does not affect runtime behaviour.

All logic paths are covered by the new tests. The URL construction correctly percent-encodes the workflow ID, the dry-run path leaves workflow_id as None so no URL is printed for a dry run, and the default swift_path reproduces the old hardcoded Swift destination exactly. The one noted issue is that BaseTask.task_cfg is typed as TaskCfg | None while ExperimentOutputTask._get_outputs accesses .swift_path on it without narrowing, which would be flagged by a strict type checker even though it is always safe at runtime.

osmo/tasks/experiment_output_task.py — the _get_outputs method accesses self.task_cfg.swift_path without narrowing the inherited TaskCfg | None annotation.

Important Files Changed

Filename Overview
osmo/tasks/experiment_output_task.py Adds ExperimentOutputTaskCfg, URL derivation helpers, and wires task_cfg into ExperimentOutputTask; minor type-narrowing gap in _get_outputs()
osmo/submit_arena_experiment.py Adds experiment_output field to ArenaExperimentSubmissionCfg and prints the browser report URL after a successful, non-dry-run submission; logic looks correct
osmo/workflows/arena_experiment_workflow.py Threads experiment_output_task_cfg through the workflow constructor to ExperimentOutputTask; clean, no issues
isaaclab_arena/tests/test_osmo_experiment_workflow.py Adds well-targeted tests for URL derivation, report URL printing, and Hydra override validation for the new field

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant submit as submit_arena_experiment
    participant workflow as Pi0ArenaExperimentWorkflow
    participant outputTask as ExperimentOutputTask
    participant osmo as OSMO CLI

    User->>submit: ArenaExperimentSubmissionCfg(experiment_output.swift_path)
    submit->>workflow: "experiment_output_task_cfg=ExperimentOutputTaskCfg(swift_path)"
    workflow->>outputTask: "task_cfg=experiment_output_task_cfg"
    outputTask-->>workflow: _get_outputs returns swift URL with workflow_id token
    workflow-->>submit: rendered YAML
    submit->>osmo: osmo workflow submit yaml
    osmo-->>submit: "WorkflowSubmissionResult(returncode=0, workflow_id)"
    submit->>submit: experiment_report_https_url(swift_path, workflow_id)
    submit-->>User: Report HTTPS URL printed to stdout
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant submit as submit_arena_experiment
    participant workflow as Pi0ArenaExperimentWorkflow
    participant outputTask as ExperimentOutputTask
    participant osmo as OSMO CLI

    User->>submit: ArenaExperimentSubmissionCfg(experiment_output.swift_path)
    submit->>workflow: "experiment_output_task_cfg=ExperimentOutputTaskCfg(swift_path)"
    workflow->>outputTask: "task_cfg=experiment_output_task_cfg"
    outputTask-->>workflow: _get_outputs returns swift URL with workflow_id token
    workflow-->>submit: rendered YAML
    submit->>osmo: osmo workflow submit yaml
    osmo-->>submit: "WorkflowSubmissionResult(returncode=0, workflow_id)"
    submit->>submit: experiment_report_https_url(swift_path, workflow_id)
    submit-->>User: Report HTTPS URL printed to stdout
Loading

Reviews (1): Last reviewed commit: "Expose uploaded OSMO report URLs" | Re-trigger Greptile

Comment on lines 102 to +104
def _get_outputs(self) -> list[dict[str, Any]]:
"""Publish the final Experiment directory, including all Runs and ``index.html``."""
return [{"url": DATASET_SWIFT_URL}]
return [{"url": experiment_output_swift_url(self.task_cfg.swift_path)}]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 self.task_cfg not narrowed to ExperimentOutputTaskCfg

BaseTask declares self.task_cfg as TaskCfg | None, so a static type-checker will flag the .swift_path access on line 104 as an unknown attribute and a potential None dereference. At runtime it's always safe because ExperimentOutputTask.__init__ requires a non-optional ExperimentOutputTaskCfg, but the declared type doesn't reflect that. Adding a typed attribute annotation (e.g. task_cfg: ExperimentOutputTaskCfg on the class body) would let type checkers verify this without changing behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant