@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
@@ -0,0 +1,83 @@
1
+ /*
2
+ * Copyright OpenSearch Contributors
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ /**
6
+ * Bedrock model compatibility helpers shared by every Bedrock Converse call
7
+ * site (judge, skill eval generator, skill improver, failure clustering,
8
+ * assistant fallback).
9
+ *
10
+ * Two concerns live here so the policy is defined exactly once:
11
+ *
12
+ * 1. **Temperature deprecation** — newer Anthropic models (Claude Opus 4.5+,
13
+ * Sonnet 4.6+, and the Claude 5 family incl. Fable/Mythos) reject an
14
+ * explicit `temperature` with `ValidationException: 'temperature' is
15
+ * deprecated for this model`. `buildInferenceConfig()` omits the field for
16
+ * those models and lets the model use its default. (GitHub issue #299)
17
+ *
18
+ * 2. **Region-aware inference profiles** — the default model registry pins
19
+ * `us.`-prefixed cross-region inference profile ids, which only resolve
20
+ * from US regions. `resolveRegionAwareModelId()` swaps the prefix to the
21
+ * one matching the active AWS region (`eu.` / `apac.`) at call time, so
22
+ * the registry itself stays region-neutral. (GitHub issue #298)
23
+ */
24
+ /**
25
+ * Model-id patterns that have deprecated the `temperature` parameter.
26
+ * Matched case-insensitively against the full model/inference-profile id.
27
+ */
28
+ const TEMPERATURE_DEPRECATED_PATTERNS = [
29
+ /claude-opus-4-[5-9]/, // Opus 4.5, 4.6, 4.7, 4.8, ...
30
+ /claude-sonnet-4-[6-9]/, // Sonnet 4.6+ (4.5 still accepts temperature)
31
+ /claude-[a-z]+-5(?![0-9])/, // Claude 5 family: fable-5, mythos-5, opus-5, sonnet-5, ...
32
+ ];
33
+ /** Whether the given Bedrock model still accepts an explicit `temperature`. */
34
+ export function modelSupportsTemperature(modelId) {
35
+ const id = (modelId || '').toLowerCase();
36
+ return !TEMPERATURE_DEPRECATED_PATTERNS.some((p) => p.test(id));
37
+ }
38
+ /**
39
+ * Build a Converse `inferenceConfig`, including `temperature` only when the
40
+ * target model accepts it. Callers pass their preferred temperature; for
41
+ * models that have deprecated the parameter it is silently omitted (the
42
+ * model's own default applies).
43
+ */
44
+ export function buildInferenceConfig(modelId, opts) {
45
+ const cfg = { maxTokens: opts.maxTokens };
46
+ if (opts.temperature !== undefined && modelSupportsTemperature(modelId)) {
47
+ cfg.temperature = opts.temperature;
48
+ }
49
+ return cfg;
50
+ }
51
+ /** Inference-profile prefix appropriate for the given (or current) AWS region. */
52
+ export function regionInferencePrefix(region) {
53
+ const r = (region ||
54
+ process.env.AWS_REGION ||
55
+ process.env.AWS_DEFAULT_REGION ||
56
+ 'us-east-1').toLowerCase();
57
+ if (r.startsWith('eu-'))
58
+ return 'eu.';
59
+ if (r.startsWith('ap-'))
60
+ return 'apac.';
61
+ return 'us.';
62
+ }
63
+ const CROSS_REGION_PREFIXES = ['us.', 'eu.', 'apac.'];
64
+ /**
65
+ * Re-home a cross-region inference-profile id to the active AWS region.
66
+ *
67
+ * `us.anthropic.claude-...` → `eu.anthropic.claude-...` when running in an
68
+ * EU region, etc. Ids that carry no regional prefix (bare model ids,
69
+ * `global.` profiles, non-Bedrock ids like `mock://` or `gpt-4o`) are
70
+ * returned unchanged.
71
+ */
72
+ export function resolveRegionAwareModelId(modelId, region) {
73
+ if (!modelId)
74
+ return modelId;
75
+ const target = regionInferencePrefix(region);
76
+ for (const prefix of CROSS_REGION_PREFIXES) {
77
+ if (modelId.startsWith(prefix)) {
78
+ return prefix === target ? modelId : target + modelId.slice(prefix.length);
79
+ }
80
+ }
81
+ return modelId;
82
+ }
83
+ //# sourceMappingURL=bedrockCompat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bedrockCompat.js","sourceRoot":"","sources":["../../bedrockCompat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;GAGG;AACH,MAAM,+BAA+B,GAAa;IAChD,qBAAqB,EAAE,+BAA+B;IACtD,uBAAuB,EAAE,8CAA8C;IACvE,0BAA0B,EAAE,4DAA4D;CACzF,CAAC;AAEF,+EAA+E;AAC/E,MAAM,UAAU,wBAAwB,CAAC,OAAe;IACtD,MAAM,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IACzC,OAAO,CAAC,+BAA+B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAClC,OAAe,EACf,IAAiD;IAEjD,MAAM,GAAG,GAAgD,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;IACvF,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,wBAAwB,CAAC,OAAO,CAAC,EAAE,CAAC;QACxE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IACrC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,qBAAqB,CAAC,MAAe;IACnD,MAAM,CAAC,GAAG,CACR,MAAM;QACN,OAAO,CAAC,GAAG,CAAC,UAAU;QACtB,OAAO,CAAC,GAAG,CAAC,kBAAkB;QAC9B,WAAW,CACZ,CAAC,WAAW,EAAE,CAAC;IAChB,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IACxC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAU,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAe,EAAE,MAAe;IACxE,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IAC7B,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC7C,KAAK,MAAM,MAAM,IAAI,qBAAqB,EAAE,CAAC;QAC3C,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Pure helpers for the benchmark case-review matrix.
3
+ *
4
+ * The benchmark document supplies the canonical run/case relationship, while
5
+ * lightweight report summaries supply the actual pass/fail/error verdicts.
6
+ * Keeping this logic outside React makes the bucket priority and pager order
7
+ * deterministic (and cheap to test) for suites with hundreds of cases.
8
+ */
9
+ export type CaseVerdict = 'passed' | 'failed' | 'errored' | 'not-run';
10
+ export type CaseReviewBucket = 'needs-attention' | 'flaky' | 'stable' | 'no-data';
11
+ export type CaseReviewFilter = 'all' | Exclude<CaseReviewBucket, 'no-data'>;
12
+ export type SwipeDirection = 'prev' | 'next';
13
+ export interface PagerDragInput {
14
+ dx: number;
15
+ dy: number;
16
+ latched: boolean;
17
+ atStart: boolean;
18
+ atEnd: boolean;
19
+ }
20
+ export interface PagerDragResult {
21
+ offset: number;
22
+ latched: boolean;
23
+ }
24
+ /**
25
+ * Latch a horizontal pager drag after a small slop, then preserve that latch
26
+ * for the rest of the gesture. Pulling beyond either end receives resistance
27
+ * so the pane communicates the boundary without changing cases.
28
+ *
29
+ * Reduced-motion behavior intentionally stays out of this geometry helper;
30
+ * callers suppress the returned offset while retaining gesture navigation.
31
+ */
32
+ export declare function computePagerDrag({ dx, dy, latched, atStart, atEnd, }: PagerDragInput): PagerDragResult;
33
+ /**
34
+ * Resolve a completed gesture without suppressing native touch movement. A
35
+ * negative x displacement is a left swipe (next); a positive one is previous.
36
+ */
37
+ export declare function resolveSwipeDirection(dx: number, dy: number, touchCount?: number): SwipeDirection | null;
38
+ export interface VerdictReportSummary {
39
+ status?: string;
40
+ passFailStatus?: 'passed' | 'failed' | null;
41
+ metricsStatus?: string;
42
+ }
43
+ export interface VerdictRunResult {
44
+ reportId?: string;
45
+ status?: string;
46
+ /** Present on newer embedded benchmark results; reports remain authoritative. */
47
+ passFailStatus?: 'passed' | 'failed';
48
+ }
49
+ export interface VerdictRun {
50
+ id: string;
51
+ createdAt: string;
52
+ status?: string;
53
+ results?: Record<string, VerdictRunResult>;
54
+ }
55
+ export interface ReviewableCase {
56
+ id: string;
57
+ name: string;
58
+ prompt?: string;
59
+ }
60
+ export interface CaseReviewRow<T extends ReviewableCase = ReviewableCase> {
61
+ testCase: T;
62
+ verdicts: CaseVerdict[];
63
+ bucket: CaseReviewBucket;
64
+ passRate: number | null;
65
+ }
66
+ /** A legacy run with no top-level status is complete once all results are terminal. */
67
+ export declare function isCompletedVerdictRun(run: VerdictRun): boolean;
68
+ export declare function getRecentCompletedRuns<T extends VerdictRun>(runs: T[], limit?: number): T[];
69
+ /**
70
+ * Resolve one case×run cell. A real pass/fail verdict from the report is
71
+ * authoritative and outranks `metricsStatus === 'error'`: metrics/cost
72
+ * enrichment runs after the agent-vs-judge verdict is already known, so a
73
+ * later enrichment failure must not overwrite a genuine pass/fail with
74
+ * 'errored'. `metricsStatus === 'error'` only decides the cell when the
75
+ * report has no real passFailStatus yet.
76
+ */
77
+ export declare function deriveCaseVerdict(run: VerdictRun, testCaseId: string, reportsById: Record<string, VerdictReportSummary | undefined>): CaseVerdict;
78
+ export declare function deriveCaseVerdicts(runs: VerdictRun[], testCaseId: string, reportsById: Record<string, VerdictReportSummary | undefined>): CaseVerdict[];
79
+ /**
80
+ * Buckets are disjoint by priority. Evaluator errors require attention but do
81
+ * not become failed verdicts or enter the pass-rate denominator.
82
+ */
83
+ export declare function classifyCaseVerdicts(verdicts: CaseVerdict[]): CaseReviewBucket;
84
+ export declare function getCasePassRate(verdicts: CaseVerdict[]): number | null;
85
+ export declare function buildCaseReviewRows<T extends ReviewableCase>(testCases: T[], recentRuns: VerdictRun[], reportsById: Record<string, VerdictReportSummary | undefined>): CaseReviewRow<T>[];
86
+ /** Search/filter first, then pass-rate ascending; no-data sorts last. */
87
+ export declare function filterAndSortCaseRows<T extends ReviewableCase>(rows: CaseReviewRow<T>[], search: string, filter: CaseReviewFilter): CaseReviewRow<T>[];
88
+ export declare function getCasePagerPosition<T extends ReviewableCase>(rows: CaseReviewRow<T>[], selectedCaseId: string | undefined): {
89
+ index: number;
90
+ position: number;
91
+ total: number;
92
+ previousId?: string;
93
+ nextId?: string;
94
+ };
95
+ export interface VersionedRunResult {
96
+ reportId?: string;
97
+ }
98
+ export interface VersionedRun {
99
+ results?: Record<string, VersionedRunResult>;
100
+ }
101
+ export interface VersionedReportSummary {
102
+ testCaseVersion?: number;
103
+ }
104
+ /**
105
+ * The Cases tab always renders a case's *current* definition, even when the
106
+ * user arrived from a specific historical run (e.g. a heat-strip cell click).
107
+ * This detects that mismatch so callers can show a minimal, honest notice
108
+ * instead of silently presenting a definition the run never actually used.
109
+ * Deliberately does not resurrect the old per-version selector — just a
110
+ * disclosure that the definition may have changed since some of the runs
111
+ * shown here.
112
+ */
113
+ export declare function hasHistoricalVersionMismatch(currentVersion: number, runs: VersionedRun[], testCaseId: string, reportsById: Record<string, VersionedReportSummary | undefined>): boolean;
114
+ //# sourceMappingURL=benchmarkCaseReview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmarkCaseReview.d.ts","sourceRoot":"","sources":["../../benchmarkCaseReview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,177 @@
1
+ /*
2
+ * Copyright OpenSearch Contributors
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ const MIN_SWIPE_DISTANCE = 48;
6
+ const HORIZONTAL_SWIPE_RATIO = 1.5;
7
+ const PAGER_DRAG_SLOP = 10;
8
+ const PAGER_EDGE_RESISTANCE = 0.35;
9
+ /**
10
+ * Latch a horizontal pager drag after a small slop, then preserve that latch
11
+ * for the rest of the gesture. Pulling beyond either end receives resistance
12
+ * so the pane communicates the boundary without changing cases.
13
+ *
14
+ * Reduced-motion behavior intentionally stays out of this geometry helper;
15
+ * callers suppress the returned offset while retaining gesture navigation.
16
+ */
17
+ export function computePagerDrag({ dx, dy, latched, atStart, atEnd, }) {
18
+ const nextLatched = latched || (Math.abs(dx) > PAGER_DRAG_SLOP &&
19
+ Math.abs(dx) > Math.abs(dy));
20
+ if (!nextLatched)
21
+ return { offset: 0, latched: false };
22
+ const beyondStart = atStart && dx > 0;
23
+ const beyondEnd = atEnd && dx < 0;
24
+ return {
25
+ offset: (beyondStart || beyondEnd) ? dx * PAGER_EDGE_RESISTANCE : dx,
26
+ latched: true,
27
+ };
28
+ }
29
+ /**
30
+ * Resolve a completed gesture without suppressing native touch movement. A
31
+ * negative x displacement is a left swipe (next); a positive one is previous.
32
+ */
33
+ export function resolveSwipeDirection(dx, dy, touchCount = 1) {
34
+ if (touchCount !== 1)
35
+ return null;
36
+ if (Math.abs(dx) < MIN_SWIPE_DISTANCE)
37
+ return null;
38
+ if (Math.abs(dx) < HORIZONTAL_SWIPE_RATIO * Math.abs(dy))
39
+ return null;
40
+ return dx < 0 ? 'next' : 'prev';
41
+ }
42
+ /** A legacy run with no top-level status is complete once all results are terminal. */
43
+ export function isCompletedVerdictRun(run) {
44
+ if (run.status)
45
+ return run.status === 'completed';
46
+ const results = Object.values(run.results || {});
47
+ return results.length > 0 && results.every(result => result.status !== 'pending' && result.status !== 'running');
48
+ }
49
+ export function getRecentCompletedRuns(runs, limit = 5) {
50
+ return [...runs]
51
+ .filter(isCompletedVerdictRun)
52
+ .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
53
+ .slice(0, limit);
54
+ }
55
+ /**
56
+ * Resolve one case×run cell. A real pass/fail verdict from the report is
57
+ * authoritative and outranks `metricsStatus === 'error'`: metrics/cost
58
+ * enrichment runs after the agent-vs-judge verdict is already known, so a
59
+ * later enrichment failure must not overwrite a genuine pass/fail with
60
+ * 'errored'. `metricsStatus === 'error'` only decides the cell when the
61
+ * report has no real passFailStatus yet.
62
+ */
63
+ export function deriveCaseVerdict(run, testCaseId, reportsById) {
64
+ const result = run.results?.[testCaseId];
65
+ if (!result || result.status === 'pending' || result.status === 'running')
66
+ return 'not-run';
67
+ const report = result.reportId ? reportsById[result.reportId] : undefined;
68
+ if (report?.passFailStatus === 'passed')
69
+ return 'passed';
70
+ if (report?.passFailStatus === 'failed')
71
+ return 'failed';
72
+ if (report?.metricsStatus === 'error')
73
+ return 'errored';
74
+ // New benchmark documents carry this summary. It is a resilience fallback
75
+ // for deleted/legacy report documents, not the primary source of truth.
76
+ if (result.passFailStatus === 'passed')
77
+ return 'passed';
78
+ if (result.passFailStatus === 'failed')
79
+ return 'failed';
80
+ if (result.status === 'failed' || result.status === 'cancelled' || report?.status === 'failed') {
81
+ return 'failed';
82
+ }
83
+ // A completed result without a verdict means the evaluator did not produce
84
+ // a usable score. Keep it visually/semantically separate from agent failure.
85
+ if (result.status === 'completed')
86
+ return 'errored';
87
+ return 'not-run';
88
+ }
89
+ export function deriveCaseVerdicts(runs, testCaseId, reportsById) {
90
+ return runs.map(run => deriveCaseVerdict(run, testCaseId, reportsById));
91
+ }
92
+ /**
93
+ * Buckets are disjoint by priority. Evaluator errors require attention but do
94
+ * not become failed verdicts or enter the pass-rate denominator.
95
+ */
96
+ export function classifyCaseVerdicts(verdicts) {
97
+ const observed = verdicts.filter(verdict => verdict !== 'not-run');
98
+ if (observed.length === 0)
99
+ return 'no-data';
100
+ const latestThree = verdicts.slice(0, 3);
101
+ if (latestThree.some(verdict => verdict === 'failed' || verdict === 'errored')) {
102
+ return 'needs-attention';
103
+ }
104
+ const scored = verdicts.filter(verdict => verdict === 'passed' || verdict === 'failed');
105
+ const hasPass = scored.includes('passed');
106
+ const hasFail = scored.includes('failed');
107
+ if (hasPass && hasFail)
108
+ return 'flaky';
109
+ if (hasPass)
110
+ return 'stable';
111
+ // Sparse histories can put an old failure/error outside the last-three
112
+ // window. They still have data and are not passing, so attention is the only
113
+ // honest bucket.
114
+ return 'needs-attention';
115
+ }
116
+ export function getCasePassRate(verdicts) {
117
+ const passed = verdicts.filter(verdict => verdict === 'passed').length;
118
+ const failed = verdicts.filter(verdict => verdict === 'failed').length;
119
+ return passed + failed === 0 ? null : passed / (passed + failed);
120
+ }
121
+ export function buildCaseReviewRows(testCases, recentRuns, reportsById) {
122
+ return testCases.map(testCase => {
123
+ const verdicts = deriveCaseVerdicts(recentRuns, testCase.id, reportsById);
124
+ return {
125
+ testCase,
126
+ verdicts,
127
+ bucket: classifyCaseVerdicts(verdicts),
128
+ passRate: getCasePassRate(verdicts),
129
+ };
130
+ });
131
+ }
132
+ /** Search/filter first, then pass-rate ascending; no-data sorts last. */
133
+ export function filterAndSortCaseRows(rows, search, filter) {
134
+ const query = search.trim().toLocaleLowerCase();
135
+ return rows
136
+ .filter(row => filter === 'all' || row.bucket === filter)
137
+ .filter(row => !query ||
138
+ row.testCase.name.toLocaleLowerCase().includes(query) ||
139
+ (row.testCase.prompt || '').toLocaleLowerCase().includes(query))
140
+ .sort((a, b) => {
141
+ if (a.passRate === null && b.passRate !== null)
142
+ return 1;
143
+ if (a.passRate !== null && b.passRate === null)
144
+ return -1;
145
+ if (a.passRate !== null && b.passRate !== null && a.passRate !== b.passRate) {
146
+ return a.passRate - b.passRate;
147
+ }
148
+ return a.testCase.name.localeCompare(b.testCase.name);
149
+ });
150
+ }
151
+ export function getCasePagerPosition(rows, selectedCaseId) {
152
+ const index = selectedCaseId ? rows.findIndex(row => row.testCase.id === selectedCaseId) : -1;
153
+ return {
154
+ index,
155
+ position: index >= 0 ? index + 1 : 0,
156
+ total: rows.length,
157
+ previousId: index > 0 ? rows[index - 1].testCase.id : undefined,
158
+ nextId: index >= 0 && index < rows.length - 1 ? rows[index + 1].testCase.id : undefined,
159
+ };
160
+ }
161
+ /**
162
+ * The Cases tab always renders a case's *current* definition, even when the
163
+ * user arrived from a specific historical run (e.g. a heat-strip cell click).
164
+ * This detects that mismatch so callers can show a minimal, honest notice
165
+ * instead of silently presenting a definition the run never actually used.
166
+ * Deliberately does not resurrect the old per-version selector — just a
167
+ * disclosure that the definition may have changed since some of the runs
168
+ * shown here.
169
+ */
170
+ export function hasHistoricalVersionMismatch(currentVersion, runs, testCaseId, reportsById) {
171
+ return runs.some(run => {
172
+ const result = run.results?.[testCaseId];
173
+ const report = result?.reportId ? reportsById[result.reportId] : undefined;
174
+ return typeof report?.testCaseVersion === 'number' && report.testCaseVersion !== currentVersion;
175
+ });
176
+ }
177
+ //# sourceMappingURL=benchmarkCaseReview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmarkCaseReview.js","sourceRoot":"","sources":["../../benchmarkCaseReview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { BenchmarkImage, TestCase } from '../types/index.js';
2
+ /** Eval conditions frozen into an image digest. */
3
+ export interface ImageEvalConditions {
4
+ evaluatorId?: string;
5
+ judgeModelId?: string;
6
+ }
7
+ /** Bump when the digest input shape changes (invalidates old digests). */
8
+ export declare const IMAGE_DIGEST_VERSION = 1;
9
+ /**
10
+ * Deterministic JSON: objects serialized with sorted keys, recursively.
11
+ * Arrays keep their order (order-sensitivity is decided by the caller).
12
+ */
13
+ export declare function canonicalStringify(value: unknown): string;
14
+ /**
15
+ * Content fingerprint of a single test case. Uses CONTENT only — never the
16
+ * storage id — so re-imported test cases (fresh ids, same content) fingerprint
17
+ * identically. Fields chosen to match what actually changes agent behavior
18
+ * and judging: prompt, context, expected outcomes/trajectory, tools.
19
+ */
20
+ export declare function fingerprintTestCase(tc: Partial<TestCase> & {
21
+ name: string;
22
+ }): {
23
+ name: string;
24
+ contentHash: string;
25
+ };
26
+ /**
27
+ * Compute the image digest for a set of test cases + eval conditions.
28
+ * Order-insensitive over test cases (fingerprints are sorted), content- and
29
+ * condition-sensitive.
30
+ */
31
+ export declare function computeImageDigest(input: {
32
+ testCases: Array<Partial<TestCase> & {
33
+ name: string;
34
+ }>;
35
+ evalConditions?: ImageEvalConditions;
36
+ }): string;
37
+ /** Storage id for an image doc (content-addressed — one doc per digest). */
38
+ export declare function imageIdForDigest(digest: string): string;
39
+ /**
40
+ * Build a full image doc for storage. `create` on the storage side is
41
+ * find-or-create keyed on the digest, so calling this repeatedly for the
42
+ * same inputs is harmless.
43
+ */
44
+ export declare function buildImageDoc(input: {
45
+ testCases: Array<Partial<TestCase> & {
46
+ id?: string;
47
+ name: string;
48
+ }>;
49
+ evalConditions?: ImageEvalConditions;
50
+ tags?: string[];
51
+ }): BenchmarkImage;
52
+ //# sourceMappingURL=benchmarkImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmarkImage.d.ts","sourceRoot":"","sources":["../../benchmarkImage.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExD,mDAAmD;AACnD,MAAM,WAAW,mBAAmB;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,0EAA0E;AAC1E,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEzD;AAmBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAYvC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,cAAc,CAAC,EAAE,mBAAmB,CAAC;CACtC,GAAG,MAAM,CAaT;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB,GAAG,cAAc,CAkBjB"}
@@ -0,0 +1,113 @@
1
+ /*
2
+ * Copyright OpenSearch Contributors
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ /**
6
+ * Benchmark images — content-addressed identity for evaluation conditions.
7
+ *
8
+ * An image freezes the "controls" of an evaluation run: the test-case
9
+ * contents and the eval conditions (evaluator, judge model). The digest is a
10
+ * SHA-256 over a canonical serialization, so:
11
+ *
12
+ * - two runs with the same digest are comparable **by construction**
13
+ * (same tests, same judge conditions — only the agent varies);
14
+ * - re-running the same command yields the same digest → the image is
15
+ * found, not re-created (inherent dedup: identity is content, not name).
16
+ *
17
+ * Names are docker-style *tags*: mutable labels pointing at a digest, never
18
+ * identity. See the benchmark-dedup design discussion for rationale.
19
+ */
20
+ import { createHash } from 'crypto';
21
+ /** Bump when the digest input shape changes (invalidates old digests). */
22
+ export const IMAGE_DIGEST_VERSION = 1;
23
+ /**
24
+ * Deterministic JSON: objects serialized with sorted keys, recursively.
25
+ * Arrays keep their order (order-sensitivity is decided by the caller).
26
+ */
27
+ export function canonicalStringify(value) {
28
+ return JSON.stringify(sortValue(value));
29
+ }
30
+ function sortValue(value) {
31
+ if (Array.isArray(value))
32
+ return value.map(sortValue);
33
+ if (value && typeof value === 'object') {
34
+ const out = {};
35
+ for (const key of Object.keys(value).sort()) {
36
+ const v = value[key];
37
+ if (v !== undefined)
38
+ out[key] = sortValue(v);
39
+ }
40
+ return out;
41
+ }
42
+ return value;
43
+ }
44
+ function sha256Hex(input) {
45
+ return createHash('sha256').update(input, 'utf8').digest('hex');
46
+ }
47
+ /**
48
+ * Content fingerprint of a single test case. Uses CONTENT only — never the
49
+ * storage id — so re-imported test cases (fresh ids, same content) fingerprint
50
+ * identically. Fields chosen to match what actually changes agent behavior
51
+ * and judging: prompt, context, expected outcomes/trajectory, tools.
52
+ */
53
+ export function fingerprintTestCase(tc) {
54
+ const content = {
55
+ name: tc.name,
56
+ initialPrompt: tc.initialPrompt ?? null,
57
+ context: tc.context ?? null,
58
+ tools: tc.tools ?? null,
59
+ expectedOutcomes: tc.expectedOutcomes ?? null,
60
+ expectedTrajectory: tc.expectedTrajectory ?? null,
61
+ // Code-imported cases: sourceHash already fingerprints the executable body.
62
+ sourceHash: tc.sourceHash ?? null,
63
+ };
64
+ return { name: tc.name, contentHash: sha256Hex(canonicalStringify(content)) };
65
+ }
66
+ /**
67
+ * Compute the image digest for a set of test cases + eval conditions.
68
+ * Order-insensitive over test cases (fingerprints are sorted), content- and
69
+ * condition-sensitive.
70
+ */
71
+ export function computeImageDigest(input) {
72
+ const fingerprints = input.testCases
73
+ .map(fingerprintTestCase)
74
+ .sort((a, b) => a.contentHash.localeCompare(b.contentHash));
75
+ const payload = {
76
+ v: IMAGE_DIGEST_VERSION,
77
+ testCases: fingerprints.map((f) => f.contentHash),
78
+ evalConditions: {
79
+ evaluatorId: input.evalConditions?.evaluatorId ?? null,
80
+ judgeModelId: input.evalConditions?.judgeModelId ?? null,
81
+ },
82
+ };
83
+ return sha256Hex(canonicalStringify(payload));
84
+ }
85
+ /** Storage id for an image doc (content-addressed — one doc per digest). */
86
+ export function imageIdForDigest(digest) {
87
+ return `img-${digest}`;
88
+ }
89
+ /**
90
+ * Build a full image doc for storage. `create` on the storage side is
91
+ * find-or-create keyed on the digest, so calling this repeatedly for the
92
+ * same inputs is harmless.
93
+ */
94
+ export function buildImageDoc(input) {
95
+ const digest = computeImageDigest(input);
96
+ const fingerprints = input.testCases
97
+ .map((tc) => ({ ...fingerprintTestCase(tc), id: tc.id }))
98
+ .sort((a, b) => a.contentHash.localeCompare(b.contentHash));
99
+ return {
100
+ id: imageIdForDigest(digest),
101
+ docType: 'benchmark-image',
102
+ digest,
103
+ tags: input.tags ?? [],
104
+ testCaseFingerprints: fingerprints,
105
+ testCaseCount: fingerprints.length,
106
+ evalConditions: {
107
+ ...(input.evalConditions?.evaluatorId ? { evaluatorId: input.evalConditions.evaluatorId } : {}),
108
+ ...(input.evalConditions?.judgeModelId ? { judgeModelId: input.evalConditions.judgeModelId } : {}),
109
+ },
110
+ createdAt: new Date().toISOString(),
111
+ };
112
+ }
113
+ //# sourceMappingURL=benchmarkImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"benchmarkImage.js","sourceRoot":"","sources":["../../benchmarkImage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AASpC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACvE,MAAM,CAAC,GAAI,KAAiC,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,CAAC,KAAK,SAAS;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,EAAwC;IAExC,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,aAAa,EAAE,EAAE,CAAC,aAAa,IAAI,IAAI;QACvC,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,IAAI;QAC3B,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI;QACvB,gBAAgB,EAAE,EAAE,CAAC,gBAAgB,IAAI,IAAI;QAC7C,kBAAkB,EAAE,EAAE,CAAC,kBAAkB,IAAI,IAAI;QACjD,4EAA4E;QAC5E,UAAU,EAAE,EAAE,CAAC,UAAU,IAAI,IAAI;KAClC,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;AAChF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAGlC;IACC,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS;SACjC,GAAG,CAAC,mBAAmB,CAAC;SACxB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG;QACd,CAAC,EAAE,oBAAoB;QACvB,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QACjD,cAAc,EAAE;YACd,WAAW,EAAE,KAAK,CAAC,cAAc,EAAE,WAAW,IAAI,IAAI;YACtD,YAAY,EAAE,KAAK,CAAC,cAAc,EAAE,YAAY,IAAI,IAAI;SACzD;KACF,CAAC;IACF,OAAO,SAAS,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO,OAAO,MAAM,EAAE,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,KAI7B;IACC,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS;SACjC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;SACxD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9D,OAAO;QACL,EAAE,EAAE,gBAAgB,CAAC,MAAM,CAAC;QAC5B,OAAO,EAAE,iBAAiB;QAC1B,MAAM;QACN,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE;QACtB,oBAAoB,EAAE,YAAY;QAClC,aAAa,EAAE,YAAY,CAAC,MAAM;QAClC,cAAc,EAAE;YACd,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/F,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnG;QACD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC"}