Skip to content

refactor(evaluator): clarify SDK ref handling contracts - #128

Merged
SandyChapman merged 1 commit into
mainfrom
evaluator-ref-contract-cleanup/SandyChapman
Jun 3, 2026
Merged

refactor(evaluator): clarify SDK ref handling contracts#128
SandyChapman merged 1 commit into
mainfrom
evaluator-ref-contract-cleanup/SandyChapman

Conversation

@SandyChapman

@SandyChapman SandyChapman commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • remove the SDK EvaluationRequest handoff in favor of explicit backend fields
  • remove dataset_glob_pattern; dataset paths can now encode local glob selection directly
  • keep platform-only refs out of the SDK contract by resolving FilesetRef and ModelRef in the plugin layer
  • add FilesetRef download/path-safety handling and ModelRef submit support
  • tighten target/config validation with resolve_params and overloads
  • sync the vendored evaluator SDK wrapper

Validation

  • uv run --frozen ty check packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/evaluator.py plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py plugins/nemo-evaluator/tests/test_filesets.py
  • uv run --frozen pytest plugins/nemo-evaluator/tests/test_filesets.py plugins/nemo-evaluator/tests/test_evaluate_job.py -q
  • bash tools/lint/lint-python-style.sh
  • remote smoke tests covering FilesetRef + ModelRef target, multi-metric FilesetRef, metric-level ModelRef, and artifact download

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Documentation preview is ready

Preview: https://nvidia-nemo.github.io/nemo-platform/pr-preview/pr-128/pr-128/

Built from 6564f1b in workflow run.

This preview is deployed from this PR branch, updates when docs changes are pushed, and will be removed when the PR closes.

Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 18480/24466 75.5% 62.0%
Integration Tests 11888/23243 51.1% 26.4%

@SandyChapman SandyChapman changed the title Clarify evaluator SDK ref handling contracts chore(evaluator): Clarify evaluator SDK ref handling contracts Jun 2, 2026
@SandyChapman
SandyChapman force-pushed the evaluator-ref-contract-cleanup/SandyChapman branch from 64b27d7 to 5c90393 Compare June 2, 2026 13:07
@SandyChapman
SandyChapman marked this pull request as ready for review June 2, 2026 13:10
@SandyChapman
SandyChapman requested review from a team as code owners June 2, 2026 13:10
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

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

Removes EvaluationRequest wrapper; passes explicit dataset/params/target/prompt/aggregate/hooks through backends and SDK; introduces FilesetRef and download helpers; adds EvaluateInputSpec/to_spec; refactors executors to package specs for local job runs; updates tests and docs; tightens params validation.

Changes

Backend contract and configuration parameter resolution

Layer / File(s) Summary
Backend protocol signature updates
packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/backends/base.py
EvaluationBackend and SyncEvaluationBackend replace request: EvaluationRequest with explicit dataset, params, target, field_mapping, prompt_template, aggregate_fields, preprocess_hooks, postprocess_hooks. Introduces BackendParams alias.
Params resolution and metric typing
packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/config.py, packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/metric_execution.py
Replace normalize_params with resolve_params enforcing strict target/params subtype compatibility; remove EvaluationRequest dataclass; ComputeMetricPipeline requires non-optional params per target type.

Backend implementation and evaluator entry points

Layer / File(s) Summary
LocalBackend implementation
packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/backends/local/backend.py
Update _evaluate_one, evaluate, and evaluate_benchmark to accept explicit dataset/params/target/prompt_template/aggregate_fields and hooks; prepare dataset rows and conditionally merge online hooks.
Evaluator.run and Evaluator.run_sync refactoring
packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/evaluator.py
Remove dataset_glob_pattern, resolve params via resolve_params(config, target), normalize hooks into tuples, and dispatch using metric-form type guards; add stricter overloads.

Fileset utilities and job specification

Layer / File(s) Summary
Fileset utilities module
plugins/nemo-evaluator/src/nemo_evaluator/filesets.py
Add FilesetRef with # fragment support, glob-matching helpers, normalize_fileset_path, _safe_child_path, and async/sync download_dataset helpers.
Job specification and evaluation job updates
plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py, plugins/nemo-evaluator/src/nemo_evaluator/jobs/utils.py
Introduce EvaluateInputSpec; make EvaluateSpec extend it with validators to resolve params for target and reject unresolved bundled ModelRefs; add EvaluateJob.to_spec for hydration/resolution and canonicalization; jobs/utils delegates downloads to shared filesets helpers.

Plugin executor refactoring and SDK resource updates

Layer / File(s) Summary
Plugin executor implementation
plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
Add EvaluateRequestSpec and SubmitTargetSpec; refactor sync/async executors to accept packaged specs or explicit dataset/params, run local jobs via NemoJobScheduler.run_local, submit remote jobs with explicit fields, and validate metric bundling.
SDK resource and standalone backend updates
plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py, plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py
Remove dataset_glob_pattern from run/submit signatures, add overloads constraining config/target/prompt_template, support ModelRef in submit targets via SubmitTargetSpec, and update NMPBackend/AsyncNMPBackend to accept explicit dataset/params/target/prompt/hooks and enforce packager for remote evaluate.

SDK module reorganization and documentation

Layer / File(s) Summary
SDK types and values reorganization
plugins/nemo-evaluator/src/nemo_evaluator/sdk/__init__.py, plugins/nemo-evaluator/src/nemo_evaluator/sdk/types.py, plugins/nemo-evaluator/src/nemo_evaluator/sdk/values/filesets.py, plugins/nemo-evaluator/src/nemo_evaluator/sdk/http_utils.py
Import FilesetRef from nemo_evaluator.filesets; convert sdk/values/filesets.py to a re-export; widen http_utils.create_job_payload to accept `EvaluateInputSpec
Documentation updates
docs/evaluator/sdk-resources.md, packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/README.md
Expand dataset docs to include local glob paths and fileset fragment selectors; remove dataset_glob_pattern rows; drop EvaluationRequest from public surface docs.

Test suite updates

Layer / File(s) Summary
Backend and config tests
packages/nemo_evaluator_sdk/tests/execution/backends/local/test_backend.py, packages/nemo_evaluator_sdk/tests/execution/test_config.py
Stop constructing EvaluationRequest in tests; pass explicit dataset/params/hooks and assert params identity and omission of derived fail_fast; add TestResolveParams covering resolve_params rules.
Evaluator and executor tests
packages/nemo_evaluator_sdk/tests/execution/test_evaluator.py, plugins/nemo-evaluator/tests/test_sdk.py
Fake backends record metric(s) plus kwargs dicts; update assertions to inspect forwarded params, aggregate_fields, and absence of fail_fast; executor tests assert run_local receives packaged EvaluateInputSpec and ModelRef resolution occurs before job creation.
Metric execution and API tests
packages/nemo_evaluator_sdk/tests/execution/test_metric_execution.py, packages/nemo_evaluator_sdk/tests/test_api.py
Remove EvaluationRequest usage; adjust tests to use RunConfigOnlineModel/RunConfigOnline where appropriate; replace glob-based API test with direct file path evaluation.
Job and SDK integration tests
plugins/nemo-evaluator/tests/test_evaluate_job.py, plugins/nemo-evaluator/tests/test_sdk.py
Add tests for EvaluateSpec validation, to_spec resolution, FilesetRef fragment preservation, counting-metric job-param application, and ModelRef submit handling; update RunConfig variants in parametrizations.
Standalone backend tests
plugins/nemo-evaluator/tests/test_standalone_sdk_backend.py
Update tests to call NMPBackend/AsyncNMPBackend with explicit dataset/params/target/prompt/aggregate/hooks and adjust hook-rejection parametrization.

Sequence Diagram(s)

No visible sequence diagrams included.

Possibly related PRs

Suggested reviewers

  • ngoncharenko
  • arpitsardhana
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch evaluator-ref-contract-cleanup/SandyChapman

@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

Caution

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

⚠️ Outside diff range comments (1)
packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/metric_execution.py (1)

543-565: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore runtime param validation in ComputeMetricPipeline.__init__.

This now stores raw params instead of resolve_params(params, target). Static overloads do not protect runtime callers, so invalid pairs like target=Agent with offline/model params can slip through and run with wrong defaults instead of failing fast.

Proposed fix
         self.metric = metric
         self.target = target
         self.metric_key = metric_key
         self.prompt_template = prompt_template
-        self.params = params
+        self.params = resolve_params(params, target)
         self.inference_fn = inference_fn
🤖 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
`@packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/metric_execution.py`
around lines 543 - 565, The constructor for ComputeMetricPipeline currently
assigns the raw params directly, skipping runtime validation; restore runtime
validation by calling resolve_params(params, target) inside
ComputeMetricPipeline.__init__ and store the resolved value back to self.params
(and use the resolved params for any downstream logic), so invalid combinations
like target=Agent with offline/model RunConfig are rejected at init time;
reference the resolve_params function and the params and target parameters in
ComputeMetricPipeline.__init__ when making this change.
🧹 Nitpick comments (1)
packages/nemo_evaluator_sdk/tests/test_api.py (1)

97-105: 💤 Low value

Test name no longer reflects behavior.

This test passes a specific file path (tmp_path / "train.jsonl"), not a glob pattern. Consider renaming to test_evaluate_ignores_other_files_in_directory or similar.

🤖 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 `@packages/nemo_evaluator_sdk/tests/test_api.py` around lines 97 - 105, Rename
the test function test_evaluate_with_glob_path to a name that reflects it passes
a specific file path and ignores other files in the same directory (for example
test_evaluate_ignores_other_files_in_directory); update the test function
declaration and any references to it, keeping the body intact (it calls
ExactMatchMetric and uses Evaluator().run_sync with dataset=tmp_path /
"train.jsonl") so the name accurately describes that only the provided file is
evaluated.
🤖 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/evaluator/sdk-resources.md`:
- Line 39: Update the docs tables to match the paragraph: add "local glob paths"
as an accepted form for the dataset argument in both argument tables (the one
for evaluator calls and the one for submit/SDK methods), and update the submit()
target parameter documentation to include ModelRef alongside whatever other
types are listed; ensure the entries referencing dataset, config,
aggregate_fields, target, prompt_template, and submit() are consistent with the
paragraph so the tables document inline rows, local dataset paths, local glob
paths, fileset references (with optional fragment selectors) and that submit()'s
target lists ModelRef.

In `@plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py`:
- Around line 65-73: The ModelRef branch in _submit_params forces callers to
pass RunConfigOnlineModel; instead resolve the submit target first and then call
resolve_params so ModelRef and direct Model behave the same. Replace the
special-case branch in _submit_params (which checks isinstance(target, ModelRef)
and raises TypeError) with logic that first calls _resolve_submit_target(...) on
the provided target, then passes the resolved target to resolve_params(params,
resolved_target) and returns that result; apply the same change to the async
variant so both sync and async submit paths use resolved_target before calling
resolve_params and remove the ModelRef-specific branch.

In `@plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py`:
- Around line 25-31: The function _reject_unsupported_hooks currently treats
empty tuples as supported because it only checks "is not None"; change the
condition to only raise when hooks actually contain items — e.g., replace the
`is not None` checks for preprocess_hooks and postprocess_hooks with a truthy
check or an explicit length check (e.g., "if preprocess_hooks and
len(preprocess_hooks) > 0" / "if postprocess_hooks and len(postprocess_hooks) >
0") so empty tuples are treated as "no hooks" and only non-empty tuples trigger
the NotImplementedError.

---

Outside diff comments:
In
`@packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/metric_execution.py`:
- Around line 543-565: The constructor for ComputeMetricPipeline currently
assigns the raw params directly, skipping runtime validation; restore runtime
validation by calling resolve_params(params, target) inside
ComputeMetricPipeline.__init__ and store the resolved value back to self.params
(and use the resolved params for any downstream logic), so invalid combinations
like target=Agent with offline/model RunConfig are rejected at init time;
reference the resolve_params function and the params and target parameters in
ComputeMetricPipeline.__init__ when making this change.

---

Nitpick comments:
In `@packages/nemo_evaluator_sdk/tests/test_api.py`:
- Around line 97-105: Rename the test function test_evaluate_with_glob_path to a
name that reflects it passes a specific file path and ignores other files in the
same directory (for example test_evaluate_ignores_other_files_in_directory);
update the test function declaration and any references to it, keeping the body
intact (it calls ExactMatchMetric and uses Evaluator().run_sync with
dataset=tmp_path / "train.jsonl") so the name accurately describes that only the
provided file is evaluated.
🪄 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: a76b615c-cafb-4be3-ac46-edd2b01de2b6

📥 Commits

Reviewing files that changed from the base of the PR and between 254747b and 5c90393.

⛔ Files ignored due to path filters (5)
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/backends/base.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/backends/local/backend.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/config.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/evaluator.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/metric_execution.py is excluded by !sdk/**
📒 Files selected for processing (25)
  • docs/evaluator/sdk-resources.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/README.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/backends/base.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/backends/local/backend.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/config.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/evaluator.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/metric_execution.py
  • packages/nemo_evaluator_sdk/tests/execution/backends/local/test_backend.py
  • packages/nemo_evaluator_sdk/tests/execution/test_config.py
  • packages/nemo_evaluator_sdk/tests/execution/test_evaluator.py
  • packages/nemo_evaluator_sdk/tests/execution/test_metric_execution.py
  • packages/nemo_evaluator_sdk/tests/test_api.py
  • plugins/nemo-evaluator/src/nemo_evaluator/filesets.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/__init__.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/http_utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/types.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/values/filesets.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • plugins/nemo-evaluator/tests/test_sdk.py
  • plugins/nemo-evaluator/tests/test_standalone_sdk_backend.py
💤 Files with no reviewable changes (1)
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/README.md

Comment thread docs/evaluator/sdk-resources.md
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py Outdated
@SandyChapman
SandyChapman force-pushed the evaluator-ref-contract-cleanup/SandyChapman branch 2 times, most recently from 3fa0923 to 8fa253b Compare June 2, 2026 13:28

@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 (1)
plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py (1)

99-103: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Require prompt_template (non-optional) for model-target overloads

Evaluator/AsyncEvaluator model-target overloads still allow prompt_template: ... | None = None, but EvaluateJob.compile raises ValueError("prompt_template is required when EvaluateSpec.target is a model") when it’s missing (tests cover both model + agent online targets). Update the model-target overloads to require prompt_template (str | dict[...] with no | None and no default).

Suggested overload fix
     def submit(
         self,
         *,
         metric: Metric,
         dataset: PluginDatasetInput,
         config: RunConfigOnlineModel,
         target: Model | ModelRef,
-        prompt_template: str | dict[str, Any] | None = None,
+        prompt_template: str | dict[str, Any],
         metric_bundle_packager: MetricBundlePackager | None = None,
     ) -> EvaluatorJobResource: ...
@@
     def run(
         self,
         *,
         metric: Metric,
         dataset: PluginDatasetInput,
         config: RunConfigOnlineModel,
         target: Model,
-        prompt_template: str | dict[str, Any] | None = None,
+        prompt_template: str | dict[str, Any],
         aggregate_fields: tuple[AggregateFieldName, ...] | None = None,
     ) -> EvaluationResult: ...
@@
     async def run(
         self,
         *,
         metric: Metric,
         dataset: PluginDatasetInput,
         config: RunConfigOnlineModel,
         target: Model,
-        prompt_template: str | dict[str, Any] | None = None,
+        prompt_template: str | dict[str, Any],
         aggregate_fields: tuple[AggregateFieldName, ...] | None = None,
     ) -> EvaluationResult: ...
@@
     async def submit(
         self,
         *,
         metric: Metric,
         dataset: PluginDatasetInput,
         config: RunConfigOnlineModel,
         target: Model | ModelRef,
-        prompt_template: str | dict[str, Any] | None = None,
+        prompt_template: str | dict[str, Any],
         metric_bundle_packager: MetricBundlePackager | None = None,
     ) -> AsyncEvaluatorJobResource: ...
🤖 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-evaluator/src/nemo_evaluator/sdk/resources.py` around lines 99 -
103, The model-target overloads in Evaluator/AsyncEvaluator should require a
prompt_template instead of allowing None; update the signatures (in
plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py) where target is
typed as Model | ModelRef so that prompt_template is typed as str | dict[str,
Any] with no " | None" and no default value (remove "= None"), matching
EvaluateJob.compile's requirement; ensure you change all corresponding
overloads/method declarations for both Evaluator and AsyncEvaluator so callers
must pass a prompt_template.
🤖 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-evaluator/src/nemo_evaluator/sdk/resources.py`:
- Around line 99-103: The model-target overloads in Evaluator/AsyncEvaluator
should require a prompt_template instead of allowing None; update the signatures
(in plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py) where target is
typed as Model | ModelRef so that prompt_template is typed as str | dict[str,
Any] with no " | None" and no default value (remove "= None"), matching
EvaluateJob.compile's requirement; ensure you change all corresponding
overloads/method declarations for both Evaluator and AsyncEvaluator so callers
must pass a prompt_template.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: ebdd0522-4721-49f3-b644-ee35c956af30

📥 Commits

Reviewing files that changed from the base of the PR and between 5c90393 and 3fa0923.

📒 Files selected for processing (11)
  • plugins/nemo-evaluator/src/nemo_evaluator/filesets.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/__init__.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/http_utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/types.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/values/filesets.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • plugins/nemo-evaluator/tests/test_sdk.py
🚧 Files skipped from review as they are similar to previous changes (7)
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/types.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/init.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/values/filesets.py
  • plugins/nemo-evaluator/src/nemo_evaluator/filesets.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
  • plugins/nemo-evaluator/tests/test_sdk.py

Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py

@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: 2

🤖 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 `@packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/config.py`:
- Around line 29-32: resolve_params() currently allows RunConfigOnlineModel for
Agent targets because RunConfigOnlineModel subclasses RunConfigOnline; update
the Agent branch to reject model-only configs by tightening the type check (for
example require exact type RunConfigOnline or explicitly disallow
isinstance(params, RunConfigOnlineModel)). Specifically, change the check inside
the "if isinstance(target, Agent):" block (the code that now raises
TypeError("agent target requires RunConfigOnline")) so it does not accept
RunConfigOnlineModel—this prevents model-only params from flowing into
_merge_online_hooks(), inference.new_hooks(), generate_online_sample(), and
ultimately make_agent_inference_request().

In `@plugins/nemo-evaluator/src/nemo_evaluator/filesets.py`:
- Around line 138-157: The code joins untrusted values (base_path, pattern,
relative_path, ref) into local Paths before fetching, allowing directory
traversal or absolute writes; fix by resolving and validating each candidate
destination path after constructing file_dest/full path: use
Path(destination)/base_path then for every file_dest compute resolved =
file_dest.resolve() and ensure
resolved.is_relative_to(Path(destination).resolve()) (or compare commonpath) and
reject or raise if not; apply the same validation before calling fs._get_file or
fs._get (including the single-file branch that builds full_remote_path and
file_dest) and also normalize/sanitize inputs (strip leading slashes, collapse
..) before joins.
🪄 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: d1843172-3273-4b6f-ae02-0a3c57fc0c2d

📥 Commits

Reviewing files that changed from the base of the PR and between 8fa253b and c154160.

⛔ Files ignored due to path filters (5)
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/backends/base.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/backends/local/backend.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/config.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/evaluator.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/metric_execution.py is excluded by !sdk/**
📒 Files selected for processing (25)
  • docs/evaluator/sdk-resources.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/README.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/backends/base.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/backends/local/backend.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/config.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/evaluator.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/metric_execution.py
  • packages/nemo_evaluator_sdk/tests/execution/backends/local/test_backend.py
  • packages/nemo_evaluator_sdk/tests/execution/test_config.py
  • packages/nemo_evaluator_sdk/tests/execution/test_evaluator.py
  • packages/nemo_evaluator_sdk/tests/execution/test_metric_execution.py
  • packages/nemo_evaluator_sdk/tests/test_api.py
  • plugins/nemo-evaluator/src/nemo_evaluator/filesets.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/__init__.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/http_utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/types.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/values/filesets.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • plugins/nemo-evaluator/tests/test_sdk.py
  • plugins/nemo-evaluator/tests/test_standalone_sdk_backend.py
💤 Files with no reviewable changes (1)
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/README.md
✅ Files skipped from review due to trivial changes (1)
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/init.py
🚧 Files skipped from review as they are similar to previous changes (21)
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/types.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/http_utils.py
  • docs/evaluator/sdk-resources.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/backends/base.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/utils.py
  • packages/nemo_evaluator_sdk/tests/execution/test_config.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/backends/local/backend.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/evaluator.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/values/filesets.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/metric_execution.py
  • packages/nemo_evaluator_sdk/tests/execution/test_metric_execution.py
  • plugins/nemo-evaluator/tests/test_standalone_sdk_backend.py
  • packages/nemo_evaluator_sdk/tests/test_api.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py
  • plugins/nemo-evaluator/tests/test_sdk.py
  • packages/nemo_evaluator_sdk/tests/execution/backends/local/test_backend.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • packages/nemo_evaluator_sdk/tests/execution/test_evaluator.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py

Comment thread plugins/nemo-evaluator/src/nemo_evaluator/filesets.py Outdated
@SandyChapman
SandyChapman force-pushed the evaluator-ref-contract-cleanup/SandyChapman branch from c154160 to 4491ecc Compare June 2, 2026 14:18
Comment thread plugins/nemo-evaluator/tests/test_filesets.py Fixed

@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.

🧹 Nitpick comments (1)
services/evaluator/src/nmp/evaluator/api/v2/metrics/manager.py (1)

444-450: ⚡ Quick win

Source parallelism and params from one RunConfig.

This passes two independent defaults into ComputeMetricPipeline. If DEFAULT_PARALLELISM and RunConfig().parallelism ever diverge, offline evaluation runs with inconsistent config.

Suggested change
-        pipeline = ComputeMetricPipeline(
+        run_config = RunConfig(parallelism=DEFAULT_PARALLELISM)
+        pipeline = ComputeMetricPipeline(
             rows=rows,
-            parallelism=DEFAULT_PARALLELISM,
+            parallelism=run_config.parallelism,
             metric=metric_impl,
             target=None,
             metric_key=metric_type_name(metric_impl),
-            params=RunConfig(),
+            params=run_config,
         )
🤖 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 `@services/evaluator/src/nmp/evaluator/api/v2/metrics/manager.py` around lines
444 - 450, Currently DEFAULT_PARALLELISM and a freshly constructed RunConfig()
are passed separately into ComputeMetricPipeline causing possible divergence;
instead instantiate a single RunConfig (e.g., run_cfg = RunConfig()), use
run_cfg.parallelism for the pipeline's parallelism argument and pass run_cfg as
the params argument so ComputeMetricPipeline(...) uses one consistent RunConfig
for parallelism and other settings (apply this change where
ComputeMetricPipeline is constructed with rows, parallelism, metric=metric_impl,
metric_key=metric_type_name(metric_impl), params=...).
🤖 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.

Nitpick comments:
In `@services/evaluator/src/nmp/evaluator/api/v2/metrics/manager.py`:
- Around line 444-450: Currently DEFAULT_PARALLELISM and a freshly constructed
RunConfig() are passed separately into ComputeMetricPipeline causing possible
divergence; instead instantiate a single RunConfig (e.g., run_cfg =
RunConfig()), use run_cfg.parallelism for the pipeline's parallelism argument
and pass run_cfg as the params argument so ComputeMetricPipeline(...) uses one
consistent RunConfig for parallelism and other settings (apply this change where
ComputeMetricPipeline is constructed with rows, parallelism, metric=metric_impl,
metric_key=metric_type_name(metric_impl), params=...).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6742c317-5a2c-486f-b622-a3655dd0f208

📥 Commits

Reviewing files that changed from the base of the PR and between c154160 and 4491ecc.

⛔ Files ignored due to path filters (58)
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/__init__.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/agent_inference.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/dataset_schemas/compatibility.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/dataset_schemas/templates.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/datasets/__init__.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/datasets/loader.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/_protocols.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/backends/base.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/backends/local/backend.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/benchmark_execution.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/config.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/evaluator.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/job_poll.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/metric_execution.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/pipeline.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/runs.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/samples.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/scoring.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/execution/utils.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/inference.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/aggregation.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/bleu.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/exact_match.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/f1.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/hooks.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/llm_judge.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/llm_judge_defaults.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/number_check.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/protocol.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/ragas/__init__.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/ragas/base.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/ragas/imports.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/ragas/metrics.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/remote.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/resolution.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/rouge.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/string_check.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/template_rendering.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/tool_calling.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/metrics/types.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/resilience/api.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/resilience/classifier.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/resilience/errors.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/resilience/policy.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/resilience/scheduler.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/resilience/types.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/structured_output.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/__init__.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/agents.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/dataset_schemas.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/datasets.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/metrics.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/models.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/multi_metric_results.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/params.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/protocol.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/results.py is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/beta/evaluator/values/scores.py is excluded by !sdk/**
📒 Files selected for processing (18)
  • Makefile
  • docs/evaluator/sdk-resources.md
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/config.py
  • packages/nemo_evaluator_sdk/tests/execution/test_config.py
  • plugins/nemo-evaluator/src/nemo_evaluator/filesets.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/__init__.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/http_utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/types.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/values/filesets.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • plugins/nemo-evaluator/tests/test_filesets.py
  • plugins/nemo-evaluator/tests/test_sdk.py
  • plugins/nemo-evaluator/tests/test_standalone_sdk_backend.py
  • services/evaluator/src/nmp/evaluator/api/v2/metrics/manager.py
✅ Files skipped from review due to trivial changes (2)
  • plugins/nemo-evaluator/tests/test_filesets.py
  • docs/evaluator/sdk-resources.md
🚧 Files skipped from review as they are similar to previous changes (13)
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/types.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/values/filesets.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/http_utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/utils.py
  • plugins/nemo-evaluator/src/nemo_evaluator/filesets.py
  • packages/nemo_evaluator_sdk/tests/execution/test_config.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
  • plugins/nemo-evaluator/tests/test_standalone_sdk_backend.py
  • packages/nemo_evaluator_sdk/src/nemo_evaluator_sdk/execution/config.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py
  • plugins/nemo-evaluator/tests/test_sdk.py

@SandyChapman
SandyChapman force-pushed the evaluator-ref-contract-cleanup/SandyChapman branch from 4491ecc to fbd5cda Compare June 2, 2026 15:00
@SandyChapman
SandyChapman force-pushed the evaluator-ref-contract-cleanup/SandyChapman branch 2 times, most recently from 05f2624 to 59c8666 Compare June 2, 2026 15:34
@SandyChapman SandyChapman changed the title chore(evaluator): Clarify evaluator SDK ref handling contracts refactor(evaluator): clarify SDK ref handling contracts Jun 2, 2026
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py Outdated
Comment thread docs/evaluator/sdk-resources.md
Signed-off-by: Sandy Chapman <schapman@nvidia.com>
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.

3 participants