Skip to content

evals UI: Include comments in grouped question CSV#68

Merged
nishika26 merged 3 commits intomainfrom
enhancement/eval_grouped_comment
Mar 16, 2026
Merged

evals UI: Include comments in grouped question CSV#68
nishika26 merged 3 commits intomainfrom
enhancement/eval_grouped_comment

Conversation

@nishika26
Copy link
Copy Markdown
Contributor

@nishika26 nishika26 commented Mar 16, 2026

Target issue is #67

Summary by CodeRabbit

  • New Features
    • CSV export now emits a quoted header for each score plus a dedicated comment column per score in both grouped and individual/row formats, ensuring consistent column alignment.
  • Bug Fixes / Security
    • Questions, answers, ground-truths and per-score comments are sanitized and headers are escaped to prevent CSV injection and ensure correct CSV formatting.

@nishika26 nishika26 self-assigned this Mar 16, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

Updates CSV export generation in the evaluations page to add per-score comment columns and stronger CSV cell handling: values are escaped (quotes/newlines), optionally prefixed to prevent CSV-injection, and both grouped (horizontal) and row (individual) formats emit two quoted headers per score (value + comment).

Changes

Cohort / File(s) Summary
CSV export changes
app/evaluations/[id]/page.tsx
Added CSV helper utilities for escaping and CSV-injection prevention; adjusted headers to emit two quoted headers per score (" (i)" and " (i) - comment"); serialized question, answer, ground truth, score values, and per-score comments using sanitization; aligned grouped and row export formats.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • Evaluation: Group Export #25: Modifies CSV export logic in app/evaluations/[id]/page.tsx, addressing grouped vs row export handling and column alignment.

Suggested reviewers

  • Prajna1999
  • AkhileshNegi

Poem

🐰 I hopped through headers, quoted tight,
I fenced off tricks that hide in sight,
Each score now keeps its comment near,
Safe cells, neat rows — a joyful cheer,
CSV hops home, stars shining bright. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 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: adding comment columns to the grouped question CSV export in the evaluations UI.

✏️ 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 enhancement/eval_grouped_comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

You can disable sequence diagrams in the walkthrough.

Disable the reviews.sequence_diagrams setting to disable sequence diagrams in the walkthrough.

@nishika26 nishika26 added the enhancement New feature or request label Mar 16, 2026
@nishika26 nishika26 linked an issue Mar 16, 2026 that may be closed by this pull request
@nishika26 nishika26 changed the title evals UI: include comments in grouped question CSV evals UI: Include comments in grouped question CSV Mar 16, 2026
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: 2

🤖 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/evaluations/`[id]/page.tsx:
- Line 240: The CSV export currently writes raw comment text via the expression
score?.comment inside the row.push(...) call, which allows CSV/formula injection
if a comment begins with =, +, -, or @; sanitize comments before CSVizing by
first escaping internal quotes/newlines as already done, then detect leading
characters (=, +, -, @) and prefix the cell content with a safe neutral
character (e.g. a single quote or a space) to neutralize spreadsheet formula
evaluation; apply this same sanitization wherever score?.comment is exported
(including the other occurrence with row.push(...)). Ensure you still wrap
fields in quotes after this sanitization.
- Line 215: The header concatenation injects raw score `name` values into
`csvContent`, which breaks CSV structure when names contain commas, quotes, or
newlines; sanitize `name` before interpolation by creating/using a small helper
(e.g., escapeCsv) that replaces internal double quotes with two double quotes
and wraps the field in double quotes (to cover commas/newlines) and then use
that sanitized value when building the header (the line where csvContent is
appended with `,${name} (${i}),${name} (${i}) - comment`); update any other
places that write `name` into CSV cells to use the same escapeCsv helper.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3c153828-ecc3-4d54-9c51-7c304bc501f5

📥 Commits

Reviewing files that changed from the base of the PR and between 39b6e9c and 53e21d8.

📒 Files selected for processing (1)
  • app/evaluations/[id]/page.tsx

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.

🧹 Nitpick comments (1)
app/evaluations/[id]/page.tsx (1)

238-250: CSV injection prevention is correctly implemented for grouped export comments.

The implementation properly defends against spreadsheet formula injection by prefixing dangerous characters. The quote escaping and column alignment for missing comments are handled correctly.

For consistency, consider applying the same injection prevention to the row export at line 315, which currently lacks this safeguard:

score?.comment ? `"${score.comment.replace(/"/g, '""').replace(/\n/g, ' ')}"` : ''

,

Suggested refactor for row export consistency (line 315)
 ...scoreNames.flatMap(name => {
   const score = item.trace_scores?.find(s => s.name === name);
+  let commentValue = '';
+  if (score?.comment) {
+    let sanitized = score.comment.replace(/"/g, '""').replace(/\n/g, ' ');
+    if (/^[=+\-@]/.test(sanitized)) {
+      sanitized = ' ' + sanitized;
+    }
+    commentValue = `"${sanitized}"`;
+  }
   return [
     score ? score.value : 'N/A',
-    score?.comment ? `"${score.comment.replace(/"/g, '""').replace(/\n/g, ' ')}"` : ''
+    commentValue
   ];
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/evaluations/`[id]/page.tsx around lines 238 - 250, The row export at the
score rendering (`score?.comment ? \`"\${score.comment.replace(/"/g,
'""').replace(/\n/g, ' ')}"\` : ''`) lacks CSV-injection protection; update that
expression to mirror the grouped export logic used in the scoreNames.forEach
block: first escape double-quotes and newlines, then prefix a space if the
sanitized string begins with =, +, -, or @, and finally wrap in quotes (or emit
empty string when missing). Locate the inline ternary that references
score?.comment and replace it with this sanitized flow so both grouped and row
exports use the same CSV-injection-safe routine.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/evaluations/`[id]/page.tsx:
- Around line 238-250: The row export at the score rendering (`score?.comment ?
\`"\${score.comment.replace(/"/g, '""').replace(/\n/g, ' ')}"\` : ''`) lacks
CSV-injection protection; update that expression to mirror the grouped export
logic used in the scoreNames.forEach block: first escape double-quotes and
newlines, then prefix a space if the sanitized string begins with =, +, -, or @,
and finally wrap in quotes (or emit empty string when missing). Locate the
inline ternary that references score?.comment and replace it with this sanitized
flow so both grouped and row exports use the same CSV-injection-safe routine.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dbb51fdf-db60-49e2-a584-3a6f74705bf0

📥 Commits

Reviewing files that changed from the base of the PR and between 53e21d8 and 48beddd.

📒 Files selected for processing (1)
  • app/evaluations/[id]/page.tsx

Copy link
Copy Markdown
Collaborator

@vprashrex vprashrex left a comment

Choose a reason for hiding this comment

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

(Nitpick) can add helper function for escape characters .. since in this file there are alot of place same thing u are repeating, so it would be best for to add the helper function for this

example: name.replace(/"/g, '""').replace(/\n/g, ' ');

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 (1)
app/evaluations/[id]/page.tsx (1)

48-60: ⚠️ Potential issue | 🟡 Minor

Handle carriage returns in CSV escaping.

escapeCSVValue only replaces \n (LF), leaving \r (CR) intact. This can cause issues with Windows-style line endings (\r\n) or standalone carriage returns, potentially breaking CSV structure in some parsers.

Proposed fix
 const escapeCSVValue = (value: string): string => {
-  return value.replace(/"/g, '""').replace(/\n/g, ' ');
+  return value.replace(/"/g, '""').replace(/[\r\n]+/g, ' ');
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/evaluations/`[id]/page.tsx around lines 48 - 60, escapeCSVValue currently
only replaces LF (\n) and misses CR (\r), so update escapeCSVValue to normalize
all line endings by replacing CRLF, CR, or LF with a single space (e.g. use
value.replace(/\r\n|\r|\n/g, ' ')). Keep sanitizeCSVCell behavior the same (it
should call the updated escapeCSVValue and then apply the
preventFormulaInjection check on the returned sanitized string before wrapping
it in quotes), referencing the escapeCSVValue and sanitizeCSVCell functions.
🧹 Nitpick comments (1)
app/evaluations/[id]/page.tsx (1)

251-256: Consider escaping score values for robustness.

Score values are pushed without CSV escaping. While numeric values and typical categorical strings (e.g., "PASS", "FAIL") are safe, custom categorical values containing commas or quotes would break CSV structure.

Proposed fix
 // Scores with comments
 scoreNames.forEach(name => {
   const score = group.scores[i]?.find(s => s.name === name);
-  row.push(score ? String(score.value) : '');
+  row.push(score ? sanitizeCSVCell(String(score.value)) : '');
   row.push(score?.comment ? sanitizeCSVCell(score.comment, true) : '');
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/evaluations/`[id]/page.tsx around lines 251 - 256, The CSV export
currently pushes raw score values into row (inside the scoreNames.forEach loop),
which can break CSV when values contain commas/quotes; update the loop that
iterates scoreNames (and accesses group.scores[i]?.find) to run each score.value
through the existing sanitizeCSVCell utility (same way comments are sanitized)
before pushing, e.g. replace the raw String(score.value) push with a sanitized
version via sanitizeCSVCell(score.value, true) while keeping the conditional
empty-string behavior when score is missing.
🤖 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/evaluations/`[id]/page.tsx:
- Around line 48-60: escapeCSVValue currently only replaces LF (\n) and misses
CR (\r), so update escapeCSVValue to normalize all line endings by replacing
CRLF, CR, or LF with a single space (e.g. use value.replace(/\r\n|\r|\n/g, '
')). Keep sanitizeCSVCell behavior the same (it should call the updated
escapeCSVValue and then apply the preventFormulaInjection check on the returned
sanitized string before wrapping it in quotes), referencing the escapeCSVValue
and sanitizeCSVCell functions.

---

Nitpick comments:
In `@app/evaluations/`[id]/page.tsx:
- Around line 251-256: The CSV export currently pushes raw score values into row
(inside the scoreNames.forEach loop), which can break CSV when values contain
commas/quotes; update the loop that iterates scoreNames (and accesses
group.scores[i]?.find) to run each score.value through the existing
sanitizeCSVCell utility (same way comments are sanitized) before pushing, e.g.
replace the raw String(score.value) push with a sanitized version via
sanitizeCSVCell(score.value, true) while keeping the conditional empty-string
behavior when score is missing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c5dbbd18-9a4b-453e-a3b9-194624847e07

📥 Commits

Reviewing files that changed from the base of the PR and between 48beddd and d423b4a.

📒 Files selected for processing (1)
  • app/evaluations/[id]/page.tsx

@nishika26 nishika26 merged commit 1b29e4b into main Mar 16, 2026
1 check passed
@Ayush8923 Ayush8923 deleted the enhancement/eval_grouped_comment branch March 20, 2026 11:35
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.

Evaluation: Include comments in traces

2 participants