(value: unknown)
| 338 | } |
| 339 | |
| 340 | function decodeSubjectExecution(value: unknown): SubjectExecutionResult { |
| 341 | const subject = exactRecord( |
| 342 | value, |
| 343 | ['usage', 'costUsd', 'durationMs', 'status', 'failureReason', 'artifacts'], |
| 344 | ['output'], |
| 345 | ); |
| 346 | if ( |
| 347 | subject.status !== 'completed' && |
| 348 | subject.status !== 'failed' && |
| 349 | subject.status !== 'infra_failed' && |
| 350 | subject.status !== 'indeterminate' |
| 351 | ) { |
| 352 | throw new Error('subject status is invalid'); |
| 353 | } |
| 354 | if (subject.output !== undefined && typeof subject.output !== 'string') { |
| 355 | throw new Error('subject output is invalid'); |
| 356 | } |
| 357 | const decoded = decodeEvalResult({ |
| 358 | score: null, |
| 359 | usage: subject.usage, |
| 360 | costUsd: subject.costUsd, |
| 361 | durationMs: subject.durationMs, |
| 362 | status: subject.status === 'failed' ? 'subject_failed' : subject.status, |
| 363 | failureReason: subject.failureReason, |
| 364 | artifacts: subject.artifacts, |
| 365 | }); |
| 366 | return { |
| 367 | ...(subject.output === undefined ? {} : { output: subject.output }), |
| 368 | usage: decoded.usage, |
| 369 | costUsd: decoded.costUsd, |
| 370 | durationMs: decoded.durationMs, |
| 371 | status: subject.status, |
| 372 | failureReason: decoded.failureReason, |
| 373 | artifacts: decoded.artifacts, |
| 374 | }; |
| 375 | } |
| 376 | |
| 377 | function decodeVerification(value: unknown): ExecutorVerification { |
| 378 | const verification = exactRecord(value, ['status', 'score', 'failureReason', 'artifacts']); |
no test coverage detected