Skip to content

feat(evaluator): add metric-types CLI support - #105

Merged
ngoncharenko merged 4 commits into
mainfrom
ngoncharenko/metric-types
Jun 3, 2026
Merged

feat(evaluator): add metric-types CLI support#105
ngoncharenko merged 4 commits into
mainfrom
ngoncharenko/metric-types

Conversation

@ngoncharenko

@ngoncharenko ngoncharenko commented May 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add the evaluator plugin metric-types CLI subcommand to list registered metric schemas and inspect individual metric schema contracts. Current explain command returns the entire schema which fills the agent's context with unrelated to the task data and contradicts the progressive disclosure principle
  • Update evaluator skill guidance and root skill assets so examples point at the plugin-backed nemo evaluator workflow.
  • Make plugin-owned evaluator and data-designer skill directories symlink reflections of the root skills/ source-of-truth directories.
  • Add focused exact-match and LLM-judge spec assets plus a compact local SDK smoke example with helper tests.
  • Update evaluator plugin SDK examples to use example-facing execution modes run and submit instead of local and remote.

Details

  • nemo evaluator metric-types lists available metric types with names and descriptions.
  • nemo evaluator metric-types <name> returns the selected metric schema and reports a clear error for unknown names.
  • plugins/nemo-evaluator/src/nemo_evaluator/skills/evaluator-plugin now symlinks to skills/nemo-evaluator-plugin so plugin packaging reflects the entire root skill directory, including assets.
  • plugins/nemo-data-designer/src/nemo_data_designer_plugin/skills/data-designer now symlinks to skills/nemo-data-designer-plugin for the same source-of-truth behavior.
  • Skill docs keep nemo evaluator evaluate explain as the schema source of truth and clarify local environment secrets vs submit-time platform secrets.
  • SDK examples default to safe run-mode examples; submit/model-calling flows require explicit flags.

Related

https://github.com/NVIDIA-NeMo/nemo-platform/pull/104/changes

Summary by CodeRabbit

  • New Features

    • CLI: added metric listing/inspection with optional schema output and standardized JSON output for info.
  • Documentation

    • Rewrote evaluator plugin docs to center on the CLI, added metric-types usage, spec-file examples, and clarified remote auth mapping for submissions and LLM-judge.
  • Examples

    • Added SDK example script and new exact-match and LLM-judge spec files; updated example runner to use "run"/"submit" modes.
  • Tests

    • Added CLI and spec parsing tests validating metric-type catalog ordering, schema output, and error handling.

@ngoncharenko
ngoncharenko requested review from a team as code owners May 29, 2026 06:54
@ngoncharenko ngoncharenko self-assigned this May 29, 2026
@ngoncharenko
ngoncharenko requested a review from SandyChapman May 29, 2026 06:54
@ngoncharenko
ngoncharenko force-pushed the ngoncharenko/metric-types branch from 5517ab5 to fb86a80 Compare May 29, 2026 07:37
@ngoncharenko

Copy link
Copy Markdown
Contributor Author

/nvskills-ci

@ngoncharenko
ngoncharenko changed the base branch from ngoncharenko/add-root-skills to main May 29, 2026 18:34
@ngoncharenko

Copy link
Copy Markdown
Contributor Author

/nvskills-ci

@coderabbitai

coderabbitai Bot commented May 29, 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

CLI metric type introspection helpers added to derive available metric names and schemas. Plugin examples refactored to use run/submit execution modes with updated secret resolution. New SDK example script, evaluation spec templates, and documentation covering metric listing, spec structure, and remote job submission with platform secrets.

Changes

CLI Metric Type Introspection

Layer / File(s) Summary
Metric type introspection and JSON helpers
plugins/nemo-evaluator/src/nemo_evaluator/cli.py
Helpers inspect Metric annotations for nested Annotated/Union types, extract metric type names with docstring descriptions, detect RAGAS metrics, convert Enum values for JSON, and provide _echo_json wrapper for consistent output.
CLI command handler updates
plugins/nemo-evaluator/src/nemo_evaluator/cli.py
info command uses _echo_json; metric-types conditionally prints full metric catalog or selected metric's Pydantic JSON schema, with "Unknown metric name" error and exit code 1 for invalid names.

SDK Example Execution Model Refactoring

Layer / File(s) Summary
Execution mode type and imports
plugins/nemo-evaluator/examples/plugin_examples.py
Introduces ExampleExecutionMode = Literal["run", "submit"] type; updates typing imports to include Literal.
Connection error message tweaks
plugins/nemo-evaluator/examples/plugin_examples.py
Minor formatting adjustments to plugin connectivity failure messages in async and sync client setup; exception type and condition unchanged.
Submit mode secret resolution
plugins/nemo-evaluator/examples/plugin_examples.py
New ensure_submit_evaluator_api_key_secret normalizes secret names (env-var to hyphenated form), attempts platform secret lookup, falls back to environment variables, and creates the secret on demand while tolerating conflicts.
Model selection and metric execution branching
plugins/nemo-evaluator/examples/plugin_examples.py
model_with_valid_secret and _evaluate_metric updated to accept ExampleExecutionMode; secret resolution occurs only for submit mode; run-vs-submit dispatch uses execution_mode == "run". All example function signatures updated to the new mode type with "run" default.
Flag-driven example runners and CLI entrypoint
plugins/nemo-evaluator/examples/plugin_examples.py
Replaces hardcoded runner with parameterized run_examples and run_sync_examples accepting flags; adds parse_args and main entrypoint; updates __main__ to use SystemExit(main()).

SDK Example, Specs, and Documentation

Layer / File(s) Summary
SDK smoke example script and utilities
skills/nemo-evaluator-plugin/assets/examples/plugin_sdk_examples.py
Adds standalone example with DEFAULT_BASE_URL/DEFAULT_ROWS constants, JSONL write/load helpers (gzip-aware), build_exact_match_spec builder, run_local_exact_match using NeMoPlatform client with controlled lifecycle, CLI main with --run flag, and module entrypoint.
Example evaluation specifications
skills/nemo-evaluator-plugin/assets/specs/exact_match_metric.json, skills/nemo-evaluator-plugin/assets/specs/llm_as_judge.json, skills/nemo-evaluator-plugin/assets/specs/exact_match_benchmark.json
Three evaluation spec templates: exact-match with templated reference/candidate and sample dataset; LLM-judge with structured scoring, model config, and inline dataset; exact-match benchmark combining metrics, passing/failing test cases, and target config.
Documentation updates for evaluator plugin usage
skills/nemo-evaluator-plugin/SKILL.md, skills/nemo-evaluator-plugin/references/api-auth.md, skills/nemo-evaluator-plugin/references/llm-judge.md, plugins/nemo-evaluator/src/nemo_evaluator/docs/index.md
SKILL.md rewritten for nemo evaluator CLI workflows: added prerequisites, metric-types guidance, evaluation spec shape, run/submit examples, SDK snippet; api-auth.md and llm-judge.md clarify platform secret requirements and mapping from local env vars; docs updated to show spec-file usage.

Possibly related PRs

Suggested reviewers

  • arpitsardhana
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 67.27% 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
Title check ✅ Passed The title accurately describes the main change: adding metric-types CLI support. It's concise, specific, and directly reflects the primary functionality addition.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ngoncharenko/metric-types

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

@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 `@plugins/nemo-evaluator/src/nemo_evaluator/cli.py`:
- Around line 50-55: The _metric_type_models function currently overwrites
entries when multiple model classes returned by
_unwrap_metric_model_classes(Metric) expose the same metric type from
_metric_type_values, so add duplicate detection: while building metric_types in
_metric_type_models, check if metric_type already exists and if so raise a clear
ValueError (or RuntimeError) that includes the conflicting metric_type and both
model class names (the existing model_cls and the one being added) to fail fast
and surface collisions; keep returning the sorted dict only if no duplicates are
found.

In `@skills/nemo-evaluator-plugin/SKILL.md`:
- Line 15: The MD022/MD031 lint errors come from headings and fenced code blocks
lacking surrounding blank lines in SKILL.md; edit the file to ensure a blank
line both before and after each heading and each fenced code block (e.g., the
"### Prerequisites:" heading and all other headings/code fences referenced at
lines 25-26, 28, 33, 44, 55-56, 71, 77, 88, 106) so every heading and ``` fenced
block is separated by an empty line above and below, then re-run markdownlint to
confirm the violations are resolved.
- Around line 32-35: Replace the ambiguous field-path style placeholder in the
CLI example so users understand it's a single metric name: change the command
example `nemo evaluator metric-types <metric_types.name>` to use a concrete CLI
arg placeholder like `nemo evaluator metric-types <metric-name>` (update the
README/ SKILL.md text that displays the command and any related explanation
mentioning `metric_types.name` to use `<metric-name>` instead).
🪄 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: 2c05a00a-7349-4727-809d-746a88ffceab

📥 Commits

Reviewing files that changed from the base of the PR and between 0d06ad4 and a79bef2.

📒 Files selected for processing (11)
  • packages/nemo_evaluator_sdk/examples/plugin_examples.py
  • plugins/nemo-evaluator/src/nemo_evaluator/cli.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • skills/nemo-evaluator-plugin/SKILL.md
  • skills/nemo-evaluator-plugin/assets/examples/plugin_sdk_examples.py
  • skills/nemo-evaluator-plugin/assets/examples/test_plugin_sdk_examples.py
  • skills/nemo-evaluator-plugin/assets/specs/exact_match_benchmark.json
  • skills/nemo-evaluator-plugin/assets/specs/exact_match_metric.json
  • skills/nemo-evaluator-plugin/assets/specs/llm_as_judge.json
  • skills/nemo-evaluator-plugin/resources/api-auth.md
  • skills/nemo-evaluator-plugin/resources/llm-judge.md

Comment thread plugins/nemo-evaluator/src/nemo_evaluator/cli.py
Comment thread skills/nemo-evaluator-plugin/SKILL.md Outdated
Comment thread skills/nemo-evaluator-plugin/SKILL.md Outdated
@github-actions

github-actions Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 18649/24682 75.6% 62.1%
Integration Tests 11967/23459 51.0% 26.2%

Comment thread plugins/nemo-evaluator/src/nemo_evaluator/cli.py Outdated
Comment thread skills/nemo-evaluator-plugin/assets/specs/llm_as_judge.json

@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/examples/plugin_examples.py (1)

535-539: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Sync client doesn't resolve secrets for submit mode.

When is_online=True and execution_mode="submit", this uses the global model with env-var-style secret reference (NVIDIA_API_KEY). The async version at lines 462-466 properly calls model_with_valid_secret() to get the hyphenated platform secret name.

Current run_sync_examples only calls with is_online=False, so this path isn't exercised. However, the function is public and will fail if invoked with is_online=True, execution_mode="submit".

Proposed fix

Add synchronous secret resolution (requires a sync helper):

         if is_online:
             metric = _online_exact_match_metric()
             config = RunConfigOnlineModel(parallelism=4, limit_samples=limit_samples)
-            run_kwargs["target"] = model
+            if execution_mode == "submit":
+                secret_name = ensure_submit_evaluator_api_key_secret_sync(DEFAULT_WORKSPACE, client)
+                run_kwargs["target"] = model.model_copy(update={"api_key_secret": SecretRef(root=secret_name)})
+            else:
+                run_kwargs["target"] = model
             run_kwargs["prompt_template"] = ONLINE_CHAT_PROMPT_TEMPLATE

This requires adding a sync version of ensure_submit_evaluator_api_key_secret. Alternatively, document that is_online=True + execution_mode="submit" is unsupported for the sync client.

🤖 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/examples/plugin_examples.py` around lines 535 - 539,
The sync path in run_sync_examples uses the raw global model (env-var style
secret) when is_online=True and execution_mode=="submit", so add a synchronous
secret-resolution step: create a sync helper (e.g.,
ensure_submit_evaluator_api_key_secret_sync or model_with_valid_secret_sync)
that mirrors ensure_submit_evaluator_api_key_secret() behavior and call it
before setting run_kwargs["target"] in run_sync_examples; replace the direct use
of the global model with the resolved model (same hyphenated secret name used by
the async model_with_valid_secret()) so submit-mode online runs get a valid
secret.
🤖 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/examples/plugin_examples.py`:
- Around line 535-539: The sync path in run_sync_examples uses the raw global
model (env-var style secret) when is_online=True and execution_mode=="submit",
so add a synchronous secret-resolution step: create a sync helper (e.g.,
ensure_submit_evaluator_api_key_secret_sync or model_with_valid_secret_sync)
that mirrors ensure_submit_evaluator_api_key_secret() behavior and call it
before setting run_kwargs["target"] in run_sync_examples; replace the direct use
of the global model with the resolved model (same hyphenated secret name used by
the async model_with_valid_secret()) so submit-mode online runs get a valid
secret.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0c0e4ebe-706d-4d3f-afdd-aba94063da1e

📥 Commits

Reviewing files that changed from the base of the PR and between 3e0c341 and bf07bc8.

📒 Files selected for processing (2)
  • plugins/nemo-evaluator/examples/plugin_examples.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/nemo-evaluator/tests/test_evaluate_job.py

@ngoncharenko
ngoncharenko force-pushed the ngoncharenko/metric-types branch from bf07bc8 to 610317d Compare June 2, 2026 03:39
Comment thread plugins/nemo-evaluator/tests/test_evaluate_job.py Dismissed
@ngoncharenko
ngoncharenko force-pushed the ngoncharenko/metric-types branch 3 times, most recently from 0dd34e1 to b7f7043 Compare June 2, 2026 21:58
@ngoncharenko
ngoncharenko force-pushed the ngoncharenko/metric-types branch from e339738 to dc85a0c Compare June 3, 2026 16:59
Signed-off-by: Nick Goncharenko <ngoncharenko@nvidia.com>
@ngoncharenko
ngoncharenko force-pushed the ngoncharenko/metric-types branch from f3ca3f1 to c288524 Compare June 3, 2026 17:30
Signed-off-by: Nick Goncharenko <ngoncharenko@nvidia.com>
@ngoncharenko
ngoncharenko force-pushed the ngoncharenko/metric-types branch from c288524 to de6f523 Compare June 3, 2026 17:41
@svvarom

svvarom commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

/nvskills-ci

Signed-off-by: nvskills-svc-account <svc-nvskills-signing@nvidia.com>
@ngoncharenko
ngoncharenko enabled auto-merge June 3, 2026 22:30
@ngoncharenko
ngoncharenko added this pull request to the merge queue Jun 3, 2026
Merged via the queue into main with commit 8fbe4a2 Jun 3, 2026
32 of 33 checks passed
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.

5 participants