@@ -22,6 +22,12 @@ type RadarAxis = {
2222 label : string
2323 description : string
2424 score : ( model : ModelCatalogEntry ) => number | undefined
25+ capability ?: "reasoning" | "toolCall"
26+ }
27+
28+ type RadarScore = {
29+ value : number
30+ fallback ?: string
2531}
2632
2733type RadarPoint = {
@@ -37,7 +43,7 @@ export function ComparisonRadar(props: ComparisonRadarProps) {
3743 name : model . name ,
3844 labName : model . labName ,
3945 color : radarColors [ index % radarColors . length ] ,
40- scores : axes ( ) . map ( ( axis ) => ( model . catalog ? axis . score ( model . catalog ) : undefined ) ) ,
46+ scores : axes ( ) . map ( ( axis ) => resolveRadarScore ( axis , model . catalog ) ) ,
4147 } ) ) ,
4248 )
4349 const accessibleDescription = createMemo ( ( ) =>
@@ -62,6 +68,9 @@ export function ComparisonRadar(props: ComparisonRadarProps) {
6268 < span >
6369 < strong > { model . name } </ strong >
6470 < Show when = { model . labName } > { ( name ) => < small > { name ( ) } </ small > } </ Show >
71+ < Show when = { model . scores . some ( ( score ) => score . fallback ) } >
72+ < small data-slot = "compare-radar-coverage" > Hollow points use fallbacks · hover for details</ small >
73+ </ Show >
6574 </ span >
6675 </ li >
6776 ) }
@@ -89,10 +98,16 @@ export function ComparisonRadar(props: ComparisonRadarProps) {
8998 < polygon data-slot = "compare-radar-area" points = { radarSeriesPolygon ( model . scores ) } />
9099 < For each = { model . scores } >
91100 { ( score , index ) => {
92- const point = ( ) => radarPoint ( index ( ) , axes ( ) . length , score ?? 0 )
101+ const point = ( ) => radarPoint ( index ( ) , axes ( ) . length , score . value )
93102 return (
94103 < >
95- < circle data-slot = "compare-radar-point" cx = { point ( ) . x } cy = { point ( ) . y } r = "0.95" />
104+ < circle
105+ data-slot = "compare-radar-point"
106+ data-fallback = { score . fallback ? "true" : undefined }
107+ cx = { point ( ) . x }
108+ cy = { point ( ) . y }
109+ r = "0.95"
110+ />
96111 < circle
97112 data-slot = "compare-radar-point-hit"
98113 cx = { point ( ) . x }
@@ -138,6 +153,13 @@ export function ComparisonRadar(props: ComparisonRadarProps) {
138153 >
139154 < strong > { axes ( ) [ activeAxis ( ) ?? 0 ] ?. label } </ strong >
140155 < p > { axes ( ) [ activeAxis ( ) ?? 0 ] ?. description } </ p >
156+ < For each = { series ( ) } >
157+ { ( model ) => (
158+ < p >
159+ { model . name } : { formatRadarScore ( model . scores [ activeAxis ( ) ?? 0 ] ) }
160+ </ p >
161+ ) }
162+ </ For >
141163 </ div >
142164 </ Show >
143165 </ div >
@@ -166,7 +188,7 @@ export function ComparisonRadar(props: ComparisonRadarProps) {
166188 )
167189}
168190
169- function buildRadarAxes ( catalogModels : readonly ModelCatalogEntry [ ] ) : RadarAxis [ ] {
191+ export function buildRadarAxes ( catalogModels : readonly ModelCatalogEntry [ ] ) : RadarAxis [ ] {
170192 const benchmarks = benchmarkScoreGroups ( catalogModels )
171193 const toolUseBenchmarks = benchmarkScoreGroups ( catalogModels , true )
172194 const costs = catalogModels . flatMap ( ( model ) => {
@@ -180,9 +202,10 @@ function buildRadarAxes(catalogModels: readonly ModelCatalogEntry[]): RadarAxis[
180202 return [
181203 {
182204 label : "Reasoning" ,
183- description : "Ability to solve complex, multi-step problems. Based on reasoning benchmarks when available." ,
184- score : ( model ) =>
185- benchmarkPercentile ( model , benchmarks , reasoningBenchmarkPattern ) ?? ( model . reasoning ? 100 : 0 ) ,
205+ capability : "reasoning" ,
206+ description :
207+ "Ability to solve complex, multi-step problems. Benchmarks take priority; reasoning support defaults to 50/100." ,
208+ score : ( model ) => benchmarkPercentile ( model , benchmarks , reasoningBenchmarkPattern ) ,
186209 } ,
187210 {
188211 label : "Coding" ,
@@ -218,7 +241,8 @@ function buildRadarAxes(catalogModels: readonly ModelCatalogEntry[]): RadarAxis[
218241 } ,
219242 {
220243 label : "Tool use" ,
221- description : "Performance on agent benchmarks including Terminal-Bench, Tau3, and Claw-Eval." ,
244+ capability : "toolCall" ,
245+ description : "Agent benchmark performance. Benchmarks take priority; tool calling support defaults to 50/100." ,
222246 score : ( model ) =>
223247 benchmarkPercentile ( model , toolUseBenchmarks , toolUseBenchmarkPattern , {
224248 aggregate : "average" ,
@@ -324,9 +348,9 @@ function radarPolygonPoints(count: number, score: number) {
324348 . join ( " " )
325349}
326350
327- function radarSeriesPolygon ( scores : ( number | undefined ) [ ] ) {
351+ function radarSeriesPolygon ( scores : RadarScore [ ] ) {
328352 return scores
329- . map ( ( score , index ) => radarPoint ( index , scores . length , score ?? 0 ) )
353+ . map ( ( score , index ) => radarPoint ( index , scores . length , score . value ) )
330354 . map ( ( point ) => `${ point . x } ,${ point . y } ` )
331355 . join ( " " )
332356}
@@ -355,6 +379,17 @@ function roundRadarCoordinate(value: number) {
355379 return Math . round ( value * 1000 ) / 1000
356380}
357381
358- function formatRadarScore ( score : number | undefined ) {
359- return score === undefined ? "No data" : `${ Math . round ( score ) } /100`
382+ function formatRadarScore ( score : RadarScore ) {
383+ return `${ Math . round ( score . value ) } /100${ score . fallback ? ` — ${ score . fallback } ` : "" } `
384+ }
385+
386+ export function resolveRadarScore ( axis : RadarAxis , model : ModelCatalogEntry | null ) : RadarScore {
387+ const score = model ? axis . score ( model ) : undefined
388+ if ( score !== undefined ) return { value : score }
389+ const supported = axis . capability ? model ?. [ axis . capability ] : undefined
390+ if ( supported === undefined ) return { value : 50 , fallback : "No data; neutral placeholder" }
391+ const capability = axis . capability === "toolCall" ? "Tool calling" : "Reasoning"
392+ return supported
393+ ? { value : 50 , fallback : `${ capability } supported; no comparable benchmark` }
394+ : { value : 0 , fallback : `${ capability } not supported` }
360395}
0 commit comments