Skip to content

docs: add Experimentalist PR walkthrough - #1041

Open
gaiadilorenzo wants to merge 6 commits into
mainfrom
772-enable-example-agent-walkthrough/gdilorenzo
Open

docs: add Experimentalist PR walkthrough#1041
gaiadilorenzo wants to merge 6 commits into
mainfrom
772-enable-example-agent-walkthrough/gdilorenzo

Conversation

@gaiadilorenzo

@gaiadilorenzo gaiadilorenzo commented Aug 3, 2026

Copy link
Copy Markdown

Summary

  • document creating a private standalone Git repository for the Tau3 example agent
  • show GitHub/GitLab CLI authentication and draft PR/MR publication for a validated winner
  • explain optional candidate-branch archival and how to list and compare non-winning candidates after a run
  • normalize Git SSH provenance to HTTPS so Experiment mirror projection accepts source links
  • publish every candidate file except agent-repository ignores; the example ignores .env, generated metadata.json, and __pycache__/

Validation

  • uv run --frozen pytest plugins/nemo-experimentalist/tests/test_resolve.py -q (65 passed)
  • uv run --frozen pytest plugins/nemo-experimentalist/tests/experimentalist/test_repository.py -q (73 passed)
  • focused Experiment mirror tests

Linear: https://linear.app/nvidia/issue/ASE-772/enable-example-agent-walk-trough-with-pr-creation

Summary by CodeRabbit

  • New Features

    • Added concurrent task execution and repository-backed experimental workflows.
    • Winning candidates are now published as draft pull or merge requests by default.
    • Added trace uploads from existing Harbor runs without rerunning trials.
    • Added optional candidate archiving.
  • Documentation

    • Expanded guidance for repository setup, authentication, optimization, review, and local execution.
  • Bug Fixes

    • Improved repository and candidate links with consistent HTTPS URLs and safer credential handling.
    • Preserved required metadata and runtime files in candidate snapshots.
    • Prevented local credentials and generated artifacts from being committed.
    • Improved storage configuration handling and validation.

@gaiadilorenzo
gaiadilorenzo requested review from a team as code owners August 3, 2026 17:00
@github-actions github-actions Bot added the docs label Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The changes document repository-backed Experimentalist execution, enable candidate publication and archiving, normalize provenance and candidate links, preserve Git-managed candidate files, update storage serialization, and add upload-only Harbor trace processing.

Changes

Experimentalist workflows

Layer / File(s) Summary
Repository setup and candidate publication
docs/get-started/example-agent.mdx, plugins/nemo-experimentalist/examples/tau3-nooa-agent/experimentalist-smoke.yaml, plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/config.py, plugins/nemo-experimentalist/tests/test_resolve.py, plugins/nemo-experimentalist/examples/tau3-nooa-agent/.gitignore
Documents repository setup, concurrent execution, draft PR/MR publication, local execution, and candidate archiving. publish_winner now defaults to True. The example ignores credentials and generated artifacts.
Repository provenance and candidate snapshots
plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/repository.py, plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/experiment_mirror.py, plugins/nemo-experimentalist/tests/experimentalist/test_repository.py, plugins/nemo-experimentalist/tests/test_experiment_mirror_mapping.py
Repository sources now record normalized HTTPS provenance URLs. Candidate overlays use .gitignore for staging. Snapshots retain metadata and runtime files. Optimization candidate links now use HTTPS URLs. Tests cover SSH and SCP-style Git URLs and snapshot contents.
Storage configuration serialization
plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/cli.py, plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/resolve.py
Run and doctor checks omit unset storage fields for non-Git agents. Git agents retain all storage fields. Explicitly configured values remain in resolved profile flags.
Harbor trace upload workflow
plugins/nemo-experimentalist/examples/tau3-nooa-agent/record_tau_airline_traces.py
Adds --upload-dir support for uploading completed Harbor trial traces without rerunning trials. The script validates outputs, waits for Intake visibility, and writes an upload summary.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant record_tau_airline_traces.py
  participant HarborOutput
  participant Intake
  User->>record_tau_airline_traces.py: Select --upload-dir
  record_tau_airline_traces.py->>HarborOutput: Resolve and validate completed trials
  record_tau_airline_traces.py->>Intake: Upload trial traces
  Intake-->>record_tau_airline_traces.py: Confirm trace visibility
  record_tau_airline_traces.py-->>User: Write upload summary
Loading

Possibly related PRs

Suggested labels: feat

Suggested reviewers: schuellc-nvidia, sklinglernv, aleckhoury

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.30% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main user-facing change: adding an Experimentalist PR walkthrough to the documentation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 772-enable-example-agent-walkthrough/gdilorenzo

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/get-started/example-agent.mdx`:
- Line 151: Update the section heading to say “create a draft PR or MR” instead
of “create a PR,” preserving the existing reference to Experimentalist.
- Around line 168-169: Update the branch-selection description in the
Experimentalist instructions so it states that the `@main` suffix selects the
source ref to optimize, while pr_base_branch: main selects the target branch for
the draft PR or MR.
- Around line 83-88: Remove the populated .env file from the copied agent
directory before the git -C "$TAU3_AGENT_DIR" add . command, while preserving
the existing initialization and commit flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3d91e9b6-bf4c-4741-a658-868de7b587af

📥 Commits

Reviewing files that changed from the base of the PR and between 2cb9a08 and 9b5930d.

📒 Files selected for processing (1)
  • docs/get-started/example-agent.mdx

Comment thread docs/get-started/example-agent.mdx Outdated
Comment thread docs/get-started/example-agent.mdx Outdated
Comment thread docs/get-started/example-agent.mdx Outdated
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 30406/38435 79.1% 63.8%
Integration Tests 18010/37104 48.5% 21.0%

@gaiadilorenzo gaiadilorenzo self-assigned this Aug 4, 2026
@gaiadilorenzo
gaiadilorenzo marked this pull request as draft August 4, 2026 14:40
@gaiadilorenzo
gaiadilorenzo force-pushed the 772-enable-example-agent-walkthrough/gdilorenzo branch 3 times, most recently from 599d0ef to 6602778 Compare August 4, 2026 14:57
Signed-off-by: Gaia Di Lorenzo <gdilorenzo@ethz.ch>
@gaiadilorenzo
gaiadilorenzo force-pushed the 772-enable-example-agent-walkthrough/gdilorenzo branch from 6602778 to 97a885e Compare August 4, 2026 15:00
Gaia Di Lorenzo added 2 commits August 4, 2026 17:01
@gaiadilorenzo
gaiadilorenzo marked this pull request as ready for review August 4, 2026 15:06

@coderabbitai coderabbitai Bot left a comment

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/experiment_mirror.py (1)

167-169: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep ancestor lookup split-aware.

This loop supports arbitrary reward channels, but _parent_experiment_id always retrieves (candidate.ancestor, "train"). If a candidate uses only validation or a custom channel, its ancestor link is omitted even when the matching Experiment exists. Pass split into _parent_experiment_id and retrieve the ancestor Experiment for that split.

Proposed fix
-        parent = await self._parent_experiment_id(candidate, gname)
+        parent = await self._parent_experiment_id(candidate, gname, split)

-    async def _parent_experiment_id(self, candidate: Candidate, gname: str) -> str | None:
+    async def _parent_experiment_id(self, candidate: Candidate, gname: str, split: str) -> str | None:
         if not candidate.ancestor:
             return None
-        cached = self._experiment_ids.get((candidate.ancestor, "train"))
+        cached = self._experiment_ids.get((candidate.ancestor, split))
         if cached is not None:
             return cached
         try:
             exp = await self._client.evaluations.retrieve(
-                experiment_name(gname, candidate.ancestor, "train"), workspace=self._workspace
+                experiment_name(gname, candidate.ancestor, split), workspace=self._workspace
             )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/experiment_mirror.py`
around lines 167 - 169, Update the reward-channel loop in the experiment
mirroring flow to pass each `split` into `_parent_experiment_id`, and change
that method to look up the ancestor Experiment using the supplied split instead
of hardcoding `"train"`. Preserve support for validation and custom reward
channels while keeping the existing ancestor candidate lookup behavior.
plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/config.py (1)

54-54: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Add extra='forbid' to configuration models.

Pydantic v2 BaseModel silently ignores unknown keys. A typo like stroage: {publish_winner: false} instead of storage: {publish_winner: false} causes the entire key to be discarded, leaving publish_winner=True by default. The run then publishes a winner branch and PR/MR despite the operator's intent to disable publication. Add ConfigDict(extra='forbid') to EvolutionaryOptimizerConfig, CandidateStorageConfig, and AgentSourceConfig to reject unknown keys and surface configuration errors.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/config.py` at
line 54, Add ConfigDict(extra='forbid') to the Pydantic model configuration for
EvolutionaryOptimizerConfig, CandidateStorageConfig, and AgentSourceConfig,
ensuring unknown configuration keys raise validation errors instead of being
ignored.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/config.py`:
- Line 54: Add ConfigDict(extra='forbid') to the Pydantic model configuration
for EvolutionaryOptimizerConfig, CandidateStorageConfig, and AgentSourceConfig,
ensuring unknown configuration keys raise validation errors instead of being
ignored.

In
`@plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/experiment_mirror.py`:
- Around line 167-169: Update the reward-channel loop in the experiment
mirroring flow to pass each `split` into `_parent_experiment_id`, and change
that method to look up the ancestor Experiment using the supplied split instead
of hardcoding `"train"`. Preserve support for validation and custom reward
channels while keeping the existing ancestor candidate lookup behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3db119ba-c939-405b-b25d-eed1178055db

📥 Commits

Reviewing files that changed from the base of the PR and between 9b5930d and 895044d.

📒 Files selected for processing (9)
  • docs/get-started/example-agent.mdx
  • plugins/nemo-experimentalist/examples/tau3-nooa-agent/experimentalist-smoke.yaml
  • plugins/nemo-experimentalist/examples/tau3-nooa-agent/record_tau_airline_traces.py
  • plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/config.py
  • plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/repository.py
  • plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/experiment_mirror.py
  • plugins/nemo-experimentalist/tests/experimentalist/test_repository.py
  • plugins/nemo-experimentalist/tests/test_experiment_mirror_mapping.py
  • plugins/nemo-experimentalist/tests/test_resolve.py

Signed-off-by: Gaia Di Lorenzo <gdilorenzo@ethz.ch>

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/nemo-experimentalist/examples/tau3-nooa-agent/.gitignore`:
- Around line 1-2: Add the required NVIDIA copyright SPDX header and Apache-2.0
license identifier at the top of the .gitignore file, before the existing
credential-ignore entry.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c393858e-e084-4a98-98ee-1670d6a8bced

📥 Commits

Reviewing files that changed from the base of the PR and between 895044d and 27615be.

📒 Files selected for processing (3)
  • plugins/nemo-experimentalist/examples/tau3-nooa-agent/.gitignore
  • plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/experimentalist/components/repository.py
  • plugins/nemo-experimentalist/tests/experimentalist/test_repository.py

Comment on lines +1 to +2
# Local inference credentials
.env

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add the required SPDX header.

Line 1 lacks the NVIDIA copyright SPDX header and the Apache-2.0 identifier.

Proposed fix
+# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
 # Local inference credentials
 .env
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Local inference credentials
.env
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Local inference credentials
.env
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/nemo-experimentalist/examples/tau3-nooa-agent/.gitignore` around
lines 1 - 2, Add the required NVIDIA copyright SPDX header and Apache-2.0
license identifier at the top of the .gitignore file, before the existing
credential-ignore entry.

Source: Coding guidelines

Signed-off-by: Gaia Di Lorenzo <gdilorenzo@ethz.ch>
Preserve explicitly configured storage flags while keeping implicit remote persistence quiet for local sources, and apply required formatting.

Signed-off-by: Alec Khoury <akhoury@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/cli.py`:
- Line 279: Update the shared looks_like_git() predicate to identify and reject
local filesystem paths before checking whether the normalized source ends with
“.git”. Ensure paths such as /tmp/agent.git are classified as local while
genuine remote Git sources retain the existing suffix-based behavior, including
both call sites using this predicate.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d3801c4d-867c-4121-a3d9-4098b374d8c1

📥 Commits

Reviewing files that changed from the base of the PR and between ebca8f5 and e214686.

📒 Files selected for processing (4)
  • plugins/nemo-experimentalist/examples/tau3-nooa-agent/record_tau_airline_traces.py
  • plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/cli.py
  • plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/resolve.py
  • plugins/nemo-experimentalist/tests/test_experiment_mirror_mapping.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/nemo-experimentalist/tests/test_experiment_mirror_mapping.py
  • plugins/nemo-experimentalist/examples/tau3-nooa-agent/record_tau_airline_traces.py

task_template=plan.task_template,
agent_source=plan.agent,
storage=plan.config.storage.model_dump(),
storage=plan.config.storage.model_dump(exclude_unset=not looks_like_git(str(plan.agent))),

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not classify local .git paths as remote Git sources.

looks_like_git() returns true when the normalized source ends with .git. A local agent directory such as /tmp/agent.git is therefore treated as a Git source. exclude_unset=False then retains implicit persistence defaults and can trigger remote-persistence checks for a local agent.

Update the shared predicate to reject filesystem paths before applying the .git suffix rule.

Also applies to: 422-422

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/nemo-experimentalist/src/nemo_experimentalist_plugin/cli.py` at line
279, Update the shared looks_like_git() predicate to identify and reject local
filesystem paths before checking whether the normalized source ends with “.git”.
Ensure paths such as /tmp/agent.git are classified as local while genuine remote
Git sources retain the existing suffix-based behavior, including both call sites
using this predicate.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants