@@ -68,14 +68,20 @@ function addSpan(map, file, start, end) {
6868 map . set ( clean , list ) ;
6969}
7070
71+ function finiteNumber ( value ) {
72+ if ( value === null || value === undefined || value === '' ) return null ;
73+ const numeric = Number ( value ) ;
74+ return Number . isFinite ( numeric ) ? numeric : null ;
75+ }
76+
7177function estimateTokensFromBytes ( bytes ) {
7278 if ( ! Number . isFinite ( bytes ) ) return null ;
7379 return Math . ceil ( bytes / 4 ) ;
7480}
7581
7682function measuredNumber ( value , unit , source , unavailableReason = 'not captured in source artifact' ) {
77- const numeric = Number ( value ) ;
78- if ( Number . isFinite ( numeric ) ) return { value : numeric , unit, source } ;
83+ const numeric = finiteNumber ( value ) ;
84+ if ( numeric !== null ) return { value : numeric , unit, source } ;
7985 return { value : null , unit, source, unavailableReason } ;
8086}
8187
@@ -99,20 +105,20 @@ function buildTimeMetrics(readiness, evaluator, rowWallDurationMs, evaluatorSkip
99105
100106function buildTokenMetrics ( selection , prediction ) {
101107 const candidateMetrics = selection . candidateMetrics || selection . readiness ?. candidateMetrics || { } ;
102- const candidateBytes = Number ( candidateMetrics . bytes ) ;
103- const candidateEstimatedTokens = Number ( candidateMetrics . estimatedTokens ) ;
108+ const candidateBytes = finiteNumber ( candidateMetrics . bytes ) ;
109+ const candidateEstimatedTokens = finiteNumber ( candidateMetrics . estimatedTokens ) ;
104110 const predictionBytes = byteCount ( JSON . stringify ( prediction || { } ) ) ;
105111 const selectorUsage = selection . selectorUsage || { } ;
106112 return {
107113 estimator : 'ceil(utf8_bytes/4); cost estimate only, not provider billing telemetry' ,
108114 candidatePack : {
109- candidateCount : Number ( selection . readiness ?. candidateCount ?? selection . candidateCount ?? candidateMetrics . candidateCount ?? 0 ) ,
110- fileCount : Number . isFinite ( Number ( candidateMetrics . fileCount ) ) ? Number ( candidateMetrics . fileCount ) : null ,
111- spanCount : Number . isFinite ( Number ( candidateMetrics . spanCount ) ) ? Number ( candidateMetrics . spanCount ) : null ,
112- bytes : Number . isFinite ( candidateBytes )
115+ candidateCount : finiteNumber ( selection . readiness ?. candidateCount ?? selection . candidateCount ?? candidateMetrics . candidateCount ) ?? 0 ,
116+ fileCount : finiteNumber ( candidateMetrics . fileCount ) ,
117+ spanCount : finiteNumber ( candidateMetrics . spanCount ) ,
118+ bytes : candidateBytes !== null
113119 ? measuredNumber ( candidateBytes , 'bytes' , candidateMetrics . source || 'candidate pack artifact' )
114120 : measuredNumber ( null , 'bytes' , candidateMetrics . source || 'candidate pack artifact' , candidateMetrics . unavailableReason || 'candidate pack bytes were not emitted for this lane' ) ,
115- estimatedTokens : Number . isFinite ( candidateEstimatedTokens )
121+ estimatedTokens : candidateEstimatedTokens !== null
116122 ? measuredNumber ( candidateEstimatedTokens , 'tokens' , candidateMetrics . source || 'candidate pack artifact' )
117123 : measuredNumber ( null , 'tokens' , candidateMetrics . source || 'candidate pack artifact' , candidateMetrics . unavailableReason || 'candidate pack token estimate was not emitted for this lane' ) ,
118124 } ,
@@ -217,7 +223,7 @@ for (const selection of laneSelections) {
217223 setupStatus : readiness . setupStatus || selection . setupStatus || 'unknown' ,
218224 indexStatus : readiness . indexStatus || selection . indexStatus || 'unknown' ,
219225 toolCallable : Boolean ( readiness . toolCallable ?? selection . toolCallable ) ,
220- candidateCount : Number ( readiness . candidateCount ?? selection . candidateCount ?? 0 ) ,
226+ candidateCount : finiteNumber ( readiness . candidateCount ?? selection . candidateCount ) ?? 0 ,
221227 setupIndex : readiness . setupIndex || selection . setupIndex || null ,
222228 nonEmptyPrediction,
223229 predFiles : predFiles . length ,
0 commit comments