@opensearch-project/agent-health 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/dist/index.js +722 -330
- package/dist/assets/index-D-Np_l_T.js +246 -0
- package/dist/assets/index-vZt9QZKf.css +1 -0
- package/dist/index.html +2 -2
- package/docs/CLI.md +138 -1
- package/docs/CONNECTORS.md +1 -1
- package/docs/SDK.md +126 -2
- package/docs/skills/add-connector/SKILL.md +5 -1
- package/lib/dist/lib/agentTrends.d.ts +210 -0
- package/lib/dist/lib/agentTrends.d.ts.map +1 -0
- package/lib/dist/lib/agentTrends.js +360 -0
- package/lib/dist/lib/agentTrends.js.map +1 -0
- package/lib/dist/lib/benchmarkCaseReview.d.ts +114 -0
- package/lib/dist/lib/benchmarkCaseReview.d.ts.map +1 -0
- package/lib/dist/lib/benchmarkCaseReview.js +177 -0
- package/lib/dist/lib/benchmarkCaseReview.js.map +1 -0
- package/lib/dist/lib/benchmarkRunsTable.d.ts +109 -0
- package/lib/dist/lib/benchmarkRunsTable.d.ts.map +1 -0
- package/lib/dist/lib/benchmarkRunsTable.js +212 -0
- package/lib/dist/lib/benchmarkRunsTable.js.map +1 -0
- package/lib/dist/lib/comparisonInsights.d.ts +49 -2
- package/lib/dist/lib/comparisonInsights.d.ts.map +1 -1
- package/lib/dist/lib/comparisonInsights.js +65 -7
- package/lib/dist/lib/comparisonInsights.js.map +1 -1
- package/lib/dist/lib/config/loader.d.ts.map +1 -1
- package/lib/dist/lib/config/loader.js +11 -1
- package/lib/dist/lib/config/loader.js.map +1 -1
- package/lib/dist/lib/dashboardMetrics.d.ts +11 -2
- package/lib/dist/lib/dashboardMetrics.d.ts.map +1 -1
- package/lib/dist/lib/dashboardMetrics.js +38 -3
- package/lib/dist/lib/dashboardMetrics.js.map +1 -1
- package/lib/dist/lib/evaluationRerun.d.ts +39 -0
- package/lib/dist/lib/evaluationRerun.d.ts.map +1 -1
- package/lib/dist/lib/evaluationRerun.js +49 -0
- package/lib/dist/lib/evaluationRerun.js.map +1 -1
- package/lib/dist/lib/judgeFailureSummary.d.ts +66 -0
- package/lib/dist/lib/judgeFailureSummary.d.ts.map +1 -0
- package/lib/dist/lib/judgeFailureSummary.js +68 -0
- package/lib/dist/lib/judgeFailureSummary.js.map +1 -0
- package/lib/dist/lib/judgeStrategies.d.ts +108 -0
- package/lib/dist/lib/judgeStrategies.d.ts.map +1 -0
- package/lib/dist/lib/judgeStrategies.js +135 -0
- package/lib/dist/lib/judgeStrategies.js.map +1 -0
- package/lib/dist/lib/matchers/expect.d.ts +21 -1
- package/lib/dist/lib/matchers/expect.d.ts.map +1 -1
- package/lib/dist/lib/matchers/expect.js +51 -0
- package/lib/dist/lib/matchers/expect.js.map +1 -1
- package/lib/dist/lib/matchers/judgeAccessor.d.ts +4 -0
- package/lib/dist/lib/matchers/judgeAccessor.d.ts.map +1 -1
- package/lib/dist/lib/matchers/judgeAccessor.js +13 -2
- package/lib/dist/lib/matchers/judgeAccessor.js.map +1 -1
- package/lib/dist/lib/matchers/judgeReasoningParse.d.ts +49 -0
- package/lib/dist/lib/matchers/judgeReasoningParse.d.ts.map +1 -0
- package/lib/dist/lib/matchers/judgeReasoningParse.js +128 -0
- package/lib/dist/lib/matchers/judgeReasoningParse.js.map +1 -0
- package/lib/dist/lib/matchers/types.d.ts +25 -0
- package/lib/dist/lib/matchers/types.d.ts.map +1 -1
- package/lib/dist/lib/resolveCanonicalRun.d.ts +23 -0
- package/lib/dist/lib/resolveCanonicalRun.d.ts.map +1 -0
- package/lib/dist/lib/resolveCanonicalRun.js +26 -0
- package/lib/dist/lib/resolveCanonicalRun.js.map +1 -0
- package/lib/dist/lib/runActions.d.ts +120 -0
- package/lib/dist/lib/runActions.d.ts.map +1 -0
- package/lib/dist/lib/runActions.js +130 -0
- package/lib/dist/lib/runActions.js.map +1 -0
- package/lib/dist/lib/runInsights.d.ts +86 -0
- package/lib/dist/lib/runInsights.d.ts.map +1 -0
- package/lib/dist/lib/runInsights.js +185 -0
- package/lib/dist/lib/runInsights.js.map +1 -0
- package/lib/dist/lib/runName.d.ts +29 -0
- package/lib/dist/lib/runName.d.ts.map +1 -0
- package/lib/dist/lib/runName.js +38 -0
- package/lib/dist/lib/runName.js.map +1 -0
- package/lib/dist/lib/runReportPath.d.ts +16 -0
- package/lib/dist/lib/runReportPath.d.ts.map +1 -0
- package/lib/dist/lib/runReportPath.js +22 -0
- package/lib/dist/lib/runReportPath.js.map +1 -0
- package/lib/dist/lib/runSort.d.ts +27 -0
- package/lib/dist/lib/runSort.d.ts.map +1 -0
- package/lib/dist/lib/runSort.js +31 -0
- package/lib/dist/lib/runSort.js.map +1 -0
- package/lib/dist/lib/runStats.d.ts +86 -6
- package/lib/dist/lib/runStats.d.ts.map +1 -1
- package/lib/dist/lib/runStats.js +170 -19
- package/lib/dist/lib/runStats.js.map +1 -1
- package/lib/dist/lib/testCases/define.d.ts.map +1 -1
- package/lib/dist/lib/testCases/define.js +93 -46
- package/lib/dist/lib/testCases/define.js.map +1 -1
- package/lib/dist/lib/testCases/judge.d.ts.map +1 -1
- package/lib/dist/lib/testCases/judge.js +22 -4
- package/lib/dist/lib/testCases/judge.js.map +1 -1
- package/lib/dist/lib/testCases/loader.d.ts +24 -0
- package/lib/dist/lib/testCases/loader.d.ts.map +1 -1
- package/lib/dist/lib/testCases/loader.js +253 -36
- package/lib/dist/lib/testCases/loader.js.map +1 -1
- package/lib/dist/lib/trajectoryStepDisplay.d.ts +25 -0
- package/lib/dist/lib/trajectoryStepDisplay.d.ts.map +1 -0
- package/lib/dist/lib/trajectoryStepDisplay.js +42 -0
- package/lib/dist/lib/trajectoryStepDisplay.js.map +1 -0
- package/lib/dist/lib/utils.d.ts +19 -0
- package/lib/dist/lib/utils.d.ts.map +1 -1
- package/lib/dist/lib/utils.js +27 -0
- package/lib/dist/lib/utils.js.map +1 -1
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts +68 -32
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts.map +1 -1
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js +148 -125
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js.map +1 -1
- package/lib/dist/services/connectors/kiro/KiroConnector.d.ts +21 -13
- package/lib/dist/services/connectors/kiro/KiroConnector.d.ts.map +1 -1
- package/lib/dist/services/connectors/kiro/KiroConnector.js +22 -25
- package/lib/dist/services/connectors/kiro/KiroConnector.js.map +1 -1
- package/lib/dist/services/connectors/pi/PiConnector.d.ts +49 -10
- package/lib/dist/services/connectors/pi/PiConnector.d.ts.map +1 -1
- package/lib/dist/services/connectors/pi/PiConnector.js +102 -86
- package/lib/dist/services/connectors/pi/PiConnector.js.map +1 -1
- package/lib/dist/services/connectors/subprocess/SubprocessConnector.d.ts +59 -14
- package/lib/dist/services/connectors/subprocess/SubprocessConnector.d.ts.map +1 -1
- package/lib/dist/services/connectors/subprocess/SubprocessConnector.js +87 -61
- package/lib/dist/services/connectors/subprocess/SubprocessConnector.js.map +1 -1
- package/lib/dist/services/evaluation/bedrockJudge.d.ts +11 -0
- package/lib/dist/services/evaluation/bedrockJudge.d.ts.map +1 -1
- package/lib/dist/services/evaluation/bedrockJudge.js +2 -0
- package/lib/dist/services/evaluation/bedrockJudge.js.map +1 -1
- package/lib/dist/services/evaluation/index.d.ts +18 -1
- package/lib/dist/services/evaluation/index.d.ts.map +1 -1
- package/lib/dist/services/evaluation/index.js +156 -19
- package/lib/dist/services/evaluation/index.js.map +1 -1
- package/lib/dist/services/metrics.d.ts +55 -0
- package/lib/dist/services/metrics.d.ts.map +1 -0
- package/lib/dist/services/metrics.js +89 -0
- package/lib/dist/services/metrics.js.map +1 -0
- package/lib/dist/services/storage/asyncBenchmarkStorage.d.ts.map +1 -1
- package/lib/dist/services/storage/asyncBenchmarkStorage.js +16 -0
- package/lib/dist/services/storage/asyncBenchmarkStorage.js.map +1 -1
- package/lib/dist/services/storage/asyncRunStorage.d.ts +11 -0
- package/lib/dist/services/storage/asyncRunStorage.d.ts.map +1 -1
- package/lib/dist/services/storage/asyncRunStorage.js +49 -2
- package/lib/dist/services/storage/asyncRunStorage.js.map +1 -1
- package/lib/dist/services/storage/asyncTestCaseStorage.d.ts +1 -1
- package/lib/dist/services/storage/asyncTestCaseStorage.d.ts.map +1 -1
- package/lib/dist/services/storage/asyncTestCaseStorage.js +2 -1
- package/lib/dist/services/storage/asyncTestCaseStorage.js.map +1 -1
- package/lib/dist/services/storage/opensearchClient.d.ts +12 -0
- package/lib/dist/services/storage/opensearchClient.d.ts.map +1 -1
- package/lib/dist/services/storage/opensearchClient.js.map +1 -1
- package/lib/dist/services/traces/browserRecovery.d.ts.map +1 -1
- package/lib/dist/services/traces/browserRecovery.js +3 -0
- package/lib/dist/services/traces/browserRecovery.js.map +1 -1
- package/lib/dist/services/traces/index.d.ts +8 -1
- package/lib/dist/services/traces/index.d.ts.map +1 -1
- package/lib/dist/services/traces/index.js +33 -12
- package/lib/dist/services/traces/index.js.map +1 -1
- package/lib/dist/services/traces/judgeAgentsHints.d.ts +98 -3
- package/lib/dist/services/traces/judgeAgentsHints.d.ts.map +1 -1
- package/lib/dist/services/traces/judgeAgentsHints.js +144 -3
- package/lib/dist/services/traces/judgeAgentsHints.js.map +1 -1
- package/lib/dist/services/traces/spansToTrajectory.js +4 -4
- package/lib/dist/services/traces/spansToTrajectory.js.map +1 -1
- package/lib/dist/services/traces/tracePoller.d.ts.map +1 -1
- package/lib/dist/services/traces/tracePoller.js +17 -20
- package/lib/dist/services/traces/tracePoller.js.map +1 -1
- package/lib/dist/services/traces/trajectoryMerge.d.ts +79 -0
- package/lib/dist/services/traces/trajectoryMerge.d.ts.map +1 -0
- package/lib/dist/services/traces/trajectoryMerge.js +109 -0
- package/lib/dist/services/traces/trajectoryMerge.js.map +1 -0
- package/lib/dist/types/index.d.ts +195 -2
- package/lib/dist/types/index.d.ts.map +1 -1
- package/lib/dist/types/index.js +24 -0
- package/lib/dist/types/index.js.map +1 -1
- package/package.json +6 -5
- package/server/dist/app.js +3398 -926
- package/server/dist/index.js +3401 -929
- package/dist/assets/index-BfxtxmKc.css +0 -1
- package/dist/assets/index-CrjAfDHu.js +0 -243
package/lib/dist/lib/runStats.js
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
* Copyright OpenSearch Contributors
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
|
+
/** Run statuses after which no further per-case progress can happen. */
|
|
6
|
+
export const TERMINAL_RUN_STATUSES = new Set(['completed', 'failed', 'cancelled']);
|
|
7
|
+
export function isTerminalRunStatus(status) {
|
|
8
|
+
return status !== undefined && TERMINAL_RUN_STATUSES.has(status);
|
|
9
|
+
}
|
|
5
10
|
/**
|
|
6
11
|
* Bucket a run's per-test-case results into passed/failed/errored/pending using
|
|
7
12
|
* ONLY the persisted result fields (status + passFailStatus) — no reports
|
|
@@ -18,16 +23,46 @@
|
|
|
18
23
|
* the evaluator couldn't produce one (judge validation error, trace timeout).
|
|
19
24
|
* Excluded from passed/failed — exactly as calculateRunStats does via the
|
|
20
25
|
* report's metricsStatus.
|
|
26
|
+
*
|
|
27
|
+
* `plannedTotal` (bug: runs list showed no in-flight indication, 2026-09-01):
|
|
28
|
+
* for a genuinely in-progress run, `results` only gets an entry once a test
|
|
29
|
+
* case has actually STARTED — a run 9 cases into a planned 62 has a
|
|
30
|
+
* `results` map of length 9, so `total` here would report 9, not 62. Pass
|
|
31
|
+
* the run's snapshotted test-case count (`testCaseSnapshots.length`) as
|
|
32
|
+
* `plannedTotal` and the shortfall (planned - observed) is folded into
|
|
33
|
+
* `pending` so the invariant `total === passed+failed+errored+pending+notRun`
|
|
34
|
+
* still holds and callers see the true "53 more to go" total instead of a
|
|
35
|
+
* misleadingly small, already-100%-accounted-for total that looks finished.
|
|
36
|
+
*
|
|
37
|
+
* `runStatus` (bug: cancelled/failed runs rendered a phantom "n pending ⟳"
|
|
38
|
+
* forever, 2026-09-04): the shortfall above is only *pending* while the run
|
|
39
|
+
* can still make progress. Once the run is TERMINAL (cancelled / failed /
|
|
40
|
+
* completed) nothing will ever start those cases, so they are bucketed as
|
|
41
|
+
* `notRun` instead — a cancelled 34/62 run reads "34 executed · 28 not run",
|
|
42
|
+
* not "28 pending" with a spinner. The same applies to per-case entries a
|
|
43
|
+
* terminal run left behind in `pending`/`running` (an executor that died
|
|
44
|
+
* mid-case) and to entries explicitly marked `status: 'cancelled'` (written
|
|
45
|
+
* for never-started cases when a run is cancelled — see
|
|
46
|
+
* `EvaluationRun.results` in types/index.ts). Without `runStatus` the legacy
|
|
47
|
+
* behaviour (shortfall = pending) is preserved.
|
|
21
48
|
*/
|
|
22
|
-
export function bucketRunResults(results) {
|
|
23
|
-
|
|
49
|
+
export function bucketRunResults(results, plannedTotal, runStatus) {
|
|
50
|
+
const terminal = isTerminalRunStatus(runStatus);
|
|
51
|
+
let passed = 0, failed = 0, errored = 0, pending = 0, notRun = 0, total = 0;
|
|
24
52
|
for (const r of Object.values(results || {})) {
|
|
25
53
|
total++;
|
|
54
|
+
if (r.status === 'cancelled') {
|
|
55
|
+
notRun++;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
26
58
|
if (r.status === 'pending' || r.status === 'running') {
|
|
27
|
-
|
|
59
|
+
if (terminal)
|
|
60
|
+
notRun++;
|
|
61
|
+
else
|
|
62
|
+
pending++;
|
|
28
63
|
continue;
|
|
29
64
|
}
|
|
30
|
-
if (r.status === 'failed'
|
|
65
|
+
if (r.status === 'failed') {
|
|
31
66
|
failed++;
|
|
32
67
|
continue;
|
|
33
68
|
}
|
|
@@ -40,9 +75,39 @@ export function bucketRunResults(results) {
|
|
|
40
75
|
errored++; // completed without a verdict = judge errored (#242)
|
|
41
76
|
continue;
|
|
42
77
|
}
|
|
43
|
-
|
|
78
|
+
// Unknown / missing status: while the run is live this is "not settled
|
|
79
|
+
// yet" (pending). On a TERMINAL run an entry with no recognised status is
|
|
80
|
+
// schema drift or a bad writer — surface it as `errored` (amber ⚠) rather
|
|
81
|
+
// than hide it in the neutral notRun bucket (codex review).
|
|
82
|
+
if (terminal)
|
|
83
|
+
errored++;
|
|
84
|
+
else
|
|
85
|
+
pending++;
|
|
44
86
|
}
|
|
45
|
-
|
|
87
|
+
if (plannedTotal !== undefined && plannedTotal > total) {
|
|
88
|
+
if (terminal)
|
|
89
|
+
notRun += plannedTotal - total;
|
|
90
|
+
else
|
|
91
|
+
pending += plannedTotal - total;
|
|
92
|
+
total = plannedTotal;
|
|
93
|
+
}
|
|
94
|
+
return { passed, failed, errored, pending, notRun, total };
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Pass rate (0-100) over the JUDGED set only: `passed / (passed + failed)`.
|
|
98
|
+
* Excluded: errored (executed, but the evaluator produced no verdict — the
|
|
99
|
+
* repo-wide #242 convention, same as the benchmark runs table and the run
|
|
100
|
+
* inspector), pending (not finished) and notRun (never started). So a run
|
|
101
|
+
* cancelled at 34/62 reports the pass rate of the cases that were actually
|
|
102
|
+
* judged, and an in-flight run doesn't read as "12%" because 50 cases
|
|
103
|
+
* haven't happened yet. Named for what it is — callers that surface it
|
|
104
|
+
* should footnote the excluded errored/notRun counts (the detail page does).
|
|
105
|
+
* Returns `null` when nothing has been judged so callers can render "—"
|
|
106
|
+
* rather than a fabricated 0%.
|
|
107
|
+
*/
|
|
108
|
+
export function passRateOverJudged(stats) {
|
|
109
|
+
const judged = stats.passed + stats.failed;
|
|
110
|
+
return judged > 0 ? Math.round((stats.passed / judged) * 100) : null;
|
|
46
111
|
}
|
|
47
112
|
/**
|
|
48
113
|
* Calculate statistics for a benchmark run.
|
|
@@ -61,6 +126,7 @@ export function calculateRunStats(run, reports) {
|
|
|
61
126
|
let failed = 0;
|
|
62
127
|
let pending = 0;
|
|
63
128
|
let errored = 0;
|
|
129
|
+
let notRun = 0;
|
|
64
130
|
let total = 0;
|
|
65
131
|
Object.entries(run.results || {}).forEach(([testCaseId, result]) => {
|
|
66
132
|
total++;
|
|
@@ -69,7 +135,12 @@ export function calculateRunStats(run, reports) {
|
|
|
69
135
|
pending++;
|
|
70
136
|
return;
|
|
71
137
|
}
|
|
72
|
-
|
|
138
|
+
// Never started (run cancelled before reaching it) — not a failure.
|
|
139
|
+
if (result.status === 'cancelled') {
|
|
140
|
+
notRun++;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (result.status === 'failed') {
|
|
73
144
|
failed++;
|
|
74
145
|
return;
|
|
75
146
|
}
|
|
@@ -107,15 +178,16 @@ export function calculateRunStats(run, reports) {
|
|
|
107
178
|
pending++;
|
|
108
179
|
}
|
|
109
180
|
});
|
|
110
|
-
// Pass rate is computed over the evaluable set (total minus errored
|
|
111
|
-
// If every run errored, expose 0% rather than dividing by zero.
|
|
112
|
-
const evaluable = Math.max(0, total - errored);
|
|
181
|
+
// Pass rate is computed over the evaluable set (total minus errored minus
|
|
182
|
+
// never-run). If every run errored, expose 0% rather than dividing by zero.
|
|
183
|
+
const evaluable = Math.max(0, total - errored - notRun);
|
|
113
184
|
const passRate = evaluable > 0 ? Math.round((passed / evaluable) * 100) : 0;
|
|
114
185
|
return {
|
|
115
186
|
passed,
|
|
116
187
|
failed,
|
|
117
188
|
pending,
|
|
118
189
|
errored,
|
|
190
|
+
notRun,
|
|
119
191
|
total,
|
|
120
192
|
passRate,
|
|
121
193
|
};
|
|
@@ -161,19 +233,67 @@ export function getReportIdsFromRun(run) {
|
|
|
161
233
|
* simply ignore the extra `pending` field.
|
|
162
234
|
*/
|
|
163
235
|
export function computeRunStats(run) {
|
|
236
|
+
const plannedTotal = run.testCaseSnapshots?.length;
|
|
237
|
+
// Terminal-aware bucketing (see bucketRunResults): the planned-but-absent
|
|
238
|
+
// remainder is `pending` only while the run is still running. Only the
|
|
239
|
+
// EXPLICIT persisted status is trusted here — the results-derived legacy
|
|
240
|
+
// fallback in getEffectiveRunStatus reports 'completed' for any status-less
|
|
241
|
+
// run whose observed results happen to all be settled, which is exactly
|
|
242
|
+
// what an in-flight legacy run looks like between two cases.
|
|
243
|
+
const effectiveStatus = run.status;
|
|
164
244
|
if (run.results && Object.keys(run.results).length > 0) {
|
|
165
|
-
|
|
245
|
+
const bucketed = bucketRunResults(run.results, plannedTotal, effectiveStatus);
|
|
246
|
+
// Legacy-shape fallback (goyamegh/pr-run-report-v2, run-list all-errored bug):
|
|
247
|
+
// runs created before per-result passFailStatus denormalization landed
|
|
248
|
+
// (evaluationRunner.ts writing `results[testCaseId].passFailStatus`) only
|
|
249
|
+
// persisted `{ reportId, status: 'completed' }` on each result -- no
|
|
250
|
+
// verdict field at all. bucketRunResults correctly treats a 'completed'
|
|
251
|
+
// result with no passFailStatus as `errored` (#242), which is right for a
|
|
252
|
+
// genuine judge failure, but wrong here: EVERY case in the run buckets as
|
|
253
|
+
// errored (0 passed, 0 failed) even though the run actually has real
|
|
254
|
+
// verdicts. Detect that specific signature and, only when the
|
|
255
|
+
// denormalized `run.stats` independently shows real pass/fail evidence
|
|
256
|
+
// (computed by the report-fetching `computeStatsForRun`, verified against
|
|
257
|
+
// linked reports' actual passFailStatus -- see tests/unit/lib/runStats.test.ts
|
|
258
|
+
// 'legacy run shape' cases), trust `run.stats` instead of asserting the
|
|
259
|
+
// whole run errored. A run that is genuinely all-errored (no result ever
|
|
260
|
+
// resolved a verdict) will have run.stats.passed === run.stats.failed === 0
|
|
261
|
+
// too, so it still falls through to the errored bucketing below.
|
|
262
|
+
const allBucketedAsErrored = bucketed.errored > 0 && bucketed.passed === 0 && bucketed.failed === 0;
|
|
263
|
+
const statsHaveRealVerdicts = !!run.stats && ((run.stats.passed ?? 0) > 0 || (run.stats.failed ?? 0) > 0);
|
|
264
|
+
if (allBucketedAsErrored && statsHaveRealVerdicts && run.stats) {
|
|
265
|
+
return statsFallback(run.stats, run.stats.total ?? bucketed.total, effectiveStatus);
|
|
266
|
+
}
|
|
267
|
+
return bucketed;
|
|
166
268
|
}
|
|
167
269
|
if (run.stats && (run.stats.total ?? 0) > 0) {
|
|
168
|
-
return
|
|
169
|
-
passed: run.stats.passed ?? 0,
|
|
170
|
-
failed: run.stats.failed ?? 0,
|
|
171
|
-
errored: run.stats.errored ?? 0,
|
|
172
|
-
pending: run.stats.pending ?? 0,
|
|
173
|
-
total: run.stats.total ?? 0,
|
|
174
|
-
};
|
|
270
|
+
return statsFallback(run.stats, run.stats.total ?? 0, effectiveStatus);
|
|
175
271
|
}
|
|
176
|
-
|
|
272
|
+
// No results and no stats: a run that never started a case. Terminal →
|
|
273
|
+
// every planned case is "not run"; otherwise they're all still pending.
|
|
274
|
+
const planned = plannedTotal || 0;
|
|
275
|
+
return isTerminalRunStatus(effectiveStatus)
|
|
276
|
+
? { passed: 0, failed: 0, errored: 0, pending: 0, notRun: planned, total: planned }
|
|
277
|
+
: { passed: 0, failed: 0, errored: 0, pending: planned, notRun: 0, total: planned };
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Denormalized `run.stats` fallback, made terminal-aware: stats persisted
|
|
281
|
+
* before `notRun` existed carry the never-started remainder in `pending`
|
|
282
|
+
* even for a cancelled run. Re-home that remainder so a legacy cancelled
|
|
283
|
+
* run can't render a phantom spinner either.
|
|
284
|
+
*/
|
|
285
|
+
function statsFallback(stats, total, effectiveStatus) {
|
|
286
|
+
const pending = stats.pending ?? 0;
|
|
287
|
+
const notRun = stats.notRun ?? 0;
|
|
288
|
+
const terminal = isTerminalRunStatus(effectiveStatus);
|
|
289
|
+
return {
|
|
290
|
+
passed: stats.passed ?? 0,
|
|
291
|
+
failed: stats.failed ?? 0,
|
|
292
|
+
errored: stats.errored ?? 0,
|
|
293
|
+
pending: terminal ? 0 : pending,
|
|
294
|
+
notRun: terminal ? notRun + pending : notRun,
|
|
295
|
+
total,
|
|
296
|
+
};
|
|
177
297
|
}
|
|
178
298
|
export function computeRunStatsFromReports(run, reports) {
|
|
179
299
|
const reportsMap = {};
|
|
@@ -186,7 +306,38 @@ export function computeRunStatsFromReports(run, reports) {
|
|
|
186
306
|
failed: fullStats.failed,
|
|
187
307
|
pending: fullStats.pending,
|
|
188
308
|
errored: fullStats.errored,
|
|
309
|
+
notRun: fullStats.notRun,
|
|
189
310
|
total: fullStats.total,
|
|
190
311
|
};
|
|
191
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Single canonical "is this run actively in progress" check, shared by every
|
|
315
|
+
* runs-list surface (bug: the Evaluation Runs page and the benchmark-scoped
|
|
316
|
+
* Runs panel each grew their own copy of this, and only one of them actually
|
|
317
|
+
* rendered a running indicator). `status` is authoritative when present
|
|
318
|
+
* (always true for `EvaluationRun`; `BenchmarkRun.status` is only undefined
|
|
319
|
+
* for legacy pre-status data). Falls back to inspecting `results` so legacy
|
|
320
|
+
* runs without a top-level `status` still get a sensible effective status.
|
|
321
|
+
*/
|
|
322
|
+
export function getEffectiveRunStatus(run) {
|
|
323
|
+
if (run.status)
|
|
324
|
+
return run.status;
|
|
325
|
+
const results = Object.values(run.results || {});
|
|
326
|
+
if (results.some(r => r.status === 'running'))
|
|
327
|
+
return 'running';
|
|
328
|
+
if (results.some(r => r.status === 'pending') &&
|
|
329
|
+
!results.some(r => r.status === 'completed' || r.status === 'failed'))
|
|
330
|
+
return 'running';
|
|
331
|
+
if (results.some(r => r.status === 'completed') || results.some(r => r.status === 'failed'))
|
|
332
|
+
return 'completed';
|
|
333
|
+
return 'failed';
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* True when a run has neither reached a terminal status nor accounted for
|
|
337
|
+
* every planned test case yet. Used to decide whether a runs-list page
|
|
338
|
+
* should keep polling for live updates.
|
|
339
|
+
*/
|
|
340
|
+
export function isRunInProgress(run) {
|
|
341
|
+
return getEffectiveRunStatus(run) === 'running';
|
|
342
|
+
}
|
|
192
343
|
//# sourceMappingURL=runStats.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runStats.js","sourceRoot":"","sources":["../../runStats.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"runStats.js","sourceRoot":"","sources":["../../runStats.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuDH,wEAAwE;AACxE,MAAM,CAAC,MAAM,qBAAqB,GAAoC,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;AAEpH,MAAM,UAAU,mBAAmB,CAAC,MAAsC;IACxE,OAAO,MAAM,KAAK,SAAS,IAAI,qBAAqB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAiF,EACjF,YAAqB,EACrB,SAA8B;IAE9B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;IAC5E,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;QAC7C,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAAC,MAAM,EAAE,CAAC;YAAC,SAAS;QAAC,CAAC;QACrD,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACrD,IAAI,QAAQ;gBAAE,MAAM,EAAE,CAAC;;gBAAM,OAAO,EAAE,CAAC;YACvC,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAAC,MAAM,EAAE,CAAC;YAAC,SAAS;QAAC,CAAC;QAClD,IAAI,CAAC,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,CAAC,cAAc,KAAK,QAAQ;gBAAE,MAAM,EAAE,CAAC;iBACvC,IAAI,CAAC,CAAC,cAAc,KAAK,QAAQ;gBAAE,MAAM,EAAE,CAAC;;gBAC5C,OAAO,EAAE,CAAC,CAAC,qDAAqD;YACrE,SAAS;QACX,CAAC;QACD,uEAAuE;QACvE,0EAA0E;QAC1E,0EAA0E;QAC1E,4DAA4D;QAC5D,IAAI,QAAQ;YAAE,OAAO,EAAE,CAAC;;YAAM,OAAO,EAAE,CAAC;IAC1C,CAAC;IACD,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,GAAG,KAAK,EAAE,CAAC;QACvD,IAAI,QAAQ;YAAE,MAAM,IAAI,YAAY,GAAG,KAAK,CAAC;;YACxC,OAAO,IAAI,YAAY,GAAG,KAAK,CAAC;QACrC,KAAK,GAAG,YAAY,CAAC;IACvB,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAyC;IAC1E,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3C,OAAO,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAiB,EACjB,OAAgD;IAEhD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,EAAE;QACjE,KAAK,EAAE,CAAC;QAER,4BAA4B;QAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC/D,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,oEAAoE;QACpE,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,MAAM,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QAED,2DAA2D;QAC3D,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAExC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,yCAAyC;gBACzC,OAAO,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YAED,oDAAoD;YACpD,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,KAAK,aAAa,EAAE,CAAC;gBACjF,OAAO,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YAED,sEAAsE;YACtE,8DAA8D;YAC9D,+DAA+D;YAC/D,IAAI,MAAM,CAAC,aAAa,KAAK,OAAO,EAAE,CAAC;gBACrC,OAAO,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YAED,+CAA+C;YAC/C,IAAI,MAAM,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;gBACvC,MAAM,EAAE,CAAC;YACX,CAAC;iBAAM,CAAC;gBACN,6DAA6D;gBAC7D,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC;aAAM,CAAC;YACN,yDAAyD;YACzD,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,0EAA0E;IAC1E,4EAA4E;IAC5E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5E,OAAO;QACL,MAAM;QACN,MAAM;QACN,OAAO;QACP,OAAO;QACP,MAAM;QACN,KAAK;QACL,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAiB;IACnD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;QAClD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;GAOG;AACH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAC7B,GAKC;IAED,MAAM,YAAY,GAAG,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnD,0EAA0E;IAC1E,uEAAuE;IACvE,yEAAyE;IACzE,4EAA4E;IAC5E,wEAAwE;IACxE,6DAA6D;IAC7D,MAAM,eAAe,GAAG,GAAG,CAAC,MAAM,CAAC;IACnC,IAAI,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;QAE9E,+EAA+E;QAC/E,uEAAuE;QACvE,0EAA0E;QAC1E,qEAAqE;QACrE,wEAAwE;QACxE,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,8DAA8D;QAC9D,uEAAuE;QACvE,0EAA0E;QAC1E,+EAA+E;QAC/E,wEAAwE;QACxE,yEAAyE;QACzE,4EAA4E;QAC5E,iEAAiE;QACjE,MAAM,oBAAoB,GAAG,QAAQ,CAAC,OAAO,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;QACpG,MAAM,qBAAqB,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1G,IAAI,oBAAoB,IAAI,qBAAqB,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAC/D,OAAO,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QACtF,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,EAAE,eAAe,CAAC,CAAC;IACzE,CAAC;IACD,uEAAuE;IACvE,wEAAwE;IACxE,MAAM,OAAO,GAAG,YAAY,IAAI,CAAC,CAAC;IAClC,OAAO,mBAAmB,CAAC,eAAe,CAAC;QACzC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;QACnF,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACxF,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CACpB,KAA4B,EAC5B,KAAa,EACb,eAA+C;IAE/C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACtD,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC;QACzB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC;QACzB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,CAAC;QAC3B,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;QAC/B,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM;QAC5C,KAAK;KACN,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,GAAiB,EACjB,OAA2B;IAE3B,MAAM,UAAU,GAA4C,EAAE,CAAC;IAC/D,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACvB,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAErD,OAAO;QACL,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,OAAO,EAAE,SAAS,CAAC,OAAO;QAC1B,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,KAAK,EAAE,SAAS,CAAC,KAAK;KACvB,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,GAAmF;IAEnF,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACjD,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAChE,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;QACzC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5F,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;QAAE,OAAO,WAAW,CAAC;IAChH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAmF;IAEnF,OAAO,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;AAClD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../../testCases/define.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,MAAM,EAEN,cAAc,EACf,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../../testCases/define.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,MAAM,EAEN,cAAc,EACf,MAAM,YAAY,CAAC;AAkFpB,gBAAgB;AAChB,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CASpD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACjD,IAAI,CAAC;AACR,wBAAgB,IAAI,CAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,EACpB,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GACjD,IAAI,CAAC;AAwDR;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAuB3D;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAIpE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE,CAItE;AAED,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAUrD;AA6BD;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAmC;AAE9E;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAkC;AAE5E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAoC;AAEhF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAmC;AAS9E,yBAAiB,IAAI,CAAC;IAEb,MAAM,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAA4C,CAAC;IAE9E,MAAM,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAA2C,CAAC;IAE5E,MAAM,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAA6C,CAAC;IAEhF,MAAM,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAA4C,CAAC;CACtF"}
|
|
@@ -3,25 +3,65 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { readEnv } from '../envCompat.js';
|
|
6
|
-
const registries = new Map();
|
|
7
|
-
// Hooks live in a parallel registry keyed by file path, exactly matching
|
|
8
|
-
// the test() registry. The HookOrchestrator filters by describePath at
|
|
9
|
-
// run time. Cross-file hooks never leak — the loader resets per file.
|
|
10
|
-
const hookRegistries = new Map();
|
|
11
|
-
let activeFile = null;
|
|
12
6
|
const DEFAULT_KEY = '__default__';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Registration state lives behind a `globalThis`-keyed symbol instead of
|
|
9
|
+
* plain module-level variables. Why: `.eval.js` files are `eval()`'d in a
|
|
10
|
+
* synthetic CJS context where `require('@opensearch-project/agent-health')`
|
|
11
|
+
* is intercepted by the loader and handed this same module's exports
|
|
12
|
+
* directly — but `.eval.ts` / `.eval.mjs` files are loaded via a plain
|
|
13
|
+
* native `import()`, which resolves `@opensearch-project/agent-health`
|
|
14
|
+
* through Node's normal module resolution (the package's `exports` map,
|
|
15
|
+
* e.g. `./lib/dist/lib/index.js`). When the host process itself runs from
|
|
16
|
+
* TypeScript *source* (dev CLI under tsx, or a project-local `node_modules`
|
|
17
|
+
* symlink pointing at this repo — both real setups), that resolution lands
|
|
18
|
+
* on a PHYSICALLY DIFFERENT file on disk than the one this module's own
|
|
19
|
+
* code imports internally. Two different files means two different ES
|
|
20
|
+
* module instances, each with its own module-level `Map` — so a `.eval.ts`
|
|
21
|
+
* file's `test()` calls landed in an orphaned registry the loader never
|
|
22
|
+
* read from, and `getRegisteredTests()` came back empty ("Module ... has no
|
|
23
|
+
* test cases").
|
|
24
|
+
*
|
|
25
|
+
* `Symbol.for(key)` returns the SAME symbol from the process-wide global
|
|
26
|
+
* symbol registry no matter which module instance asks for it (dist vs
|
|
27
|
+
* source, CJS vs ESM, symlinked vs installed) — so keying the shared state
|
|
28
|
+
* off `globalThis[Symbol.for(...)]` makes every instance of this module
|
|
29
|
+
* read and write the same underlying `Map`s, regardless of how many times /
|
|
30
|
+
* from where it gets loaded. This fixes the module-instance mismatch at the
|
|
31
|
+
* root instead of special-casing each way it can occur.
|
|
32
|
+
*/
|
|
33
|
+
const REGISTRY_KEY = Symbol.for('agent-health.test-registry.v1');
|
|
34
|
+
function getSharedState() {
|
|
35
|
+
// Invariant this design relies on: eval files are loaded SEQUENTIALLY
|
|
36
|
+
// (setActiveFile -> synchronously evaluate one file's top-level test()/
|
|
37
|
+
// describe() calls -> move to the next), never concurrently, within a
|
|
38
|
+
// process. `activeFile` and `describeStack` are shared state now (not
|
|
39
|
+
// just per-module-instance as before this fix), so two files loading in
|
|
40
|
+
// parallel would race on them. Verified true for both real callers as of
|
|
41
|
+
// this fix: services/sourceResolver.ts's two loops and
|
|
42
|
+
// cli/commands/benchmark.ts's file-mode loader all `await
|
|
43
|
+
// loadTestCasesFromModule(...)` inside a plain `for` loop, never
|
|
44
|
+
// `Promise.all`. If a future caller parallelizes file loading, this
|
|
45
|
+
// invariant breaks and registration could scramble across files.
|
|
46
|
+
const g = globalThis;
|
|
47
|
+
let state = g[REGISTRY_KEY];
|
|
48
|
+
if (!state) {
|
|
49
|
+
state = {
|
|
50
|
+
registries: new Map(),
|
|
51
|
+
hookRegistries: new Map(),
|
|
52
|
+
activeFile: null,
|
|
53
|
+
describeStack: [],
|
|
54
|
+
experimentalWarningEmitted: false,
|
|
55
|
+
};
|
|
56
|
+
g[REGISTRY_KEY] = state;
|
|
57
|
+
}
|
|
58
|
+
return state;
|
|
59
|
+
}
|
|
21
60
|
function emitExperimentalWarningOnce() {
|
|
22
|
-
|
|
61
|
+
const state = getSharedState();
|
|
62
|
+
if (state.experimentalWarningEmitted)
|
|
23
63
|
return;
|
|
24
|
-
experimentalWarningEmitted = true;
|
|
64
|
+
state.experimentalWarningEmitted = true;
|
|
25
65
|
if (readEnv('AH_SUPPRESS_EXPERIMENTAL', 'AGENT_HEALTH_SUPPRESS_EXPERIMENTAL') === '1')
|
|
26
66
|
return;
|
|
27
67
|
// eslint-disable-next-line no-console
|
|
@@ -32,15 +72,16 @@ function emitExperimentalWarningOnce() {
|
|
|
32
72
|
}
|
|
33
73
|
/** @internal */
|
|
34
74
|
export function _resetExperimentalWarning() {
|
|
35
|
-
experimentalWarningEmitted = false;
|
|
75
|
+
getSharedState().experimentalWarningEmitted = false;
|
|
36
76
|
}
|
|
37
77
|
export function setActiveFile(filePath) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
78
|
+
const state = getSharedState();
|
|
79
|
+
state.activeFile = filePath;
|
|
80
|
+
if (!state.registries.has(filePath)) {
|
|
81
|
+
state.registries.set(filePath, []);
|
|
41
82
|
}
|
|
42
|
-
if (!hookRegistries.has(filePath)) {
|
|
43
|
-
hookRegistries.set(filePath, []);
|
|
83
|
+
if (!state.hookRegistries.has(filePath)) {
|
|
84
|
+
state.hookRegistries.set(filePath, []);
|
|
44
85
|
}
|
|
45
86
|
}
|
|
46
87
|
export function test(name, optionsOrBody, maybeBody) {
|
|
@@ -62,17 +103,18 @@ export function test(name, optionsOrBody, maybeBody) {
|
|
|
62
103
|
if (typeof evaluate !== 'function') {
|
|
63
104
|
throw new Error(`test("${name}") requires a body function`);
|
|
64
105
|
}
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
106
|
+
const state = getSharedState();
|
|
107
|
+
const key = state.activeFile ?? DEFAULT_KEY;
|
|
108
|
+
if (!state.registries.has(key)) {
|
|
109
|
+
state.registries.set(key, []);
|
|
68
110
|
}
|
|
69
|
-
const registry = registries.get(key);
|
|
111
|
+
const registry = state.registries.get(key);
|
|
70
112
|
// Within-file uniqueness guard: a name+benchmarkPath pair must be unique.
|
|
71
113
|
// The same name in two different describe blocks is allowed because they
|
|
72
114
|
// map to different benchmarks.
|
|
73
|
-
const benchmarkPath = describeStack.length > 0 ? describeStack.join(' > ') : undefined;
|
|
115
|
+
const benchmarkPath = state.describeStack.length > 0 ? state.describeStack.join(' > ') : undefined;
|
|
74
116
|
if (registry.some(t => t.name === name && t.benchmarkPath === benchmarkPath)) {
|
|
75
|
-
const fileLabel = activeFile ? ` in ${activeFile}` : '';
|
|
117
|
+
const fileLabel = state.activeFile ? ` in ${state.activeFile}` : '';
|
|
76
118
|
const groupLabel = benchmarkPath ? ` (in describe "${benchmarkPath}")` : '';
|
|
77
119
|
throw new Error(`Duplicate test name "${name}"${groupLabel}${fileLabel}. ` +
|
|
78
120
|
`Test names must be unique within their describe block. ` +
|
|
@@ -82,7 +124,7 @@ export function test(name, optionsOrBody, maybeBody) {
|
|
|
82
124
|
name,
|
|
83
125
|
options,
|
|
84
126
|
evaluate,
|
|
85
|
-
sourceFile: activeFile ?? undefined,
|
|
127
|
+
sourceFile: state.activeFile ?? undefined,
|
|
86
128
|
benchmarkPath,
|
|
87
129
|
});
|
|
88
130
|
}
|
|
@@ -110,7 +152,8 @@ export function describe(name, fn) {
|
|
|
110
152
|
if (typeof fn !== 'function') {
|
|
111
153
|
throw new Error(`describe("${name}") requires a body function`);
|
|
112
154
|
}
|
|
113
|
-
|
|
155
|
+
const state = getSharedState();
|
|
156
|
+
state.describeStack.push(name);
|
|
114
157
|
try {
|
|
115
158
|
const result = fn();
|
|
116
159
|
if (result && typeof result.then === 'function') {
|
|
@@ -121,13 +164,14 @@ export function describe(name, fn) {
|
|
|
121
164
|
}
|
|
122
165
|
}
|
|
123
166
|
finally {
|
|
124
|
-
describeStack.pop();
|
|
167
|
+
state.describeStack.pop();
|
|
125
168
|
}
|
|
126
169
|
}
|
|
127
170
|
export function getRegisteredTests(filePath) {
|
|
171
|
+
const state = getSharedState();
|
|
128
172
|
if (filePath)
|
|
129
|
-
return [...(registries.get(filePath) ?? [])];
|
|
130
|
-
return [...registries.values()].flatMap(r => [...r]);
|
|
173
|
+
return [...(state.registries.get(filePath) ?? [])];
|
|
174
|
+
return [...state.registries.values()].flatMap(r => [...r]);
|
|
131
175
|
}
|
|
132
176
|
/**
|
|
133
177
|
* Return all hooks registered for the given file (or every file when no
|
|
@@ -135,20 +179,22 @@ export function getRegisteredTests(filePath) {
|
|
|
135
179
|
* effect on the registry.
|
|
136
180
|
*/
|
|
137
181
|
export function getRegisteredHooks(filePath) {
|
|
182
|
+
const state = getSharedState();
|
|
138
183
|
if (filePath)
|
|
139
|
-
return [...(hookRegistries.get(filePath) ?? [])];
|
|
140
|
-
return [...hookRegistries.values()].flatMap(r => [...r]);
|
|
184
|
+
return [...(state.hookRegistries.get(filePath) ?? [])];
|
|
185
|
+
return [...state.hookRegistries.values()].flatMap(r => [...r]);
|
|
141
186
|
}
|
|
142
187
|
export function clearRegistry(filePath) {
|
|
188
|
+
const state = getSharedState();
|
|
143
189
|
if (filePath) {
|
|
144
|
-
registries.delete(filePath);
|
|
145
|
-
hookRegistries.delete(filePath);
|
|
190
|
+
state.registries.delete(filePath);
|
|
191
|
+
state.hookRegistries.delete(filePath);
|
|
146
192
|
}
|
|
147
193
|
else {
|
|
148
|
-
registries.clear();
|
|
149
|
-
hookRegistries.clear();
|
|
194
|
+
state.registries.clear();
|
|
195
|
+
state.hookRegistries.clear();
|
|
150
196
|
}
|
|
151
|
-
activeFile = null;
|
|
197
|
+
state.activeFile = null;
|
|
152
198
|
}
|
|
153
199
|
/**
|
|
154
200
|
* Internal helper used by the four public hook registrars below.
|
|
@@ -163,15 +209,16 @@ function registerHook(kind, fn) {
|
|
|
163
209
|
if (typeof fn !== 'function') {
|
|
164
210
|
throw new Error(`${kind}() requires a function as its first argument`);
|
|
165
211
|
}
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
212
|
+
const state = getSharedState();
|
|
213
|
+
const key = state.activeFile ?? DEFAULT_KEY;
|
|
214
|
+
if (!state.hookRegistries.has(key)) {
|
|
215
|
+
state.hookRegistries.set(key, []);
|
|
169
216
|
}
|
|
170
|
-
const describePath = describeStack.length > 0 ? describeStack.join(' > ') : undefined;
|
|
171
|
-
hookRegistries.get(key).push({
|
|
217
|
+
const describePath = state.describeStack.length > 0 ? state.describeStack.join(' > ') : undefined;
|
|
218
|
+
state.hookRegistries.get(key).push({
|
|
172
219
|
kind,
|
|
173
220
|
fn,
|
|
174
|
-
sourceFile: activeFile ?? undefined,
|
|
221
|
+
sourceFile: state.activeFile ?? undefined,
|
|
175
222
|
describePath,
|
|
176
223
|
});
|
|
177
224
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../../testCases/define.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../../testCases/define.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../../testCases/judge.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK9C,8EAA8E;AAC9E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAuB3C,8EAA8E;AAC9E,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,cAAc,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACpC,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,IAAI,EAAE,SAAS,CAAC;IAChB,8DAA8D;IAC9D,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC;CACpB;AAED,uEAAuE;AACvE,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC;AAEnC;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../../testCases/judge.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK9C,8EAA8E;AAC9E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAuB3C,8EAA8E;AAC9E,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,cAAc,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACpC,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,IAAI,EAAE,SAAS,CAAC;IAChB,8DAA8D;IAC9D,OAAO,EAAE,OAAO,CAAC;IACjB,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,OAAO,IAAI,OAAO,CAAC;CACpB;AAED,uEAAuE;AACvE,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC;AAEnC;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAmBD,2EAA2E;AAC3E,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AA0CD,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,UAAU,UAAU;IAClB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA8BD;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,CACE,kBAAkB,EAAE,UAAU,GAAG,cAAc,EAAE,EACjD,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,EAChC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB;;;OAGG;IACH,OAAO,CACL,kBAAkB,EAAE,UAAU,GAAG,cAAc,EAAE,EACjD,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,EAChC,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AA4OD;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,EAAE,OAanB,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,QAAQ,CAAC,EAAE;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CA+BV"}
|
|
@@ -144,10 +144,19 @@ async function runJudge(resultOrTrajectory, claimOrClaims, options, role) {
|
|
|
144
144
|
// Record the success path identically whether the verdict came fresh from
|
|
145
145
|
// the endpoint or from the in-process cache.
|
|
146
146
|
const finalize = (raw, durationMs) => {
|
|
147
|
-
|
|
147
|
+
// Headline score precedence: legacy `accuracy` metric → server-computed
|
|
148
|
+
// weighted overall (custom evaluators declare their own dimensions and
|
|
149
|
+
// rarely emit `accuracy`) → none. Never fabricate a 0: pre-fix this
|
|
150
|
+
// defaulted to 0, so every custom-evaluator verdict rendered as
|
|
151
|
+
// "score 0%" — even passing ones.
|
|
152
|
+
const headline = typeof raw.metrics?.accuracy === 'number'
|
|
153
|
+
? raw.metrics.accuracy
|
|
154
|
+
: typeof raw.overallScore === 'number'
|
|
155
|
+
? raw.overallScore
|
|
156
|
+
: undefined;
|
|
148
157
|
const verdict = makeVerdict({
|
|
149
158
|
passFailStatus: raw.passFailStatus ?? 'failed',
|
|
150
|
-
accuracy,
|
|
159
|
+
accuracy: headline ?? 0,
|
|
151
160
|
reasoning: raw.llmJudgeReasoning ?? '',
|
|
152
161
|
role,
|
|
153
162
|
skipped: false,
|
|
@@ -159,10 +168,16 @@ async function runJudge(resultOrTrajectory, claimOrClaims, options, role) {
|
|
|
159
168
|
method: 'llm-judge',
|
|
160
169
|
role,
|
|
161
170
|
durationMs,
|
|
162
|
-
score
|
|
171
|
+
// Only record a score when the judge actually produced a headline
|
|
172
|
+
// number — a fabricated 0 renders as a misleading "score 0%".
|
|
173
|
+
...(headline !== undefined ? { score: headline / 100 } : {}),
|
|
163
174
|
reasoning: verdict.reasoning,
|
|
164
175
|
model: options?.model,
|
|
165
|
-
|
|
176
|
+
// NOTE: no `errorMessage` mirror. It used to copy `reasoning` verbatim
|
|
177
|
+
// on failure, which persisted the same multi-KB string twice and made
|
|
178
|
+
// the UI render it twice (once red as "error", once as "reasoning").
|
|
179
|
+
// `reasoning` is the single source of truth; consumers that need a
|
|
180
|
+
// failure detail fall back to it (see expect.toPass()).
|
|
166
181
|
// Preserve the rest of the judge payload — these were silently
|
|
167
182
|
// dropped before, which made SDK `judge()` calls strictly less
|
|
168
183
|
// informative than the legacy auto-judge path. See MatcherResult.
|
|
@@ -172,6 +187,9 @@ async function runJudge(resultOrTrajectory, claimOrClaims, options, role) {
|
|
|
172
187
|
...(raw.metrics && typeof raw.metrics === 'object'
|
|
173
188
|
? { judgeMetrics: { ...raw.metrics } }
|
|
174
189
|
: {}),
|
|
190
|
+
...(raw.extraFields && typeof raw.extraFields === 'object' && Object.keys(raw.extraFields).length > 0
|
|
191
|
+
? { judgeExtraFields: raw.extraFields }
|
|
192
|
+
: {}),
|
|
175
193
|
});
|
|
176
194
|
return verdict;
|
|
177
195
|
};
|