| 265 | } |
| 266 | |
| 267 | function toEvalSummaries(exportData: EvaluationRunExport[]): EvalSummary[] { |
| 268 | const evalMap = new Map<string, ModelSummary[]>(); |
| 269 | const labelMap = new Map<string, string>(); |
| 270 | |
| 271 | exportData.forEach((run, index) => { |
| 272 | assert( |
| 273 | run !== null && typeof run === "object", |
| 274 | `Invalid evaluation entry at index ${index}`, |
| 275 | ); |
| 276 | |
| 277 | const repo = run.evaluation?.repo; |
| 278 | assert( |
| 279 | typeof repo === "string" && repo.length > 0, |
| 280 | `Missing evaluation repo for entry at index ${index}`, |
| 281 | ); |
| 282 | |
| 283 | const identifier = run.evaluation?.identifier ?? repo; |
| 284 | assert( |
| 285 | typeof identifier === "string" && identifier.length > 0, |
| 286 | `Missing evaluation identifier for "${repo}" (index ${index})`, |
| 287 | ); |
| 288 | |
| 289 | assert( |
| 290 | Array.isArray(run.scores), |
| 291 | `Missing scores array for evaluation "${repo}" (index ${index})`, |
| 292 | ); |
| 293 | |
| 294 | assert( |
| 295 | typeof run.jobUrl === "string" && run.jobUrl.length > 0, |
| 296 | `Missing job URL for evaluation "${repo}" model "${run.model}"`, |
| 297 | ); |
| 298 | |
| 299 | const modelIds = Array.isArray(run.model) ? run.model : [run.model]; |
| 300 | const modelRows = run.scores.map((score) => ({ |
| 301 | name: score.assignment.name, |
| 302 | weight: score.assignment.weight, |
| 303 | normalizedWeight: score.normalizedWeight, |
| 304 | average: score.averageScore, |
| 305 | variance: score.variance, |
| 306 | })); |
| 307 | |
| 308 | const summaries = evalMap.get(identifier) ?? []; |
| 309 | |
| 310 | modelIds.forEach((modelId) => { |
| 311 | const agentName = (run.agent ?? "").trim(); |
| 312 | const prefixedId = `${agentName}:${modelId}`; |
| 313 | |
| 314 | summaries.push({ |
| 315 | id: prefixedId, |
| 316 | rawModelId: modelId, |
| 317 | agentId: agentName.length > 0 ? agentName : run.agent, |
| 318 | final: run.finalScore, |
| 319 | jobUrl: run.jobUrl, |
| 320 | rows: modelRows, |
| 321 | episodes: modelId.includes("claude") ? claudeEpisodes : gptEpisodes, |
| 322 | }); |
| 323 | }); |
| 324 | |