Skip to content

feat(evaluator): bundle metrics for plugin execution - #46

Merged
SandyChapman merged 2 commits into
mainfrom
metric-bundling-cloudpickle-on-resolvers/schapman
Jun 1, 2026
Merged

feat(evaluator): bundle metrics for plugin execution#46
SandyChapman merged 2 commits into
mainfrom
metric-bundling-cloudpickle-on-resolvers/schapman

Conversation

@SandyChapman

@SandyChapman SandyChapman commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add bundle-native metric wire models and cloudpickle bundling primitives
  • make evaluator plugin backend submit bundled metrics and hydrate by payload kind at execution time
  • add plugin-native job compilation, task entrypoint, and smoke coverage

Note: rebased onto main after the resolver branch landed in #38. Remote result-registration fix will be split into a separate main-based PR.

Summary by CodeRabbit

  • New Features

    • Users can bundle and submit custom Python metrics for remote evaluation; example updated to demonstrate packaging and submission.
    • Evaluation API now accepts bundled metrics so multiple metrics can be submitted and hydrated at runtime.
    • Packaged metrics include validation (output contract checks) and runtime compatibility checks to prevent invalid or incompatible bundles.
  • Chores

    • Added cloudpickle dependency to support metric serialization.

@SandyChapman
SandyChapman force-pushed the metric-bundling-cloudpickle-on-resolvers/schapman branch 4 times, most recently from 420568a to 78018ea Compare May 27, 2026 13:56
@SandyChapman
SandyChapman force-pushed the 4050-evaluator-metric-resolvers/schapman branch 3 times, most recently from ea313db to 210323a Compare May 28, 2026 15:09
@SandyChapman
SandyChapman force-pushed the metric-bundling-cloudpickle-on-resolvers/schapman branch from 78018ea to 859c50a Compare May 28, 2026 15:15
@SandyChapman
SandyChapman force-pushed the 4050-evaluator-metric-resolvers/schapman branch from 210323a to 2315857 Compare May 28, 2026 15:22
@SandyChapman
SandyChapman force-pushed the metric-bundling-cloudpickle-on-resolvers/schapman branch from 859c50a to 9c070c9 Compare May 28, 2026 15:28
@SandyChapman
SandyChapman marked this pull request as ready for review May 28, 2026 15:33
@SandyChapman
SandyChapman requested review from a team as code owners May 28, 2026 15:33
@SandyChapman
SandyChapman force-pushed the 4050-evaluator-metric-resolvers/schapman branch 5 times, most recently from 5145619 to 9dcbc66 Compare May 29, 2026 12:22
Make evaluator plugin job specs bundle-native so backend execution receives MetricBundle payloads, hydrates runtime metrics dynamically, and resolves platform model refs at execution time.

Add cloudpickle bundle primitives, plugin compiler/runtime wiring, and local/remote smoke coverage.

Signed-off-by: Sandy Chapman <schapman@nvidia.com>
@SandyChapman
SandyChapman force-pushed the metric-bundling-cloudpickle-on-resolvers/schapman branch from 9c070c9 to 50cfeba Compare May 29, 2026 13:38
@SandyChapman
SandyChapman changed the base branch from 4050-evaluator-metric-resolvers/schapman to main May 29, 2026 13:38
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/bundles.py Outdated

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

Can you add how input spec will look like from user when submitting a custom metric

Comment thread plugins/nemo-evaluator/src/nemo_evaluator/jobs/compiler.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/cloudpickle.py Outdated
@SandyChapman

Copy link
Copy Markdown
Contributor Author

Replying to the review note: "Can you add how input spec will look like from user when submitting a custom metric"

Added a small custom metric example that shows the user-facing flow: define a metric object, generate the cloudpickle bundle from code with CloudpickleMetricBundlePackager, and build the EvaluateSpec from that generated payload. The example calls out that the base64 payload is not intended to be hand-authored.

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 19143279-44ae-43c2-a47e-76c408d44e03

📥 Commits

Reviewing files that changed from the base of the PR and between 8e76a89 and 4e5b80f.

📒 Files selected for processing (12)
  • packages/nemo_evaluator_sdk/examples/plugin_examples.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/compiler.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.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/shared/metric_bundles/bundles.py
  • plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/cloudpickle.py
  • plugins/nemo-evaluator/tests/shared/metric_bundles/test_cloudpickle.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • plugins/nemo-evaluator/tests/test_sdk.py
  • plugins/nemo-evaluator/tests/test_sdk_job_resources.py
  • plugins/nemo-evaluator/tests/test_standalone_sdk_backend.py
🚧 Files skipped from review as they are similar to previous changes (9)
  • plugins/nemo-evaluator/tests/test_sdk_job_resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/compiler.py
  • packages/nemo_evaluator_sdk/examples/plugin_examples.py
  • plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/bundles.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py
  • plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/cloudpickle.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • plugins/nemo-evaluator/tests/shared/metric_bundles/test_cloudpickle.py

📝 Walkthrough

Walkthrough

This PR adds a backend-neutral metric bundling system (registry, envelope, helpers), a Cloudpickle packager, changes EvaluateSpec to accept bundled metrics, adds compile_evaluate_job, updates executors to require/forward packagers and resolve FilesetRef datasets, adds a task entrypoint, updates examples, pyproject deps, license, and extensive tests to the bundled-metric flow.

Changes

Metric Bundle Infrastructure and Packaging

Layer / File(s) Summary
Bundle domain model and registry
plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/bundles.py
Defines MetricBundle envelope, payload base, packager protocol, in-process registry, bundle_metric/unbundle_metric, and helpers for metadata/secret extraction and validation.
Cloudpickle metric bundle packager
plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/cloudpickle.py
Implements CloudpickleMetricPayload with size and Python-version checks, CloudpickleMetricBundlePackager that serializes/deserializes metrics with cloudpickle, and registers "cloudpickle" kind.
Cloudpickle bundle roundtrip tests
plugins/nemo-evaluator/tests/shared/metric_bundles/test_cloudpickle.py
Parametrized tests for built-in and custom metrics, secret capture, digest/metadata assertions, oversize and Python-version rejection, and registry conflict behavior.

Job Schema and Compilation Refactoring

Layer / File(s) Summary
EvaluateSpec bundled metric schema
plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py
MetricSpec now a non-empty list[MetricBundle]; EvaluateSpec.metric renamed to metrics; metric-resolution helpers operate on hydrated list[Metric].
Bundle-aware job compilation
plugins/nemo-evaluator/src/nemo_evaluator/jobs/compiler.py
Adds compile_evaluate_job(spec, profile=...) validating target/prompt/runconfig compatibility, building a single evaluate PlatformJobStep, and assembling secret-backed environment variables from bundles and target API keys.
Job compile and run with bundle hydration
plugins/nemo-evaluator/src/nemo_evaluator/jobs/evaluate.py, plugins/nemo-evaluator/src/nemo_evaluator/tasks/evaluate.py
EvaluateJob.compile delegates to compile_evaluate_job; run hydrates MetricBundles, resolves ModelRefs via SDKs, and invokes SDKEvaluator run APIs; adds task entrypoint module wiring EvaluateJob for platform tasks.
Job utils reduction
plugins/nemo-evaluator/src/nemo_evaluator/jobs/utils.py
Removes remote-metric compilation and submit-dataset helpers; retains resolve_run_dataset for local dataset download.

Executor Integration and Dataset Resolution

Layer / File(s) Summary
Executor policy and imports
plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
Adds MetricBundlePackagerPolicyError, _require_metric_bundle_packager, and supporting imports/types for packaging and FilesetRef resolution.
FilesetRef resolution & spec building
plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
Implements sync/async FilesetRef resolution context managers and updates _build_evaluate_spec to require a metric_bundle_packager and build EvaluateSpec.metrics from bundled metrics.
Sync/Async evaluation paths
plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
Sync/async submit/evaluate_remote accept metric_bundle_packager and forward it; local evaluate paths resolve FilesetRef datasets and call SDKEvaluator.run_sync/run.
Bundle helpers replacement
plugins/nemo-evaluator/src/nemo_evaluator/sdk/_executor.py
Removes old metric_config helpers and adds bundle_metrics_for_spec to package runtime Metric objects into MetricBundle list.

Public API and Adapter Integration

Layer / File(s) Summary
Evaluator.submit APIs
plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
Adds metric_bundle_packager keyword-only param to Evaluator.submit and AsyncEvaluator.submit, validates non-None and forwards to executor.
Standalone backend packager support
plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py
NMPBackend and AsyncNMPBackend gain optional metric_bundle_packager field; remote evaluate enforces presence and forwards packager to executor.

Example Usage and Dependency Updates

Layer / File(s) Summary
Custom metric example
packages/nemo_evaluator_sdk/examples/plugin_examples.py
Adds CustomResponseLengthMetric, build_custom_metric_submit_spec_example() to bundle and serialize a custom metric with CloudpickleMetricBundlePackager, and updates example submit calls to pass the packager.
Cloudpickle dependency and license
packages/nemo_platform/pyproject.toml, plugins/nemo-evaluator/pyproject.toml, third_party/licenses.jsonl
Adds cloudpickle>=3.1.1 to package dependencies and adds cloudpickle BSD-3-CLAUSE license entry.
Tests: SDK, job, resources updates
plugins/nemo-evaluator/tests/*
Multiple tests updated/added to construct bundled metrics, assert new EvaluateSpec.metrics shapes, forward packager through submit/evaluate_remote, validate FilesetRef download flows, and test task entrypoint dispatch.

Suggested reviewers

  • ngoncharenko
  • mckornfield
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.61% 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 accurately reflects the main change: introducing metric bundling infrastructure for plugin execution.
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.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch metric-bundling-cloudpickle-on-resolvers/schapman

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: 4

Caution

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

⚠️ Outside diff range comments (2)
plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py (1)

33-49: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remote backend mode should reject missing metric_bundle_packager before delegating.

With execution_mode="remote" and default metric_bundle_packager=None, calls fail later in executor policy checks. Validate this in backend adapter methods and raise a direct configuration error.

Proposed fix
     def evaluate(
@@
         _reject_unsupported_hooks(request)
         if self.execution_mode == "remote":
+            if self.metric_bundle_packager is None:
+                raise ValueError(
+                    "metric_bundle_packager is required when execution_mode='remote'."
+                )
             return self.resource._executor.evaluate_remote(
@@
     async def evaluate(
@@
         _reject_unsupported_hooks(request)
         if self.execution_mode == "remote":
+            if self.metric_bundle_packager is None:
+                raise ValueError(
+                    "metric_bundle_packager is required when execution_mode='remote'."
+                )
             return await self.resource._executor.evaluate_remote(

Also applies to: 83-99

🤖 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/standalone_sdk/backend.py`
around lines 33 - 49, The backend must validate that metric_bundle_packager is
provided when execution_mode == "remote"; in the evaluate method (and the other
backend adapter methods such as the batch evaluation variant around the same
area) check self.execution_mode == "remote" and if so raise a clear
configuration error if self.metric_bundle_packager is None instead of delegating
to self.resource._executor.evaluate_remote (and the corresponding remote call in
the other adapter), so callers get an immediate, descriptive exception about the
missing metric_bundle_packager.
plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py (1)

79-99: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

submit() advertises an optional packager, but remote submit requires it.

Both sync and async submit default metric_bundle_packager=None, yet the downstream remote-spec path requires a concrete packager and throws at runtime. Make this fail fast at this API boundary (or make the parameter required in the signature) to avoid misleading callers.

Proposed fix (fail fast at public API boundary)
 def submit(
@@
-    metric_bundle_packager: MetricBundlePackager | None = None,
+    metric_bundle_packager: MetricBundlePackager | None = None,
 ) -> EvaluatorJobResource:
@@
+    if metric_bundle_packager is None:
+        raise ValueError(
+            "metric_bundle_packager is required for submit(); "
+            "pass CloudpickleMetricBundlePackager() to enable metric bundling."
+        )
     return self._executor.submit(
@@
 async def submit(
@@
-    metric_bundle_packager: MetricBundlePackager | None = None,
+    metric_bundle_packager: MetricBundlePackager | None = None,
 ) -> AsyncEvaluatorJobResource:
@@
+    if metric_bundle_packager is None:
+        raise ValueError(
+            "metric_bundle_packager is required for submit(); "
+            "pass CloudpickleMetricBundlePackager() to enable metric bundling."
+        )
     return await self._executor.submit(

Also applies to: 186-206

🤖 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 79 -
99, The submit() API in nemo_evaluator.sdk.resources currently allows
metric_bundle_packager=None but downstream _executor.submit requires a concrete
MetricBundlePackager and fails at runtime; update the public API to fail fast by
validating metric_bundle_packager at the start of submit (and the async
counterpart, same-named method around the 186-206 region) and raise a clear
ValueError if it's None, or alternatively make metric_bundle_packager a required
non-optional parameter in the method signature; ensure the check references the
submit method and _executor.submit call so callers get an immediate, descriptive
error instead of a downstream exception.
🤖 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/jobs/compiler.py`:
- Around line 48-52: The helper _add_secret_ref currently allows bundle secret
env names to collide with reserved job env vars (e.g.
PERSISTENT_JOB_STORAGE_PATH_ENVVAR); update _add_secret_ref to explicitly check
if env_name equals any reserved env var constants and raise a ValueError with a
clear message if so, then proceed with the existing conflict check and
assignment; apply the same reserved-name check to the analogous helper handling
bundle secret refs in the 63-73 region to prevent duplicate/reserved env var
collisions.
- Around line 85-86: The container task currently invokes Python directly via
entrypoint=["python","-m"] and command=["nemo_evaluator.tasks.evaluate"]; update
the entrypoint to use uv run so it becomes entrypoint=["uv","run","python","-m"]
(leave command as ["nemo_evaluator.tasks.evaluate"]) so the module is executed
through uv run; modify the entrypoint value wherever it is defined in the
compiler job (look for entrypoint and command in the code around the
container/task spec).

In `@plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/bundles.py`:
- Around line 109-121: register_metric_bundle_kind currently overwrites any
existing entry in _BUNDLE_REGISTRY for the same kind; update it to prevent
silent re-registration by first checking if kind exists in _BUNDLE_REGISTRY:
retrieve existing = _BUNDLE_REGISTRY.get(kind) and if existing is None, proceed
to insert the new _MetricBundleRegistration(payload_type=payload_type,
packager_factory=packager_factory); if existing is present, compare
existing.payload_type and existing.packager_factory to the incoming payload_type
and packager_factory and if they are identical do nothing (idempotent),
otherwise raise a ValueError describing the conflicting registration for that
kind so callers cannot accidentally override implementations.
- Around line 207-212: The current check only compares output names
(output_names vs bundled_output_names) and misses structural differences; change
the validation in the bundling logic so that you compare the full hydrated
output specs returned by metric.output_spec() against bundle.outputs (not just
.name), e.g. validate equality of each output object's schema/description/fields
with the corresponding bundle.outputs entry, and raise MetricBundlingError with
the same message if any structural mismatch occurs; keep the existing metric
type check (validate_metric_type(metric) vs bundle.metric_type) intact.

---

Outside diff comments:
In `@plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py`:
- Around line 79-99: The submit() API in nemo_evaluator.sdk.resources currently
allows metric_bundle_packager=None but downstream _executor.submit requires a
concrete MetricBundlePackager and fails at runtime; update the public API to
fail fast by validating metric_bundle_packager at the start of submit (and the
async counterpart, same-named method around the 186-206 region) and raise a
clear ValueError if it's None, or alternatively make metric_bundle_packager a
required non-optional parameter in the method signature; ensure the check
references the submit method and _executor.submit call so callers get an
immediate, descriptive error instead of a downstream exception.

In `@plugins/nemo-evaluator/src/nemo_evaluator/sdk/standalone_sdk/backend.py`:
- Around line 33-49: The backend must validate that metric_bundle_packager is
provided when execution_mode == "remote"; in the evaluate method (and the other
backend adapter methods such as the batch evaluation variant around the same
area) check self.execution_mode == "remote" and if so raise a clear
configuration error if self.metric_bundle_packager is None instead of delegating
to self.resource._executor.evaluate_remote (and the corresponding remote call in
the other adapter), so callers get an immediate, descriptive exception about the
missing metric_bundle_packager.
🪄 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: 488c6c84-830f-49a7-a104-1e6a15715d7d

📥 Commits

Reviewing files that changed from the base of the PR and between a018dee and 8e76a89.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (18)
  • packages/nemo_evaluator_sdk/examples/plugin_examples.py
  • packages/nemo_platform/pyproject.toml
  • plugins/nemo-evaluator/pyproject.toml
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/compiler.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/_executor.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/shared/metric_bundles/bundles.py
  • plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/cloudpickle.py
  • plugins/nemo-evaluator/src/nemo_evaluator/tasks/evaluate.py
  • plugins/nemo-evaluator/tests/shared/metric_bundles/test_cloudpickle.py
  • plugins/nemo-evaluator/tests/test_evaluate_job.py
  • plugins/nemo-evaluator/tests/test_sdk.py
  • plugins/nemo-evaluator/tests/test_sdk_job_resources.py
  • plugins/nemo-evaluator/tests/test_standalone_sdk_backend.py
  • third_party/licenses.jsonl

Comment thread plugins/nemo-evaluator/src/nemo_evaluator/jobs/compiler.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/jobs/compiler.py
Comment thread plugins/nemo-evaluator/src/nemo_evaluator/shared/metric_bundles/bundles.py Outdated
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 18404/24386 75.5% 61.8%
Integration Tests 11802/23163 50.9% 26.2%

Signed-off-by: Sandy Chapman <schapman@nvidia.com>
@SandyChapman
SandyChapman force-pushed the metric-bundling-cloudpickle-on-resolvers/schapman branch from 8e76a89 to 4e5b80f Compare June 1, 2026 15:24
@SandyChapman

Copy link
Copy Markdown
Contributor Author

Addressed the two CodeRabbit outside-diff notes in 4e5b80f as well: sync/async Evaluator.submit() now fail fast when metric_bundle_packager is missing, and sync/async standalone remote backends now validate metric_bundle_packager before delegating to the executor.

@SandyChapman
SandyChapman added this pull request to the merge queue Jun 1, 2026

from __future__ import annotations

from nemo_evaluator.jobs.evaluate import EvaluateSpec
from nemo_evaluator.jobs.utils import resolve_run_dataset
from nemo_evaluator.resolvers import PlatformModelResolver
from nemo_evaluator.shared.metric_bundles.bundles import MetricBundle, unbundle_metric
from nemo_evaluator.shared.metric_bundles.cloudpickle import CloudpickleMetricPayload # noqa: F401
)
"""Compile canonical spec to a plugin-native evaluator job."""
del workspace, entity_client, job_name, async_sdk, options
from nemo_evaluator.jobs.compiler import compile_evaluate_job
@abstractmethod
def kind(self) -> str:
"""Payload discriminator used to select the packager implementation."""
...
@abstractmethod
def digest(self) -> str:
"""Format-specific digest for the payload contents."""
...

def package(self, metric: Metric) -> MetricBundlePayload:
"""Package a runtime metric object into a format-specific payload."""
...

def load(self, payload: MetricBundlePayload) -> Metric:
"""Hydrate an executable metric from a bundle payload."""
...
import sys
from typing import Annotated, Literal

import cloudpickle
],
"dataset": [{"expected": "a", "output": "a"}],
}
_LEGACY_EXACT_MATCH_SPEC = {
Merged via the queue into main with commit 6f3a82a Jun 1, 2026
23 checks passed
@SandyChapman
SandyChapman deleted the metric-bundling-cloudpickle-on-resolvers/schapman branch June 2, 2026 11:58
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