From ce91c6d77dccc240273c69dcbbaa2649cb52ca5a Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Thu, 13 Aug 2026 22:31:11 -0500 Subject: [PATCH 1/2] Restore AgentX interactivity defaults --- .../calculator/useThroughputData.ts | 13 -- .../components/inference/InferenceContext.tsx | 2 +- .../components/inference/ui/ChartDisplay.tsx | 186 ++---------------- .../components/inference/ui/ScatterGraph.tsx | 6 +- packages/app/src/lib/overview-data.ts | 3 +- 5 files changed, 17 insertions(+), 193 deletions(-) diff --git a/packages/app/src/components/calculator/useThroughputData.ts b/packages/app/src/components/calculator/useThroughputData.ts index fe2c2549..f755937a 100644 --- a/packages/app/src/components/calculator/useThroughputData.ts +++ b/packages/app/src/components/calculator/useThroughputData.ts @@ -24,7 +24,6 @@ import { recoverReciprocalNumerator, sign, } from './interpolation'; -import { restrictAgenticPointsToE2eFrontier } from '@/lib/agentic-frontier'; import type { CostProvider, GPUDataPoint, InterpolatedResult } from './types'; // Re-export pure functions so existing imports from this module keep working. @@ -154,18 +153,6 @@ export function buildGpuGroups( }); } - if (sequence === Sequence.AgenticTraces) { - for (const groupKey of Object.keys(grouped)) { - const restricted = restrictAgenticPointsToE2eFrontier(grouped[groupKey]); - if (restricted.length === 0) { - delete grouped[groupKey]; - delete groupMeta[groupKey]; - } else { - grouped[groupKey] = restricted; - } - } - } - return { grouped, groupMeta, hwConfigMap }; } diff --git a/packages/app/src/components/inference/InferenceContext.tsx b/packages/app/src/components/inference/InferenceContext.tsx index 991c583d..fb10ffa0 100644 --- a/packages/app/src/components/inference/InferenceContext.tsx +++ b/packages/app/src/components/inference/InferenceContext.tsx @@ -619,7 +619,7 @@ export function InferenceProvider({ // — fall through to the default snap below. return; } - handleSetXAxisMode(kind === 'agentic' ? 'e2e-normalized-interactivity' : 'interactivity'); + handleSetXAxisMode('interactivity'); }, [sequenceResolved, effectiveSequence, selectedXAxisMode, handleSetXAxisMode]); // Reconcile selectedE2eXAxisMetric whenever the mode, sequence kind, or diff --git a/packages/app/src/components/inference/ui/ChartDisplay.tsx b/packages/app/src/components/inference/ui/ChartDisplay.tsx index dfc4c9a1..a917076f 100644 --- a/packages/app/src/components/inference/ui/ChartDisplay.tsx +++ b/packages/app/src/components/inference/ui/ChartDisplay.tsx @@ -3,7 +3,7 @@ import { DISPLAY_MODEL_TO_DB } from '@semianalysisai/inferencex-constants'; import { track } from '@/lib/analytics'; import dynamic from 'next/dynamic'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { BarChart3, Check, ChevronDown, Table2 } from 'lucide-react'; +import { BarChart3, Table2 } from 'lucide-react'; import chartDefinitions from '@/components/inference/inference-chart-config.json'; import { useInference } from '@/components/inference/InferenceContext'; @@ -23,14 +23,12 @@ import { } from '@/components/inference/utils/comparisonEntry'; import { dataRunsForDate } from '@/components/inference/utils/runEnumeration'; import { matchesQuickFilters } from '@/components/inference/utils/quickFilters'; -import { canonicalNormalizedFrontierIds } from '@/components/inference/utils/canonicalFrontier'; import { bestSeriesPerSku } from '@/components/inference/utils/best-series-per-sku'; import InferenceTable from '@/components/inference/ui/InferenceTable'; import ScatterGraph from '@/components/inference/ui/ScatterGraph'; import { Card } from '@/components/ui/card'; import { ChartButtons } from '@/components/ui/chart-buttons'; import { type SegmentedToggleOption, SegmentedToggle } from '@/components/ui/segmented-toggle'; -import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { ChartShareActions, MetricAssumptionNotes } from '@/components/ui/chart-display-helpers'; import { UnofficialDomainNotice } from '@/components/ui/unofficial-domain-notice'; @@ -38,7 +36,7 @@ import { metricLabel, metricTitle } from '@/lib/chart-utils'; import { exportToCsv } from '@/lib/csv-export'; import { inferenceChartToCsv } from '@/lib/csv-export-helpers'; import { knownIssueCsvNote, matchKnownConfigIssues } from '@/lib/known-issues'; -import { cn, getDisplayLabel } from '@/lib/utils'; +import { getDisplayLabel } from '@/lib/utils'; import { Skeleton } from '@/components/ui/skeleton'; import { useUnofficialRun } from '@/components/unofficial-run-provider'; import { @@ -51,19 +49,13 @@ import { sequenceKind, } from '@/lib/data-mappings'; import { useComparisonChangelogs } from '@/hooks/api/use-comparison-changelogs'; -import { - derivedModeRoofline, - isAgenticOnlyXAxisMode, - type RooflineDirection, - type XAxisMode, -} from '@/components/inference/hooks/useChartData'; +import { isAgenticOnlyXAxisMode, type XAxisMode } from '@/components/inference/hooks/useChartData'; import { useDerivedAgenticMetrics, type DerivedAgenticMetric, } from '@/hooks/api/use-derived-agentic-metrics'; import { getHardwareConfig, hardwareKeyMatchesAnyBase } from '@/lib/constants'; import { isPersistedBenchmarkId } from '@/lib/benchmark-id'; -import type { Locale } from '@/lib/i18n'; import { useLocale } from '@/lib/use-locale'; import ChartControls from './ChartControls'; @@ -98,8 +90,6 @@ const STRINGS = { vsTtft: (word: string) => `vs. ${word} Time To First Token`, vsE2eLatency: (pctl?: string) => pctl ? `vs. ${pctl} End-to-end Latency` : 'vs. End-to-end Latency', - advancedXAxis: 'Advanced', - advancedXAxisWith: (label: string) => `Advanced: ${label}`, }, zh: { inferencePerformance: '推理性能', @@ -115,8 +105,6 @@ const STRINGS = { viewMode: '视图模式', vsTtft: (word: string) => `vs. ${word === 'Median' ? '中位' : word} 首 token 延迟(TTFT)`, vsE2eLatency: (pctl?: string) => (pctl ? `vs. ${pctl} 端到端延迟` : 'vs. 端到端延迟'), - advancedXAxis: '高级', - advancedXAxisWith: (label: string) => `高级:${label}`, }, } as const; @@ -152,103 +140,6 @@ const X_AXIS_MODE_BUTTONS: { value: XAxisMode; label: string; labelZh: string }[ { value: 'ttft', label: 'TTFT', labelZh: 'TTFT' }, ]; -/** - * X-axis modes tucked behind the "Advanced" menu on agentic charts. - * - * AgentX headlines E2E Normalized Interactivity, so the three per-request - * latency views are secondary there and would otherwise crowd the strip. They - * stay flat top-level tabs on every other scenario: E2E Normalized - * Interactivity is agentic-only, so collapsing them elsewhere would leave the - * strip with nothing in it. - */ -const ADVANCED_X_AXIS_MODES: readonly XAxisMode[] = ['interactivity', 'e2e', 'ttft']; - -const isAdvancedXAxisMode = (mode: XAxisMode): boolean => ADVANCED_X_AXIS_MODES.includes(mode); - -/** - * "Advanced" x-axis picker for agentic charts. Styled to sit in the tab strip - * beside the real tabs, but it is a menu button rather than a `TabsTrigger`: - * Radix would otherwise treat it as a fifth tab stop and steal arrow-key - * navigation from the modes inside it. The active mode's label is shown on the - * trigger so the strip still says which metric the x-axis is plotting. - */ -function AdvancedXAxisMenu({ - selected, - onSelect, - locale, - labels, -}: { - selected: XAxisMode; - onSelect: (mode: XAxisMode) => void; - locale: Locale; - labels: { advanced: string; advancedWith: (label: string) => string }; -}) { - const [open, setOpen] = useState(false); - const active = isAdvancedXAxisMode(selected); - const options = X_AXIS_MODE_BUTTONS.filter(({ value }) => isAdvancedXAxisMode(value)); - const activeLabel = options.find(({ value }) => value === selected); - const activeText = activeLabel && (locale === 'zh' ? activeLabel.labelZh : activeLabel.label); - - return ( - - - {active && activeText ? labels.advancedWith(activeText) : labels.advanced} - - - -
    - {options.map(({ value, label, labelZh }) => { - const isActive = value === selected; - return ( -
  • - -
  • - ); - })} -
-
-
- ); -} - /** Presentation and data plumbing for trace-derived agentic x-axis modes. */ interface DerivedXModeSpec { xLabel: (percentileLabel: string) => string; @@ -478,9 +369,6 @@ export default function ChartDisplay() { { isAgentic, selectedPercentile, - // Unofficial rows lack persisted request traces, so they cannot be - // admitted to the normalized north-star frontier on any agentic axis. - restrictToNormalizedFrontier: isAgentic, }, ); @@ -719,9 +607,7 @@ export default function ChartDisplay() { const isAgenticSequence = sequenceKind(selectedSequence) === 'agentic'; const useDerivedXAxis = isAgenticSequence && isAgenticOnlyXAxisMode(selectedXAxisMode); const derivedTargetIds = useMemo(() => { - // Every agentic x-axis is classified by the normalized north-star - // frontier, so all modes need the persisted trace-derived metric. - if (!isAgenticSequence) return [] as number[]; + if (!useDerivedXAxis) return [] as number[]; const ids = new Set(); for (const graph of visibleGraphs) { const points = [...graph.data, ...(graph.clippedData ?? []).map((entry) => entry.point)]; @@ -732,11 +618,11 @@ export default function ChartDisplay() { } } return [...ids]; - }, [isAgenticSequence, visibleGraphs]); + }, [useDerivedXAxis, visibleGraphs]); const derivedQuery = useDerivedAgenticMetrics(derivedTargetIds, isAgenticSequence); const derivedMetrics = derivedQuery.data; - const isCanonicalFrontierLoading = - isAgenticSequence && + const isDerivedXAxisLoading = + useDerivedXAxis && derivedTargetIds.length > 0 && (derivedQuery.isPending || derivedQuery.isFetching) && !derivedMetrics; @@ -746,40 +632,18 @@ export default function ChartDisplay() { if (!isAgenticSequence) return visibleGraphs; if (!derivedMetrics) { // Legacy AgentX axes can still render transient/non-persisted rows, which - // have no ids to request. Persisted rows remain gated on their derived - // metrics so every displayed frontier can enforce canonical eligibility. + // have no ids to request. if (!derivedSpec && derivedTargetIds.length === 0) return visibleGraphs; return visibleGraphs.map((graph) => ({ ...graph, data: [], clippedData: [] })); } return visibleGraphs.map((graph) => { - const rooflineKey = `${selectedYAxisMetric}_roofline` as keyof typeof graph.chartDefinition; - // The normalized axis is higher-is-better. Compute its true Pareto - // direction once, regardless of which x-axis is currently displayed. - const configuredCorner = graph.chartDefinition[rooflineKey] as RooflineDirection | undefined; - const canonicalCorner = - graph.chartDefinition.chartType === 'e2e' - ? derivedModeRoofline(configuredCorner, true) - : configuredCorner; - const allPoints = [...graph.data, ...(graph.clippedData ?? []).map((entry) => entry.point)]; - const canonicalIds = canonicalNormalizedFrontierIds( - allPoints, - derivedMetrics, - selectedPercentile, - canonicalCorner, - ); - const preparePoint = (point: InferenceData): InferenceData | null => { const pointId = isPersistedBenchmarkId(point.id) ? point.id : null; - const stamped = { - ...point, - isOnNormalizedInteractivityFrontier: - canonicalIds === null ? undefined : pointId !== null && canonicalIds.has(pointId), - }; - if (!derivedSpec) return stamped; + if (!derivedSpec) return point; if (pointId === null) return null; const raw = derivedSpec.value(derivedMetrics[pointId], selectedPercentile); if (raw === null || raw === undefined || !Number.isFinite(raw)) return null; - return { ...stamped, x: derivedSpec.toX(raw) }; + return { ...point, x: derivedSpec.toX(raw) }; }; const data = graph.data @@ -800,7 +664,6 @@ export default function ChartDisplay() { ...graph.chartDefinition, x_label: xLabelFn(selectedPercentile.toUpperCase()), y_latency_limit: undefined, - ...(canonicalCorner ? { [rooflineKey]: canonicalCorner } : {}), }; return { ...graph, chartDefinition, data, clippedData }; }); @@ -810,13 +673,12 @@ export default function ChartDisplay() { derivedTargetIds.length, visibleGraphs, derivedMetrics, - selectedYAxisMetric, selectedPercentile, locale, ]); const displayGraphs = - isFirstLoad || isCanonicalFrontierLoading + isFirstLoad || isDerivedXAxisLoading ? [ @@ -1151,16 +1013,7 @@ export default function ChartDisplay() { )} - {/* - Manual activation: with Radix's default automatic mode, merely focusing - a trigger fires onValueChange. On agentic the strip renders a single tab - while the selected mode may live in the Advanced menu, so tabbing to - that lone trigger would silently snap the x-axis back to E2E Normalized - Interactivity. Manual activation also suits a control whose every change - redraws the chart — arrow keys move focus, Enter/Space commits. - */} { setSelectedXAxisMode(value as XAxisMode); @@ -1173,11 +1026,9 @@ export default function ChartDisplay() { className="flex-wrap justify-center gap-x-1 gap-y-1.5 sm:gap-x-1.5" > {X_AXIS_MODE_BUTTONS.filter(({ value }) => { - // Before mount, render the flat strip so SSR and first client render match. + // Before mount, render all buttons so SSR and first client render match. if (!mounted) return true; - if (isAgenticOnlyXAxisMode(value)) return isAgenticSequence; - // On agentic these three move into the Advanced menu below. - return !(isAgenticSequence && isAdvancedXAxisMode(value)); + return !isAgenticOnlyXAxisMode(value) || isAgenticSequence; }).map(({ value, label, labelZh }) => ( ))} - {mounted && isAgenticSequence && ( - { - setSelectedXAxisMode(mode); - track('latency_x_axis_mode_selected', { mode }); - }} - locale={locale} - labels={{ advanced: t.advancedXAxis, advancedWith: t.advancedXAxisWith }} - /> - )}
{displayGraphs}
diff --git a/packages/app/src/components/inference/ui/ScatterGraph.tsx b/packages/app/src/components/inference/ui/ScatterGraph.tsx index 063d007c..2baf295a 100644 --- a/packages/app/src/components/inference/ui/ScatterGraph.tsx +++ b/packages/app/src/components/inference/ui/ScatterGraph.tsx @@ -417,8 +417,7 @@ const SCATTER_STRINGS = { logScale: 'Log Scale', optimalOnly: 'Optimal Only', bestPerSku: 'Best per SKU', - optimalInfo: - 'On agentic, optimal points must be Pareto-optimal on the selected x-axis and also belong to the E2E Normalized Interactivity frontier.', + optimalInfo: 'Optimal points form the Pareto frontier for the selected axes.', labels: 'Labels', highContrast: 'High Contrast', parallelismLabels: 'Parallelism Labels', @@ -433,8 +432,7 @@ const SCATTER_STRINGS = { logScale: '对数缩放', optimalOnly: '仅最优', bestPerSku: '每个 SKU 仅显示最佳配置', - optimalInfo: - '在智能体场景中,最优点既必须在当前横轴上满足 Pareto 最优,也必须属于端到端归一化交互性的 Pareto 前沿。', + optimalInfo: '最优点构成当前所选坐标轴的 Pareto 前沿。', labels: '标签', highContrast: '高对比度', parallelismLabels: '并行配置标签', diff --git a/packages/app/src/lib/overview-data.ts b/packages/app/src/lib/overview-data.ts index 1c9c8df1..d77912fd 100644 --- a/packages/app/src/lib/overview-data.ts +++ b/packages/app/src/lib/overview-data.ts @@ -1,6 +1,5 @@ import { resolveFrameworkPartLabel } from '@semianalysisai/inferencex-constants'; -import { restrictAgenticPointsToE2eFrontier } from './agentic-frontier'; import type { BenchmarkRow } from './api'; import { rowToAggDataEntry } from './benchmark-transform'; import { buildAvailabilityHwKey } from './chart-utils'; @@ -639,7 +638,7 @@ function buildAgenticTierReads(rows: readonly BenchmarkRow[]): TcoTierRead[] { }, ]; }); - return computeTierReads(restrictAgenticPointsToE2eFrontier(points), OVERVIEW_TIERS); + return computeTierReads(points, OVERVIEW_TIERS); } /** Single-turn 8K/1K: frontier points at the chart's stored interactivity, From 63bc225a25a038805edbddc7cdada538828b05b7 Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Thu, 13 Aug 2026 22:35:22 -0500 Subject: [PATCH 2/2] Fix normalized interactivity frontier direction --- .../src/components/inference/ui/ChartDisplay.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/app/src/components/inference/ui/ChartDisplay.tsx b/packages/app/src/components/inference/ui/ChartDisplay.tsx index a917076f..9face0fa 100644 --- a/packages/app/src/components/inference/ui/ChartDisplay.tsx +++ b/packages/app/src/components/inference/ui/ChartDisplay.tsx @@ -49,7 +49,12 @@ import { sequenceKind, } from '@/lib/data-mappings'; import { useComparisonChangelogs } from '@/hooks/api/use-comparison-changelogs'; -import { isAgenticOnlyXAxisMode, type XAxisMode } from '@/components/inference/hooks/useChartData'; +import { + derivedModeRoofline, + isAgenticOnlyXAxisMode, + type RooflineDirection, + type XAxisMode, +} from '@/components/inference/hooks/useChartData'; import { useDerivedAgenticMetrics, type DerivedAgenticMetric, @@ -637,6 +642,13 @@ export default function ChartDisplay() { return visibleGraphs.map((graph) => ({ ...graph, data: [], clippedData: [] })); } return visibleGraphs.map((graph) => { + const rooflineKey = `${selectedYAxisMetric}_roofline` as keyof typeof graph.chartDefinition; + const configuredCorner = graph.chartDefinition[rooflineKey] as RooflineDirection | undefined; + const derivedCorner = + graph.chartDefinition.chartType === 'e2e' + ? derivedModeRoofline(configuredCorner, true) + : configuredCorner; + const preparePoint = (point: InferenceData): InferenceData | null => { const pointId = isPersistedBenchmarkId(point.id) ? point.id : null; if (!derivedSpec) return point; @@ -664,6 +676,7 @@ export default function ChartDisplay() { ...graph.chartDefinition, x_label: xLabelFn(selectedPercentile.toUpperCase()), y_latency_limit: undefined, + ...(derivedCorner ? { [rooflineKey]: derivedCorner } : {}), }; return { ...graph, chartDefinition, data, clippedData }; }); @@ -673,6 +686,7 @@ export default function ChartDisplay() { derivedTargetIds.length, visibleGraphs, derivedMetrics, + selectedYAxisMetric, selectedPercentile, locale, ]);