Skip to content

Evals UI: Filter text eval jobs for eval jobs page#52

Closed
nishika26 wants to merge 3 commits intomainfrom
fix/type_filter
Closed

Evals UI: Filter text eval jobs for eval jobs page#52
nishika26 wants to merge 3 commits intomainfrom
fix/type_filter

Conversation

@nishika26
Copy link
Copy Markdown
Contributor

@nishika26 nishika26 commented Mar 3, 2026

Target issue is #53

Summary by CodeRabbit

  • Bug Fixes

    • Evaluation display now consistently filters to show text-type items only
  • Refactor

    • Logging for evaluations that are only text evaluations, when you are opening or in text evaluation pages, earlier not only would it show data of all the evaluations, it would show logs for all the evaluations including the stt ones as well

Summary by CodeRabbit

  • New Features

    • Tab navigation renamed from "Upload/Results" to "Datasets/Evaluations"; default tab now "Datasets" and post-evaluation redirects to "Evaluations".
    • API list views now expose only matching dataset/evaluation types (text or STT) in their respective sections.
  • Bug Fixes

    • Improved response handling so backend errors surface correctly and returned data is filtered to relevant types only.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 3, 2026

📝 Walkthrough

Walkthrough

API routes now filter backend payloads to expose only relevant dataset/evaluation item types (text or stt) and surface backend errors; the evaluations UI renames tabs and components (Upload → Datasets, Results → Evaluations) and updates navigation, labels, and redirects accordingly.

Changes

Cohort / File(s) Summary
Evaluations API — text filtering
app/api/evaluations/route.ts
Add runtime guard for backend errors; filter returned payloads (array or nested data) to only items with type === 'text'; return filtered payload to client.
Datasets API — text filtering
app/api/evaluations/datasets/route.ts
GET now filters dataset responses to include only type === 'text' (supports array and nested data shapes); POST/error paths unchanged.
STT datasets API — stt filtering + docblock
app/api/evaluations/stt/datasets/route.ts
Added docblock; GET branches on response.ok and, when ok, filters payloads to type === 'stt' (supports array and nested data), otherwise returns backend error/status.
UI — tab renames and prop/component updates
app/evaluations/page.tsx
Rename tab type and defaults from `'upload'

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • UI: STT Evals #44 — Modifies app/api/evaluations/stt/datasets/route.ts GET/POST handlers; closely related to the STT datasets filtering changes in this PR.

Suggested reviewers

  • Prajna1999

Poem

"I'm a rabbit in the code-glow night,
Hopping through types to set things right.
I filter text and whisper STT,
Rename the tabs — tidy as can be.
Logs and datasets, neat and bright."

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: filtering text evaluation jobs for the evaluations page. It is specific, concise, and directly relates to the primary objective of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/type_filter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@nishika26 nishika26 self-assigned this Mar 4, 2026
@nishika26 nishika26 added the enhancement New feature or request label Mar 4, 2026
Copy link
Copy Markdown
Contributor

@AkhileshNegi AkhileshNegi left a comment

Choose a reason for hiding this comment

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

can you fix the listing dataset also to show only text datasets
image

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 (1)
app/api/evaluations/stt/datasets/route.ts (1)

12-19: ⚠️ Potential issue | 🟠 Major

Fail fast on missing X-API-KEY in GET.

GET currently forwards an empty API key instead of returning 401, unlike POST. This creates inconsistent auth behavior and avoidable backend traffic.

Proposed fix
   const apiKey = request.headers.get('X-API-KEY');
+  if (!apiKey) {
+    return NextResponse.json(
+      { error: 'Missing X-API-KEY header' },
+      { status: 401 }
+    );
+  }

   try {
     const response = await fetch(`${backendUrl}/api/v1/evaluations/stt/datasets`, {
       headers: {
-        'X-API-KEY': apiKey || '',
+        'X-API-KEY': apiKey,
       },
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/evaluations/stt/datasets/route.ts` around lines 12 - 19, The GET
handler currently reads const apiKey = request.headers.get('X-API-KEY') then
forwards an empty string to fetch; instead, fail fast when apiKey is missing by
returning a 401 response immediately. Update the logic around the apiKey
constant (before the fetch to `${backendUrl}/api/v1/evaluations/stt/datasets`)
to check if apiKey is falsy and return an appropriate 401 response (matching the
POST behavior) rather than calling fetch with an empty 'X-API-KEY' header.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/api/evaluations/datasets/route.ts`:
- Around line 43-45: The code assumes data.data is an array before calling
.filter; update the conditional in the datasets response assignment to guard
with Array.isArray(data.data) so you only call data.data.filter when
Array.isArray(data.data) is true (otherwise leave data unchanged); locate the
expression that builds the final result (the ternary using data.data ? {
...data, data: data.data.filter(...) } : data) and add the Array.isArray check
to prevent runtime errors.
- Around line 40-47: The endpoint in route.ts is hard-filtering datasets to type
=== 'text' (see the filteredData construction using data.filter and
data.data.filter), which hides non-text datasets for other consumers; revert
this global filter and instead implement conditional filtering based on a query
parameter (e.g. check req.nextUrl.searchParams.get('type') === 'text' before
applying the filter) or create a separate text-only endpoint used by
app/evaluations/page.tsx; update the logic that builds filteredData to only
filter when the type query is set (leave the default behavior to return all
dataset types) and ensure the variable names filteredData and data are reused
accordingly.

In `@app/api/evaluations/route.ts`:
- Around line 27-32: The handler currently filters evaluations into the local
variable items but still returns the original data, so clients receive
unfiltered mixed types; update the response in the route handler (where data is
returned) to use the filtered items variable (or construct a response object
that replaces data with items) so the API returns text-only evaluations; ensure
you reference the items variable and the same data structure shape used
elsewhere in this file (e.g., where items is populated) so pagination/metadata
(if any) is preserved or reattached when returning the filtered payload.

In `@app/api/evaluations/stt/datasets/route.ts`:
- Around line 27-32: The STT filtering logic in the route uses filteredData and
currently only handles top-level arrays and data.data, which misses the
data.datasets shape and calls .filter without array guards; update the
filteredData computation to check for Array.isArray on data, data.data, and
data.datasets and apply dataset => dataset.type === 'stt' only when each is an
array (preserve non-array branches unchanged), referencing the filteredData
variable and the dataset.type predicate so all response shapes (data, data.data,
data.datasets) are safely filtered for 'stt'.

---

Outside diff comments:
In `@app/api/evaluations/stt/datasets/route.ts`:
- Around line 12-19: The GET handler currently reads const apiKey =
request.headers.get('X-API-KEY') then forwards an empty string to fetch;
instead, fail fast when apiKey is missing by returning a 401 response
immediately. Update the logic around the apiKey constant (before the fetch to
`${backendUrl}/api/v1/evaluations/stt/datasets`) to check if apiKey is falsy and
return an appropriate 401 response (matching the POST behavior) rather than
calling fetch with an empty 'X-API-KEY' header.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d9cbe595-7fb4-40d1-b4aa-afcca5517f6f

📥 Commits

Reviewing files that changed from the base of the PR and between d06957f and c83e2ba.

📒 Files selected for processing (4)
  • app/api/evaluations/datasets/route.ts
  • app/api/evaluations/route.ts
  • app/api/evaluations/stt/datasets/route.ts
  • app/evaluations/page.tsx

Comment on lines +40 to +47
// Filter to only return text datasets
const filteredData = Array.isArray(data)
? data.filter((dataset: any) => dataset.type === 'text')
: data.data
? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'text') }
: data;

return NextResponse.json(filteredData, { status: 200 });
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid hard-filtering this shared datasets endpoint.

This route is consumed by both app/evaluations/page.tsx (text eval flow) and app/datasets/page.tsx (datasets management). Applying type === 'text' here makes non-text datasets silently disappear in other pages. Prefer a dedicated text-only endpoint (or a ?type=text query) instead of changing the default behavior globally.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/evaluations/datasets/route.ts` around lines 40 - 47, The endpoint in
route.ts is hard-filtering datasets to type === 'text' (see the filteredData
construction using data.filter and data.data.filter), which hides non-text
datasets for other consumers; revert this global filter and instead implement
conditional filtering based on a query parameter (e.g. check
req.nextUrl.searchParams.get('type') === 'text' before applying the filter) or
create a separate text-only endpoint used by app/evaluations/page.tsx; update
the logic that builds filteredData to only filter when the type query is set
(leave the default behavior to return all dataset types) and ensure the variable
names filteredData and data are reused accordingly.

Comment on lines +43 to +45
: data.data
? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'text') }
: data;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard nested payload shape before calling .filter().

If data.data is present but not an array, Line 44 throws at runtime. Add an Array.isArray(data.data) check before filtering.

Proposed fix
-const filteredData = Array.isArray(data)
-  ? data.filter((dataset: any) => dataset.type === 'text')
-  : data.data
-    ? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'text') }
-    : data;
+const filteredData = Array.isArray(data)
+  ? data.filter((dataset: any) => dataset.type === 'text')
+  : Array.isArray(data?.data)
+    ? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'text') }
+    : data;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
: data.data
? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'text') }
: data;
const filteredData = Array.isArray(data)
? data.filter((dataset: any) => dataset.type === 'text')
: Array.isArray(data?.data)
? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'text') }
: data;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/evaluations/datasets/route.ts` around lines 43 - 45, The code assumes
data.data is an array before calling .filter; update the conditional in the
datasets response assignment to guard with Array.isArray(data.data) so you only
call data.data.filter when Array.isArray(data.data) is true (otherwise leave
data unchanged); locate the expression that builds the final result (the ternary
using data.data ? { ...data, data: data.data.filter(...) } : data) and add the
Array.isArray check to prevent runtime errors.

Comment on lines +27 to +32
// Filter to only return STT datasets (additional safety check)
const filteredData = Array.isArray(data)
? data.filter((dataset: any) => dataset.type === 'stt')
: data.data
? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'stt') }
: data;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

STT filtering misses the data.datasets shape and lacks array guards.

This code only filters top-level arrays and data.data. But the STT page also handles data.datasets; in that response shape, filtering is skipped entirely. Also, calling .filter without Array.isArray checks risks runtime errors.

Proposed fix
-    const filteredData = Array.isArray(data)
-      ? data.filter((dataset: any) => dataset.type === 'stt')
-      : data.data
-        ? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'stt') }
-        : data;
+    const filteredData = Array.isArray(data)
+      ? data.filter((dataset: any) => dataset.type === 'stt')
+      : Array.isArray(data?.datasets)
+        ? { ...data, datasets: data.datasets.filter((dataset: any) => dataset.type === 'stt') }
+        : Array.isArray(data?.data)
+          ? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'stt') }
+          : data;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Filter to only return STT datasets (additional safety check)
const filteredData = Array.isArray(data)
? data.filter((dataset: any) => dataset.type === 'stt')
: data.data
? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'stt') }
: data;
// Filter to only return STT datasets (additional safety check)
const filteredData = Array.isArray(data)
? data.filter((dataset: any) => dataset.type === 'stt')
: Array.isArray(data?.datasets)
? { ...data, datasets: data.datasets.filter((dataset: any) => dataset.type === 'stt') }
: Array.isArray(data?.data)
? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'stt') }
: data;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/evaluations/stt/datasets/route.ts` around lines 27 - 32, The STT
filtering logic in the route uses filteredData and currently only handles
top-level arrays and data.data, which misses the data.datasets shape and calls
.filter without array guards; update the filteredData computation to check for
Array.isArray on data, data.data, and data.datasets and apply dataset =>
dataset.type === 'stt' only when each is an array (preserve non-array branches
unchanged), referencing the filteredData variable and the dataset.type predicate
so all response shapes (data, data.data, data.datasets) are safely filtered for
'stt'.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
app/api/evaluations/datasets/route.ts (2)

43-45: ⚠️ Potential issue | 🟠 Major

Guard nested payload shape before calling .filter().

Line 43 only checks truthiness of data.data. If backend returns a non-array (e.g. object), Line 44 throws at runtime. Use Array.isArray(data?.data) in that branch.

Proposed fix
-const filteredData = Array.isArray(data)
-  ? data.filter((dataset: any) => dataset.type === 'text')
-  : data.data
-    ? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'text') }
-    : data;
+const filteredData = Array.isArray(data)
+  ? data.filter((dataset: any) => dataset.type === 'text')
+  : Array.isArray(data?.data)
+    ? { ...data, data: data.data.filter((dataset: any) => dataset.type === 'text') }
+    : data;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/evaluations/datasets/route.ts` around lines 43 - 45, The current
conditional uses truthiness of data.data and then calls .filter, which will
throw if data.data is not an array; update the branch that maps datasets (in
app/api/evaluations/datasets/route.ts where you compute the filtered result from
variable data) to first guard with Array.isArray(data?.data) and only call
.filter when that check is true, otherwise fall back to the original value so
non-array payloads are handled safely.

40-45: ⚠️ Potential issue | 🟠 Major

Avoid unconditional text filtering on this route.

Line 40 through Line 45 hard-filter to type === 'text' for every request. If this endpoint is still used as a general datasets source anywhere, non-text datasets will disappear silently. Prefer conditional filtering (e.g. query-param gated) or keep this route generic and move text-only behavior to a dedicated endpoint.

#!/bin/bash
# Verify whether this route is consumed as a generic datasets endpoint.
# Expected: if consumers require mixed dataset types, unconditional filtering is unsafe.
rg -n -C3 "/api/evaluations/datasets" --type=ts --type=tsx
rg -n -C3 "evaluations/datasets" --type=ts --type=tsx
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/evaluations/datasets/route.ts` around lines 40 - 45, The current
route unconditionally filters datasets to text-only by assigning to filteredData
using dataset.type === 'text', which can silently remove non-text datasets;
update the route handler to apply this filter conditionally (e.g., check a query
parameter like "type=text" or "textOnly=true" from the incoming request) and
only perform the data.filter(...) when that param is present, otherwise return
the original data as-is; alternatively, if you prefer separation of concerns,
move the text-only logic into a dedicated endpoint and keep this route generic
(refer to the filteredData assignment and the route handler that reads "data" to
implement the conditional gating).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@app/api/evaluations/datasets/route.ts`:
- Around line 43-45: The current conditional uses truthiness of data.data and
then calls .filter, which will throw if data.data is not an array; update the
branch that maps datasets (in app/api/evaluations/datasets/route.ts where you
compute the filtered result from variable data) to first guard with
Array.isArray(data?.data) and only call .filter when that check is true,
otherwise fall back to the original value so non-array payloads are handled
safely.
- Around line 40-45: The current route unconditionally filters datasets to
text-only by assigning to filteredData using dataset.type === 'text', which can
silently remove non-text datasets; update the route handler to apply this filter
conditionally (e.g., check a query parameter like "type=text" or "textOnly=true"
from the incoming request) and only perform the data.filter(...) when that param
is present, otherwise return the original data as-is; alternatively, if you
prefer separation of concerns, move the text-only logic into a dedicated
endpoint and keep this route generic (refer to the filteredData assignment and
the route handler that reads "data" to implement the conditional gating).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fca1ac70-c18f-4abf-a4f8-a864f72b26d3

📥 Commits

Reviewing files that changed from the base of the PR and between c83e2ba and 9bb39ac.

📒 Files selected for processing (2)
  • app/api/evaluations/datasets/route.ts
  • app/api/evaluations/route.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/api/evaluations/route.ts

@nishika26
Copy link
Copy Markdown
Contributor Author

we fixed this issue from backend instead of frontend, where evaluation apis being used for text evaluation will only return text evaluation response, and same for stt evaluation

@nishika26 nishika26 closed this Mar 5, 2026
@Ayush8923 Ayush8923 deleted the fix/type_filter branch April 1, 2026 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants