Skip to content

feat(evaluator): persist agent-eval tasks as entities (AALGO-307) - #527

Merged
SandyChapman merged 1 commit into
mainfrom
aalgo-307-task-entity/schapman
Jul 3, 2026
Merged

feat(evaluator): persist agent-eval tasks as entities (AALGO-307)#527
SandyChapman merged 1 commit into
mainfrom
aalgo-307-task-entity/schapman

Conversation

@SandyChapman

@SandyChapman SandyChapman commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds Task as a first-class entity / endpoint / SDK resource in the nemo-evaluator plugin, mapping the SDK AgentEvalTask shape so agent-eval tasks can be persisted and queried (AALGO-307).

Stacked on #515 (eval-results-persistence). Review/merge that first; this PR's diff is scoped to the Task work. Base will retarget to main once #515 lands.

What's here

  • TaskEntity + Task/TaskInput DTOs.
  • /tasks CRUD routes (list/create/get/delete) with authz + filter/sort, mirroring /metrics.
  • client.evaluator.tasks SDK resource (sync + async).
  • Inline-metric normalization: an inline metric submitted on a task is offloaded to a content-addressed derived stored metric (Files-backed, derived=True), so a persisted task holds metric references only. Identical inline metrics across tasks dedupe to one stored bundle.
  • Derived metrics are hidden from the default /metrics listing; pass include_derived=true to surface them. Metric SDK list() gains include_derived parity with the route.

Testing

  • Unit: task entity round-trip, TaskService (incl. inline→derived normalization), /tasks routes, SDK resources, and derived-metric storage (digest naming, content-addressed dedup, list exclusion). Full evaluator unit suite green (428).
  • Integration (RUN_AGENT_EVAL_INTEGRATION=1, real entity store + Files): inline task metric → derived ref, cross-task dedup, derived metric retrievable/derived=True/Files-backed, hidden by default and visible with include_derived. Verified live — this caught a real bug: the content-addressed name derived.<sha256> (72 chars) exceeded the entity store's 63-char name limit; the digest is now truncated to fit.

Not in this PR

  • task_refs on the agent-eval submit path (running an eval over stored tasks by reference) — intended as a follow-up stacked on this branch.
  • Taskset entity — deferred within AALGO-307.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added evaluator task CRUD APIs and SDK support (create, retrieve, list with pagination/sort/filter, and delete).
    • Task inputs and metadata are now strongly typed, with metadata key uniqueness enforced.
    • Metrics can now mark derived/task-internal items, and metric listing can optionally include them via include_derived.
  • Bug Fixes

    • Derived metrics are hidden by default to keep results clean, but remain retrievable when requested.
    • Task details are now stored and returned with consistent normalization of inputs/metadata and metric references.

@github-actions github-actions Bot added the feat label Jun 30, 2026
@SandyChapman
SandyChapman force-pushed the eval-results-persistence/schapman branch from dcef462 to cfc423d Compare July 2, 2026 13:07
@SandyChapman
SandyChapman force-pushed the aalgo-307-task-entity/schapman branch from 0e5d9cd to b10bb1d Compare July 2, 2026 14:22
Base automatically changed from eval-results-persistence/schapman to main July 2, 2026 16:11
@SandyChapman
SandyChapman force-pushed the aalgo-307-task-entity/schapman branch from 9d7eb25 to 637dfb2 Compare July 2, 2026 19:15
@SandyChapman
SandyChapman marked this pull request as ready for review July 2, 2026 19:18
@SandyChapman
SandyChapman requested review from a team as code owners July 2, 2026 19:18
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 22524/29649 76.0% 60.9%
Integration Tests 13010/28329 45.9% 19.4%

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds persisted task CRUD for evaluator workspaces, plus derived metric storage and filtering. Updates the task and metric contracts, wires API/SDK surfaces, and adjusts agent-eval serialization to use structured task inputs and metadata.

Changes

Task and derived-metric feature

Layer / File(s) Summary
OpenAPI and schema contracts
plugins/nemo-evaluator/openapi/openapi.yaml, plugins/nemo-evaluator/src/nemo_evaluator/api/schemas.py
Adds task CRUD paths, structured task schemas, MetricRef, MetadataItem, and derived fields on metric models and filters.
Derived metric storage in MetricService
plugins/nemo-evaluator/src/nemo_evaluator/api/service/metric_service.py, plugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.py, plugins/nemo-evaluator/src/nemo_evaluator/sdk/metric_resources.py, plugins/nemo-evaluator/tests/api/service/test_metric_service.py, plugins/nemo-evaluator/tests/api/v2/test_metrics_routes.py, plugins/nemo-evaluator/tests/sdk/test_metric_sdk_resources.py
Stores inline metrics as derived refs, excludes them by default from listings, and threads include_derived through API and SDK callers.
TaskEntity persistence model
plugins/nemo-evaluator/src/nemo_evaluator/entities.py, plugins/nemo-evaluator/tests/test_task_entity.py
Adds the persisted task entity and verifies JSON round-trip serialization.
TaskService CRUD implementation
plugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.py, plugins/nemo_evaluator/tests/api/service/test_task_service.py
Implements task create/get/list/delete with metric normalization, pagination mapping, and entity conflict/not-found handling.
Task API routes and dependency wiring
plugins/nemo-evaluator/src/nemo_evaluator/api/dependencies.py, plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.py, plugins/nemo-evaluator/src/nemo_evaluator/service.py, plugins/nemo-evaluator/tests/api/v2/test_tasks_routes.py
Adds the task service dependency, REST endpoints, router registration, and route-level behavior tests.
SDK task and metric resources
plugins/nemo-evaluator/src/nemo_evaluator/sdk/task_resources.py, plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py, plugins/nemo-evaluator/src/nemo_evaluator/sdk/metric_resources.py, plugins/nemo-evaluator/tests/sdk/test_task_sdk_resources.py
Adds sync/async task SDK clients, exposes them on evaluator clients, and extends metric listing with derived-metric inclusion.
Agent-eval spec and runtime updates
plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_spec.py, plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_evaluate.py, plugins/nemo_evaluator/src/nemo_evaluator/metric_refs.py, plugins/nemo-evaluator/tests/integration/*, plugins/nemo-evaluator/tests/test_agent_evaluate.py
Reuses shared task and metric reference types, updates runtime task serialization, and switches task input keys in agent-eval tests.

Possibly related PRs

Suggested labels: feat

Suggested reviewers: arpitsardhana

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: persisting agent-eval tasks as entities in the evaluator plugin.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch aalgo-307-task-entity/schapman

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

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/jobs/agent_evaluate.py (1)

93-104: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Duplicate metadata keys silently collapse.

{item.key: item.value for item in task.metadata} drops earlier entries when MetadataItem keys repeat. Since metadata is now a list (presumably to allow duplicates/ordering, unlike the old dict), silently losing entries on collapse could confuse callers who intentionally add multiple annotations with the same key.

💡 Optional: warn or reject duplicate keys
-        metadata={item.key: item.value for item in task.metadata},
+        metadata=_dedupe_metadata(task.metadata),
def _dedupe_metadata(items: list[MetadataItem]) -> dict[str, str]:
    result: dict[str, str] = {}
    for item in items:
        if item.key in result:
            logger.warning("Duplicate task metadata key %r; keeping last value.", item.key)
        result[item.key] = item.value
    return result
🤖 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/jobs/agent_evaluate.py` around
lines 93 - 104, The metadata reconstruction in _to_runtime_task currently
collapses repeated MetadataItem keys by building a dict comprehension, which can
silently drop earlier values. Update this conversion to handle duplicates
explicitly: either reject duplicate keys with a clear error or dedupe them in a
dedicated helper like _dedupe_metadata, and if deduping, log a warning when a
key repeats so callers can detect the overwrite. Keep the change localized to
_to_runtime_task and the metadata mapping logic used there.
plugins/nemo-evaluator/openapi/openapi.yaml (1)

1708-1793: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Breaking /agent-evaluate/jobs payload contract inputs now only accepts TaskInputs.instruction, and metadata is array<MetadataItem>. Clients still sending inputs.prompt or dict metadata will 422; stored specs in the old shape need migration/backfill or a version bump.

Source: Linters/SAST tools

🧹 Nitpick comments (2)
plugins/nemo-evaluator/tests/sdk/test_task_sdk_resources.py (1)

111-121: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add async coverage for create/list/delete.

Only retrieve is tested for AsyncEvaluatorTasksResource; sync counterpart covers create/retrieve/list/delete. Since sync/async implementations are independent code, an async-only regression here would go undetected.

🤖 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/tests/sdk/test_task_sdk_resources.py` around lines 111
- 121, Add async test coverage for AsyncEvaluatorTasksResource beyond retrieve
by creating focused tests for create, list, and delete, since the sync suite
already covers these paths but the async implementation is independent. Use the
existing async test pattern in test_async_retrieve_parses_dto as a guide, and
verify the relevant AsyncEvaluatorTasksResource methods call the expected
http_client operations and parse DTOs correctly, referencing create, list,
delete, and retrieve for easy location.
plugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.py (1)

70-102: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Inline metrics get stored even when task create fails.

_normalize_metrics writes derived metric entities before create_task attempts the entity write. On EntityConflictError (or any other create failure), the derived metric is already persisted with nothing referencing it — no rollback, no cleanup path in this PR. Content-addressing limits damage on retries of identical content, but distinct inline metrics on a failed/duplicate create leak permanently.

Consider checking for an existing task (or reordering) before normalizing metrics, so a conflict doesn't leave orphaned derived-metric writes.

🤖 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/api/service/task_service.py` around
lines 70 - 102, The task creation flow persists derived metrics too early, so a
failed create can leave orphaned inline metric entities behind. Update
create_task to avoid calling _normalize_metrics before you know the task write
will succeed, ideally by checking for an existing task or otherwise reordering
the entity creation so EntityConflictError happens before store_derived_metric
is invoked. Keep the fix scoped around create_task and _normalize_metrics,
preserving the current MetricRef/MetricInline handling while preventing metric
writes on failed task creation.
🤖 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/api/service/metric_service.py`:
- Around line 184-217: store_derived_metric is deduping on only
RuntimeMetricBundle.payload.digest, which can collapse distinct inline metrics
that share code but differ in secrets, outputs, labels, or metric_type. Update
the naming/dedup key in store_derived_metric to use a digest of the full
metric/bundle content (for example, the serialized RuntimeMetricBundle or
equivalent full bundle JSON) so that the existing get/create path only reuses
entries when the entire submitted contract matches.

---

Outside diff comments:
In `@plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_evaluate.py`:
- Around line 93-104: The metadata reconstruction in _to_runtime_task currently
collapses repeated MetadataItem keys by building a dict comprehension, which can
silently drop earlier values. Update this conversion to handle duplicates
explicitly: either reject duplicate keys with a clear error or dedupe them in a
dedicated helper like _dedupe_metadata, and if deduping, log a warning when a
key repeats so callers can detect the overwrite. Keep the change localized to
_to_runtime_task and the metadata mapping logic used there.

---

Nitpick comments:
In `@plugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.py`:
- Around line 70-102: The task creation flow persists derived metrics too early,
so a failed create can leave orphaned inline metric entities behind. Update
create_task to avoid calling _normalize_metrics before you know the task write
will succeed, ideally by checking for an existing task or otherwise reordering
the entity creation so EntityConflictError happens before store_derived_metric
is invoked. Keep the fix scoped around create_task and _normalize_metrics,
preserving the current MetricRef/MetricInline handling while preventing metric
writes on failed task creation.

In `@plugins/nemo-evaluator/tests/sdk/test_task_sdk_resources.py`:
- Around line 111-121: Add async test coverage for AsyncEvaluatorTasksResource
beyond retrieve by creating focused tests for create, list, and delete, since
the sync suite already covers these paths but the async implementation is
independent. Use the existing async test pattern in
test_async_retrieve_parses_dto as a guide, and verify the relevant
AsyncEvaluatorTasksResource methods call the expected http_client operations and
parse DTOs correctly, referencing create, list, delete, and retrieve for easy
location.
🪄 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: 95570b2e-1aa8-47c8-80c0-910c765dbf7f

📥 Commits

Reviewing files that changed from the base of the PR and between bd70579 and 637dfb2.

📒 Files selected for processing (25)
  • plugins/nemo-evaluator/openapi/openapi.yaml
  • plugins/nemo-evaluator/src/nemo_evaluator/api/dependencies.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/schemas.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/service/metric_service.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.py
  • plugins/nemo-evaluator/src/nemo_evaluator/entities.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_evaluate.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_spec.py
  • plugins/nemo-evaluator/src/nemo_evaluator/metric_refs.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/metric_resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/task_resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/service.py
  • plugins/nemo-evaluator/tests/api/service/test_metric_service.py
  • plugins/nemo-evaluator/tests/api/service/test_task_service.py
  • plugins/nemo-evaluator/tests/api/v2/test_metrics_routes.py
  • plugins/nemo-evaluator/tests/api/v2/test_tasks_routes.py
  • plugins/nemo-evaluator/tests/integration/test_agent_evaluate_job.py
  • plugins/nemo-evaluator/tests/integration/test_task_derived_metrics.py
  • plugins/nemo-evaluator/tests/sdk/test_metric_sdk_resources.py
  • plugins/nemo-evaluator/tests/sdk/test_task_sdk_resources.py
  • plugins/nemo-evaluator/tests/test_agent_evaluate.py
  • plugins/nemo-evaluator/tests/test_task_entity.py

Add Task as a first-class entity / endpoint / SDK resource in the
nemo-evaluator plugin, mapping the SDK AgentEvalTask shape.

- TaskEntity + Task/TaskInput DTOs, /tasks CRUD routes (decorator authz),
  and a client.evaluator.tasks SDK resource (sync + async).
- Inline task metrics are normalized to content-addressed *derived* stored
  metrics (Files-backed, derived=True); the task holds refs only. Derived
  metrics are hidden from the default /metrics listing (include_derived=true
  to surface them); metric SDK list() gains include_derived parity.
- Typed task fields instead of opaque dicts: TaskInputs (single recognized
  `instruction` field, extra="forbid") and metadata as a list of
  MetadataItem {key, value} pairs. Applied to Task/TaskInput/TaskEntity and
  the AgentEvalTaskSpec submit path; the runtime AgentEvalTask stays
  dict-typed via a conversion at the boundary.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Sandy Chapman <schapman@nvidia.com>
@SandyChapman
SandyChapman force-pushed the aalgo-307-task-entity/schapman branch from 637dfb2 to cf09270 Compare July 2, 2026 19:58
@SandyChapman

Copy link
Copy Markdown
Contributor Author

Thanks @coderabbitai — both findings addressed in cf092701a5:

  • [Major] Derived-metric content-address now covers the full bundle, not just payload.digest (see inline reply on metric_service.py).
  • [Minor] Duplicate metadata keys collapsing in _to_runtime_task — rather than warn-and-drop at the runtime fold, I reject duplicates at the DTO boundary: a shared TaskMetadataList (list[MetadataItem] + AfterValidator) rejects duplicate keys on every task metadata field (Task, TaskInput, TaskEntity, AgentEvalTaskSpec). The list → dict fold is now safe by construction, and the route returns 422 on duplicate keys (test added).

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh api repos/NVIDIA-NeMo/nemo-platform/commits/cf092701a5 --jq '.files[] | select(.filename | test("metric_service.py|schemas.py|entities.py|agent_spec.py")) | .filename'

Length of output: 629


Confirmed — commit cf092701a5 touches metric_service.py, schemas.py, entities.py, agent_spec.py, and adds test coverage. Both fixes look in place.

@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-evaluator/openapi/openapi.yaml`:
- Around line 1331-1338: The GET/DELETE task routes are missing the same path
validation used by create_task, so the name parameter is inconsistent across
CRUD operations. Update the path parameter definition for get_task and
delete_task to reuse the same MAX_NAME_LENGTH and NAME_PATTERN constraints
already applied in create_task, using the existing name schema in the OpenAPI
spec so all three routes enforce identical validation.
🪄 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: 64efb1a2-b7f2-4a0b-b265-e23d3d8ad450

📥 Commits

Reviewing files that changed from the base of the PR and between 637dfb2 and cf09270.

📒 Files selected for processing (25)
  • plugins/nemo-evaluator/openapi/openapi.yaml
  • plugins/nemo-evaluator/src/nemo_evaluator/api/dependencies.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/schemas.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/service/metric_service.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.py
  • plugins/nemo-evaluator/src/nemo_evaluator/entities.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_evaluate.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_spec.py
  • plugins/nemo-evaluator/src/nemo_evaluator/metric_refs.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/metric_resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/task_resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/service.py
  • plugins/nemo-evaluator/tests/api/service/test_metric_service.py
  • plugins/nemo-evaluator/tests/api/service/test_task_service.py
  • plugins/nemo-evaluator/tests/api/v2/test_metrics_routes.py
  • plugins/nemo-evaluator/tests/api/v2/test_tasks_routes.py
  • plugins/nemo-evaluator/tests/integration/test_agent_evaluate_job.py
  • plugins/nemo-evaluator/tests/integration/test_task_derived_metrics.py
  • plugins/nemo-evaluator/tests/sdk/test_metric_sdk_resources.py
  • plugins/nemo-evaluator/tests/sdk/test_task_sdk_resources.py
  • plugins/nemo-evaluator/tests/test_agent_evaluate.py
  • plugins/nemo-evaluator/tests/test_task_entity.py
🚧 Files skipped from review as they are similar to previous changes (22)
  • plugins/nemo-evaluator/tests/api/v2/test_metrics_routes.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_evaluate.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/service.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/v2/metrics.py
  • plugins/nemo-evaluator/tests/test_agent_evaluate.py
  • plugins/nemo-evaluator/tests/integration/test_agent_evaluate_job.py
  • plugins/nemo-evaluator/src/nemo_evaluator/jobs/agent_spec.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/dependencies.py
  • plugins/nemo-evaluator/tests/sdk/test_metric_sdk_resources.py
  • plugins/nemo-evaluator/tests/api/service/test_metric_service.py
  • plugins/nemo-evaluator/tests/api/v2/test_tasks_routes.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/metric_resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/sdk/task_resources.py
  • plugins/nemo-evaluator/src/nemo_evaluator/entities.py
  • plugins/nemo-evaluator/src/nemo_evaluator/metric_refs.py
  • plugins/nemo-evaluator/tests/api/service/test_task_service.py
  • plugins/nemo-evaluator/tests/integration/test_task_derived_metrics.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/service/task_service.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/schemas.py
  • plugins/nemo-evaluator/src/nemo_evaluator/api/v2/tasks.py
  • plugins/nemo-evaluator/tests/sdk/test_task_sdk_resources.py

Comment thread plugins/nemo-evaluator/openapi/openapi.yaml
@SandyChapman
SandyChapman added this pull request to the merge queue Jul 3, 2026
Merged via the queue into main with commit 6e774b3 Jul 3, 2026
54 checks passed
@SandyChapman
SandyChapman deleted the aalgo-307-task-entity/schapman branch July 3, 2026 11:13
arpitsardhana pushed a commit that referenced this pull request Jul 9, 2026
Add Task as a first-class entity / endpoint / SDK resource in the
nemo-evaluator plugin, mapping the SDK AgentEvalTask shape.

- TaskEntity + Task/TaskInput DTOs, /tasks CRUD routes (decorator authz),
  and a client.evaluator.tasks SDK resource (sync + async).
- Inline task metrics are normalized to content-addressed *derived* stored
  metrics (Files-backed, derived=True); the task holds refs only. Derived
  metrics are hidden from the default /metrics listing (include_derived=true
  to surface them); metric SDK list() gains include_derived parity.
- Typed task fields instead of opaque dicts: TaskInputs (single recognized
  `instruction` field, extra="forbid") and metadata as a list of
  MetadataItem {key, value} pairs. Applied to Task/TaskInput/TaskEntity and
  the AgentEvalTaskSpec submit path; the runtime AgentEvalTask stays
  dict-typed via a conversion at the boundary.

Signed-off-by: Sandy Chapman <schapman@nvidia.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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