@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
|
@@ -14,7 +14,14 @@ export function isCodeFile(filename) {
|
|
|
14
14
|
const lower = filename.toLowerCase();
|
|
15
15
|
return CODE_EXTENSIONS.some(ext => lower.endsWith(ext));
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
// Re-exported so CLI/server importers keep a single import path
|
|
18
|
+
// (`@/lib/testCases/loader`) for both the loader and the language
|
|
19
|
+
// detector, while the browser-side EvalSourceCodeView component imports
|
|
20
|
+
// the same isomorphic implementation directly from `@/lib/utils` (this
|
|
21
|
+
// module pulls in `fs`/`module`, which are Node-only and unsafe to bundle
|
|
22
|
+
// into the browser).
|
|
23
|
+
export { detectSourceLanguage } from '../../lib/utils.js';
|
|
24
|
+
export function computeTestCaseHash(tc, fileSource) {
|
|
18
25
|
const content = JSON.stringify({
|
|
19
26
|
name: tc.name,
|
|
20
27
|
prompt: tc.options.prompt,
|
|
@@ -28,30 +35,138 @@ export function computeTestCaseHash(tc) {
|
|
|
28
35
|
// would never reach storage.
|
|
29
36
|
expectedOutcomes: tc.options.expectedOutcomes,
|
|
30
37
|
expectedTrajectory: tc.options.expectedTrajectory,
|
|
38
|
+
// Fold in the WHOLE file's raw text (optional -- omitted by callers that
|
|
39
|
+
// don't have it, e.g. existing unit tests exercising this function in
|
|
40
|
+
// isolation). Without this, editing ONLY the evaluate() body, a helper
|
|
41
|
+
// function, an import, or even just a comment would leave every
|
|
42
|
+
// options-derived field above unchanged, `sourceHash` would stay put,
|
|
43
|
+
// `bulkUpsert` would classify the row as unchanged, and the persisted
|
|
44
|
+
// `sourceCode` -- the entire point of the eval-source viewer -- would
|
|
45
|
+
// silently go stale relative to the real file on disk.
|
|
46
|
+
fileSource,
|
|
31
47
|
});
|
|
32
48
|
return createHash('sha256').update(content).digest('hex');
|
|
33
49
|
}
|
|
50
|
+
/** Upper bound on the persisted evaluate-body text (per test). */
|
|
51
|
+
export const DEFINITION_BODY_SOURCE_MAX_CHARS = 32 * 1024;
|
|
52
|
+
const BODY_TRUNCATION_MARKER = '\n/* … truncated — see whole file … */';
|
|
53
|
+
/**
|
|
54
|
+
* Build the per-test `definition` capture from a registered test.
|
|
55
|
+
*
|
|
56
|
+
* `options` goes through a JSON round-trip so anything a user smuggled into
|
|
57
|
+
* the options object that isn't data (a function, a symbol, `undefined`) is
|
|
58
|
+
* dropped rather than serialized as `{}` or rejected by storage. `bodySource`
|
|
59
|
+
* is `Function.prototype.toString()` of the evaluate callback — for the
|
|
60
|
+
* synthetic-CJS `.js`/`.ts` paths that's the text as it appeared in the
|
|
61
|
+
* executed source (esbuild-transpiled for `.ts`), bounded so a pathological
|
|
62
|
+
* body can't bloat the document.
|
|
63
|
+
*/
|
|
64
|
+
export function captureTestDefinition(tc) {
|
|
65
|
+
let options = {};
|
|
66
|
+
try {
|
|
67
|
+
const parsed = JSON.parse(JSON.stringify(tc.options ?? {}));
|
|
68
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
|
|
69
|
+
options = parsed;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Circular or otherwise unserializable options: persist nothing rather
|
|
73
|
+
// than fail the import. The whole-file view is still available.
|
|
74
|
+
}
|
|
75
|
+
let bodySource = '';
|
|
76
|
+
try {
|
|
77
|
+
bodySource = typeof tc.evaluate === 'function' ? Function.prototype.toString.call(tc.evaluate) : '';
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
bodySource = '';
|
|
81
|
+
}
|
|
82
|
+
let bodyTruncated = false;
|
|
83
|
+
if (bodySource.length > DEFINITION_BODY_SOURCE_MAX_CHARS) {
|
|
84
|
+
bodySource = bodySource.slice(0, DEFINITION_BODY_SOURCE_MAX_CHARS) + BODY_TRUNCATION_MARKER;
|
|
85
|
+
bodyTruncated = true;
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
registeredAs: 'sdk',
|
|
89
|
+
options,
|
|
90
|
+
bodySource,
|
|
91
|
+
...(bodyTruncated ? { bodyTruncated: true } : {}),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Memoized dynamic import of esbuild's `transformSync`. A plain module-level
|
|
96
|
+
* cached Promise, NOT a cross-load cache of any TRANSPILED code (see
|
|
97
|
+
* `requireLocalTsModule` below for that) -- this only avoids re-running
|
|
98
|
+
* `import('esbuild')` itself on every single file load. Resolved once
|
|
99
|
+
* per process; after that, every caller gets the same already-resolved
|
|
100
|
+
* function reference and can call it fully synchronously (required, since
|
|
101
|
+
* CommonJS `require()` -- and therefore this loader's `wrappedRequire`
|
|
102
|
+
* inside `runAsSyntheticCjs` -- cannot itself be async).
|
|
103
|
+
*/
|
|
104
|
+
let esbuildTransformSyncPromise;
|
|
105
|
+
function getEsbuildTransformSync() {
|
|
106
|
+
if (!esbuildTransformSyncPromise) {
|
|
107
|
+
esbuildTransformSyncPromise = import('esbuild').then(m => m.transformSync);
|
|
108
|
+
}
|
|
109
|
+
return esbuildTransformSyncPromise;
|
|
110
|
+
}
|
|
34
111
|
export async function loadTestCasesFromModule(filePath) {
|
|
35
112
|
const absPath = resolve(filePath);
|
|
113
|
+
// Read the raw file text up front, before any execution path below --
|
|
114
|
+
// both the .js and .ts (synthetic-CJS) paths reuse this single read AS
|
|
115
|
+
// the executed source. For .mjs, native `import()` reads the file
|
|
116
|
+
// independently via Node's own module loader a few lines later -- in the
|
|
117
|
+
// extremely narrow window where the file is edited between this read and
|
|
118
|
+
// that import resolving, `fileSource` could theoretically diverge from
|
|
119
|
+
// what actually ran. That's an accepted, practically negligible risk
|
|
120
|
+
// (same file, same synchronous-ish call, no network hop) rather than a
|
|
121
|
+
// guarantee.
|
|
122
|
+
const fileSource = readFileSync(absPath, 'utf-8');
|
|
36
123
|
// Clear any prior registration for this file and set it as active
|
|
37
124
|
clearRegistry(absPath);
|
|
38
125
|
setActiveFile(absPath);
|
|
126
|
+
// Resolved once per load (not per require()) so that any NESTED `.ts`
|
|
127
|
+
// require encountered synchronously while executing the CJS wrapper
|
|
128
|
+
// below can transpile without itself needing to `await` -- `require()`
|
|
129
|
+
// must be synchronous. Resolved for BOTH .js and .ts entry points (a
|
|
130
|
+
// `.eval.js` file requiring a shared `./helper.ts` hits the exact same
|
|
131
|
+
// "plain CJS can't load raw TypeScript" problem an `.eval.ts` entry does)
|
|
132
|
+
// -- skipped for `.mjs`, which never calls `runAsSyntheticCjs` at all.
|
|
133
|
+
const transformSync = absPath.endsWith('.mjs') ? undefined : await getEsbuildTransformSync();
|
|
134
|
+
// Per-load cache of already-transpiled-and-executed helper `.ts` modules,
|
|
135
|
+
// keyed by resolved absolute path. Deliberately scoped to THIS call (a
|
|
136
|
+
// local variable, not module-level) so a helper required twice within
|
|
137
|
+
// ONE load executes exactly once (matching normal CJS require() caching
|
|
138
|
+
// semantics for the duration of a single load), but nothing survives
|
|
139
|
+
// into the NEXT `loadTestCasesFromModule` call for the same file --
|
|
140
|
+
// consistent with the top-level file itself never being cached across
|
|
141
|
+
// loads either (see the .ts branch's rationale below).
|
|
142
|
+
const tsModuleCache = new Map();
|
|
39
143
|
let module;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
144
|
+
// Execute `code` (already-valid CJS source) in a fresh Module instance,
|
|
145
|
+
// with our test() registrar injected via require() interception. Shared
|
|
146
|
+
// by real .eval.js files AND by the esbuild-transpiled .eval.ts path
|
|
147
|
+
// below — both need the exact same wrappedRequire behavior so a
|
|
148
|
+
// fixture's `require(...)` call for the SDK package name resolves to the
|
|
149
|
+
// SAME authoring surface (and therefore the same shared registry)
|
|
150
|
+
// regardless of which path produced the CJS source. Building a fresh
|
|
151
|
+
// `Module` + `eval()` on every call (never caching) is what lets a file
|
|
152
|
+
// be re-loaded any number of times in one process and register tests
|
|
153
|
+
// again each time — see the .ts branch below for why that matters.
|
|
154
|
+
//
|
|
155
|
+
// `modulePath` is the file THIS particular call is executing -- the
|
|
156
|
+
// outer entry file on the first call, or a resolved helper `.ts` path on
|
|
157
|
+
// a recursive call from `requireLocalTsModule` below.
|
|
158
|
+
const runAsSyntheticCjs = (code, modulePath) => {
|
|
159
|
+
const fileDir = dirname(modulePath);
|
|
45
160
|
// NOTE: do not call require('module') here — this file is bundled as ESM
|
|
46
161
|
// by esbuild for the server, and Dynamic require of built-ins is unsupported
|
|
47
162
|
// in ESM output. Use the statically-imported NodeModule instead.
|
|
48
163
|
const Module = NodeModule;
|
|
49
|
-
const m = new Module(
|
|
50
|
-
m.filename =
|
|
164
|
+
const m = new Module(modulePath);
|
|
165
|
+
m.filename = modulePath;
|
|
51
166
|
m.paths = Module._nodeModulePaths(fileDir);
|
|
52
167
|
// Provide a require function scoped to the file's directory, but override
|
|
53
168
|
// any require of the define module to return our own instance
|
|
54
|
-
const fileRequire = createRequire(
|
|
169
|
+
const fileRequire = createRequire(modulePath);
|
|
55
170
|
// Match if `id` looks like our own define module before doing any
|
|
56
171
|
// filesystem resolution. Required because:
|
|
57
172
|
// 1) the loader is bundled as ESM by esbuild, so synthetic CJS
|
|
@@ -75,44 +190,172 @@ export async function loadTestCasesFromModule(filePath) {
|
|
|
75
190
|
// source of truth shared with the package exports (see authoringSurface)
|
|
76
191
|
// so `.js` and `.ts`/`.mjs` files see the SAME surface — no drift (#232).
|
|
77
192
|
const sdkExports = getAuthoringSurface();
|
|
193
|
+
// A helper `.ts` module required (directly or transitively) from this
|
|
194
|
+
// file. Transpiled with the SAME esbuild settings as the entry file and
|
|
195
|
+
// executed through this SAME `runAsSyntheticCjs` function recursively --
|
|
196
|
+
// otherwise `import './helper.ts'` in the entry file, rewritten by
|
|
197
|
+
// esbuild's straight CJS transform into `require('./helper.ts')`, would
|
|
198
|
+
// reach real Node's `require()`, which has no loader registered for a
|
|
199
|
+
// raw `.ts` extension and throws (an ERR_UNKNOWN_FILE_EXTENSION-shaped
|
|
200
|
+
// failure, the exact class of bug this loader already fixes for the
|
|
201
|
+
// ENTRY file -- multi-file .eval.ts needs the identical fix applied at
|
|
202
|
+
// every nested require, not just the top-level import()).
|
|
203
|
+
const requireLocalTsModule = (resolvedTsPath) => {
|
|
204
|
+
const cached = tsModuleCache.get(resolvedTsPath);
|
|
205
|
+
if (cached !== undefined)
|
|
206
|
+
return cached;
|
|
207
|
+
if (!transformSync) {
|
|
208
|
+
// Unreachable in practice -- transformSync is resolved above for
|
|
209
|
+
// every extension that can reach this function (.js/.ts entries)
|
|
210
|
+
// -- but keeps the error path honest if that ever changes.
|
|
211
|
+
throw new Error(`Cannot import TypeScript file: ${resolvedTsPath}\n` +
|
|
212
|
+
'esbuild (required to load .ts files) was not resolved for this load.');
|
|
213
|
+
}
|
|
214
|
+
const helperSource = readFileSync(resolvedTsPath, 'utf-8');
|
|
215
|
+
const helperCjs = transformSync(helperSource, {
|
|
216
|
+
loader: 'ts',
|
|
217
|
+
format: 'cjs',
|
|
218
|
+
target: 'node18',
|
|
219
|
+
sourcefile: resolvedTsPath,
|
|
220
|
+
}).code;
|
|
221
|
+
const helperExports = runAsSyntheticCjs(helperCjs, resolvedTsPath);
|
|
222
|
+
tsModuleCache.set(resolvedTsPath, helperExports);
|
|
223
|
+
return helperExports;
|
|
224
|
+
};
|
|
78
225
|
const wrappedRequire = (id) => {
|
|
79
226
|
if (isDefineId(id) || isPackageName(id)) {
|
|
80
227
|
return sdkExports;
|
|
81
228
|
}
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
229
|
+
// Resolve once, up front, so both the "is this our own define
|
|
230
|
+
// module by a different path" check below AND the new "does this
|
|
231
|
+
// resolve to a raw .ts file" check can reuse the same resolution
|
|
232
|
+
// instead of duplicating fileRequire.resolve() calls.
|
|
233
|
+
let resolved;
|
|
85
234
|
try {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
235
|
+
resolved = fileRequire.resolve(id);
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// ignore unresolvable IDs — the fileRequire() call below will
|
|
239
|
+
// surface the real error (e.g. MODULE_NOT_FOUND)
|
|
240
|
+
}
|
|
241
|
+
if (resolved) {
|
|
242
|
+
const normalizedResolved = resolved.replace(/\\/g, '/');
|
|
243
|
+
// Fall back to a resolution-based check so that fixtures requiring
|
|
244
|
+
// the SDK by absolute path or via the published package name still
|
|
245
|
+
// hand back our test() registrar (and therefore land in our
|
|
246
|
+
// file-scoped registry).
|
|
247
|
+
if (normalizedResolved.endsWith('/lib/testCases/define.js') ||
|
|
248
|
+
normalizedResolved.endsWith('/lib/testCases/define')) {
|
|
90
249
|
return sdkExports;
|
|
91
250
|
}
|
|
251
|
+
if (normalizedResolved.endsWith('.ts')) {
|
|
252
|
+
return requireLocalTsModule(resolved);
|
|
253
|
+
}
|
|
92
254
|
}
|
|
93
|
-
|
|
94
|
-
|
|
255
|
+
try {
|
|
256
|
+
return fileRequire(id);
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
if (err.code === 'ERR_REQUIRE_ESM') {
|
|
260
|
+
throw new Error(`.eval.ts fixtures cannot import ESM-only packages via require() (attempted: '${id}').\n` +
|
|
261
|
+
`'${id}' has no CommonJS entry point, and .eval.ts files execute as synthetic CJS.\n` +
|
|
262
|
+
'Use .eval.mjs (real ESM -- can import ESM-only packages) or pre-compile to .eval.js instead.');
|
|
263
|
+
}
|
|
264
|
+
throw err;
|
|
95
265
|
}
|
|
96
|
-
return fileRequire(id);
|
|
97
266
|
};
|
|
98
267
|
wrappedRequire.resolve = fileRequire.resolve;
|
|
99
268
|
const wrapper = `(function(exports, require, module, __filename, __dirname) { ${code}\n});`;
|
|
100
269
|
const compiledFn = eval(wrapper);
|
|
101
|
-
compiledFn(m.exports, wrappedRequire, m,
|
|
102
|
-
|
|
270
|
+
compiledFn(m.exports, wrappedRequire, m, modulePath, fileDir);
|
|
271
|
+
return m.exports;
|
|
272
|
+
};
|
|
273
|
+
if (absPath.endsWith('.js')) {
|
|
274
|
+
// For CJS .js files, execute in a fresh context with our test() function
|
|
275
|
+
// injected. This avoids module caching issues across multiple loads.
|
|
276
|
+
module = runAsSyntheticCjs(fileSource, absPath);
|
|
277
|
+
}
|
|
278
|
+
else if (absPath.endsWith('.ts')) {
|
|
279
|
+
// .eval.ts ALWAYS goes through the esbuild-transpile -> synthetic-CJS
|
|
280
|
+
// path below, on every Node version — never a native `import()`, not
|
|
281
|
+
// even as a "try native first, fall back to esbuild" strategy. Two
|
|
282
|
+
// reasons this has to be unconditional rather than fallback-only:
|
|
283
|
+
//
|
|
284
|
+
// 1. Dual semantics: native `import()` under Node 22.6+/24's built-in
|
|
285
|
+
// TypeScript type-stripping gives the file REAL ESM module
|
|
286
|
+
// semantics (its own module registry entry, `import.meta`,
|
|
287
|
+
// top-level `await`, live bindings) — a completely different
|
|
288
|
+
// execution model from the synthetic-CJS path a fallback-only
|
|
289
|
+
// design would give the exact same file on Node <22.6. Two Node
|
|
290
|
+
// majors running one .eval.ts file through two different module
|
|
291
|
+
// systems is exactly the kind of gap that let the shared-registry
|
|
292
|
+
// bug documented above (`globalThis[Symbol.for(...)]`) happen in
|
|
293
|
+
// the first place — unifying on one path removes the gap instead
|
|
294
|
+
// of quietly reintroducing a second copy of it.
|
|
295
|
+
// 2. ESM cache staleness: `import()` caches by resolved URL. A
|
|
296
|
+
// long-lived server process re-loading the SAME .eval.ts file a
|
|
297
|
+
// second time (a normal `agent-health benchmark -f` re-run after
|
|
298
|
+
// editing the fixture, not an exotic case) would silently get back
|
|
299
|
+
// the ALREADY-cached module without re-executing its top-level
|
|
300
|
+
// code, so `test()`/`describe()` never fire a second time and the
|
|
301
|
+
// `clearRegistry()` call above has nothing to refill — "has no
|
|
302
|
+
// test cases" on the second load with no code change at all.
|
|
303
|
+
// `.eval.js` never had this problem: `runAsSyntheticCjs` builds a
|
|
304
|
+
// fresh `Module` instance and `eval()`s the source on every single
|
|
305
|
+
// call, uncached. `.eval.ts` now shares that exact same
|
|
306
|
+
// never-cached execution path.
|
|
307
|
+
//
|
|
308
|
+
// Trade-off this accepts: an .eval.ts fixture can no longer use
|
|
309
|
+
// `import.meta` or a top-level `await` (esbuild's CJS output has
|
|
310
|
+
// neither) — documented in docs/SDK.md. Same trade-off applies to any
|
|
311
|
+
// helper `.ts` file it imports (see `requireLocalTsModule` above).
|
|
312
|
+
// esbuild is a required runtime dependency of this package
|
|
313
|
+
// specifically because of this unconditional path (see package.json
|
|
314
|
+
// "dependencies").
|
|
315
|
+
if (!transformSync) {
|
|
316
|
+
throw new Error(`Cannot import TypeScript file: ${filePath}\nesbuild was not resolved.`);
|
|
317
|
+
}
|
|
318
|
+
let cjsSource;
|
|
319
|
+
try {
|
|
320
|
+
cjsSource = transformSync(fileSource, {
|
|
321
|
+
loader: 'ts',
|
|
322
|
+
format: 'cjs',
|
|
323
|
+
target: 'node18',
|
|
324
|
+
sourcefile: absPath,
|
|
325
|
+
}).code;
|
|
326
|
+
}
|
|
327
|
+
catch (esbuildErr) {
|
|
328
|
+
throw new Error(`Cannot import TypeScript file: ${filePath}\n` +
|
|
329
|
+
`esbuild (required to load .eval.ts files) failed to transpile it: ${esbuildErr.message}\n` +
|
|
330
|
+
'Or pre-compile .eval.ts to .eval.js before running.');
|
|
331
|
+
}
|
|
332
|
+
module = runAsSyntheticCjs(cjsSource, absPath);
|
|
103
333
|
}
|
|
104
334
|
else {
|
|
105
|
-
//
|
|
335
|
+
// .eval.mjs: plain ESM with no TypeScript to strip, so native
|
|
336
|
+
// `import()` works unconditionally on every Node version this package
|
|
337
|
+
// supports — it stays the only path for this extension. Unlike .ts,
|
|
338
|
+
// there is no synthetic-CJS equivalent to unify onto here (real ESM
|
|
339
|
+
// files, `import.meta`, top-level `await`, etc. are all first-class
|
|
340
|
+
// for .mjs, and always were).
|
|
341
|
+
//
|
|
342
|
+
// Same ESM cache-staleness bug class fixed for .ts above (see that
|
|
343
|
+
// branch's rationale #2) applies here too: `import()` caches by
|
|
344
|
+
// resolved URL, so re-loading the SAME .eval.mjs file a second time in
|
|
345
|
+
// one process (a normal `agent-health benchmark -f` re-run after
|
|
346
|
+
// editing the fixture) would otherwise silently return the
|
|
347
|
+
// already-executed cached module without re-running its top-level
|
|
348
|
+
// `test()` calls. Cache-busted with a unique query string per load --
|
|
349
|
+
// there is no synthetic-CJS escape hatch available for real ESM the
|
|
350
|
+
// way there is for .ts, so this is the fix here. Accepted cost: every
|
|
351
|
+
// reload leaks one cached module instance under a never-reused query
|
|
352
|
+
// string for the life of the process -- negligible for CLI/server
|
|
353
|
+
// process lifetimes (a handful to a few hundred loads, not millions).
|
|
106
354
|
try {
|
|
107
|
-
const fileUrl = pathToFileURL(absPath).href
|
|
355
|
+
const fileUrl = `${pathToFileURL(absPath).href}?ah-reload=${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
108
356
|
module = await import(fileUrl);
|
|
109
357
|
}
|
|
110
358
|
catch (err) {
|
|
111
|
-
if (err.code === 'ERR_UNKNOWN_FILE_EXTENSION' && absPath.endsWith('.ts')) {
|
|
112
|
-
throw new Error(`Cannot import TypeScript file: ${filePath}\n` +
|
|
113
|
-
'Install tsx as a dependency: npm install tsx\n' +
|
|
114
|
-
'Or pre-compile .eval.ts to .eval.js before running.');
|
|
115
|
-
}
|
|
116
359
|
throw new Error(`Failed to import module: ${filePath}\n${err.message}`);
|
|
117
360
|
}
|
|
118
361
|
}
|
|
@@ -124,10 +367,14 @@ export async function loadTestCasesFromModule(filePath) {
|
|
|
124
367
|
if (testCases.length === 0) {
|
|
125
368
|
throw new Error(`Module ${filePath} has no test cases. Register tests with test(name, options?, body) inside the file.`);
|
|
126
369
|
}
|
|
127
|
-
// Compute per-test-case hash
|
|
370
|
+
// Compute per-test-case hash. Includes fileSource (see
|
|
371
|
+
// computeTestCaseHash) so ANY change to the file -- not just the
|
|
372
|
+
// options fields already tracked -- invalidates the hash and triggers a
|
|
373
|
+
// re-persist, keeping the stored sourceCode in sync with disk.
|
|
128
374
|
const loaded = testCases.map(tc => ({
|
|
129
375
|
...tc,
|
|
130
|
-
hash: computeTestCaseHash(tc),
|
|
376
|
+
hash: computeTestCaseHash(tc, fileSource),
|
|
377
|
+
definition: captureTestDefinition(tc),
|
|
131
378
|
}));
|
|
132
379
|
// Derive describe-group → test names mapping. Tests outside any
|
|
133
380
|
// describe() have benchmarkPath=undefined and are excluded; the CLI/
|
|
@@ -144,6 +391,6 @@ export async function loadTestCasesFromModule(filePath) {
|
|
|
144
391
|
// beforeEach/afterEach/beforeAll/afterAll were called — the orchestrator
|
|
145
392
|
// is a no-op in that case so existing tests are unaffected.
|
|
146
393
|
const hooks = getRegisteredHooks(absPath);
|
|
147
|
-
return { testCases: loaded, filePath: absPath, benchmarks, hooks };
|
|
394
|
+
return { testCases: loaded, filePath: absPath, benchmarks, hooks, fileSource };
|
|
148
395
|
}
|
|
149
396
|
//# sourceMappingURL=loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../testCases/loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../testCases/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { TrajectoryStep } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Re-derive the intended `user` step for one specific, unambiguous legacy
|
|
4
|
+
* shape: a `thinking` step whose content starts with the literal `User: `
|
|
5
|
+
* echo prefix. We can't retroactively rewrite stored reports, so every
|
|
6
|
+
* surface that renders or compares trajectories (the Test Case Output tab,
|
|
7
|
+
* side-by-side comparison views, and the trajectory diff/similarity engine)
|
|
8
|
+
* calls this at read time instead of leaving old reports permanently
|
|
9
|
+
* mislabeled — and, just as importantly, so an old-shape report and a
|
|
10
|
+
* freshly-run new-shape report showing the identical prompt don't register
|
|
11
|
+
* as a false "modified"/"added+removed" diff purely because of the step's
|
|
12
|
+
* `type` and `content` prefix.
|
|
13
|
+
*
|
|
14
|
+
* Deliberately NOT restricted to index 0: the old producers emitted this
|
|
15
|
+
* shape for every user turn in a multi-turn session, not just the opening
|
|
16
|
+
* one, so restricting the check to the first step would leave later turns
|
|
17
|
+
* in old reports mislabeled. The exact-prefix match is a strong, specific
|
|
18
|
+
* signal (a real chain-of-thought paragraph starting with the literal
|
|
19
|
+
* string "User: ") so the false-positive risk of checking every step is
|
|
20
|
+
* low and no worse than the risk already accepted for the first step.
|
|
21
|
+
*/
|
|
22
|
+
export declare function normalizeLegacyUserStep(step: TrajectoryStep): TrajectoryStep;
|
|
23
|
+
/** Apply {@link normalizeLegacyUserStep} across a full trajectory. */
|
|
24
|
+
export declare function normalizeTrajectorySteps(steps: TrajectoryStep[]): TrajectoryStep[];
|
|
25
|
+
//# sourceMappingURL=trajectoryStepDisplay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trajectoryStepDisplay.d.ts","sourceRoot":"","sources":["../../trajectoryStepDisplay.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAUzC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc,CAK5E;AAED,sEAAsE;AACtE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAElF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright OpenSearch Contributors
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Legacy prefix stamped by older producers (services/traces/spansToTrajectory.ts,
|
|
7
|
+
* pre owner-papercut fix) that echoed the user's prompt as a `thinking` step
|
|
8
|
+
* instead of giving it its own `'user'` step type. Producers no longer emit
|
|
9
|
+
* this shape, but old persisted reports still have it.
|
|
10
|
+
*/
|
|
11
|
+
const LEGACY_USER_PREFIX = 'User: ';
|
|
12
|
+
/**
|
|
13
|
+
* Re-derive the intended `user` step for one specific, unambiguous legacy
|
|
14
|
+
* shape: a `thinking` step whose content starts with the literal `User: `
|
|
15
|
+
* echo prefix. We can't retroactively rewrite stored reports, so every
|
|
16
|
+
* surface that renders or compares trajectories (the Test Case Output tab,
|
|
17
|
+
* side-by-side comparison views, and the trajectory diff/similarity engine)
|
|
18
|
+
* calls this at read time instead of leaving old reports permanently
|
|
19
|
+
* mislabeled — and, just as importantly, so an old-shape report and a
|
|
20
|
+
* freshly-run new-shape report showing the identical prompt don't register
|
|
21
|
+
* as a false "modified"/"added+removed" diff purely because of the step's
|
|
22
|
+
* `type` and `content` prefix.
|
|
23
|
+
*
|
|
24
|
+
* Deliberately NOT restricted to index 0: the old producers emitted this
|
|
25
|
+
* shape for every user turn in a multi-turn session, not just the opening
|
|
26
|
+
* one, so restricting the check to the first step would leave later turns
|
|
27
|
+
* in old reports mislabeled. The exact-prefix match is a strong, specific
|
|
28
|
+
* signal (a real chain-of-thought paragraph starting with the literal
|
|
29
|
+
* string "User: ") so the false-positive risk of checking every step is
|
|
30
|
+
* low and no worse than the risk already accepted for the first step.
|
|
31
|
+
*/
|
|
32
|
+
export function normalizeLegacyUserStep(step) {
|
|
33
|
+
if (step.type === 'thinking' && step.content.startsWith(LEGACY_USER_PREFIX)) {
|
|
34
|
+
return { ...step, type: 'user', content: step.content.slice(LEGACY_USER_PREFIX.length) };
|
|
35
|
+
}
|
|
36
|
+
return step;
|
|
37
|
+
}
|
|
38
|
+
/** Apply {@link normalizeLegacyUserStep} across a full trajectory. */
|
|
39
|
+
export function normalizeTrajectorySteps(steps) {
|
|
40
|
+
return steps.map(normalizeLegacyUserStep);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=trajectoryStepDisplay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trajectoryStepDisplay.js","sourceRoot":"","sources":["../../trajectoryStepDisplay.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAoB;IAC1D,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC5E,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC3F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,wBAAwB,CAAC,KAAuB;IAC9D,OAAO,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;AAC5C,CAAC"}
|
package/lib/dist/lib/utils.d.ts
CHANGED
|
@@ -26,6 +26,25 @@ export declare const formatRelativeTime: (timestamp: string) => string;
|
|
|
26
26
|
* Gets the display name for a model ID from config
|
|
27
27
|
*/
|
|
28
28
|
export declare const getModelName: (modelId: string) => string;
|
|
29
|
+
/**
|
|
30
|
+
* Display label for the judge model column on the Evaluation Runs page.
|
|
31
|
+
* Judge model ids share the same registry as agent model ids
|
|
32
|
+
* (DEFAULT_CONFIG.models), so this reuses {@link getModelName} for the
|
|
33
|
+
* shortened display name. Runs created before `judgeModelId` was tracked
|
|
34
|
+
* (or agentic-provider judges that pick their own model) have no value —
|
|
35
|
+
* render an em dash rather than a blank cell so the missing-field state is
|
|
36
|
+
* visually distinct from a zero-width label.
|
|
37
|
+
*/
|
|
38
|
+
export declare const getJudgeModelLabel: (judgeModelId?: string | null) => string;
|
|
39
|
+
/**
|
|
40
|
+
* Display label for the evaluator column on the Evaluation Runs page.
|
|
41
|
+
* `nameById` is a lightweight id→name lookup (built once from
|
|
42
|
+
* GET /api/storage/evaluators, not per-row) so this stays a pure function of
|
|
43
|
+
* already-fetched data. Falls back to the raw id if the evaluator was
|
|
44
|
+
* deleted/renamed since the run executed, and to an em dash if the run has
|
|
45
|
+
* no `evaluatorId` at all (legacy runs, or providers that don't record one).
|
|
46
|
+
*/
|
|
47
|
+
export declare const getEvaluatorLabel: (evaluatorId: string | undefined | null, nameById: Map<string, string>) => string;
|
|
29
48
|
/**
|
|
30
49
|
* Returns a short, stable suffix for a TestCaseRun id, suitable for embedding
|
|
31
50
|
* in an auto-generated run name. Run ids are shaped
|
|
@@ -93,4 +112,19 @@ export declare const getMetricTextColor: (type: "primary" | "success" | "error"
|
|
|
93
112
|
* Truncates text to a specified length with ellipsis
|
|
94
113
|
*/
|
|
95
114
|
export declare const truncate: (text: string, length: number) => string;
|
|
115
|
+
/**
|
|
116
|
+
* Detect the syntax-highlighting language for a code-SDK eval file from its
|
|
117
|
+
* extension. Isomorphic (no Node built-ins) so it's shared by the CLI/server
|
|
118
|
+
* import path (lib/testCases/loader.ts, which re-exports this) AND the
|
|
119
|
+
* browser-side EvalSourceCodeView component -- one source of truth for
|
|
120
|
+
* "what language is this file" instead of duplicating the extension check.
|
|
121
|
+
*
|
|
122
|
+
* `.mjs`/`.js`/`.cjs` -> javascript, everything else code-like (`.ts` and
|
|
123
|
+
* unknown extensions) -> typescript. There's no `.jsx`/`.tsx` case today --
|
|
124
|
+
* eval files are plain Node scripts, not React -- but typescript's grammar
|
|
125
|
+
* is a superset of JS syntax so defaulting unknown-but-code extensions to
|
|
126
|
+
* it is the safer guess for highlighting purposes (worst case: a few
|
|
127
|
+
* JS-only tokens render unstyled, never mis-highlighted).
|
|
128
|
+
*/
|
|
129
|
+
export declare function detectSourceLanguage(fileName: string): 'javascript' | 'typescript';
|
|
96
130
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../utils.ts"],"names":[],"mappings":"AAKA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAE5C,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAGvD,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AA0BD;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAS7C,CAAC;AASF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,YAAY,UAAU,KAAG,MAE3D,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACrB,WAAW,MAAM,EACjB,UAAS,iBAA8B,KACtC,MAiBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,WAAW,MAAM,KAAG,MAatD,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,MAG9C,CAAC;AAIF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAG7C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,MAGtE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,GAAG,IAAI,KAC7D,MAAM,GAAG,IASX,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,KAAG,MAWnD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,KAAG,MAS7F,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,KAAG,MAU7G,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,MAGvD,CAAC"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../utils.ts"],"names":[],"mappings":"AAKA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAE5C,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAGvD,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AA0BD;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAS7C,CAAC;AASF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,YAAY,UAAU,KAAG,MAE3D,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACrB,WAAW,MAAM,EACjB,UAAS,iBAA8B,KACtC,MAiBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,WAAW,MAAM,KAAG,MAatD,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,MAG9C,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAAI,eAAe,MAAM,GAAG,IAAI,KAAG,MAGjE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAC5B,aAAa,MAAM,GAAG,SAAS,GAAG,IAAI,EACtC,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAC5B,MAGF,CAAC;AAIF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,MAG7C,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,MAGtE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,GAAG,IAAI,KAC7D,MAAM,GAAG,IASX,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,KAAG,MAWnD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,KAAG,MAS7F,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,KAAG,MAU7G,CAAC;AAIF;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,MAGvD,CAAC;AAIF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,YAAY,CAMlF"}
|
package/lib/dist/lib/utils.js
CHANGED
|
@@ -106,6 +106,33 @@ export const getModelName = (modelId) => {
|
|
|
106
106
|
const model = DEFAULT_CONFIG.models[modelId];
|
|
107
107
|
return model?.display_name || modelId;
|
|
108
108
|
};
|
|
109
|
+
/**
|
|
110
|
+
* Display label for the judge model column on the Evaluation Runs page.
|
|
111
|
+
* Judge model ids share the same registry as agent model ids
|
|
112
|
+
* (DEFAULT_CONFIG.models), so this reuses {@link getModelName} for the
|
|
113
|
+
* shortened display name. Runs created before `judgeModelId` was tracked
|
|
114
|
+
* (or agentic-provider judges that pick their own model) have no value —
|
|
115
|
+
* render an em dash rather than a blank cell so the missing-field state is
|
|
116
|
+
* visually distinct from a zero-width label.
|
|
117
|
+
*/
|
|
118
|
+
export const getJudgeModelLabel = (judgeModelId) => {
|
|
119
|
+
if (!judgeModelId)
|
|
120
|
+
return '—';
|
|
121
|
+
return getModelName(judgeModelId);
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Display label for the evaluator column on the Evaluation Runs page.
|
|
125
|
+
* `nameById` is a lightweight id→name lookup (built once from
|
|
126
|
+
* GET /api/storage/evaluators, not per-row) so this stays a pure function of
|
|
127
|
+
* already-fetched data. Falls back to the raw id if the evaluator was
|
|
128
|
+
* deleted/renamed since the run executed, and to an em dash if the run has
|
|
129
|
+
* no `evaluatorId` at all (legacy runs, or providers that don't record one).
|
|
130
|
+
*/
|
|
131
|
+
export const getEvaluatorLabel = (evaluatorId, nameById) => {
|
|
132
|
+
if (!evaluatorId)
|
|
133
|
+
return '—';
|
|
134
|
+
return nameById.get(evaluatorId) || evaluatorId;
|
|
135
|
+
};
|
|
109
136
|
// ==================== Run Utilities ====================
|
|
110
137
|
/**
|
|
111
138
|
* Returns a short, stable suffix for a TestCaseRun id, suitable for embedding
|
|
@@ -229,4 +256,26 @@ export const truncate = (text, length) => {
|
|
|
229
256
|
return text;
|
|
230
257
|
return text.substring(0, length).trim() + '...';
|
|
231
258
|
};
|
|
259
|
+
// ==================== Eval Source Language Detection ====================
|
|
260
|
+
/**
|
|
261
|
+
* Detect the syntax-highlighting language for a code-SDK eval file from its
|
|
262
|
+
* extension. Isomorphic (no Node built-ins) so it's shared by the CLI/server
|
|
263
|
+
* import path (lib/testCases/loader.ts, which re-exports this) AND the
|
|
264
|
+
* browser-side EvalSourceCodeView component -- one source of truth for
|
|
265
|
+
* "what language is this file" instead of duplicating the extension check.
|
|
266
|
+
*
|
|
267
|
+
* `.mjs`/`.js`/`.cjs` -> javascript, everything else code-like (`.ts` and
|
|
268
|
+
* unknown extensions) -> typescript. There's no `.jsx`/`.tsx` case today --
|
|
269
|
+
* eval files are plain Node scripts, not React -- but typescript's grammar
|
|
270
|
+
* is a superset of JS syntax so defaulting unknown-but-code extensions to
|
|
271
|
+
* it is the safer guess for highlighting purposes (worst case: a few
|
|
272
|
+
* JS-only tokens render unstyled, never mis-highlighted).
|
|
273
|
+
*/
|
|
274
|
+
export function detectSourceLanguage(fileName) {
|
|
275
|
+
const lower = fileName.toLowerCase();
|
|
276
|
+
if (lower.endsWith('.js') || lower.endsWith('.mjs') || lower.endsWith('.cjs')) {
|
|
277
|
+
return 'javascript';
|
|
278
|
+
}
|
|
279
|
+
return 'typescript';
|
|
280
|
+
}
|
|
232
281
|
//# sourceMappingURL=utils.js.map
|