11import { useEffect , useMemo , useRef , useState } from 'react' ;
2- import type { RerankerTrainMetricEvent } from '@/types/generated' ;
32
43type ProjectionPoint = {
54 ts : string ;
@@ -10,24 +9,39 @@ type ProjectionPoint = {
109 dy ?: number ;
1110} ;
1211
13- function parseProjectionPoints ( events : RerankerTrainMetricEvent [ ] ) : ProjectionPoint [ ] {
12+ type MetricEventLike = {
13+ ts : string ;
14+ step ?: number | null ;
15+ proj_x ?: number | null ;
16+ proj_y ?: number | null ;
17+ proj_dx ?: number | null ;
18+ proj_dy ?: number | null ;
19+ // Back-compat: some older emitters stuffed telemetry into metrics.
20+ metrics ?: Record < string , unknown > | null ;
21+ } ;
22+
23+ function parseProjectionPoints ( events : MetricEventLike [ ] ) : ProjectionPoint [ ] {
1424 const points : ProjectionPoint [ ] = [ ] ;
25+ let prev : ProjectionPoint | null = null ;
1526 for ( const ev of events ) {
16- const m = ev . metrics as Record < string , unknown > | null | undefined ;
17- const x = m ?. proj_x ;
18- const y = m ?. proj_y ;
27+ const m = ev . metrics ;
28+ const x = typeof ev . proj_x === 'number' ? ev . proj_x : m ?. proj_x ;
29+ const y = typeof ev . proj_y === 'number' ? ev . proj_y : m ?. proj_y ;
1930 if ( typeof x !== 'number' || typeof y !== 'number' ) continue ;
2031
21- const dx = m ?. proj_dx ;
22- const dy = m ?. proj_dy ;
32+ const dx = typeof ev . proj_dx === 'number' ? ev . proj_dx : m ?. proj_dx ;
33+ const dy = typeof ev . proj_dy === 'number' ? ev . proj_dy : m ?. proj_dy ;
34+ const computedDx = prev ? x - prev . x : undefined ;
35+ const computedDy = prev ? y - prev . y : undefined ;
2336 points . push ( {
2437 ts : String ( ev . ts ) ,
2538 step : ev . step == null ? undefined : Number ( ev . step ) ,
2639 x,
2740 y,
28- dx : typeof dx === 'number' ? dx : undefined ,
29- dy : typeof dy === 'number' ? dy : undefined ,
41+ dx : typeof dx === 'number' ? dx : computedDx ,
42+ dy : typeof dy === 'number' ? dy : computedDy ,
3043 } ) ;
44+ prev = points [ points . length - 1 ] ;
3145 }
3246 return points ;
3347}
@@ -36,7 +50,7 @@ function clamp(v: number, lo: number, hi: number): number {
3650 return Math . max ( lo , Math . min ( hi , v ) ) ;
3751}
3852
39- export function GradientDescentViz ( { events } : { events : RerankerTrainMetricEvent [ ] } ) {
53+ export function GradientDescentViz ( { events } : { events : MetricEventLike [ ] } ) {
4054 const canvasRef = useRef < HTMLCanvasElement | null > ( null ) ;
4155 const points = useMemo ( ( ) => parseProjectionPoints ( events ) , [ events ] ) ;
4256
@@ -245,4 +259,3 @@ export function GradientDescentViz({ events }: { events: RerankerTrainMetricEven
245259 </ div >
246260 ) ;
247261}
248-
0 commit comments