11import { createResource , createMemo , Show , For } from "solid-js" ;
22import { api , type RunDetail as RunDetailT } from "../api" ;
33import { esc , fmtTime , fmtSec , fmtNum , evalBadge } from "../lib/format" ;
4- import { computeSessionMetrics , generateInsights } from "../lib/metrics" ;
4+ import { computeSessionMetrics , generateInsights , METRIC_DEFINITIONS } from "../lib/metrics" ;
5+ import { EVAL_STRUCTURE , getCheckDesc } from "../lib/testcase-info" ;
56import { Evidence } from "./Evidence" ;
67
78export function RunDetail ( {
@@ -60,6 +61,9 @@ export function RunDetail({
6061 < li >
6162 < span class = { "badge badge-sm mr-2 " + cls } > ✓</ span >
6263 { esc ( x ) }
64+ { getCheckDesc ( x ) && (
65+ < span class = "text-xs opacity-50 ml-2" > { getCheckDesc ( x ) } </ span >
66+ ) }
6367 </ li >
6468 ) }
6569 </ For >
@@ -114,43 +118,58 @@ export function RunDetail({
114118 < span class = "badge badge-ghost" > { esc ( d ( ) . closedNote ) } </ span >
115119 ) }
116120 </ div >
121+ < Show when = { score ( ) ?. status === "incomplete" } >
122+ < div class = "alert alert-warning my-2" >
123+ < span class = "text-sm" >
124+ 评测不完整 — agent { run ( ) . piTimedOut ? "超时" : "异常退出" }
125+ { run ( ) . piExitReason ? ` (${ run ( ) . piExitReason } )` : "" } ,pack 未产出,仅执行了{ " " }
126+ { score ( ) ?. score ?. total ?? 0 } 项静态检查
127+ </ span >
128+ </ div >
129+ </ Show >
117130 { score ( ) ?. summary && (
118131 < p class = "text-sm mt-2" >
119132 < span class = "font-bold" > 结论: </ span >
120133 { esc ( score ( ) ! . summary ) }
121134 </ p >
122135 ) }
123136
137+ < p class = "text-xs opacity-50 mb-1" > 指标由前端从 session JSONL 实时计算,可能与列表页预计算值略有差异</ p >
124138 < div class = "stats stats-shadow w-full my-3" >
125139 < div class = "stat" >
126140 < div class = "stat-value text-xl" >
127141 { fmtSec ( sessionMetrics ( ) ?. timeline ?. wallSeconds ) }
128142 </ div >
129143 < div class = "stat-title text-xs" > wall (session observed)</ div >
144+ < div class = "text-xs opacity-50" > { METRIC_DEFINITIONS . wall } </ div >
130145 </ div >
131146 < div class = "stat" >
132147 < div class = "stat-value text-xl" >
133148 { fmtNum ( sessionMetrics ( ) ?. tokens ?. totalTokens ) }
134149 </ div >
135150 < div class = "stat-title text-xs" > tokens</ div >
151+ < div class = "text-xs opacity-50" > { METRIC_DEFINITIONS . tokens } </ div >
136152 </ div >
137153 < div class = "stat" >
138154 < div class = "stat-value text-xl" >
139155 { esc ( sessionMetrics ( ) ?. agent ?. modelRequestCount ) }
140156 </ div >
141157 < div class = "stat-title text-xs" > requests</ div >
158+ < div class = "text-xs opacity-50" > { METRIC_DEFINITIONS . requests } </ div >
142159 </ div >
143160 < div class = "stat" >
144161 < div class = "stat-value text-xl" >
145162 { esc ( sessionMetrics ( ) ?. agent ?. toolCallCount ) }
146163 </ div >
147164 < div class = "stat-title text-xs" > toolCalls</ div >
165+ < div class = "text-xs opacity-50" > { METRIC_DEFINITIONS . toolCalls } </ div >
148166 </ div >
149167 < div class = "stat" >
150168 < div class = "stat-value text-xl" >
151169 { esc ( sessionMetrics ( ) ?. agent ?. toolResultErrorCount ?? 0 ) }
152170 </ div >
153171 < div class = "stat-title text-xs" > errors</ div >
172+ < div class = "text-xs opacity-50" > { METRIC_DEFINITIONS . errors } </ div >
154173 </ div >
155174 </ div >
156175
@@ -202,6 +221,11 @@ export function RunDetail({
202221 < div class = "card bg-base-200 mt-4" >
203222 < div class = "card-body" >
204223 < h3 class = "text-sm font-bold mb-1" > 评测明细</ h3 >
224+ < p class = "text-xs opacity-60 mb-2" >
225+ { score ( ) ?. status === "incomplete"
226+ ? `仅 ${ score ( ) ?. score ?. total ?? 0 } 项静态检查(pack 未产出,运行时检查未执行)`
227+ : `${ EVAL_STRUCTURE . static . total } ${ EVAL_STRUCTURE . static . label } + ${ EVAL_STRUCTURE . runtime . total } ${ EVAL_STRUCTURE . runtime . label } = ${ EVAL_STRUCTURE . fullTotal } 项总检查` }
228+ </ p >
205229 < Show
206230 when = { scoreCheck ( ) }
207231 fallback = {
@@ -215,25 +239,25 @@ export function RunDetail({
215239 < div class = "grid grid-cols-1 md:grid-cols-2 gap-2" >
216240 < div class = "bg-base-300 rounded-lg p-3" >
217241 < h4 class = "text-xs font-bold text-success" >
218- 静态通过 ({ score ( ) ?. static ?. passed ?. length ?? 0 } )
242+ 静态通过 · 文件结构与内容验证 ({ score ( ) ?. static ?. passed ?. length ?? 0 } )
219243 </ h4 >
220244 { list ( score ( ) ?. static ?. passed , "badge-success" ) }
221245 </ div >
222246 < div class = "bg-base-300 rounded-lg p-3" >
223247 < h4 class = "text-xs font-bold text-error" >
224- 静态失败 ({ score ( ) ?. static ?. failed ?. length ?? 0 } )
248+ 静态失败 · 文件结构与内容验证 ({ score ( ) ?. static ?. failed ?. length ?? 0 } )
225249 </ h4 >
226250 { list ( score ( ) ?. static ?. failed , "badge-error" ) }
227251 </ div >
228252 < div class = "bg-base-300 rounded-lg p-3" >
229253 < h4 class = "text-xs font-bold text-success" >
230- 运行时通过 ({ score ( ) ?. runtime ?. passed ?. length ?? 0 } )
254+ 运行时通过 · Docker HTTP 调用验证 ({ score ( ) ?. runtime ?. passed ?. length ?? 0 } )
231255 </ h4 >
232256 { list ( score ( ) ?. runtime ?. passed , "badge-success" ) }
233257 </ div >
234258 < div class = "bg-base-300 rounded-lg p-3" >
235259 < h4 class = "text-xs font-bold text-error" >
236- 运行时失败 ({ score ( ) ?. runtime ?. failed ?. length ?? 0 } )
260+ 运行时失败 · Docker HTTP 调用验证 ({ score ( ) ?. runtime ?. failed ?. length ?? 0 } )
237261 </ h4 >
238262 { list ( score ( ) ?. runtime ?. failed , "badge-error" ) }
239263 { score ( ) ?. runtime ?. blocked ?. length ? (
0 commit comments