From f5a6a6c78ca0f223b935d578d697a1f91305a3bd Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 9 Jul 2026 08:07:52 +0000 Subject: [PATCH 1/2] feat(web): recent question hubs, benchmark compare suggestions, hub date filters, catalog links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Track question hubs in Recent views menu alongside runs and benchmarks - Show suggested benchmark comparisons on benchmark detail pages - Add created-at date range filters to the question hub - Link model×preset catalog rows to filtered benchmarks as well as runs Co-authored-by: Eamon Boyle --- apps/web/app/benchmarks/[id]/page.tsx | 38 ++++++++++++++++- apps/web/app/catalog/page.tsx | 56 +++++++++++++++++-------- apps/web/app/questions/view/page.tsx | 29 +++++++++++++ apps/web/components/RecentViewsMenu.tsx | 6 +-- apps/web/lib/recentViews.test.ts | 14 +++++++ apps/web/lib/recentViews.ts | 6 ++- 6 files changed, 126 insertions(+), 23 deletions(-) diff --git a/apps/web/app/benchmarks/[id]/page.tsx b/apps/web/app/benchmarks/[id]/page.tsx index 0906521..30c686e 100644 --- a/apps/web/app/benchmarks/[id]/page.tsx +++ b/apps/web/app/benchmarks/[id]/page.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; import { notFound } from "next/navigation"; import { loadBenchmarkById, + loadBenchmarkArtifacts, loadBenchmarkPairsById, loadAnalysisIndex, } from "../../../lib/data"; @@ -38,6 +39,7 @@ import { import { DownloadArtifactLink } from "../../../components/DownloadArtifactLink"; import { CopyPageLink } from "../../../components/CopyPageLink"; import { RecentViewsTracker } from "../../../components/RecentViewsTracker"; +import { buildBenchmarkCompareSuggestions } from "../../../lib/benchmarkCompareSuggestions"; export async function generateMetadata({ params, @@ -58,8 +60,9 @@ export default async function BenchmarkDetailPage({ params: Promise<{ id: string }>; }) { const { id } = await params; - const [benchmark, index] = await Promise.all([ + const [benchmark, allBenchmarks, index] = await Promise.all([ loadBenchmarkById(id), + loadBenchmarkArtifacts(), loadAnalysisIndex(), ]); @@ -114,6 +117,10 @@ export default async function BenchmarkDetailPage({ const summaryDisplay = extractBenchmarkSummaryDisplay(benchmark); const claimCentroidDisplay = extractClaimCentroidDisplay(benchmark); const benchmarkTitle = `${benchmark.question.slice(0, 80)}${benchmark.question.length > 80 ? "…" : ""}`; + const compareSuggestions = buildBenchmarkCompareSuggestions( + allBenchmarks, + { left: benchmark.id }, + ); return (
@@ -213,6 +220,35 @@ export default async function BenchmarkDetailPage({ ) : null} + {compareSuggestions.length > 0 ? ( +
+

Suggested comparisons

+

+ Pair this benchmark with others on the same question or + model — one click to open the compare view. +

+
    + {compareSuggestions.map((suggestion) => ( +
  • + + Compare with {suggestion.id.slice(-16)} + + + {suggestion.reason} · {suggestion.model} ·{" "} + {suggestion.pipelinePreset} ·{" "} + {new Date( + suggestion.createdAt, + ).toLocaleString()} + +
  • + ))} +
+
+ ) : null} + {summaryDisplay.hasAny ? (

diff --git a/apps/web/app/catalog/page.tsx b/apps/web/app/catalog/page.tsx index 868cb31..cd5d13e 100644 --- a/apps/web/app/catalog/page.tsx +++ b/apps/web/app/catalog/page.tsx @@ -377,14 +377,25 @@ export default async function CatalogPage({ preset: string; }; return ( - - Filter runs - + + + Runs + + {" · "} + + Benchmarks + + ); }, }, @@ -403,15 +414,26 @@ export default async function CatalogPage({ preset: string; }; return ( - - View runs - + <> + + View runs + + + Benchmarks + + ); }} /> diff --git a/apps/web/app/questions/view/page.tsx b/apps/web/app/questions/view/page.tsx index 343efb7..1b16dd6 100644 --- a/apps/web/app/questions/view/page.tsx +++ b/apps/web/app/questions/view/page.tsx @@ -32,6 +32,7 @@ import { summarizeQuestionHubBenchmarkMetrics, summarizeQuestionHubMetrics, } from "../../../lib/questionHubMetrics"; +import { RecentViewsTracker } from "../../../components/RecentViewsTracker"; export const metadata: Metadata = { title: "Question hub", @@ -42,6 +43,8 @@ type QuestionViewSearchParams = { model?: string; preset?: string; fast?: string; + from?: string; + to?: string; }; export default async function QuestionHubPage({ @@ -78,6 +81,8 @@ export default async function QuestionHubPage({ model: params.model, preset: params.preset, fast: params.fast, + from: params.from, + to: params.to, }; const runs = filterRunArtifacts(allRuns, filterParams); const benchmarks = filterBenchmarkArtifacts(allBenchmarks, filterParams); @@ -129,8 +134,16 @@ export default async function QuestionHubPage({ const benchmarkCompareRight = benchmarks[1]?.id; const questionQuery: QuestionViewSearchParams = { question }; + const questionTitle = `${question.slice(0, 80)}${question.length > 80 ? "…" : ""}`; + return (
+

Question hub

@@ -222,6 +235,20 @@ export default async function QuestionHubPage({ + +