Skip to content

feat(web_ui): deep link eval result modals and widen the Result column - #2000

Merged
scosman merged 3 commits into
mainfrom
claude/awesome-bohr-bih389
Nov 5, 2026
Merged

scosman merged 3 commits into
mainfrom
claude/awesome-bohr-bih389

Conversation

@scosman

@scosman scosman commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Description
Add a hash-link to trace modal in eval results

Author Review (required)

  • I have done a code review

Architecture Review (select 1)

  • I did architecture review before coding
  • Small change, no architecture review needed
  • Requesting architecture review exception for other reason: NA

Review Requested from Code Reviewer (select 1)

  • Sign off on AI-only review: UI only change
  • Mixed: human review of some areas, AI on others (details below)
  • Full human: human reads everything

Agentic Code Review (must check all before requesting CR)

  • I have run /spec deep cr on this PR or used /spec CRs throughout
  • I have addressed all AI feedback (“deep cr”, CodeRabbit, etc)

What to Review
None, UI only.

UI Review (select all that apply)

  • Agentic UI clickthrough done
  • Requires UI review as part of this review
  • UI review already done by: Steve
  • No UI

Agentic PR Summary

TLDR: A refresh closes the "View Full Trace" and "View reasoning" modals on the eval results page, and a user cannot send a link to them. This PR keeps the open modal in the URL hash, and gives the Result column a fair share of the table width. Targets main.

Before this PR, the trace modal and the reasoning modal on the run_result page did not change the URL. A refresh closed the modal, and a link opened only the page. A long interaction also took almost the full row, so the Result column was about 150px wide and the eval name wrapped one word per line. After this PR, an open trace writes #trace-<eval run id> into the URL, and open reasoning writes #reasoning-<eval run id>. A refresh, a link, or a hash change on the same page opens the same modal. On load, the "Are you sure you want to peek?" warning shows on top of it. The Result column now has 40% of the table width.

Implementation

  • Opening "View Full Trace" writes #trace-<eval run id>, and opening "View reasoning" writes #reasoning-<eval run id>. Both use the SvelteKit replaceState, and closing the modal clears the hash. replaceState adds no history entry, so Back still leaves the page.
  • On load with a hash, the page waits for the results, opens the linked modal, and then opens the peek warning. Modal dialogs stack in the order that they open, so the warning shows on top. "Look Anyways" closes only the warning.
  • The page listens for the browser hashchange event. The event fires for a pasted link, an in-app link, Back, and Forward, and never for the page's own replaceState calls. A link to another row switches the open modal. A link to a missing row closes it. A link that arrives while the peek warning is open waits until the warning closes.
  • On load without a hash, the peek warning opens on mount, as before.
  • The shared component LlmJudgeResult (lib/components/eval_types/llm_judge_result.svelte) gets an optional on_view_reasoning callback. With the callback, the host page shows the reasoning in its own dialog. Without it, the component keeps its own dialog, as before. The only call site is the run_result page, through the eval-type registry. This change is in its own commit, 645629c.
  • The reasoning lookup (reasoning, then chain_of_thought) moves to lib/utils/eval_types/judge_reasoning.ts, so the component and the page read it the same way.
  • dialog_link.ts builds and parses the #trace- and #reasoning- hashes, with unit tests in dialog_link.test.ts.
  • The Result header cell gets w-2/5 when the judge shows one Result column. The older layout with the Input & Output, Thinking, and score columns does not change.
  • run_result.test.ts covers the hash write and clear, a load from each link type, the dialog order, same-page hash changes, and the peek warning wait. The test file now runs the Svelte onMount after mount, because onMount does not run under jsdom. The dialog test stub records the dialog that opened last.

Before you merge

  • This PR now changes a shared component, llm_judge_result.svelte. The repo UI gate reports SHARED_CONTROL_TOUCHED for it, which is expected. Other callers keep the old behavior.
  • A user sees a change of timing. With a hash, the peek warning opens when the results finish loading, not when the page opens. Only the loading spinner shows before that.
  • On load, a hash for a row that is not in the results opens only the peek warning. The hash stays in the URL.
  • A hand-made #reasoning- link on a page for an older judge type (for example G-Eval) opens a "Judge Reasoning" dialog, but those pages have no "View reasoning" button. No normal flow makes such a link.
  • When a run saved a judge trace, the Result column shows a "Judge trace" link in place of "View reasoning". That dialog has no URL hash.
  • "Go Back" on the peek warning calls window.history.back(). In a new tab with no history, the button only closes the warning, and the modal stays open. This behavior existed before this PR, but links make it more frequent.

Checks: uv run ./checks.sh --agent-mode green before the last review fixes. After those fixes, npm run lint, npm run format_check, npm run check, npm run test_run, and npm run build are green. No Python file changed. The optional misspell check did not run, because the tool is not installed in the agent environment. Each round went through a /spec code review by a separate sub-agent. The second review found one moderate issue: the peek warning did not show if the link left the URL before the results loaded. The fix and a test for it are in d63df4f. An agent opened the page in a browser with Playwright and took screenshots. The seeded project has no conversation traces, so the script replaced the results response in the browser with an LLM judge and long conversations.

Docs and skills updated: none needed, no doc or skill names the changed page, the shared component, or their files.

Example links
/specs/<project_id>/<task_id>/<spec_id>/<eval_id>/<eval_config_id>/<run_config_id>/run_result#trace-<eval_run_id>
/specs/<project_id>/<task_id>/<spec_id>/<eval_id>/<eval_config_id>/<run_config_id>/run_result#reasoning-<eval_run_id>

Generated by Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the previous same-page link issue is addressed.

Reviews (2) · Last reviewed commit: "feat(web_ui): follow same-page hash chan..." · Reviewed by Greptile

…e table

Opening "View Full Trace" on the eval run results page now writes
#trace-<eval run id> into the URL with SvelteKit's replaceState, and
closing the modal removes it, so a refresh or a shared link reopens the
same trace. No history entries are added, so Back still leaves the page.

When the page loads with a trace hash, it waits for the results, opens
the linked trace, and then opens the "Are you sure you want to peek?"
warning, so the warning stacks on top of the trace. Without a hash the
warning still opens on mount as before. A hash naming a row that is not
in the results opens only the warning.

The Result column header for single-renderer judges now takes 40% of the
table width, so a long interaction no longer squeezes it to a word per
line.

Adds trace_link.ts (hash build/parse) with unit tests, and page tests
for writing, clearing, and loading the hash and for the dialog order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HdZSuxJDKdgfzLkswZM3RD
@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

Caution

Review failed

The pull request is closed.

Walkthrough

The run-results page now supports hash-linked trace and judge-reasoning dialogs. It opens links for matching results, updates hashes when dialogs open or close, and coordinates linked dialogs with the peek warning. A shared utility selects judge reasoning from intermediate outputs.

Changes

Run-result dialogs

Layer / File(s) Summary
Judge-reasoning extraction and display
app/web_ui/src/lib/utils/eval_types/judge_reasoning.ts, app/web_ui/src/lib/utils/eval_types/judge_reasoning.test.ts, app/web_ui/src/lib/components/eval_types/llm_judge_result.svelte, app/web_ui/src/lib/components/eval_types/llm_judge_result.test.ts
The new judge_reasoning utility selects reasoning first, then chain_of_thought, and returns null when neither value is available. The result component can call an optional callback instead of opening its own reasoning dialog.
Dialog link hash format
app/web_ui/src/routes/(app)/specs/.../run_result/dialog_link.ts, app/web_ui/src/routes/(app)/specs/.../run_result/dialog_link.test.ts
The new helpers encode and parse trace and reasoning links in the URL hash. Tests cover supported dialog types, encoded IDs, and invalid hashes.
Run-results dialog flow
app/web_ui/src/routes/(app)/specs/.../run_result/+page.svelte, app/web_ui/src/routes/(app)/specs/.../run_result/__tests__/dialog_stub.svelte, app/web_ui/src/routes/(app)/specs/.../run_result/run_result.test.ts
The page opens a linked dialog when matching results are available, follows hash changes, and clears matching links when dialogs close. It coordinates linked dialogs with the peek warning. Tests cover the flow, including missing rows and unavailable reasoning.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant URLHash
  participant RunResultsPage
  participant Results
  participant TraceDialog
  participant JudgeReasoningDialog
  URLHash->>RunResultsPage: Provide dialog type and evaluation run ID
  RunResultsPage->>Results: Find the linked evaluation run
  Results->>RunResultsPage: Return the matching run data
  RunResultsPage->>TraceDialog: Open when trace data is available
  RunResultsPage->>JudgeReasoningDialog: Open when reasoning is available
Loading

Possibly related PRs

  • Kiln-AI/Kiln#1959: Adds judge-trace retrieval and web components used by the run-results trace behavior.

Suggested reviewers: sfierro, chiang-daniel

Merge Risk: Minimal · up to d63df

Dialog links and close behavior have no identified issue requiring a fix before merge.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

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

A rabbit follows hashes through the night
To traces tucked away and reasoning bright
One click opens the dialog’s door
One close clears the link once more
The peek warning waits nearby
Then hops along beneath the sky

@github-actions

github-actions Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

📊 Coverage Report

Overall Coverage: 94%

Diff: origin/main...HEAD

No lines with coverage information in this diff.


@scosman scosman changed the title WIP: feat(web_ui): deep link the trace modal and widen the Result column feat(web_ui): deep link the trace modal and widen the Result column Nov 5, 2026

@tawnymanticore tawnymanticore left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

works

scosman and others added 2 commits November 5, 2026 21:08
…own dialog

LlmJudgeResult gains an optional on_view_reasoning callback so a host can
show the judge's reasoning in its own dialog and deep link it. With no
callback, the component keeps its own Judge Reasoning dialog as before.
The only call site is the run_result page, through the eval-type
registry's resultRendererComponent.

The reasoning lookup (the reasoning key, falling back to
chain_of_thought) moves to lib/utils/eval_types/judge_reasoning.ts so the
component and its host read it the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HdZSuxJDKdgfzLkswZM3RD
…easoning

Addresses review feedback on the eval run result page: the trace link in
the URL hash was read only on first load. A hash-only navigation (a
pasted link, an in-app link, Back or Forward) does not remount the page,
so the linked trace never opened.

- The page now listens for the browser's hashchange event, which fires
  for those navigations and never for the page's own replaceState calls.
  A link to another row switches the open dialog. A link to a missing row,
  or to no row dialog, closes it.
- A link followed while the peek warning is still up waits until the
  warning closes, so a dialog never opens on top of it. If the link leaves
  the URL before the results load, the warning still shows.
- The "View reasoning" modal gets the same treatment: opening it writes
  #reasoning-<eval run id>, closing clears it, and loading from that hash
  opens the reasoning with the peek warning on top. The page owns one
  shared Judge Reasoning dialog through LlmJudgeResult's on_view_reasoning
  callback.
- trace_link.ts becomes dialog_link.ts, which parses both #trace- and
  #reasoning- links.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HdZSuxJDKdgfzLkswZM3RD
@scosman scosman changed the title feat(web_ui): deep link the trace modal and widen the Result column feat(web_ui): deep link eval result modals and widen the Result column Nov 5, 2026
@scosman
scosman merged commit 6a04519 into main Nov 5, 2026
16 checks passed
@scosman
scosman deleted the claude/awesome-bohr-bih389 branch November 5, 2026 21:15
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.

2 participants