Skip to content

feat(experiments): filter evaluations by agent name, agent version, or model name - #1160

Merged
shanaiabuggy merged 10 commits into
mainfrom
sbuggy/ase-809-filter-evaluations-by-agent-name-agent-version-model-name
Aug 10, 2026
Merged

feat(experiments): filter evaluations by agent name, agent version, or model name#1160
shanaiabuggy merged 10 commits into
mainfrom
sbuggy/ase-809-filter-evaluations-by-agent-name-agent-version-model-name

Conversation

@shanaiabuggy

@shanaiabuggy shanaiabuggy commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the ability to filter Evaluations by agent name, agent version, or model name. These values are ClickHouse-derived rollups that were only exposed for display; there was no way to filter the list by them. Filtering them live at workspace scale would mean scanning the whole session table on every request, so instead we denormalize the distinct name sets onto the Evaluation entity (in the entity store) and filter there with the store's existing $contains operator. The entity's numeric rollups (cost/latency/tokens/scores) are intentionally not denormalized — only the names, which have no formula and so can't go stale the way a computed aggregate can.

Today the filter surfaces in Studio on the (experiment-scoped) evaluations list, but the API/SDK support it workspace-wide.

Related Issue

Relates to ASE-809https://linear.app/nvidia/issue/ASE-809 (Linear; auto-linked via branch name).

Changes

Four commits, each self-contained:

  1. feat(intake): denormalize agent/model names onto Evaluation entities — a debounced background worker (EvaluationDenormalizer) that materializes each evaluation's distinct agent_names/agent_versions/model_names from the ClickHouse rollup onto its entity. Ingest marks (workspace, evaluation_id) dirty; the worker coalesces, drains on an interval, skips no-op writes, and drains gracefully on shutdown.
  2. feat(intake): filter evaluations by agent name, agent version, or model name — new agent_name/agent_version/model_name filters that rewrite a scalar equality into a $contains match over the denormalized list fields (mirroring experiment_id membership). Plus self-heal on read: when a read's live rollup names differ from the stored fields, the evaluation is enqueued for the denormalizer, so pre-existing data backfills as it's viewed with no migration to run on any instance.
  3. chore(sdk): regenerate OpenAPI and Python SDK — regenerated from the new EvaluationFilter fields.
  4. feat(studio): add agent/model name filters to the evaluations list — free-text filter inputs mapped to the new API params.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with documentation updates
  • Documentation only
  • Contributor tooling or automation
  • CI, build, or test infrastructure

Quality Gates

  • Tests added or updated for changed behavior
  • Documentation not applicable — justification: response/filter fields carry inline OpenAPI descriptions; no separate user docs in-repo.

Verification

  • Pull request title follows the repository's Conventional Commit format
  • Every commit includes an appropriate Signed-off-by: trailer
  • uv run pre-commit run -a passes, or any blocked checks are identified below
  • Targeted tests pass, or tests are marked not applicable above
  • No secrets, API keys, or credentials are included

Targeted validation (only targeted checks were run locally, not the full pre-commit sweep):

  • uv run --frozen pytest services/intake/tests -k "denormalizer or facet or experiment or evaluation or ingest or crud" → 231 passed
  • uv run --frozen ty check <changed intake files> → no new diagnostics (2 reported errors pre-exist on main, unrelated)
  • uv run ruff check → clean
  • pnpm --filter nemo-studio-ui typecheck && lint && test ExperimentDataView → pass, 30 tests

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Filter evaluations by observed agent name, agent version, and model name.
    • Evaluation details are automatically refreshed from newly ingested session data.
    • Added Agent Names, Agent Versions, and Models filters to the evaluation view.
  • Bug Fixes
    • Evaluation facet data now self-corrects when it is missing or outdated.
    • Filtering consistently matches evaluations containing the selected observed values.
  • Documentation
    • Documented the new evaluation filter fields and their session-derived behavior.

shanaiabuggy and others added 4 commits August 7, 2026 00:21
Add a debounced background worker (EvaluationDenormalizer) that materializes each evaluation's distinct agent_names/agent_versions/model_names from the ClickHouse rollup onto its Evaluation entity, so the list can filter by name against the entity store. Ingest marks (workspace, evaluation_id) dirty; the worker coalesces and drains on an interval, skips no-op writes, and drains gracefully on shutdown.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
…el name

Expose agent_name/agent_version/model_name filters on the evaluations list, rewriting each scalar equality into a $contains match over the denormalized list fields (mirroring experiment_id membership). Also self-heal on read: when a read's live rollup names differ from the stored fields, enqueue the evaluation for the denormalizer, backfilling pre-existing data as it is viewed with no migration.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
…ters

Regenerated from the new EvaluationFilter fields via make refresh-openapi + make stainless.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
Add free-text agent name, agent version, and model filter inputs to the evaluations list, mapped to the filter[agent_name]/[agent_version]/[model_name] API params.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
@shanaiabuggy
shanaiabuggy requested review from a team as code owners August 7, 2026 06:23
@github-actions github-actions Bot added the feat label Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 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: 752d036b-dffb-4488-9a9a-95c782a9d493

📥 Commits

Reviewing files that changed from the base of the PR and between 1c2e9d6 and 92233de.

⛔ Files ignored due to path filters (3)
  • sdk/python/nemo-platform/.nmpcontext/openapi.yaml is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/evaluations/evaluation_filter_param.py is excluded by !sdk/**
  • sdk/python/nemo-platform/tests/api_resources/test_evaluations.py is excluded by !sdk/**
📒 Files selected for processing (20)
  • openapi/ga/individual/platform.openapi.yaml
  • openapi/ga/openapi.yaml
  • openapi/openapi.yaml
  • services/intake/src/nmp/intake/api/v2/experiments/dependencies.py
  • services/intake/src/nmp/intake/api/v2/experiments/endpoints.py
  • services/intake/src/nmp/intake/api/v2/experiments/schemas.py
  • services/intake/src/nmp/intake/background_worker.py
  • services/intake/src/nmp/intake/config.py
  • services/intake/src/nmp/intake/entities/experiments.py
  • services/intake/src/nmp/intake/experiments/denormalizer.py
  • services/intake/src/nmp/intake/service.py
  • services/intake/src/nmp/intake/spans/api/dependencies.py
  • services/intake/src/nmp/intake/spans/ingest/atif.py
  • services/intake/src/nmp/intake/spans/ingest/chat_completions.py
  • services/intake/src/nmp/intake/spans/ingest/otlp.py
  • services/intake/tests/test_evaluation_denormalizer.py
  • services/intake/tests/test_evaluation_denormalizer_self_heal.py
  • services/intake/tests/test_evaluation_facet_filter.py
  • services/intake/tests/test_spans_otlp.py
  • web/packages/studio/src/components/dataViews/ExperimentDataView/index.tsx
🚧 Files skipped from review as they are similar to previous changes (15)
  • openapi/ga/individual/platform.openapi.yaml
  • web/packages/studio/src/components/dataViews/ExperimentDataView/index.tsx
  • services/intake/src/nmp/intake/api/v2/experiments/dependencies.py
  • services/intake/src/nmp/intake/spans/ingest/chat_completions.py
  • openapi/ga/openapi.yaml
  • services/intake/tests/test_evaluation_denormalizer_self_heal.py
  • services/intake/tests/test_evaluation_facet_filter.py
  • services/intake/src/nmp/intake/config.py
  • services/intake/src/nmp/intake/entities/experiments.py
  • services/intake/src/nmp/intake/service.py
  • services/intake/src/nmp/intake/spans/api/dependencies.py
  • services/intake/src/nmp/intake/api/v2/experiments/endpoints.py
  • services/intake/src/nmp/intake/api/v2/experiments/schemas.py
  • services/intake/src/nmp/intake/spans/ingest/atif.py
  • openapi/openapi.yaml

📝 Walkthrough

Walkthrough

Evaluation entities now store observed agent and model facets. Intake refreshes these facets asynchronously from ClickHouse, API filters support them, and Studio exposes corresponding text filters.

Changes

Evaluation facet denormalization

Layer / File(s) Summary
Facet contracts and entity fields
openapi/..., services/intake/src/nmp/intake/api/v2/experiments/schemas.py, services/intake/src/nmp/intake/config.py, services/intake/src/nmp/intake/entities/experiments.py
OpenAPI and intake schemas add agent name, agent version, and model name filters. Evaluation entities store the corresponding denormalized lists.
Denormalization worker lifecycle
services/intake/src/nmp/intake/background_worker.py, services/intake/src/nmp/intake/experiments/denormalizer.py, services/intake/src/nmp/intake/service.py
The background worker tracks dirty evaluations, refreshes ClickHouse rollups, updates entity facets, retries failures, and performs bounded shutdown draining.
Ingest dirty tracking
services/intake/src/nmp/intake/spans/api/dependencies.py, services/intake/src/nmp/intake/spans/ingest/{atif,chat_completions,otlp}.py
Ingest endpoints resolve the service-owned denormalizer and mark evaluations dirty after successful ingestion. OTLP extracts evaluation IDs from span attributes.
Evaluation filtering and self-healing
services/intake/src/nmp/intake/api/v2/experiments/{dependencies,endpoints}.py
Evaluation filters rewrite facet equality checks as list-membership checks. Evaluation reads enqueue refreshes when stored facets differ from rollup values.
Facet validation and Studio controls
services/intake/tests/test_evaluation_denormalizer.py, services/intake/tests/test_evaluation_denormalizer_self_heal.py, services/intake/tests/test_evaluation_facet_filter.py, services/intake/tests/test_spans_otlp.py, web/packages/studio/src/components/dataViews/ExperimentDataView/index.tsx
Tests cover worker behavior, self-healing, filtering, and OTLP evaluation IDs. Studio adds facet column mappings and text filters.

Sequence Diagram(s)

sequenceDiagram
  participant SpanIngest
  participant EvaluationDenormalizer
  participant ClickHouseRollup
  participant EvaluationEntity
  SpanIngest->>EvaluationDenormalizer: mark_dirty(workspace, evaluation_id)
  EvaluationDenormalizer->>ClickHouseRollup: fetch workspace rollups
  ClickHouseRollup-->>EvaluationDenormalizer: observed agent and model facets
  EvaluationDenormalizer->>EvaluationEntity: update denormalized facet lists
Loading

Suggested reviewers: briannewsom

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.30% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding evaluation filters for agent name, agent version, and model name.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sbuggy/ase-809-filter-evaluations-by-agent-name-agent-version-model-name

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.

🧹 Nitpick comments (2)
services/intake/tests/test_evaluation_facet_filter.py (1)

90-103: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add endpoint coverage for filter[agent_version].

The rewrite unit test bypasses public query parsing. Add a persisted agent_versions value and an endpoint request for filter[agent_version].

🤖 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/intake/tests/test_evaluation_facet_filter.py` around lines 90 - 103,
Extend the evaluation fixture setup to persist an agent_versions value, then add
a public client request using filter[agent_version] and assert it returns the
expected evaluation. Keep the existing agent_name, model_name, and
unmatched-filter assertions unchanged.
services/intake/tests/test_evaluation_denormalizer.py (1)

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

Remove from __future__ import annotations from all three test modules.

Their annotations use imported, local, or built-in types and do not require postponement.

🤖 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/intake/tests/test_evaluation_denormalizer.py` at line 6, Remove the
from __future__ import annotations statement from
services/intake/tests/test_evaluation_denormalizer.py:6,
services/intake/tests/test_evaluation_denormalizer_self_heal.py:11, and
services/intake/tests/test_evaluation_facet_filter.py:11; no other changes are
needed.

Source: Coding guidelines

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

Nitpick comments:
In `@services/intake/tests/test_evaluation_denormalizer.py`:
- Line 6: Remove the from __future__ import annotations statement from
services/intake/tests/test_evaluation_denormalizer.py:6,
services/intake/tests/test_evaluation_denormalizer_self_heal.py:11, and
services/intake/tests/test_evaluation_facet_filter.py:11; no other changes are
needed.

In `@services/intake/tests/test_evaluation_facet_filter.py`:
- Around line 90-103: Extend the evaluation fixture setup to persist an
agent_versions value, then add a public client request using
filter[agent_version] and assert it returns the expected evaluation. Keep the
existing agent_name, model_name, and unmatched-filter assertions unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f53378f5-d393-49db-bcd6-f3260ed7a384

📥 Commits

Reviewing files that changed from the base of the PR and between 20e39e0 and d989264.

⛔ Files ignored due to path filters (3)
  • sdk/python/nemo-platform/.nmpcontext/openapi.yaml is excluded by !sdk/**
  • sdk/python/nemo-platform/src/nemo_platform/types/evaluations/evaluation_filter_param.py is excluded by !sdk/**
  • sdk/python/nemo-platform/tests/api_resources/test_evaluations.py is excluded by !sdk/**
📒 Files selected for processing (17)
  • openapi/ga/individual/platform.openapi.yaml
  • openapi/ga/openapi.yaml
  • openapi/openapi.yaml
  • services/intake/src/nmp/intake/api/v2/experiments/dependencies.py
  • services/intake/src/nmp/intake/api/v2/experiments/endpoints.py
  • services/intake/src/nmp/intake/api/v2/experiments/schemas.py
  • services/intake/src/nmp/intake/config.py
  • services/intake/src/nmp/intake/entities/experiments.py
  • services/intake/src/nmp/intake/experiments/denormalizer.py
  • services/intake/src/nmp/intake/service.py
  • services/intake/src/nmp/intake/spans/api/dependencies.py
  • services/intake/src/nmp/intake/spans/ingest/atif.py
  • services/intake/src/nmp/intake/spans/ingest/chat_completions.py
  • services/intake/tests/test_evaluation_denormalizer.py
  • services/intake/tests/test_evaluation_denormalizer_self_heal.py
  • services/intake/tests/test_evaluation_facet_filter.py
  • web/packages/studio/src/components/dataViews/ExperimentDataView/index.tsx

Comment thread services/intake/src/nmp/intake/spans/ingest/chat_completions.py
…ame-agent-version-model-name

Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 32002/40616 78.8% 63.6%
Integration Tests 18555/38542 48.1% 20.8%

Comment thread services/intake/src/nmp/intake/experiments/denormalizer.py
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

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

Inline comments:
In `@services/intake/src/nmp/intake/debounced_refresher.py`:
- Around line 54-62: The stop method’s final drain can leave keys queued by
flush processing. Update DebouncedRefresher.stop to continue draining after the
task completes, repeating flush while _dirty contains pending keys; if using a
bounded retry policy instead, report any keys remaining after the limit.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 814c1c3e-d267-4b0e-893a-9fb5594de492

📥 Commits

Reviewing files that changed from the base of the PR and between e084ee3 and d15c4c0.

📒 Files selected for processing (2)
  • services/intake/src/nmp/intake/debounced_refresher.py
  • services/intake/src/nmp/intake/experiments/denormalizer.py

Comment thread services/intake/src/nmp/intake/debounced_refresher.py Outdated
…ame-agent-version-model-name

Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
Comment thread services/intake/src/nmp/intake/spans/ingest/otlp.py Outdated
Comment thread services/intake/src/nmp/intake/config.py Outdated
Comment thread services/intake/src/nmp/intake/experiments/denormalizer.py Outdated
Comment thread services/intake/src/nmp/intake/debounced_refresher.py Outdated
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@shanaiabuggy
shanaiabuggy added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit fc15bea Aug 10, 2026
56 checks passed
@shanaiabuggy
shanaiabuggy deleted the sbuggy/ase-809-filter-evaluations-by-agent-name-agent-version-model-name branch August 10, 2026 23:18
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