@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.
Files changed (230) hide show
  1. package/README.md +1 -0
  2. package/cli/dist/index.js +2325 -961
  3. package/dist/assets/index-D-Np_l_T.js +246 -0
  4. package/dist/assets/index-vZt9QZKf.css +1 -0
  5. package/dist/index.html +2 -2
  6. package/docs/CLI.md +183 -3
  7. package/docs/CONFIGURATION.md +1 -1
  8. package/docs/CONNECTORS.md +1 -1
  9. package/docs/INSTRUMENT_WITH_OTEL.md +7 -0
  10. package/docs/SDK.md +178 -5
  11. package/docs/STORAGE_INDEX_FIELD_LIMITS.md +216 -0
  12. package/docs/skills/AGENT_HEALTH.md +55 -1
  13. package/docs/skills/add-connector/SKILL.md +5 -1
  14. package/examples/eval-files/demo.eval.js +1 -1
  15. package/examples/eval-files/ops-rca-classification.eval.js +71 -0
  16. package/examples/eval-files/ops-rca-evaluator.json +15 -0
  17. package/examples/eval-files/sdk-demo.eval.js +72 -0
  18. package/examples/eval-files/sdk-describe-demo.eval.js +50 -0
  19. package/examples/eval-files/sdk-hooks-demo.eval.js +1 -1
  20. package/lib/dist/lib/agentTrends.d.ts +210 -0
  21. package/lib/dist/lib/agentTrends.d.ts.map +1 -0
  22. package/lib/dist/lib/agentTrends.js +360 -0
  23. package/lib/dist/lib/agentTrends.js.map +1 -0
  24. package/lib/dist/lib/bedrockCompat.d.ts +27 -0
  25. package/lib/dist/lib/bedrockCompat.d.ts.map +1 -0
  26. package/lib/dist/lib/bedrockCompat.js +83 -0
  27. package/lib/dist/lib/bedrockCompat.js.map +1 -0
  28. package/lib/dist/lib/benchmarkCaseReview.d.ts +114 -0
  29. package/lib/dist/lib/benchmarkCaseReview.d.ts.map +1 -0
  30. package/lib/dist/lib/benchmarkCaseReview.js +177 -0
  31. package/lib/dist/lib/benchmarkCaseReview.js.map +1 -0
  32. package/lib/dist/lib/benchmarkImage.d.ts +52 -0
  33. package/lib/dist/lib/benchmarkImage.d.ts.map +1 -0
  34. package/lib/dist/lib/benchmarkImage.js +113 -0
  35. package/lib/dist/lib/benchmarkImage.js.map +1 -0
  36. package/lib/dist/lib/benchmarkRunsTable.d.ts +109 -0
  37. package/lib/dist/lib/benchmarkRunsTable.d.ts.map +1 -0
  38. package/lib/dist/lib/benchmarkRunsTable.js +212 -0
  39. package/lib/dist/lib/benchmarkRunsTable.js.map +1 -0
  40. package/lib/dist/lib/benchmarkVersionUtils.d.ts +13 -0
  41. package/lib/dist/lib/benchmarkVersionUtils.d.ts.map +1 -1
  42. package/lib/dist/lib/benchmarkVersionUtils.js +21 -0
  43. package/lib/dist/lib/benchmarkVersionUtils.js.map +1 -1
  44. package/lib/dist/lib/chunkedFetch.d.ts +18 -0
  45. package/lib/dist/lib/chunkedFetch.d.ts.map +1 -0
  46. package/lib/dist/lib/chunkedFetch.js +40 -0
  47. package/lib/dist/lib/chunkedFetch.js.map +1 -0
  48. package/lib/dist/lib/comparisonInsights.d.ts +151 -0
  49. package/lib/dist/lib/comparisonInsights.d.ts.map +1 -0
  50. package/lib/dist/lib/comparisonInsights.js +270 -0
  51. package/lib/dist/lib/comparisonInsights.js.map +1 -0
  52. package/lib/dist/lib/config/loader.d.ts.map +1 -1
  53. package/lib/dist/lib/config/loader.js +16 -1
  54. package/lib/dist/lib/config/loader.js.map +1 -1
  55. package/lib/dist/lib/config/types.d.ts +14 -0
  56. package/lib/dist/lib/config/types.d.ts.map +1 -1
  57. package/lib/dist/lib/constants.d.ts +11 -0
  58. package/lib/dist/lib/constants.d.ts.map +1 -1
  59. package/lib/dist/lib/constants.js +10 -1
  60. package/lib/dist/lib/constants.js.map +1 -1
  61. package/lib/dist/lib/contextFormat.d.ts +26 -0
  62. package/lib/dist/lib/contextFormat.d.ts.map +1 -0
  63. package/lib/dist/lib/contextFormat.js +28 -0
  64. package/lib/dist/lib/contextFormat.js.map +1 -0
  65. package/lib/dist/lib/dashboardMetrics.d.ts +11 -2
  66. package/lib/dist/lib/dashboardMetrics.d.ts.map +1 -1
  67. package/lib/dist/lib/dashboardMetrics.js +38 -3
  68. package/lib/dist/lib/dashboardMetrics.js.map +1 -1
  69. package/lib/dist/lib/envCompat.d.ts.map +1 -1
  70. package/lib/dist/lib/envCompat.js +14 -5
  71. package/lib/dist/lib/envCompat.js.map +1 -1
  72. package/lib/dist/lib/evaluationRerun.d.ts +102 -0
  73. package/lib/dist/lib/evaluationRerun.d.ts.map +1 -0
  74. package/lib/dist/lib/evaluationRerun.js +134 -0
  75. package/lib/dist/lib/evaluationRerun.js.map +1 -0
  76. package/lib/dist/lib/judgeFailureSummary.d.ts +66 -0
  77. package/lib/dist/lib/judgeFailureSummary.d.ts.map +1 -0
  78. package/lib/dist/lib/judgeFailureSummary.js +68 -0
  79. package/lib/dist/lib/judgeFailureSummary.js.map +1 -0
  80. package/lib/dist/lib/judgeStrategies.d.ts +108 -0
  81. package/lib/dist/lib/judgeStrategies.d.ts.map +1 -0
  82. package/lib/dist/lib/judgeStrategies.js +135 -0
  83. package/lib/dist/lib/judgeStrategies.js.map +1 -0
  84. package/lib/dist/lib/matchers/expect.d.ts +21 -1
  85. package/lib/dist/lib/matchers/expect.d.ts.map +1 -1
  86. package/lib/dist/lib/matchers/expect.js +51 -0
  87. package/lib/dist/lib/matchers/expect.js.map +1 -1
  88. package/lib/dist/lib/matchers/judgeAccessor.d.ts +4 -0
  89. package/lib/dist/lib/matchers/judgeAccessor.d.ts.map +1 -1
  90. package/lib/dist/lib/matchers/judgeAccessor.js +13 -2
  91. package/lib/dist/lib/matchers/judgeAccessor.js.map +1 -1
  92. package/lib/dist/lib/matchers/judgeReasoningParse.d.ts +49 -0
  93. package/lib/dist/lib/matchers/judgeReasoningParse.d.ts.map +1 -0
  94. package/lib/dist/lib/matchers/judgeReasoningParse.js +128 -0
  95. package/lib/dist/lib/matchers/judgeReasoningParse.js.map +1 -0
  96. package/lib/dist/lib/matchers/traces.d.ts +17 -2
  97. package/lib/dist/lib/matchers/traces.d.ts.map +1 -1
  98. package/lib/dist/lib/matchers/traces.js +136 -16
  99. package/lib/dist/lib/matchers/traces.js.map +1 -1
  100. package/lib/dist/lib/matchers/tracesPricing.d.ts +38 -0
  101. package/lib/dist/lib/matchers/tracesPricing.d.ts.map +1 -0
  102. package/lib/dist/lib/matchers/tracesPricing.js +64 -0
  103. package/lib/dist/lib/matchers/tracesPricing.js.map +1 -0
  104. package/lib/dist/lib/matchers/types.d.ts +25 -0
  105. package/lib/dist/lib/matchers/types.d.ts.map +1 -1
  106. package/lib/dist/lib/resolveCanonicalRun.d.ts +23 -0
  107. package/lib/dist/lib/resolveCanonicalRun.d.ts.map +1 -0
  108. package/lib/dist/lib/resolveCanonicalRun.js +26 -0
  109. package/lib/dist/lib/resolveCanonicalRun.js.map +1 -0
  110. package/lib/dist/lib/runActions.d.ts +120 -0
  111. package/lib/dist/lib/runActions.d.ts.map +1 -0
  112. package/lib/dist/lib/runActions.js +130 -0
  113. package/lib/dist/lib/runActions.js.map +1 -0
  114. package/lib/dist/lib/runInsights.d.ts +86 -0
  115. package/lib/dist/lib/runInsights.d.ts.map +1 -0
  116. package/lib/dist/lib/runInsights.js +185 -0
  117. package/lib/dist/lib/runInsights.js.map +1 -0
  118. package/lib/dist/lib/runName.d.ts +29 -0
  119. package/lib/dist/lib/runName.d.ts.map +1 -0
  120. package/lib/dist/lib/runName.js +38 -0
  121. package/lib/dist/lib/runName.js.map +1 -0
  122. package/lib/dist/lib/runReportPath.d.ts +16 -0
  123. package/lib/dist/lib/runReportPath.d.ts.map +1 -0
  124. package/lib/dist/lib/runReportPath.js +22 -0
  125. package/lib/dist/lib/runReportPath.js.map +1 -0
  126. package/lib/dist/lib/runSort.d.ts +27 -0
  127. package/lib/dist/lib/runSort.d.ts.map +1 -0
  128. package/lib/dist/lib/runSort.js +31 -0
  129. package/lib/dist/lib/runSort.js.map +1 -0
  130. package/lib/dist/lib/runStats.d.ts +109 -5
  131. package/lib/dist/lib/runStats.d.ts.map +1 -1
  132. package/lib/dist/lib/runStats.js +193 -10
  133. package/lib/dist/lib/runStats.js.map +1 -1
  134. package/lib/dist/lib/testCases/define.d.ts.map +1 -1
  135. package/lib/dist/lib/testCases/define.js +93 -46
  136. package/lib/dist/lib/testCases/define.js.map +1 -1
  137. package/lib/dist/lib/testCases/judge.d.ts.map +1 -1
  138. package/lib/dist/lib/testCases/judge.js +22 -4
  139. package/lib/dist/lib/testCases/judge.js.map +1 -1
  140. package/lib/dist/lib/testCases/loader.d.ts +35 -1
  141. package/lib/dist/lib/testCases/loader.d.ts.map +1 -1
  142. package/lib/dist/lib/testCases/loader.js +278 -31
  143. package/lib/dist/lib/testCases/loader.js.map +1 -1
  144. package/lib/dist/lib/trajectoryStepDisplay.d.ts +25 -0
  145. package/lib/dist/lib/trajectoryStepDisplay.d.ts.map +1 -0
  146. package/lib/dist/lib/trajectoryStepDisplay.js +42 -0
  147. package/lib/dist/lib/trajectoryStepDisplay.js.map +1 -0
  148. package/lib/dist/lib/utils.d.ts +34 -0
  149. package/lib/dist/lib/utils.d.ts.map +1 -1
  150. package/lib/dist/lib/utils.js +49 -0
  151. package/lib/dist/lib/utils.js.map +1 -1
  152. package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts +68 -22
  153. package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.d.ts.map +1 -1
  154. package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js +148 -111
  155. package/lib/dist/services/connectors/claude-code/ClaudeCodeConnector.js.map +1 -1
  156. package/lib/dist/services/connectors/kiro/KiroConnector.d.ts +21 -13
  157. package/lib/dist/services/connectors/kiro/KiroConnector.d.ts.map +1 -1
  158. package/lib/dist/services/connectors/kiro/KiroConnector.js +22 -25
  159. package/lib/dist/services/connectors/kiro/KiroConnector.js.map +1 -1
  160. package/lib/dist/services/connectors/pi/PiConnector.d.ts +49 -10
  161. package/lib/dist/services/connectors/pi/PiConnector.d.ts.map +1 -1
  162. package/lib/dist/services/connectors/pi/PiConnector.js +102 -86
  163. package/lib/dist/services/connectors/pi/PiConnector.js.map +1 -1
  164. package/lib/dist/services/connectors/subprocess/SubprocessConnector.d.ts +59 -14
  165. package/lib/dist/services/connectors/subprocess/SubprocessConnector.d.ts.map +1 -1
  166. package/lib/dist/services/connectors/subprocess/SubprocessConnector.js +95 -61
  167. package/lib/dist/services/connectors/subprocess/SubprocessConnector.js.map +1 -1
  168. package/lib/dist/services/evaluation/bedrockJudge.d.ts +18 -0
  169. package/lib/dist/services/evaluation/bedrockJudge.d.ts.map +1 -1
  170. package/lib/dist/services/evaluation/bedrockJudge.js +4 -0
  171. package/lib/dist/services/evaluation/bedrockJudge.js.map +1 -1
  172. package/lib/dist/services/evaluation/index.d.ts +18 -1
  173. package/lib/dist/services/evaluation/index.d.ts.map +1 -1
  174. package/lib/dist/services/evaluation/index.js +156 -19
  175. package/lib/dist/services/evaluation/index.js.map +1 -1
  176. package/lib/dist/services/metrics.d.ts +55 -0
  177. package/lib/dist/services/metrics.d.ts.map +1 -0
  178. package/lib/dist/services/metrics.js +89 -0
  179. package/lib/dist/services/metrics.js.map +1 -0
  180. package/lib/dist/services/storage/asyncBenchmarkStorage.d.ts +1 -1
  181. package/lib/dist/services/storage/asyncBenchmarkStorage.d.ts.map +1 -1
  182. package/lib/dist/services/storage/asyncBenchmarkStorage.js +30 -3
  183. package/lib/dist/services/storage/asyncBenchmarkStorage.js.map +1 -1
  184. package/lib/dist/services/storage/asyncRunStorage.d.ts +20 -1
  185. package/lib/dist/services/storage/asyncRunStorage.d.ts.map +1 -1
  186. package/lib/dist/services/storage/asyncRunStorage.js +125 -2
  187. package/lib/dist/services/storage/asyncRunStorage.js.map +1 -1
  188. package/lib/dist/services/storage/asyncTestCaseStorage.d.ts +18 -4
  189. package/lib/dist/services/storage/asyncTestCaseStorage.d.ts.map +1 -1
  190. package/lib/dist/services/storage/asyncTestCaseStorage.js +21 -4
  191. package/lib/dist/services/storage/asyncTestCaseStorage.js.map +1 -1
  192. package/lib/dist/services/storage/opensearchClient.d.ts +47 -12
  193. package/lib/dist/services/storage/opensearchClient.d.ts.map +1 -1
  194. package/lib/dist/services/storage/opensearchClient.js +12 -5
  195. package/lib/dist/services/storage/opensearchClient.js.map +1 -1
  196. package/lib/dist/services/traces/browserRecovery.d.ts +12 -1
  197. package/lib/dist/services/traces/browserRecovery.d.ts.map +1 -1
  198. package/lib/dist/services/traces/browserRecovery.js +35 -5
  199. package/lib/dist/services/traces/browserRecovery.js.map +1 -1
  200. package/lib/dist/services/traces/index.d.ts +8 -1
  201. package/lib/dist/services/traces/index.d.ts.map +1 -1
  202. package/lib/dist/services/traces/index.js +33 -12
  203. package/lib/dist/services/traces/index.js.map +1 -1
  204. package/lib/dist/services/traces/judgeAgentsHints.d.ts +98 -3
  205. package/lib/dist/services/traces/judgeAgentsHints.d.ts.map +1 -1
  206. package/lib/dist/services/traces/judgeAgentsHints.js +144 -3
  207. package/lib/dist/services/traces/judgeAgentsHints.js.map +1 -1
  208. package/lib/dist/services/traces/messageExtraction.d.ts.map +1 -1
  209. package/lib/dist/services/traces/messageExtraction.js +95 -33
  210. package/lib/dist/services/traces/messageExtraction.js.map +1 -1
  211. package/lib/dist/services/traces/spansToTrajectory.d.ts.map +1 -1
  212. package/lib/dist/services/traces/spansToTrajectory.js +51 -13
  213. package/lib/dist/services/traces/spansToTrajectory.js.map +1 -1
  214. package/lib/dist/services/traces/tracePoller.d.ts +27 -3
  215. package/lib/dist/services/traces/tracePoller.d.ts.map +1 -1
  216. package/lib/dist/services/traces/tracePoller.js +196 -33
  217. package/lib/dist/services/traces/tracePoller.js.map +1 -1
  218. package/lib/dist/services/traces/trajectoryMerge.d.ts +79 -0
  219. package/lib/dist/services/traces/trajectoryMerge.d.ts.map +1 -0
  220. package/lib/dist/services/traces/trajectoryMerge.js +109 -0
  221. package/lib/dist/services/traces/trajectoryMerge.js.map +1 -0
  222. package/lib/dist/types/index.d.ts +250 -3
  223. package/lib/dist/types/index.d.ts.map +1 -1
  224. package/lib/dist/types/index.js +24 -0
  225. package/lib/dist/types/index.js.map +1 -1
  226. package/package.json +8 -5
  227. package/server/dist/app.js +5490 -1557
  228. package/server/dist/index.js +5490 -1557
  229. package/dist/assets/index-CCQRDlO0.js +0 -243
  230. 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
- export function computeTestCaseHash(tc) {
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
- if (absPath.endsWith('.js')) {
41
- // For CJS .js files, execute in a fresh context with our test() function
42
- // injected. This avoids module caching issues across multiple loads.
43
- const code = readFileSync(absPath, 'utf-8');
44
- const fileDir = dirname(absPath);
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(absPath);
50
- m.filename = absPath;
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(absPath);
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
- // Fall back to a resolution-based check so that fixtures requiring the
83
- // SDK by absolute path or via the published package name still hand back
84
- // our test() registrar (and therefore land in our file-scoped registry).
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
- const resolved = fileRequire.resolve(id);
87
- const normalized = resolved.replace(/\\/g, '/');
88
- if (normalized.endsWith('/lib/testCases/define.js') ||
89
- normalized.endsWith('/lib/testCases/define')) {
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
- catch {
94
- // ignore unresolvable IDs — fileRequire below will surface the error
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, absPath, fileDir);
102
- module = m.exports;
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
- // For .ts and .mjs files, use dynamic import
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;AAE7D,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAE/C,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAAgB;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM;QACzB,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO;QAC3B,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM;QACzB,WAAW,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW;QACnC,mEAAmE;QACnE,oEAAoE;QACpE,oEAAoE;QACpE,iEAAiE;QACjE,6BAA6B;QAC7B,gBAAgB,EAAE,EAAE,CAAC,OAAO,CAAC,gBAAgB;QAC7C,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,kBAAkB;KAClD,CAAC,CAAC;IACH,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAyBD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,QAAgB;IAC5D,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAElC,kEAAkE;IAClE,aAAa,CAAC,OAAO,CAAC,CAAC;IACvB,aAAa,CAAC,OAAO,CAAC,CAAC;IAEvB,IAAI,MAAW,CAAC;IAEhB,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,yEAAyE;QACzE,qEAAqE;QACrE,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACjC,yEAAyE;QACzE,6EAA6E;QAC7E,iEAAiE;QACjE,MAAM,MAAM,GAAG,UAAqC,CAAC;QACrD,MAAM,CAAC,GAAG,IAAK,MAAc,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,QAAQ,GAAG,OAAO,CAAC;QACrB,CAAC,CAAC,KAAK,GAAI,MAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACpD,0EAA0E;QAC1E,8DAA8D;QAC9D,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QAC3C,kEAAkE;QAClE,2CAA2C;QAC3C,iEAAiE;QACjE,kDAAkD;QAClD,sEAAsE;QACtE,kEAAkE;QAClE,6CAA6C;QAC7C,MAAM,UAAU,GAAG,CAAC,EAAU,EAAE,EAAE;YAChC,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC/D,OAAO,CACL,UAAU,KAAK,sBAAsB;gBACrC,UAAU,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAC7C,CAAC;QACJ,CAAC,CAAC;QACF,oEAAoE;QACpE,uEAAuE;QACvE,oEAAoE;QACpE,+BAA+B;QAC/B,MAAM,aAAa,GAAG,CAAC,EAAU,EAAE,EAAE,CACnC,EAAE,KAAK,kCAAkC;YACzC,EAAE,KAAK,0BAA0B;YACjC,EAAE,KAAK,cAAc,CAAC;QACxB,uEAAuE;QACvE,yEAAyE;QACzE,0EAA0E;QAC1E,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;QACzC,MAAM,cAAc,GAAG,CAAC,EAAU,EAAE,EAAE;YACpC,IAAI,UAAU,CAAC,EAAE,CAAC,IAAI,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC;gBACxC,OAAO,UAAU,CAAC;YACpB,CAAC;YACD,uEAAuE;YACvE,yEAAyE;YACzE,yEAAyE;YACzE,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAChD,IACE,UAAU,CAAC,QAAQ,CAAC,0BAA0B,CAAC;oBAC/C,UAAU,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAC5C,CAAC;oBACD,OAAO,UAAU,CAAC;gBACpB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,qEAAqE;YACvE,CAAC;YACD,OAAO,WAAW,CAAC,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC;QACD,cAAsB,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;QAEtD,MAAM,OAAO,GAAG,gEAAgE,IAAI,OAAO,CAAC;QAC5F,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QACjC,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,6CAA6C;QAC7C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;YAC5C,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,IAAI,KAAK,4BAA4B,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzE,MAAM,IAAI,KAAK,CACb,kCAAkC,QAAQ,IAAI;oBAC9C,gDAAgD;oBAChD,qDAAqD,CACtD,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,wEAAwE;IACxE,qEAAqE;IACrE,iCAAiC;IACjC,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAE9C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,UAAU,QAAQ,qFAAqF,CACxG,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,MAAM,MAAM,GAAqB,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACpD,GAAG,EAAE;QACL,IAAI,EAAE,mBAAmB,CAAC,EAAE,CAAC;KAC9B,CAAC,CAAC,CAAC;IAEJ,gEAAgE;IAChE,qEAAqE;IACrE,6DAA6D;IAC7D,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC/C,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;QACxB,IAAI,EAAE,CAAC,aAAa,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YACnB,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,wDAAwD;IACxD,yEAAyE;IACzE,4DAA4D;IAC5D,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACrE,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"}
@@ -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"}
@@ -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