@opensearch-project/agent-health 0.5.2 → 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/README.md +1 -0
- package/cli/dist/index.js +2325 -961
- 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 +183 -3
- package/docs/CONFIGURATION.md +1 -1
- package/docs/CONNECTORS.md +1 -1
- package/docs/INSTRUMENT_WITH_OTEL.md +7 -0
- package/docs/SDK.md +178 -5
- package/docs/STORAGE_INDEX_FIELD_LIMITS.md +216 -0
- package/docs/skills/AGENT_HEALTH.md +55 -1
- package/docs/skills/add-connector/SKILL.md +5 -1
- package/examples/eval-files/demo.eval.js +1 -1
- package/examples/eval-files/ops-rca-classification.eval.js +71 -0
- package/examples/eval-files/ops-rca-evaluator.json +15 -0
- package/examples/eval-files/sdk-demo.eval.js +72 -0
- package/examples/eval-files/sdk-describe-demo.eval.js +50 -0
- package/examples/eval-files/sdk-hooks-demo.eval.js +1 -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/bedrockCompat.d.ts +27 -0
- package/lib/dist/lib/bedrockCompat.d.ts.map +1 -0
- package/lib/dist/lib/bedrockCompat.js +83 -0
- package/lib/dist/lib/bedrockCompat.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/benchmarkImage.d.ts +52 -0
- package/lib/dist/lib/benchmarkImage.d.ts.map +1 -0
- package/lib/dist/lib/benchmarkImage.js +113 -0
- package/lib/dist/lib/benchmarkImage.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/benchmarkVersionUtils.d.ts +13 -0
- package/lib/dist/lib/benchmarkVersionUtils.d.ts.map +1 -1
- package/lib/dist/lib/benchmarkVersionUtils.js +21 -0
- package/lib/dist/lib/benchmarkVersionUtils.js.map +1 -1
- package/lib/dist/lib/chunkedFetch.d.ts +18 -0
- package/lib/dist/lib/chunkedFetch.d.ts.map +1 -0
- package/lib/dist/lib/chunkedFetch.js +40 -0
- package/lib/dist/lib/chunkedFetch.js.map +1 -0
- package/lib/dist/lib/comparisonInsights.d.ts +151 -0
- package/lib/dist/lib/comparisonInsights.d.ts.map +1 -0
- package/lib/dist/lib/comparisonInsights.js +270 -0
- package/lib/dist/lib/comparisonInsights.js.map +1 -0
- package/lib/dist/lib/config/loader.d.ts.map +1 -1
- package/lib/dist/lib/config/loader.js +16 -1
- package/lib/dist/lib/config/loader.js.map +1 -1
- package/lib/dist/lib/config/types.d.ts +14 -0
- package/lib/dist/lib/config/types.d.ts.map +1 -1
- package/lib/dist/lib/constants.d.ts +11 -0
- package/lib/dist/lib/constants.d.ts.map +1 -1
- package/lib/dist/lib/constants.js +10 -1
- package/lib/dist/lib/constants.js.map +1 -1
- package/lib/dist/lib/contextFormat.d.ts +26 -0
- package/lib/dist/lib/contextFormat.d.ts.map +1 -0
- package/lib/dist/lib/contextFormat.js +28 -0
- package/lib/dist/lib/contextFormat.js.map +1 -0
- 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/envCompat.d.ts.map +1 -1
- package/lib/dist/lib/envCompat.js +14 -5
- package/lib/dist/lib/envCompat.js.map +1 -1
- package/lib/dist/lib/evaluationRerun.d.ts +102 -0
- package/lib/dist/lib/evaluationRerun.d.ts.map +1 -0
- package/lib/dist/lib/evaluationRerun.js +134 -0
- package/lib/dist/lib/evaluationRerun.js.map +1 -0
- 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/traces.d.ts +17 -2
- package/lib/dist/lib/matchers/traces.d.ts.map +1 -1
- package/lib/dist/lib/matchers/traces.js +136 -16
- package/lib/dist/lib/matchers/traces.js.map +1 -1
- package/lib/dist/lib/matchers/tracesPricing.d.ts +38 -0
- package/lib/dist/lib/matchers/tracesPricing.d.ts.map +1 -0
- package/lib/dist/lib/matchers/tracesPricing.js +64 -0
- package/lib/dist/lib/matchers/tracesPricing.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 +109 -5
- package/lib/dist/lib/runStats.d.ts.map +1 -1
- package/lib/dist/lib/runStats.js +193 -10
- 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 +35 -1
- package/lib/dist/lib/testCases/loader.d.ts.map +1 -1
- package/lib/dist/lib/testCases/loader.js +278 -31
- 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 +34 -0
- package/lib/dist/lib/utils.d.ts.map +1 -1
- package/lib/dist/lib/utils.js +49 -0
- package/lib/dist/lib/utils.js.map +1 -1
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts +68 -22
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts.map +1 -1
- package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js +148 -111
- 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 +95 -61
- package/lib/dist/services/connectors/subprocess/SubprocessConnector.js.map +1 -1
- package/lib/dist/services/evaluation/bedrockJudge.d.ts +18 -0
- package/lib/dist/services/evaluation/bedrockJudge.d.ts.map +1 -1
- package/lib/dist/services/evaluation/bedrockJudge.js +4 -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 +1 -1
- package/lib/dist/services/storage/asyncBenchmarkStorage.d.ts.map +1 -1
- package/lib/dist/services/storage/asyncBenchmarkStorage.js +30 -3
- package/lib/dist/services/storage/asyncBenchmarkStorage.js.map +1 -1
- package/lib/dist/services/storage/asyncRunStorage.d.ts +20 -1
- package/lib/dist/services/storage/asyncRunStorage.d.ts.map +1 -1
- package/lib/dist/services/storage/asyncRunStorage.js +125 -2
- package/lib/dist/services/storage/asyncRunStorage.js.map +1 -1
- package/lib/dist/services/storage/asyncTestCaseStorage.d.ts +18 -4
- package/lib/dist/services/storage/asyncTestCaseStorage.d.ts.map +1 -1
- package/lib/dist/services/storage/asyncTestCaseStorage.js +21 -4
- package/lib/dist/services/storage/asyncTestCaseStorage.js.map +1 -1
- package/lib/dist/services/storage/opensearchClient.d.ts +47 -12
- package/lib/dist/services/storage/opensearchClient.d.ts.map +1 -1
- package/lib/dist/services/storage/opensearchClient.js +12 -5
- package/lib/dist/services/storage/opensearchClient.js.map +1 -1
- package/lib/dist/services/traces/browserRecovery.d.ts +12 -1
- package/lib/dist/services/traces/browserRecovery.d.ts.map +1 -1
- package/lib/dist/services/traces/browserRecovery.js +35 -5
- 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/messageExtraction.d.ts.map +1 -1
- package/lib/dist/services/traces/messageExtraction.js +95 -33
- package/lib/dist/services/traces/messageExtraction.js.map +1 -1
- package/lib/dist/services/traces/spansToTrajectory.d.ts.map +1 -1
- package/lib/dist/services/traces/spansToTrajectory.js +51 -13
- package/lib/dist/services/traces/spansToTrajectory.js.map +1 -1
- package/lib/dist/services/traces/tracePoller.d.ts +27 -3
- package/lib/dist/services/traces/tracePoller.d.ts.map +1 -1
- package/lib/dist/services/traces/tracePoller.js +196 -33
- 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 +250 -3
- 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 +8 -5
- package/server/dist/app.js +5490 -1557
- package/server/dist/index.js +5490 -1557
- package/dist/assets/index-CCQRDlO0.js +0 -243
- package/dist/assets/index-CNHQVbcj.css +0 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright OpenSearch Contributors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/** Map a matched verdict keyword onto the canonical kind. */
|
|
6
|
+
function verdictKind(keyword) {
|
|
7
|
+
const k = keyword.toUpperCase();
|
|
8
|
+
if (k.includes('CONTRADICT') && !k.includes('MISSING'))
|
|
9
|
+
return 'contradicted';
|
|
10
|
+
if (k.includes('MISSING') || k.includes('NOT STATED'))
|
|
11
|
+
return 'missing';
|
|
12
|
+
if (k.includes('PARTIAL'))
|
|
13
|
+
return 'partial';
|
|
14
|
+
return 'stated';
|
|
15
|
+
}
|
|
16
|
+
// Verdict keywords the judge writes inline after a fact. Order matters:
|
|
17
|
+
// longest / most specific first so "MISSING/CONTRADICTED" isn't split.
|
|
18
|
+
const VERDICT_KEYWORD = /(MISSING\s*\/\s*CONTRADICTED|FULLY\s+STATED|PARTIALLY\s+STATED|NOT\s+STATED|CONTRADICTED|MISSING|PARTIAL(?:LY)?)/i;
|
|
19
|
+
// Parse at most this much reasoning — real verdicts are a few KB; a hard cap
|
|
20
|
+
// bounds regex work on pathological inputs (defense against backtracking
|
|
21
|
+
// blowups on adversarial multi-hundred-KB strings).
|
|
22
|
+
const MAX_PARSE_CHARS = 20_000;
|
|
23
|
+
// A fact item: list marker (`1.`, `1)`, `**Fact 1:`, `Required fact 1 (`),
|
|
24
|
+
// then the fact text (quoted or plain), a separator (—, -, :, en-dash, `):`),
|
|
25
|
+
// then the verdict keyword. Fact text is capped to keep matches sane.
|
|
26
|
+
// NOTE: deliberately no lookbehind — constructed-at-import regexes with
|
|
27
|
+
// lookbehind hard-crash report rendering on older WebKit. The leading
|
|
28
|
+
// whitespace/newline is consumed instead (harmless: markers never overlap).
|
|
29
|
+
const FACT_ITEM = new RegExp(String.raw `(?:^|[\s\n])` + // start of string or after whitespace (inline numbered lists)
|
|
30
|
+
String.raw `(?:\*\*)?(?:Required\s+fact\s+\d+|Fact\s+\d+|\d+)\s*[.):\u2013\u2014-]?\s*` + // marker
|
|
31
|
+
String.raw `(?:\*\*)?\s*` +
|
|
32
|
+
String.raw `['‘"“(]?(.{4,240}?)['’"”)]?` + // fact text (lazy)
|
|
33
|
+
String.raw `(?:\*\*)?\s*[\u2013\u2014:(\u2015-]+\s*(?:\*\*)?\s*` + // separator
|
|
34
|
+
VERDICT_KEYWORD.source + // verdict
|
|
35
|
+
String.raw `(?:\s+stated)?` + // "PARTIALLY stated"
|
|
36
|
+
String.raw `[.!]?\s*` +
|
|
37
|
+
// Trailing note: lazy, stopped by the NEXT numbered/bold fact item on the
|
|
38
|
+
// same line (inline lists put every fact in one paragraph) or line end.
|
|
39
|
+
String.raw `([^\n]*?)(?=\s\d+[.)]\s*['‘"“(*]|\s\*\*(?:Required\s+fact|Fact)|\n|$)`, 'gi');
|
|
40
|
+
/**
|
|
41
|
+
* Extract per-required-fact verdicts from judge reasoning prose.
|
|
42
|
+
* Returns `[]` when nothing that looks like a fact list is present —
|
|
43
|
+
* callers must fall back to showing the raw reasoning.
|
|
44
|
+
*/
|
|
45
|
+
export function parseFactVerdicts(reasoning) {
|
|
46
|
+
if (!reasoning || reasoning.length < 20)
|
|
47
|
+
return [];
|
|
48
|
+
const text = reasoning.slice(0, MAX_PARSE_CHARS);
|
|
49
|
+
const out = [];
|
|
50
|
+
const seen = new Set();
|
|
51
|
+
for (const m of text.matchAll(FACT_ITEM)) {
|
|
52
|
+
const factRaw = (m[1] ?? '').trim();
|
|
53
|
+
const keyword = m[2] ?? '';
|
|
54
|
+
// Guard against summary-phrase false positives like
|
|
55
|
+
// "4 facts fully stated (1.0 each)": require real fact text, not a
|
|
56
|
+
// recap that itself talks about facts/statements in aggregate.
|
|
57
|
+
if (!factRaw || factRaw.length < 8)
|
|
58
|
+
continue;
|
|
59
|
+
if (/^facts?\b/i.test(factRaw) || /\bfacts fully stated\b/i.test(factRaw))
|
|
60
|
+
continue;
|
|
61
|
+
// Strip markdown/bold leftovers and trailing separators.
|
|
62
|
+
const fact = factRaw.replace(/\*\*/g, '').replace(/[\u2013\u2014:-]+$/, '').trim();
|
|
63
|
+
const key = fact.toLowerCase();
|
|
64
|
+
if (seen.has(key))
|
|
65
|
+
continue;
|
|
66
|
+
seen.add(key);
|
|
67
|
+
let note = (m[3] ?? '').replace(/\*\*/g, '').trim().slice(0, 220);
|
|
68
|
+
// Notes that are just the start of the next list item are noise.
|
|
69
|
+
if (/^\d+[.)]/.test(note))
|
|
70
|
+
note = '';
|
|
71
|
+
out.push({ fact, verdict: verdictKind(keyword), ...(note ? { note } : {}) });
|
|
72
|
+
if (out.length >= 12)
|
|
73
|
+
break; // sanity cap
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
// Hex-ish document/article ids (8+ chars, at least one a–f so bare integers
|
|
78
|
+
// like "10000000" never qualify) — what RAG corpora and judge reasoning use
|
|
79
|
+
// when naming expected vs cited sources.
|
|
80
|
+
const HEX_ID_SCAN = /\b(?=[0-9]*[a-f])[0-9a-f]{8,64}\b/i;
|
|
81
|
+
/** First hex id within `window` chars after `index` in `text`, if any. */
|
|
82
|
+
function firstIdAfter(text, index, window = 140) {
|
|
83
|
+
const m = text.slice(index, index + window).match(HEX_ID_SCAN);
|
|
84
|
+
return m?.[0];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Detect an "expected source X but cited/retrieved Y" statement.
|
|
88
|
+
* Conservative: both ids must be present and differ.
|
|
89
|
+
*/
|
|
90
|
+
export function parseSourceMismatch(reasoning) {
|
|
91
|
+
if (!reasoning)
|
|
92
|
+
return null;
|
|
93
|
+
const text = reasoning.slice(0, MAX_PARSE_CHARS);
|
|
94
|
+
// Expected id: first hex id shortly after an "expected source …" mention.
|
|
95
|
+
// (A character-class "gap" can't work here — prose like "document is
|
|
96
|
+
// article" contains hex letters — so scan a window for the first id.)
|
|
97
|
+
const expectedKw = text.match(/expected\s+source\s+(?:document|article)?/i);
|
|
98
|
+
if (!expectedKw || expectedKw.index === undefined)
|
|
99
|
+
return null;
|
|
100
|
+
const expected = firstIdAfter(text, expectedKw.index + expectedKw[0].length);
|
|
101
|
+
if (!expected)
|
|
102
|
+
return null;
|
|
103
|
+
// Cited id: first differing hex id shortly after a cite/retrieve verb.
|
|
104
|
+
const citedKw = /(?:\bcited\b|\bretrieved\b|\busing\s+article\b|\bcites\b)/gi;
|
|
105
|
+
for (const m of text.matchAll(citedKw)) {
|
|
106
|
+
if (m.index === undefined)
|
|
107
|
+
continue;
|
|
108
|
+
const id = firstIdAfter(text, m.index + m[0].length);
|
|
109
|
+
if (id && id.toLowerCase() !== expected.toLowerCase()) {
|
|
110
|
+
return { expected, cited: id };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Compact form: "(b6c9353c vs 49d9e88f)" — either order relative to expected.
|
|
114
|
+
const vs = text.match(new RegExp(String.raw `([0-9a-f]{8,64})\s*(?:vs\.?|versus)\s*([0-9a-f]{8,64})`, 'i'));
|
|
115
|
+
if (vs) {
|
|
116
|
+
const [a, b] = [vs[1], vs[2]];
|
|
117
|
+
const other = a.toLowerCase() === expected.toLowerCase() ? b : a;
|
|
118
|
+
if (other && other.toLowerCase() !== expected.toLowerCase()) {
|
|
119
|
+
return { expected, cited: other };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
/** Shorten a long doc id for display: `49d9e88fadbf…` (first 8 chars). */
|
|
125
|
+
export function shortId(id) {
|
|
126
|
+
return id.length > 12 ? `${id.slice(0, 8)}…` : id;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=judgeReasoningParse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judgeReasoningParse.js","sourceRoot":"","sources":["../../../matchers/judgeReasoningParse.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,11 +18,26 @@
|
|
|
18
18
|
* accessor.
|
|
19
19
|
*/
|
|
20
20
|
import type { Span } from '../../types/index.js';
|
|
21
|
+
/**
|
|
22
|
+
* Where `totalCost` came from:
|
|
23
|
+
* - `'reported'` — every dollar came from a real cost attribute on a span.
|
|
24
|
+
* - `'computed'` — no span carried a cost attribute; the whole total was
|
|
25
|
+
* derived from token counts via the fallback pricing table.
|
|
26
|
+
* - `'mixed'` — some spans reported cost, others were computed.
|
|
27
|
+
* - `'none'` — no LLM spans, or no cost could be determined at all.
|
|
28
|
+
*/
|
|
29
|
+
export type CostSource = 'reported' | 'computed' | 'mixed' | 'none';
|
|
21
30
|
export interface TracesAccessor {
|
|
22
|
-
/** Sum of all
|
|
31
|
+
/** Sum of all prompt/completion/cache token-usage attrs across LLM spans. */
|
|
23
32
|
totalTokens: number;
|
|
24
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* Sum of all reported cost attrs, falling back to a computed estimate
|
|
35
|
+
* (from token counts + the model pricing table) when no span reports
|
|
36
|
+
* cost directly. See `costSource` to tell which happened.
|
|
37
|
+
*/
|
|
25
38
|
totalCost: number;
|
|
39
|
+
/** Whether `totalCost` was reported by spans, computed, both, or neither. */
|
|
40
|
+
costSource: CostSource;
|
|
26
41
|
/** Tool invocation summary derived from spans. */
|
|
27
42
|
toolCalls: ReadonlyArray<{
|
|
28
43
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traces.d.ts","sourceRoot":"","sources":["../../../matchers/traces.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"traces.d.ts","sourceRoot":"","sources":["../../../matchers/traces.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAGjD;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpE,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,UAAU,EAAE,UAAU,CAAC;IACvB,kDAAkD;IAClD,SAAS,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,+EAA+E;IAC/E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,6BAA6B;IAC7B,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,CASpD;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAYxE;AAgCD,wDAAwD;AACxD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,cAAc,CA+IjE"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Copyright OpenSearch Contributors
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
|
+
import { lookupModelRates, computeCost } from './tracesPricing.js';
|
|
5
6
|
/**
|
|
6
7
|
* Empty accessor — silent zeros. Used when the agent opted out of traces
|
|
7
8
|
* (`useTraces: false`). Reading any accessor returns `0` / `[]` so user
|
|
@@ -11,6 +12,7 @@ export function emptyTracesAccessor() {
|
|
|
11
12
|
return {
|
|
12
13
|
totalTokens: 0,
|
|
13
14
|
totalCost: 0,
|
|
15
|
+
costSource: 'none',
|
|
14
16
|
toolCalls: [],
|
|
15
17
|
spanDuration: () => 0,
|
|
16
18
|
spans: [],
|
|
@@ -33,48 +35,166 @@ export function unavailableTracesAccessor(reason) {
|
|
|
33
35
|
return {
|
|
34
36
|
get totalTokens() { return fail(); },
|
|
35
37
|
get totalCost() { return fail(); },
|
|
38
|
+
get costSource() { return fail(); },
|
|
36
39
|
get toolCalls() { return fail(); },
|
|
37
40
|
get spans() { return fail(); },
|
|
38
41
|
spanDuration(_name) { return fail(); },
|
|
39
42
|
};
|
|
40
43
|
}
|
|
44
|
+
const PROMPT_TOKEN_KEYS = [
|
|
45
|
+
'gen_ai.usage.prompt_tokens',
|
|
46
|
+
'gen_ai.usage.input_tokens',
|
|
47
|
+
'llm.usage.prompt_tokens',
|
|
48
|
+
'input_tokens',
|
|
49
|
+
];
|
|
50
|
+
const COMPLETION_TOKEN_KEYS = [
|
|
51
|
+
'gen_ai.usage.completion_tokens',
|
|
52
|
+
'gen_ai.usage.output_tokens',
|
|
53
|
+
'llm.usage.completion_tokens',
|
|
54
|
+
'output_tokens',
|
|
55
|
+
];
|
|
56
|
+
const CACHE_READ_TOKEN_KEYS = [
|
|
57
|
+
'gen_ai.usage.cache_read_input_tokens',
|
|
58
|
+
'gen_ai.usage.cache_read_tokens',
|
|
59
|
+
'cache_read_tokens',
|
|
60
|
+
];
|
|
61
|
+
const CACHE_CREATION_TOKEN_KEYS = [
|
|
62
|
+
'gen_ai.usage.cache_creation_input_tokens',
|
|
63
|
+
'gen_ai.usage.cache_creation_tokens',
|
|
64
|
+
'cache_creation_tokens',
|
|
65
|
+
];
|
|
66
|
+
const MODEL_ID_KEYS = ['gen_ai.request.model', 'gen_ai.response.model', 'model'];
|
|
67
|
+
const ALL_TOKEN_KEYS = [
|
|
68
|
+
...PROMPT_TOKEN_KEYS,
|
|
69
|
+
...COMPLETION_TOKEN_KEYS,
|
|
70
|
+
...CACHE_READ_TOKEN_KEYS,
|
|
71
|
+
...CACHE_CREATION_TOKEN_KEYS,
|
|
72
|
+
];
|
|
41
73
|
/** Build a TracesAccessor from a flat list of spans. */
|
|
42
74
|
export function buildTracesAccessor(spans) {
|
|
43
75
|
let totalTokens = 0;
|
|
44
|
-
let
|
|
76
|
+
let reportedCost = 0;
|
|
77
|
+
let computedCost = 0;
|
|
78
|
+
let hadReportedCost = false;
|
|
79
|
+
let hadComputedCost = false;
|
|
80
|
+
let tokenBearingSpanCount = 0;
|
|
81
|
+
// codex_review (PR #440): a span can have recognized tokens yet resolve
|
|
82
|
+
// NEITHER a reported cost NOR a computed one (unpriced/unresolved model) —
|
|
83
|
+
// this counter drives `costUnknowable` below so totalCost refuses to
|
|
84
|
+
// silently under-report just because *some other* span in the same trace
|
|
85
|
+
// happened to be priceable.
|
|
86
|
+
let unresolvedCostSpanCount = 0;
|
|
45
87
|
const toolCalls = [];
|
|
46
88
|
for (const span of spans) {
|
|
47
89
|
const attrs = span.attributes ?? {};
|
|
48
|
-
const promptTokens = pickNumber(attrs,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
90
|
+
const promptTokens = pickNumber(attrs, PROMPT_TOKEN_KEYS);
|
|
91
|
+
const completionTokens = pickNumber(attrs, COMPLETION_TOKEN_KEYS);
|
|
92
|
+
const cacheReadTokens = pickNumber(attrs, CACHE_READ_TOKEN_KEYS);
|
|
93
|
+
const cacheCreationTokens = pickNumber(attrs, CACHE_CREATION_TOKEN_KEYS);
|
|
94
|
+
const hasTokenAttr = promptTokens !== undefined ||
|
|
95
|
+
completionTokens !== undefined ||
|
|
96
|
+
cacheReadTokens !== undefined ||
|
|
97
|
+
cacheCreationTokens !== undefined;
|
|
98
|
+
if (hasTokenAttr)
|
|
99
|
+
tokenBearingSpanCount += 1;
|
|
58
100
|
if (promptTokens)
|
|
59
101
|
totalTokens += promptTokens;
|
|
60
102
|
if (completionTokens)
|
|
61
103
|
totalTokens += completionTokens;
|
|
62
|
-
|
|
104
|
+
if (cacheReadTokens)
|
|
105
|
+
totalTokens += cacheReadTokens;
|
|
106
|
+
if (cacheCreationTokens)
|
|
107
|
+
totalTokens += cacheCreationTokens;
|
|
108
|
+
const reported = pickNumber(attrs, [
|
|
63
109
|
'gen_ai.usage.cost_usd',
|
|
64
110
|
'gen_ai.usage.cost',
|
|
65
111
|
'llm.usage.cost_usd',
|
|
66
112
|
]);
|
|
67
|
-
if (
|
|
68
|
-
|
|
113
|
+
if (reported !== undefined) {
|
|
114
|
+
hadReportedCost = true;
|
|
115
|
+
reportedCost += reported;
|
|
116
|
+
}
|
|
117
|
+
else if (hasTokenAttr) {
|
|
118
|
+
// No reported cost attribute on this span — fall back to a computed
|
|
119
|
+
// estimate from token counts, if we know pricing for the model.
|
|
120
|
+
const modelId = pickString(attrs, MODEL_ID_KEYS);
|
|
121
|
+
const rates = lookupModelRates(modelId);
|
|
122
|
+
if (rates) {
|
|
123
|
+
hadComputedCost = true;
|
|
124
|
+
computedCost += computeCost({
|
|
125
|
+
input: promptTokens ?? 0,
|
|
126
|
+
output: completionTokens ?? 0,
|
|
127
|
+
cacheRead: cacheReadTokens ?? 0,
|
|
128
|
+
cacheCreation: cacheCreationTokens ?? 0,
|
|
129
|
+
}, rates);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// This span's tokens contribute to totalTokens but NOT to totalCost —
|
|
133
|
+
// without this counter that would be a silent, plausible-looking
|
|
134
|
+
// undercount rather than the loud failure #230 asks for.
|
|
135
|
+
unresolvedCostSpanCount += 1;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
69
138
|
// Tool spans
|
|
70
139
|
const toolName = pickString(attrs, ['gen_ai.tool.name', 'llm.tool.name']);
|
|
71
140
|
if (toolName) {
|
|
72
141
|
toolCalls.push({ name: toolName, durationMs: spanDurationMs(span) });
|
|
73
142
|
}
|
|
74
143
|
}
|
|
144
|
+
const totalCostValue = reportedCost + computedCost;
|
|
145
|
+
const costSource = hadReportedCost && hadComputedCost
|
|
146
|
+
? 'mixed'
|
|
147
|
+
: hadReportedCost
|
|
148
|
+
? 'reported'
|
|
149
|
+
: hadComputedCost
|
|
150
|
+
? 'computed'
|
|
151
|
+
: 'none';
|
|
152
|
+
// Issue class: spans exist, but none of them carry any token-usage
|
|
153
|
+
// attribute we recognize. Reading totalTokens/totalCost would silently
|
|
154
|
+
// return 0, letting matchers like `expect(traces.totalCost).lessThan(2)`
|
|
155
|
+
// pass vacuously (mirrors the #230 fail-loud philosophy). A trace that
|
|
156
|
+
// genuinely has recognized-but-zero-valued attributes is fine and must
|
|
157
|
+
// NOT throw — only the "we found nothing we understand" case throws.
|
|
158
|
+
const noRecognizedTokenAttrs = spans.length > 0 && tokenBearingSpanCount === 0;
|
|
159
|
+
// Issue class: tokens were found, but AT LEAST ONE token-bearing span
|
|
160
|
+
// resolved neither a reported cost nor a computed one (unpriced model,
|
|
161
|
+
// no cost attribute). Pre-codex_review this only threw when EVERY span
|
|
162
|
+
// was unresolved — a trace with 9 priced spans and 1 unpriced span
|
|
163
|
+
// silently under-reported totalCost by exactly the unpriced span's real
|
|
164
|
+
// spend while still returning a plausible-looking number (PR #440 review
|
|
165
|
+
// finding, blocker). Throw only when reading totalCost (tokens themselves
|
|
166
|
+
// are legitimately known in this case) — any unresolved span makes the
|
|
167
|
+
// total untrustworthy, not just a total absence of resolved spans.
|
|
168
|
+
const costUnknowable = totalTokens > 0 && unresolvedCostSpanCount > 0;
|
|
75
169
|
return {
|
|
76
|
-
totalTokens
|
|
77
|
-
|
|
170
|
+
get totalTokens() {
|
|
171
|
+
if (noRecognizedTokenAttrs) {
|
|
172
|
+
throw new Error(`traces fixture: ${spans.length} span(s) present but none carried a recognized ` +
|
|
173
|
+
`token-usage attribute (checked ${ALL_TOKEN_KEYS.join(', ')}). Reading totalTokens ` +
|
|
174
|
+
`would silently return 0 — either this agent's spans use an unsupported attribute ` +
|
|
175
|
+
`shape (extend buildTracesAccessor() in lib/matchers/traces.ts), or this test case ` +
|
|
176
|
+
`has no LLM spans and should use traces.spans / traces.toolCalls instead of totalTokens.`);
|
|
177
|
+
}
|
|
178
|
+
return totalTokens;
|
|
179
|
+
},
|
|
180
|
+
get totalCost() {
|
|
181
|
+
if (noRecognizedTokenAttrs && !hadReportedCost) {
|
|
182
|
+
throw new Error(`traces fixture: ${spans.length} span(s) present but none carried a recognized ` +
|
|
183
|
+
`token-usage attribute or a cost attribute, so totalCost cannot be determined. ` +
|
|
184
|
+
`Reading totalCost would silently return 0.`);
|
|
185
|
+
}
|
|
186
|
+
if (costUnknowable) {
|
|
187
|
+
throw new Error(`traces fixture: ${unresolvedCostSpanCount} of ${tokenBearingSpanCount} span(s) with token usage ` +
|
|
188
|
+
`carried neither a cost attribute nor a model id matching the fallback pricing table (see ` +
|
|
189
|
+
`lib/matchers/tracesPricing.ts). Reading totalCost would silently UNDER-report real spend by ` +
|
|
190
|
+
`omitting those spans rather than reflect it -- add the model(s) to the pricing table or stamp a ` +
|
|
191
|
+
`cost attribute on the span(s), or use traces.spans to inspect per-span usage directly.`);
|
|
192
|
+
}
|
|
193
|
+
return totalCostValue;
|
|
194
|
+
},
|
|
195
|
+
get costSource() {
|
|
196
|
+
return costSource;
|
|
197
|
+
},
|
|
78
198
|
toolCalls,
|
|
79
199
|
spanDuration(name) {
|
|
80
200
|
const hit = spans.find(s => s.name === name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traces.js","sourceRoot":"","sources":["../../../matchers/traces.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"traces.js","sourceRoot":"","sources":["../../../matchers/traces.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fallback pricing table used by `buildTracesAccessor()` (see
|
|
3
|
+
* `lib/matchers/traces.ts`) to *compute* `totalCost` when spans carry
|
|
4
|
+
* token-usage attributes but no cost attribute (this is the common case —
|
|
5
|
+
* most OTel exporters, including Claude Code's, emit raw token counts and
|
|
6
|
+
* leave cost calculation to the consumer).
|
|
7
|
+
*
|
|
8
|
+
* Rates are USD per **million tokens** (MTok), converted to per-token below.
|
|
9
|
+
* These are point-in-time *estimates* maintained by hand — update them when
|
|
10
|
+
* pricing changes. They are intentionally separate from
|
|
11
|
+
* `server/services/codingAgents/pricing.ts` (used by the coding-agent
|
|
12
|
+
* analytics/leaderboard feature): that table silently falls back to Sonnet
|
|
13
|
+
* pricing for unknown models, which is the wrong behavior here — an eval
|
|
14
|
+
* reading `traces.totalCost` for an unpriced model must know the number is
|
|
15
|
+
* incomplete (see `buildTracesAccessor`'s fail-loud handling), not get a
|
|
16
|
+
* silently-substituted estimate.
|
|
17
|
+
*/
|
|
18
|
+
export interface ModelRates {
|
|
19
|
+
/** USD per input (prompt) token. */
|
|
20
|
+
input: number;
|
|
21
|
+
/** USD per output (completion) token. */
|
|
22
|
+
output: number;
|
|
23
|
+
/** USD per cache-read token (cheaper than a fresh input token). */
|
|
24
|
+
cacheRead: number;
|
|
25
|
+
/** USD per cache-creation/write token (pricier than a fresh input token). */
|
|
26
|
+
cacheCreation: number;
|
|
27
|
+
}
|
|
28
|
+
/** Look up rates for a model id. Returns `undefined` when no rule matches. */
|
|
29
|
+
export declare function lookupModelRates(modelId: string | undefined): ModelRates | undefined;
|
|
30
|
+
export interface UsageTokens {
|
|
31
|
+
input: number;
|
|
32
|
+
output: number;
|
|
33
|
+
cacheRead: number;
|
|
34
|
+
cacheCreation: number;
|
|
35
|
+
}
|
|
36
|
+
/** Compute USD cost for a set of token counts against a model's rates. */
|
|
37
|
+
export declare function computeCost(tokens: UsageTokens, rates: ModelRates): number;
|
|
38
|
+
//# sourceMappingURL=tracesPricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracesPricing.d.ts","sourceRoot":"","sources":["../../../matchers/tracesPricing.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,UAAU;IACzB,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,aAAa,EAAE,MAAM,CAAC;CACvB;AA8CD,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAMpF;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAO1E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright OpenSearch Contributors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
const PER_MTOK = 1_000_000;
|
|
6
|
+
/**
|
|
7
|
+
* Estimated Bedrock/Anthropic Claude rates, USD per MTok:
|
|
8
|
+
* Sonnet class: $3 in / $15 out / $0.30 cache-read / $3.75 cache-write
|
|
9
|
+
* Opus class: $15 in / $75 out / $1.50 cache-read / $18.75 cache-write
|
|
10
|
+
* Haiku class: $0.80 in / $4 out / $0.08 cache-read / $1.00 cache-write
|
|
11
|
+
* Keyed by substrings matched case-insensitively against the span's model
|
|
12
|
+
* id (see `resolveModelId`), so both raw Anthropic ids
|
|
13
|
+
* (`claude-sonnet-4-6-...`) and Bedrock ids
|
|
14
|
+
* (`us.anthropic.claude-sonnet-4-6-...`) match.
|
|
15
|
+
*/
|
|
16
|
+
const RATE_TABLE = [
|
|
17
|
+
{
|
|
18
|
+
match: /opus/i,
|
|
19
|
+
rates: {
|
|
20
|
+
input: 15 / PER_MTOK,
|
|
21
|
+
output: 75 / PER_MTOK,
|
|
22
|
+
cacheRead: 1.5 / PER_MTOK,
|
|
23
|
+
cacheCreation: 18.75 / PER_MTOK,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
match: /haiku/i,
|
|
28
|
+
rates: {
|
|
29
|
+
input: 0.8 / PER_MTOK,
|
|
30
|
+
output: 4 / PER_MTOK,
|
|
31
|
+
cacheRead: 0.08 / PER_MTOK,
|
|
32
|
+
cacheCreation: 1.0 / PER_MTOK,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
// Sonnet is the default Claude class; matched last so opus/haiku take
|
|
37
|
+
// priority, but also serves as the generic "claude" match.
|
|
38
|
+
match: /sonnet|claude/i,
|
|
39
|
+
rates: {
|
|
40
|
+
input: 3 / PER_MTOK,
|
|
41
|
+
output: 15 / PER_MTOK,
|
|
42
|
+
cacheRead: 0.3 / PER_MTOK,
|
|
43
|
+
cacheCreation: 3.75 / PER_MTOK,
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
/** Look up rates for a model id. Returns `undefined` when no rule matches. */
|
|
48
|
+
export function lookupModelRates(modelId) {
|
|
49
|
+
if (!modelId)
|
|
50
|
+
return undefined;
|
|
51
|
+
for (const { match, rates } of RATE_TABLE) {
|
|
52
|
+
if (match.test(modelId))
|
|
53
|
+
return rates;
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
/** Compute USD cost for a set of token counts against a model's rates. */
|
|
58
|
+
export function computeCost(tokens, rates) {
|
|
59
|
+
return (tokens.input * rates.input +
|
|
60
|
+
tokens.output * rates.output +
|
|
61
|
+
tokens.cacheRead * rates.cacheRead +
|
|
62
|
+
tokens.cacheCreation * rates.cacheCreation);
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=tracesPricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracesPricing.js","sourceRoot":"","sources":["../../../matchers/tracesPricing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA+BH,MAAM,QAAQ,GAAG,SAAS,CAAC;AAE3B;;;;;;;;;GASG;AACH,MAAM,UAAU,GAAgD;IAC9D;QACE,KAAK,EAAE,OAAO;QACd,KAAK,EAAE;YACL,KAAK,EAAE,EAAE,GAAG,QAAQ;YACpB,MAAM,EAAE,EAAE,GAAG,QAAQ;YACrB,SAAS,EAAE,GAAG,GAAG,QAAQ;YACzB,aAAa,EAAE,KAAK,GAAG,QAAQ;SAChC;KACF;IACD;QACE,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE;YACL,KAAK,EAAE,GAAG,GAAG,QAAQ;YACrB,MAAM,EAAE,CAAC,GAAG,QAAQ;YACpB,SAAS,EAAE,IAAI,GAAG,QAAQ;YAC1B,aAAa,EAAE,GAAG,GAAG,QAAQ;SAC9B;KACF;IACD;QACE,sEAAsE;QACtE,2DAA2D;QAC3D,KAAK,EAAE,gBAAgB;QACvB,KAAK,EAAE;YACL,KAAK,EAAE,CAAC,GAAG,QAAQ;YACnB,MAAM,EAAE,EAAE,GAAG,QAAQ;YACrB,SAAS,EAAE,GAAG,GAAG,QAAQ;YACzB,aAAa,EAAE,IAAI,GAAG,QAAQ;SAC/B;KACF;CACF,CAAC;AAEF,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,OAA2B;IAC1D,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,KAAK,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,UAAU,EAAE,CAAC;QAC1C,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;IACxC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AASD,0EAA0E;AAC1E,MAAM,UAAU,WAAW,CAAC,MAAmB,EAAE,KAAiB;IAChE,OAAO,CACL,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK;QAC1B,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;QAC5B,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS;QAClC,MAAM,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -71,5 +71,30 @@ export interface MatcherResult {
|
|
|
71
71
|
trajectory_alignment_score?: number;
|
|
72
72
|
[k: string]: number | undefined;
|
|
73
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* True for a synthetic entry the runner appends when the test body threw
|
|
76
|
+
* before reaching further matcher calls in source order — distinct from
|
|
77
|
+
* `pass: false` (a matcher that DID run and failed). This row was never
|
|
78
|
+
* *attempted*; it marks that later expect()/judge()/evaluate() calls (if
|
|
79
|
+
* any) never ran because chai's bail-on-first-failure semantics stopped
|
|
80
|
+
* the body at the first throw. Always excluded from gate/pass-rate
|
|
81
|
+
* aggregation. See `appendNotReachedMarker()` in services/evaluation/
|
|
82
|
+
* index.ts and `expect.soft()` in lib/matchers/expect.ts for the mode
|
|
83
|
+
* that avoids needing this marker by not bailing at all.
|
|
84
|
+
*/
|
|
85
|
+
notReached?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Structured, non-metric judge output beyond the typed wire fields — the
|
|
88
|
+
* SDK-side mirror of `JudgeResponse.extraFields`. Any JSON key a judge
|
|
89
|
+
* prompt emits beyond the known schema lands here (captured by
|
|
90
|
+
* `server/services/judgeResponseParser.ts`), so prompt iteration surfaces
|
|
91
|
+
* new structure without code changes. Conventional keys the UI knows how
|
|
92
|
+
* to render when present:
|
|
93
|
+
*
|
|
94
|
+
* - `facts`: Array<{ fact: string; verdict: 'stated'|'partial'|'missing'|'contradicted'; rationale?: string; credit?: number }>
|
|
95
|
+
* - `failure_causes`: Array<{ cause: string; detail?: string; dimension?: string }>
|
|
96
|
+
* - `evidence`: { expected_sources?: string[]; cited_sources?: Array<string | { id: string; title?: string }> }
|
|
97
|
+
*/
|
|
98
|
+
judgeExtraFields?: Record<string, unknown>;
|
|
74
99
|
}
|
|
75
100
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../matchers/types.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,WAAW,GACX,QAAQ,GACR,WAAW,CAAC;AAEhB,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,qCAAqC;IACrC,MAAM,EAAE,aAAa,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IASf;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,KAAK,CAAC;QAC5B,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;KACrC,CAAC,CAAC;IAEH;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;KACjC,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../matchers/types.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,WAAW,GACX,QAAQ,GACR,WAAW,CAAC;AAEhB,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,qCAAqC;IACrC,MAAM,EAAE,aAAa,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IASf;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,KAAK,CAAC;QAC5B,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;KACrC,CAAC,CAAC;IAEH;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;KACjC,CAAC;IAEF;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC5C"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the CANONICAL run object for an id that may exist in two shapes:
|
|
3
|
+
* a legacy `BenchmarkRun` projection embedded in `benchmark.runs[]` (never
|
|
4
|
+
* carries `docType`, never kept in sync after the initial write) and a
|
|
5
|
+
* first-class `EvaluationRun` doc (`docType: 'evaluation-run'`). Runs
|
|
6
|
+
* created WITH a benchmarkId are dual-written as both (see
|
|
7
|
+
* `server/routes/storage/evaluationRuns.ts`) -- the first-class doc is
|
|
8
|
+
* always the freshest/most capable representation when it exists.
|
|
9
|
+
*
|
|
10
|
+
* Extracted out of RunInspectorPage.tsx (the first caller) so the
|
|
11
|
+
* resolution logic is reusable and independently testable rather than a
|
|
12
|
+
* page-local pattern other components/route handlers would have to
|
|
13
|
+
* reinvent (see #462's Retry-judgement work, which needs the exact same
|
|
14
|
+
* resolution to make its own EvaluationRun-only capability checks
|
|
15
|
+
* meaningful on the benchmark-scoped route).
|
|
16
|
+
*
|
|
17
|
+
* `fetchEvaluationRun` is injected (rather than importing
|
|
18
|
+
* `services/client` directly) so this stays a plain, synchronously
|
|
19
|
+
* testable function with no module-mocking required.
|
|
20
|
+
*/
|
|
21
|
+
import type { BenchmarkRun, EvaluationRun } from '../types/index.js';
|
|
22
|
+
export declare function resolveCanonicalEvaluationRun(runId: string, embeddedProjection: BenchmarkRun, fetchEvaluationRun: (id: string) => Promise<EvaluationRun>): Promise<BenchmarkRun | EvaluationRun>;
|
|
23
|
+
//# sourceMappingURL=resolveCanonicalRun.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveCanonicalRun.d.ts","sourceRoot":"","sources":["../../resolveCanonicalRun.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEpE,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,MAAM,EACb,kBAAkB,EAAE,YAAY,EAChC,kBAAkB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,GACzD,OAAO,CAAC,YAAY,GAAG,aAAa,CAAC,CAsBvC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright OpenSearch Contributors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
export async function resolveCanonicalEvaluationRun(runId, embeddedProjection, fetchEvaluationRun) {
|
|
6
|
+
try {
|
|
7
|
+
// Defensive `?? embeddedProjection`: some test doubles / API layers
|
|
8
|
+
// resolve to a falsy value on "not found" instead of throwing.
|
|
9
|
+
return (await fetchEvaluationRun(runId)) ?? embeddedProjection;
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
// A 404 means this run only ever exists as a legacy BenchmarkRun
|
|
13
|
+
// (pre-#399, no first-class doc) -- expected, silent fallback. Any
|
|
14
|
+
// OTHER failure (500, network error, auth) must NOT be silently
|
|
15
|
+
// treated the same way: falling back is still the right availability
|
|
16
|
+
// choice for a read-only inspector page (this page already degrades
|
|
17
|
+
// gracefully elsewhere -- see loadData()'s report-summary fallback),
|
|
18
|
+
// but masking a real failure identically to "doesn't exist" would
|
|
19
|
+
// hide it from anyone debugging why results/stats look stale.
|
|
20
|
+
if (err?.status !== 404) {
|
|
21
|
+
console.warn(`[resolveCanonicalEvaluationRun] Failed to fetch first-class EvaluationRun doc for ${runId} (falling back to the embedded projection):`, err?.message ?? err);
|
|
22
|
+
}
|
|
23
|
+
return embeddedProjection;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=resolveCanonicalRun.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveCanonicalRun.js","sourceRoot":"","sources":["../../resolveCanonicalRun.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAyBH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,KAAa,EACb,kBAAgC,EAChC,kBAA0D;IAE1D,IAAI,CAAC;QACH,oEAAoE;QACpE,+DAA+D;QAC/D,OAAO,CAAC,MAAM,kBAAkB,CAAC,KAAK,CAAC,CAAC,IAAI,kBAAkB,CAAC;IACjE,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,iEAAiE;QACjE,mEAAmE;QACnE,gEAAgE;QAChE,qEAAqE;QACrE,oEAAoE;QACpE,qEAAqE;QACrE,kEAAkE;QAClE,8DAA8D;QAC9D,IAAI,GAAG,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CACV,qFAAqF,KAAK,6CAA6C,EACvI,GAAG,EAAE,OAAO,IAAI,GAAG,CACpB,CAAC;QACJ,CAAC;QACD,OAAO,kBAAkB,CAAC;IAC5B,CAAC;AACH,CAAC"}
|