stageflow 0.40.0 → 0.42.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 (326) hide show
  1. package/README.md +3 -1
  2. package/dist/agents/authorChat.d.ts +4 -0
  3. package/dist/agents/authorChat.js +113 -12
  4. package/dist/agents/authorSessionStore.d.ts +35 -0
  5. package/dist/agents/authorSessionStore.js +152 -0
  6. package/dist/agents/chatTurn.d.ts +2 -0
  7. package/dist/agents/chatTurn.js +17 -1
  8. package/dist/agents/errors.d.ts +1 -1
  9. package/dist/agents/errors.js +1 -0
  10. package/dist/agents/evalGate.d.ts +61 -0
  11. package/dist/agents/evalGate.js +103 -0
  12. package/dist/agents/evalSession.d.ts +26 -0
  13. package/dist/agents/evalSession.js +29 -0
  14. package/dist/agents/hostContext.d.ts +3 -0
  15. package/dist/agents/hostContext.js +4 -1
  16. package/dist/agents/runtime/piRuntime.d.ts +1 -1
  17. package/dist/agents/runtime/piRuntime.js +4 -4
  18. package/dist/agents/runtime/types.d.ts +3 -1
  19. package/dist/agents/service.d.ts +27 -2
  20. package/dist/agents/service.js +88 -13
  21. package/dist/agents/sessions.d.ts +8 -0
  22. package/dist/agents/sessions.js +50 -10
  23. package/dist/agents/store.d.ts +14 -3
  24. package/dist/agents/store.js +45 -7
  25. package/dist/agents/toolRisk.d.ts +21 -0
  26. package/dist/agents/toolRisk.js +50 -0
  27. package/dist/cli/doctorCommand.js +26 -0
  28. package/dist/cli/evalCommand.d.ts +20 -0
  29. package/dist/cli/evalCommand.js +720 -0
  30. package/dist/cli/exportAllCommand.js +1 -1
  31. package/dist/cli/hostClient.d.ts +60 -0
  32. package/dist/cli/hostClient.js +71 -0
  33. package/dist/cli/validateOutput.d.ts +2 -2
  34. package/dist/cli/validateOutput.js +2 -2
  35. package/dist/cli.js +10 -0
  36. package/dist/config/atomicWrite.d.ts +15 -0
  37. package/dist/config/atomicWrite.js +43 -0
  38. package/dist/config/browseCatalog.d.ts +2 -0
  39. package/dist/config/browseCatalog.js +4 -2
  40. package/dist/config/csv.d.ts +9 -0
  41. package/dist/config/csv.js +81 -0
  42. package/dist/config/datasetAgentCheck.d.ts +18 -0
  43. package/dist/config/datasetAgentCheck.js +109 -0
  44. package/dist/config/datasetCandidates.d.ts +22 -0
  45. package/dist/config/datasetCandidates.js +86 -0
  46. package/dist/config/datasetFromSessions.d.ts +34 -0
  47. package/dist/config/datasetFromSessions.js +105 -0
  48. package/dist/config/datasetHash.d.ts +1 -0
  49. package/dist/config/datasetHash.js +4 -0
  50. package/dist/config/datasetImport.d.ts +21 -0
  51. package/dist/config/datasetImport.js +120 -0
  52. package/dist/config/datasetStageCheck.d.ts +9 -0
  53. package/dist/config/datasetStageCheck.js +17 -0
  54. package/dist/config/datasetTypes.d.ts +27 -0
  55. package/dist/config/datasetTypes.js +1 -0
  56. package/dist/config/ensureCatalogScanRoot.d.ts +2 -1
  57. package/dist/config/ensureCatalogScanRoot.js +2 -6
  58. package/dist/config/evalCatalog.d.ts +22 -0
  59. package/dist/config/evalCatalog.js +67 -0
  60. package/dist/config/evalWriteRoots.d.ts +17 -0
  61. package/dist/config/evalWriteRoots.js +109 -0
  62. package/dist/config/hostConfig.js +1 -0
  63. package/dist/config/installEvalSample.d.ts +34 -0
  64. package/dist/config/installEvalSample.js +182 -0
  65. package/dist/config/loadDataset.d.ts +16 -0
  66. package/dist/config/loadDataset.js +318 -0
  67. package/dist/config/loadEval.d.ts +32 -0
  68. package/dist/config/loadEval.js +1085 -0
  69. package/dist/config/loadOutcome.d.ts +5 -0
  70. package/dist/config/loadStageflowManifest.js +64 -0
  71. package/dist/config/resolveAgentTarget.d.ts +32 -0
  72. package/dist/config/resolveAgentTarget.js +118 -0
  73. package/dist/config/resolveEvalTarget.d.ts +21 -0
  74. package/dist/config/resolveEvalTarget.js +89 -0
  75. package/dist/config/scanCatalogPaths.d.ts +1 -1
  76. package/dist/config/scanCatalogPaths.js +17 -5
  77. package/dist/config/validateCatalog.d.ts +1 -1
  78. package/dist/config/validateCatalog.js +9 -1
  79. package/dist/config/validateEval.d.ts +36 -0
  80. package/dist/config/validateEval.js +405 -0
  81. package/dist/config/writeDataset.d.ts +54 -0
  82. package/dist/config/writeDataset.js +186 -0
  83. package/dist/config/writeEval.d.ts +25 -0
  84. package/dist/config/writeEval.js +398 -0
  85. package/dist/diagnostics/checks.js +1 -1
  86. package/dist/evals/agentDiff.d.ts +13 -0
  87. package/dist/evals/agentDiff.js +11 -0
  88. package/dist/evals/canonical.d.ts +3 -0
  89. package/dist/evals/canonical.js +24 -0
  90. package/dist/evals/caseTask.d.ts +3 -0
  91. package/dist/evals/caseTask.js +9 -0
  92. package/dist/evals/compare.d.ts +94 -0
  93. package/dist/evals/compare.js +201 -0
  94. package/dist/evals/constants.d.ts +60 -0
  95. package/dist/evals/constants.js +95 -0
  96. package/dist/evals/engine/FakeEngine.d.ts +33 -0
  97. package/dist/evals/engine/FakeEngine.js +176 -0
  98. package/dist/evals/engine/index.d.ts +9 -0
  99. package/dist/evals/engine/index.js +19 -0
  100. package/dist/evals/engine/promptfoo/PromptfooEngine.d.ts +52 -0
  101. package/dist/evals/engine/promptfoo/PromptfooEngine.js +311 -0
  102. package/dist/evals/engine/promptfoo/errors.d.ts +5 -0
  103. package/dist/evals/engine/promptfoo/errors.js +8 -0
  104. package/dist/evals/engine/promptfoo/generate.d.ts +30 -0
  105. package/dist/evals/engine/promptfoo/generate.js +342 -0
  106. package/dist/evals/engine/promptfoo/guard.d.ts +10 -0
  107. package/dist/evals/engine/promptfoo/guard.js +116 -0
  108. package/dist/evals/engine/promptfoo/install.d.ts +17 -0
  109. package/dist/evals/engine/promptfoo/install.js +73 -0
  110. package/dist/evals/engine/promptfoo/judgeProviders.d.ts +2 -0
  111. package/dist/evals/engine/promptfoo/judgeProviders.js +9 -0
  112. package/dist/evals/engine/promptfoo/judgeServices.d.ts +6 -0
  113. package/dist/evals/engine/promptfoo/judgeServices.js +41 -0
  114. package/dist/evals/engine/promptfoo/locate.d.ts +21 -0
  115. package/dist/evals/engine/promptfoo/locate.js +68 -0
  116. package/dist/evals/engine/promptfoo/nodeVersion.d.ts +7 -0
  117. package/dist/evals/engine/promptfoo/nodeVersion.js +14 -0
  118. package/dist/evals/engine/promptfoo/normalize.d.ts +66 -0
  119. package/dist/evals/engine/promptfoo/normalize.js +261 -0
  120. package/dist/evals/engine/promptfoo/pinned.d.ts +5 -0
  121. package/dist/evals/engine/promptfoo/pinned.js +5 -0
  122. package/dist/evals/engine/promptfoo/rubricPrompt.d.ts +14 -0
  123. package/dist/evals/engine/promptfoo/rubricPrompt.js +103 -0
  124. package/dist/evals/engine/promptfoo/runTokens.d.ts +18 -0
  125. package/dist/evals/engine/promptfoo/runTokens.js +31 -0
  126. package/dist/evals/engine/promptfoo/status.d.ts +13 -0
  127. package/dist/evals/engine/promptfoo/status.js +16 -0
  128. package/dist/evals/estimate.d.ts +56 -0
  129. package/dist/evals/estimate.js +66 -0
  130. package/dist/evals/graders/codeGrader.d.ts +6 -0
  131. package/dist/evals/graders/codeGrader.js +85 -0
  132. package/dist/evals/graders/conversationCheckGrader.d.ts +6 -0
  133. package/dist/evals/graders/conversationCheckGrader.js +62 -0
  134. package/dist/evals/graders/fieldGrader.d.ts +11 -0
  135. package/dist/evals/graders/fieldGrader.js +117 -0
  136. package/dist/evals/graders/goal.d.ts +3 -0
  137. package/dist/evals/graders/goal.js +14 -0
  138. package/dist/evals/graders/index.d.ts +18 -0
  139. package/dist/evals/graders/index.js +34 -0
  140. package/dist/evals/graders/notApplicable.d.ts +5 -0
  141. package/dist/evals/graders/notApplicable.js +9 -0
  142. package/dist/evals/graders/path.d.ts +26 -0
  143. package/dist/evals/graders/path.js +75 -0
  144. package/dist/evals/graders/referenceGrader.d.ts +5 -0
  145. package/dist/evals/graders/referenceGrader.js +59 -0
  146. package/dist/evals/graders/schemaGrader.d.ts +5 -0
  147. package/dist/evals/graders/schemaGrader.js +29 -0
  148. package/dist/evals/graders/subject.d.ts +6 -0
  149. package/dist/evals/graders/subject.js +33 -0
  150. package/dist/evals/graders/toolCallsGrader.d.ts +6 -0
  151. package/dist/evals/graders/toolCallsGrader.js +100 -0
  152. package/dist/evals/graders/transcript.d.ts +12 -0
  153. package/dist/evals/graders/transcript.js +57 -0
  154. package/dist/evals/graders/types.d.ts +20 -0
  155. package/dist/evals/graders/types.js +1 -0
  156. package/dist/evals/judgeProviders.d.ts +16 -0
  157. package/dist/evals/judgeProviders.js +27 -0
  158. package/dist/evals/lineDiff.d.ts +5 -0
  159. package/dist/evals/lineDiff.js +34 -0
  160. package/dist/evals/listStatus.d.ts +31 -0
  161. package/dist/evals/listStatus.js +48 -0
  162. package/dist/evals/manager.d.ts +174 -0
  163. package/dist/evals/manager.js +787 -0
  164. package/dist/evals/plan.d.ts +58 -0
  165. package/dist/evals/plan.js +602 -0
  166. package/dist/evals/providerKeys.d.ts +1 -0
  167. package/dist/evals/providerKeys.js +21 -0
  168. package/dist/evals/read/agentTargets.d.ts +37 -0
  169. package/dist/evals/read/agentTargets.js +101 -0
  170. package/dist/evals/read/api.d.ts +196 -0
  171. package/dist/evals/read/api.js +358 -0
  172. package/dist/evals/read/compare.d.ts +4 -0
  173. package/dist/evals/read/compare.js +39 -0
  174. package/dist/evals/read/datasets.d.ts +105 -0
  175. package/dist/evals/read/datasets.js +318 -0
  176. package/dist/evals/read/list.d.ts +66 -0
  177. package/dist/evals/read/list.js +173 -0
  178. package/dist/evals/read/results.d.ts +46 -0
  179. package/dist/evals/read/results.js +107 -0
  180. package/dist/evals/read/runs.d.ts +149 -0
  181. package/dist/evals/read/runs.js +289 -0
  182. package/dist/evals/read/suggestions.d.ts +43 -0
  183. package/dist/evals/read/suggestions.js +73 -0
  184. package/dist/evals/runner/FakeAgentBackend.d.ts +40 -0
  185. package/dist/evals/runner/FakeAgentBackend.js +82 -0
  186. package/dist/evals/runner/agentCaseRunner.d.ts +24 -0
  187. package/dist/evals/runner/agentCaseRunner.js +388 -0
  188. package/dist/evals/runner/caseRunner.d.ts +7 -0
  189. package/dist/evals/runner/caseRunner.js +17 -0
  190. package/dist/evals/runner/conversationSubject.d.ts +18 -0
  191. package/dist/evals/runner/conversationSubject.js +123 -0
  192. package/dist/evals/runner/simulatorModel.d.ts +51 -0
  193. package/dist/evals/runner/simulatorModel.js +58 -0
  194. package/dist/evals/runner/simulatorPrompt.d.ts +29 -0
  195. package/dist/evals/runner/simulatorPrompt.js +59 -0
  196. package/dist/evals/runner/stageCaseRunner.d.ts +30 -0
  197. package/dist/evals/runner/stageCaseRunner.js +279 -0
  198. package/dist/evals/runner/userDriver.d.ts +71 -0
  199. package/dist/evals/runner/userDriver.js +104 -0
  200. package/dist/evals/scoring.d.ts +34 -0
  201. package/dist/evals/scoring.js +67 -0
  202. package/dist/evals/snapshot.d.ts +183 -0
  203. package/dist/evals/snapshot.js +65 -0
  204. package/dist/evals/stageDiff.d.ts +8 -0
  205. package/dist/evals/stageDiff.js +48 -0
  206. package/dist/evals/stats.d.ts +95 -0
  207. package/dist/evals/stats.js +220 -0
  208. package/dist/evals/statsAdapter.d.ts +4 -0
  209. package/dist/evals/statsAdapter.js +30 -0
  210. package/dist/evals/statsTypes.d.ts +51 -0
  211. package/dist/evals/statsTypes.js +18 -0
  212. package/dist/evals/storeError.d.ts +5 -0
  213. package/dist/evals/storeError.js +8 -0
  214. package/dist/evals/storeTypes.d.ts +207 -0
  215. package/dist/evals/storeTypes.js +1 -0
  216. package/dist/evals/tTable.d.ts +3 -0
  217. package/dist/evals/tTable.js +15 -0
  218. package/dist/evals/triage/constants.d.ts +26 -0
  219. package/dist/evals/triage/constants.js +33 -0
  220. package/dist/evals/triage/credentials.d.ts +13 -0
  221. package/dist/evals/triage/credentials.js +20 -0
  222. package/dist/evals/triage/jevClassifier.d.ts +14 -0
  223. package/dist/evals/triage/jevClassifier.js +124 -0
  224. package/dist/evals/triage/judgeClassifier.d.ts +10 -0
  225. package/dist/evals/triage/judgeClassifier.js +76 -0
  226. package/dist/evals/triage/prompts.d.ts +16 -0
  227. package/dist/evals/triage/prompts.js +64 -0
  228. package/dist/evals/triage/service.d.ts +79 -0
  229. package/dist/evals/triage/service.js +217 -0
  230. package/dist/evals/triage/stateBuilder.d.ts +19 -0
  231. package/dist/evals/triage/stateBuilder.js +125 -0
  232. package/dist/evals/triage/types.d.ts +60 -0
  233. package/dist/evals/triage/types.js +8 -0
  234. package/dist/evals/types.d.ts +347 -0
  235. package/dist/evals/types.js +1 -0
  236. package/dist/mcp/deps.d.ts +7 -0
  237. package/dist/mcp/evalTools.d.ts +3 -0
  238. package/dist/mcp/evalTools.js +280 -0
  239. package/dist/mcp/server.js +1 -0
  240. package/dist/mcp/tools.js +2 -0
  241. package/dist/models/response.d.ts +7 -2
  242. package/dist/models/response.js +6 -1
  243. package/dist/operatorAgent/agentAuthorContext.d.ts +1 -1
  244. package/dist/operatorAgent/agentAuthorContext.js +1 -1
  245. package/dist/operatorAgent/piModel.js +17 -4
  246. package/dist/operatorAgent/profiles/agentAuthor.d.ts +3 -1
  247. package/dist/operatorAgent/profiles/agentAuthor.js +145 -20
  248. package/dist/operatorAgent/profiles/agentAuthorPlaybook.d.ts +1 -1
  249. package/dist/operatorAgent/profiles/agentAuthorPlaybook.js +48 -15
  250. package/dist/operatorAgent/profiles/authorReadable.d.ts +2 -0
  251. package/dist/operatorAgent/profiles/authorReadable.js +26 -0
  252. package/dist/package-meta.d.ts +1 -1
  253. package/dist/package-meta.js +1 -1
  254. package/dist/runstore/port.d.ts +43 -0
  255. package/dist/runstore/sqlite/SqliteRunStore.d.ts +28 -0
  256. package/dist/runstore/sqlite/SqliteRunStore.js +99 -5
  257. package/dist/runstore/sqlite/evalStore.d.ts +20 -0
  258. package/dist/runstore/sqlite/evalStore.js +541 -0
  259. package/dist/runstore/sqlite/migrations/015-evals.d.ts +12 -0
  260. package/dist/runstore/sqlite/migrations/015-evals.js +157 -0
  261. package/dist/runstore/sqlite/migrations/016-eval-subject-ref.d.ts +12 -0
  262. package/dist/runstore/sqlite/migrations/016-eval-subject-ref.js +20 -0
  263. package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.d.ts +11 -0
  264. package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.js +36 -0
  265. package/dist/runstore/sqlite/migrations/index.js +6 -0
  266. package/dist/runstore/sqlite/suggestionStore.d.ts +14 -0
  267. package/dist/runstore/sqlite/suggestionStore.js +132 -0
  268. package/dist/runtime/pipelineRunner.d.ts +2 -1
  269. package/dist/runtime/pipelineRunner.js +2 -0
  270. package/dist/runtime/runManager.d.ts +2 -1
  271. package/dist/runtime/runManager.js +8 -6
  272. package/dist/runtime/runRetentionSweep.js +2 -2
  273. package/dist/server/agentAuthorRoutes.js +50 -1
  274. package/dist/server/bootstrap.d.ts +8 -0
  275. package/dist/server/bootstrap.js +56 -0
  276. package/dist/server/controlToken.js +3 -0
  277. package/dist/server/evalInternalRoutes.d.ts +14 -0
  278. package/dist/server/evalInternalRoutes.js +87 -0
  279. package/dist/server/evalRouteContext.d.ts +46 -0
  280. package/dist/server/evalRouteContext.js +43 -0
  281. package/dist/server/evalRoutes.d.ts +5 -0
  282. package/dist/server/evalRoutes.js +1427 -0
  283. package/dist/server/evalTriageRoutes.d.ts +2 -0
  284. package/dist/server/evalTriageRoutes.js +95 -0
  285. package/dist/server/http.d.ts +5 -0
  286. package/dist/server/http.js +32 -2
  287. package/dist/server/mcpHost.js +3 -0
  288. package/dist/toolkit/meta.d.ts +1 -1
  289. package/dist/toolkit/meta.js +15 -0
  290. package/dist/toolkit/profiles.js +1 -1
  291. package/dist/types/stageflowManifest.d.ts +6 -0
  292. package/dist/ui/assets/AssistantRuntimeProvider-qIX1xNoH.js +9 -0
  293. package/dist/ui/assets/{MarkdownText-D7tYaIFO.js → MarkdownText-BTrOqu5J.js} +1 -1
  294. package/dist/ui/assets/chat-Df_wCpak.js +5 -0
  295. package/dist/ui/assets/chat-P7KQznHm.css +2 -0
  296. package/dist/ui/assets/{main-BFo79krC.css → main-CHlmTNJe.css} +1 -1
  297. package/dist/ui/assets/main-CvVfxmMd.js +271 -0
  298. package/dist/ui/chat.html +3 -3
  299. package/dist/ui/index.html +3 -3
  300. package/examples/README.md +2 -0
  301. package/examples/document-policy-review/README.md +35 -0
  302. package/examples/document-policy-review/agents/compliance.agent.yaml +42 -0
  303. package/examples/document-policy-review/documents/acme-vendor-sow.md +15 -0
  304. package/examples/document-policy-review/documents/support-runbook.md +13 -0
  305. package/examples/document-policy-review/policies/acceptable-use.md +13 -0
  306. package/examples/document-policy-review/policies/data-handling.md +17 -0
  307. package/examples/document-policy-review/policies/vendor-security.md +17 -0
  308. package/examples/evals/README.md +123 -0
  309. package/examples/evals/critique-sample.dataset.jsonl +8 -0
  310. package/examples/evals/critique-sample.eval.yaml +34 -0
  311. package/examples/evals/critique-sample.task.yaml +4 -0
  312. package/examples/evals/eval-sample.pipeline.yaml +35 -0
  313. package/examples/evals/support-sample.agent.yaml +20 -0
  314. package/examples/evals/support-sample.dataset.jsonl +6 -0
  315. package/examples/evals/support-sample.eval.yaml +38 -0
  316. package/examples/stageflow.yaml +6 -0
  317. package/package.json +1 -1
  318. package/skills/stageflow/SKILL.md +5 -2
  319. package/skills/stageflow/references/control-surface.md +4 -2
  320. package/skills/stageflow/references/evals.md +68 -0
  321. package/skills/stageflow-author/SKILL.md +4 -0
  322. package/skills/stageflow-run/SKILL.md +4 -0
  323. package/dist/ui/assets/AssistantRuntimeProvider-CsiPFhCT.js +0 -9
  324. package/dist/ui/assets/chat-BbLukq9W.js +0 -5
  325. package/dist/ui/assets/chat-zIZU_bP1.css +0 -2
  326. package/dist/ui/assets/main-CijYMeM0.js +0 -259
@@ -0,0 +1,56 @@
1
+ export interface EstimatePreviousRun {
2
+ runNumber: number;
3
+ costStage: number;
4
+ costJudge: number;
5
+ resultsExecuted: number;
6
+ rubricGradesGraded: number;
7
+ wallSeconds: number | null;
8
+ }
9
+ export interface TokenPrice {
10
+ inputPerMillion: number;
11
+ outputPerMillion: number;
12
+ }
13
+ export declare const AGENT_ESTIMATE_ASSUMPTIONS: {
14
+ readonly maxTurnsCap: 6;
15
+ readonly toolCallsPerTurn: 2;
16
+ readonly agentCall: {
17
+ readonly tokensIn: 2000;
18
+ readonly tokensOut: 200;
19
+ };
20
+ readonly simulatorCall: {
21
+ readonly tokensIn: 1000;
22
+ readonly tokensOut: 60;
23
+ };
24
+ readonly judgeCall: {
25
+ readonly tokensIn: 3000;
26
+ readonly tokensOut: 100;
27
+ };
28
+ };
29
+ export interface AgentEstimateBlock {
30
+ turnsPerCase: number;
31
+ simulatorCallsPerCase: number;
32
+ judgeTranscriptTokens: number;
33
+ agentPrice?: TokenPrice | null;
34
+ simulatorPrice?: TokenPrice | null;
35
+ judgePrice?: TokenPrice | null;
36
+ }
37
+ export interface EstimateRunInput {
38
+ resultsTotal: number;
39
+ rubricGraderCount: number;
40
+ previous: EstimatePreviousRun | null;
41
+ recentStageCosts: number[];
42
+ agent?: AgentEstimateBlock;
43
+ }
44
+ export interface RunEstimate {
45
+ estimate_usd: number | null;
46
+ avg_stage_cost: number | null;
47
+ avg_judge_cost: number | null;
48
+ stage_calls: number;
49
+ judge_calls: number;
50
+ judge_excluded: boolean;
51
+ based_on_run_number: number | null;
52
+ estimate_seconds: number | null;
53
+ simulator_calls?: number;
54
+ estimate_basis?: "previous_run" | "assumptions" | null;
55
+ }
56
+ export declare function estimateRun(input: EstimateRunInput): RunEstimate;
@@ -0,0 +1,66 @@
1
+ export const AGENT_ESTIMATE_ASSUMPTIONS = {
2
+ maxTurnsCap: 6,
3
+ toolCallsPerTurn: 2,
4
+ agentCall: { tokensIn: 2000, tokensOut: 200 },
5
+ simulatorCall: { tokensIn: 1000, tokensOut: 60 },
6
+ judgeCall: { tokensIn: 3000, tokensOut: 100 },
7
+ };
8
+ function callCost(price, tokensIn, tokensOut) {
9
+ return (tokensIn * price.inputPerMillion + tokensOut * price.outputPerMillion) / 1_000_000;
10
+ }
11
+ function assumedAgentCosts(agent) {
12
+ const a = AGENT_ESTIMATE_ASSUMPTIONS;
13
+ const agentCalls = agent.turnsPerCase * (1 + a.toolCallsPerTurn);
14
+ let stage = null;
15
+ if (agent.agentPrice && (agent.simulatorCallsPerCase === 0 || agent.simulatorPrice)) {
16
+ stage = agentCalls * callCost(agent.agentPrice, a.agentCall.tokensIn, a.agentCall.tokensOut);
17
+ if (agent.simulatorPrice) {
18
+ stage += agent.simulatorCallsPerCase * callCost(agent.simulatorPrice, a.simulatorCall.tokensIn, a.simulatorCall.tokensOut);
19
+ }
20
+ }
21
+ const judge = agent.judgePrice
22
+ ? callCost(agent.judgePrice, agent.judgeTranscriptTokens, a.judgeCall.tokensOut)
23
+ : null;
24
+ return { stage, judge };
25
+ }
26
+ export function estimateRun(input) {
27
+ const { previous } = input;
28
+ const stageCalls = input.resultsTotal;
29
+ const judgeCalls = input.resultsTotal * input.rubricGraderCount;
30
+ const usePrevious = previous !== null && previous.resultsExecuted > 0;
31
+ const assumed = input.agent && !usePrevious ? assumedAgentCosts(input.agent) : null;
32
+ let avgStage = null;
33
+ if (usePrevious) {
34
+ avgStage = previous.costStage / previous.resultsExecuted;
35
+ }
36
+ else if (input.agent) {
37
+ avgStage = assumed?.stage ?? null;
38
+ }
39
+ else if (input.recentStageCosts.length > 0) {
40
+ avgStage = input.recentStageCosts.reduce((a, b) => a + b, 0) / input.recentStageCosts.length;
41
+ }
42
+ const avgJudge = previous && previous.rubricGradesGraded > 0
43
+ ? previous.costJudge / previous.rubricGradesGraded
44
+ : (assumed?.judge ?? null);
45
+ const judgeExcluded = judgeCalls > 0 && avgJudge === null;
46
+ const estimate = avgStage === null ? null : stageCalls * avgStage + judgeCalls * (avgJudge ?? 0);
47
+ const seconds = previous && previous.resultsExecuted > 0 && previous.wallSeconds !== null
48
+ ? (previous.wallSeconds * input.resultsTotal) / previous.resultsExecuted
49
+ : null;
50
+ return {
51
+ estimate_usd: estimate,
52
+ avg_stage_cost: avgStage,
53
+ avg_judge_cost: avgJudge,
54
+ stage_calls: stageCalls,
55
+ judge_calls: judgeCalls,
56
+ judge_excluded: judgeExcluded,
57
+ based_on_run_number: input.agent && !usePrevious ? null : previous ? previous.runNumber : null,
58
+ estimate_seconds: seconds,
59
+ ...(input.agent
60
+ ? {
61
+ simulator_calls: input.resultsTotal * input.agent.simulatorCallsPerCase,
62
+ estimate_basis: usePrevious ? "previous_run" : avgStage !== null ? "assumptions" : null,
63
+ }
64
+ : {}),
65
+ };
66
+ }
@@ -0,0 +1,6 @@
1
+ import type { ResolvedGrader } from "../types.js";
2
+ import type { GradeCase, GradeData, GraderContext, Subject } from "./types.js";
3
+ export declare const CODE_GRADER_TIMEOUT_MS = 5000;
4
+ export declare function gradeCode(grader: Extract<ResolvedGrader, {
5
+ type: "code";
6
+ }>, subject: Subject, testCase: GradeCase, context: GraderContext): GradeData;
@@ -0,0 +1,85 @@
1
+ import vm from "node:vm";
2
+ import { subjectRoot, truncate } from "./subject.js";
3
+ export const CODE_GRADER_TIMEOUT_MS = 5_000;
4
+ const RUNNER = `(function () {
5
+ function freeze(o) {
6
+ if (o && typeof o === "object" && !Object.isFrozen(o)) {
7
+ Object.freeze(o);
8
+ for (const k of Object.keys(o)) freeze(o[k]);
9
+ }
10
+ return o;
11
+ }
12
+ const args = JSON.parse(__args).map(freeze);
13
+ const fn = new Function("output", "testCase", "context", __body);
14
+ const out = JSON.stringify(fn(args[0], args[1], args[2]));
15
+ return out === undefined ? "undefined" : out;
16
+ })()`;
17
+ export function gradeCode(grader, subject, testCase, context) {
18
+ const base = { graderId: grader.id, graderType: "code" };
19
+ const error = (reason) => ({
20
+ ...base,
21
+ status: "error",
22
+ errorCode: "EVAL_GRADER_CODE_ERROR",
23
+ reason: truncate(reason),
24
+ });
25
+ const timeout = context.codeTimeoutMs ?? CODE_GRADER_TIMEOUT_MS;
26
+ let raw;
27
+ try {
28
+ const sandbox = vm.createContext({
29
+ __args: JSON.stringify([
30
+ subjectRoot(subject),
31
+ testCase,
32
+ { evalId: context.evalId, runId: context.runId, repeat: context.repeat },
33
+ ]),
34
+ __body: grader.code,
35
+ });
36
+ raw = new vm.Script(RUNNER).runInContext(sandbox, { timeout });
37
+ }
38
+ catch (e) {
39
+ const message = e instanceof Error ? e.message : String(e);
40
+ return error(/timed out/i.test(message) ? `code grader timed out after ${timeout} ms` : message);
41
+ }
42
+ let value;
43
+ try {
44
+ value = raw === "undefined" ? undefined : JSON.parse(String(raw));
45
+ }
46
+ catch {
47
+ return error("code grader returned a value that is not JSON-serializable");
48
+ }
49
+ if (typeof value === "boolean") {
50
+ return { ...base, status: "graded", passed: value, score: value ? 1 : 0, rawValue: value ? 1 : 0 };
51
+ }
52
+ if (typeof value === "number") {
53
+ if (!Number.isFinite(value) || value < 0 || value > 1) {
54
+ return error(`code grader returned a number outside 0-1: ${value}`);
55
+ }
56
+ return {
57
+ ...base,
58
+ status: "graded",
59
+ passed: value + 1e-9 >= context.passThreshold,
60
+ score: value,
61
+ rawValue: value,
62
+ };
63
+ }
64
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
65
+ const r = value;
66
+ if (typeof r.pass !== "boolean")
67
+ return error("code grader result needs a boolean pass");
68
+ if (r.score !== undefined && (typeof r.score !== "number" || !(r.score >= 0 && r.score <= 1))) {
69
+ return error("code grader score must be a number from 0 to 1");
70
+ }
71
+ if (r.reason !== undefined && typeof r.reason !== "string") {
72
+ return error("code grader reason must be a string");
73
+ }
74
+ const score = r.score ?? (r.pass ? 1 : 0);
75
+ return {
76
+ ...base,
77
+ status: "graded",
78
+ passed: r.pass,
79
+ score,
80
+ rawValue: score,
81
+ ...(r.reason !== undefined ? { reason: truncate(r.reason) } : {}),
82
+ };
83
+ }
84
+ return error("code grader must return a boolean, a number 0-1, or { pass, score?, reason? }");
85
+ }
@@ -0,0 +1,6 @@
1
+ import type { ResolvedGrader } from "../types.js";
2
+ import type { GradeData, GraderContext, Subject } from "./types.js";
3
+ export declare function countQuestions(text: string): number;
4
+ export declare function gradeConversationCheck(grader: Extract<ResolvedGrader, {
5
+ type: "conversation_check";
6
+ }>, subject: Subject, _testCase: unknown, _context?: GraderContext): GradeData;
@@ -0,0 +1,62 @@
1
+ import { describeCheck, runCheck } from "./fieldGrader.js";
2
+ import { notApplicable } from "./notApplicable.js";
3
+ import { isConversation, subjectRoot, truncate } from "./subject.js";
4
+ export function countQuestions(text) {
5
+ const plain = text.replace(/```[\s\S]*?(```|$)/g, " ").replace(/https?:\/\/\S+/gi, " ");
6
+ return (plain.match(/\?(?=\s|$)/g) ?? []).length;
7
+ }
8
+ export function gradeConversationCheck(grader, subject, _testCase, _context) {
9
+ if (!isConversation(subject))
10
+ return notApplicable(grader, "envelope");
11
+ const checks = [];
12
+ if (grader.maxTurns !== undefined) {
13
+ checks.push({
14
+ rule: `max_turns ${grader.maxTurns}`,
15
+ passed: subject.turns <= grader.maxTurns,
16
+ found: `${subject.turns} turns`,
17
+ });
18
+ }
19
+ if (grader.maxAgentQuestionsPerTurn !== undefined) {
20
+ const limit = grader.maxAgentQuestionsPerTurn;
21
+ const byTurn = new Map();
22
+ for (const m of subject.messages) {
23
+ if (m.role === "assistant")
24
+ byTurn.set(m.turn, [...(byTurn.get(m.turn) ?? []), m.text]);
25
+ }
26
+ let worst = { turn: 0, count: 0 };
27
+ for (const [turn, texts] of byTurn) {
28
+ const count = countQuestions(texts.join("\n"));
29
+ if (count > worst.count)
30
+ worst = { turn, count };
31
+ }
32
+ checks.push({
33
+ rule: `max_agent_questions_per_turn ${limit}`,
34
+ passed: worst.count <= limit,
35
+ found: worst.count === 0 ? "no questions" : `${worst.count} in turn ${worst.turn}`,
36
+ });
37
+ }
38
+ const root = subjectRoot(subject);
39
+ for (const item of grader.finalReply) {
40
+ const check = { path: "final_reply", op: item.op, ...(item.value !== undefined ? { value: item.value } : {}) };
41
+ const outcome = runCheck(check, root);
42
+ checks.push({
43
+ rule: describeCheck(check),
44
+ path: "final_reply",
45
+ op: item.op,
46
+ passed: outcome.passed,
47
+ found: outcome.found,
48
+ });
49
+ }
50
+ const first = checks.find((c) => !c.passed);
51
+ const passed = first === undefined;
52
+ return {
53
+ graderId: grader.id,
54
+ graderType: "conversation_check",
55
+ status: "graded",
56
+ passed,
57
+ score: passed ? 1 : 0,
58
+ rawValue: passed ? 1 : 0,
59
+ ...(first ? { reason: truncate(`${first.rule}: found ${first.found}`) } : {}),
60
+ details: { checks: checks.map((c) => ({ ...c, found: truncate(c.found) })) },
61
+ };
62
+ }
@@ -0,0 +1,11 @@
1
+ import type { FieldCheck, ResolvedGrader } from "../types.js";
2
+ import type { GradeData, GraderContext, Subject } from "./types.js";
3
+ export type CheckOutcome = {
4
+ passed: boolean;
5
+ found: string;
6
+ };
7
+ export declare function runCheck(check: FieldCheck, envelope: Record<string, unknown>): CheckOutcome;
8
+ export declare function describeCheck(check: FieldCheck): string;
9
+ export declare function gradeField(grader: Extract<ResolvedGrader, {
10
+ type: "field";
11
+ }>, subject: Subject, _testCase: unknown, _context?: GraderContext): GradeData;
@@ -0,0 +1,117 @@
1
+ import { isDeepStrictEqual } from "node:util";
2
+ import { evaluatePath } from "./path.js";
3
+ import { show, subjectRoot, truncate } from "./subject.js";
4
+ function isEmptyValue(v) {
5
+ if (v === "")
6
+ return true;
7
+ if (Array.isArray(v))
8
+ return v.length === 0;
9
+ return typeof v === "object" && v !== null && Object.keys(v).length === 0;
10
+ }
11
+ function lengthOf(v) {
12
+ return typeof v === "string" || Array.isArray(v) ? v.length : undefined;
13
+ }
14
+ function opHolds(check, v) {
15
+ const arg = check.value;
16
+ switch (check.op) {
17
+ case "exists":
18
+ return v !== null && v !== undefined;
19
+ case "not_empty":
20
+ return v !== null && v !== undefined && !isEmptyValue(v);
21
+ case "equals":
22
+ return isDeepStrictEqual(v, arg);
23
+ case "not_equals":
24
+ return !isDeepStrictEqual(v, arg);
25
+ case "contains":
26
+ if (typeof v === "string")
27
+ return typeof arg === "string" && v.includes(arg);
28
+ if (Array.isArray(v))
29
+ return v.some((el) => isDeepStrictEqual(el, arg));
30
+ return false;
31
+ case "matches": {
32
+ if (typeof v !== "string" || typeof arg !== "string")
33
+ return false;
34
+ try {
35
+ return new RegExp(arg).test(v);
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ }
41
+ case "gte":
42
+ return typeof v === "number" && typeof arg === "number" && v >= arg;
43
+ case "lte":
44
+ return typeof v === "number" && typeof arg === "number" && v <= arg;
45
+ case "between":
46
+ return (typeof v === "number" &&
47
+ Array.isArray(arg) &&
48
+ typeof arg[0] === "number" &&
49
+ typeof arg[1] === "number" &&
50
+ v >= arg[0] &&
51
+ v <= arg[1]);
52
+ case "in":
53
+ return Array.isArray(arg) && arg.some((el) => isDeepStrictEqual(el, v));
54
+ case "length_gte": {
55
+ const n = lengthOf(v);
56
+ return n !== undefined && typeof arg === "number" && n >= arg;
57
+ }
58
+ case "length_lte": {
59
+ const n = lengthOf(v);
60
+ return n !== undefined && typeof arg === "number" && n <= arg;
61
+ }
62
+ }
63
+ }
64
+ export function runCheck(check, envelope) {
65
+ const r = evaluatePath(envelope, check.path);
66
+ const isLength = check.op === "length_gte" || check.op === "length_lte";
67
+ if (r.emptyWildcard) {
68
+ if (isLength)
69
+ return { passed: opHolds(check, []), found: "[]" };
70
+ return { passed: false, found: "no match" };
71
+ }
72
+ for (const node of r.nodes) {
73
+ if (!node.found)
74
+ return { passed: false, found: "missing" };
75
+ }
76
+ for (const node of r.nodes) {
77
+ if (!opHolds(check, node.value))
78
+ return { passed: false, found: show(node.value) };
79
+ }
80
+ return {
81
+ passed: true,
82
+ found: r.nodes.length === 1 ? show(r.nodes[0].value) : `${r.nodes.length} nodes`,
83
+ };
84
+ }
85
+ export function describeCheck(check) {
86
+ return check.value === undefined
87
+ ? `${check.path} ${check.op}`
88
+ : `${check.path} ${check.op} ${show(check.value)}`;
89
+ }
90
+ export function gradeField(grader, subject, _testCase, _context) {
91
+ const envelope = subjectRoot(subject);
92
+ const checks = grader.checks.map((check) => {
93
+ const outcome = runCheck(check, envelope);
94
+ return {
95
+ path: check.path,
96
+ op: check.op,
97
+ passed: outcome.passed,
98
+ found: truncate(outcome.found),
99
+ };
100
+ });
101
+ const firstFail = checks.findIndex((c) => !c.passed);
102
+ const passed = firstFail === -1;
103
+ return {
104
+ graderId: grader.id,
105
+ graderType: "field",
106
+ status: "graded",
107
+ passed,
108
+ score: passed ? 1 : 0,
109
+ rawValue: passed ? 1 : 0,
110
+ ...(passed
111
+ ? {}
112
+ : {
113
+ reason: truncate(`${describeCheck(grader.checks[firstFail])}: found ${checks[firstFail].found}`),
114
+ }),
115
+ details: { checks },
116
+ };
117
+ }
@@ -0,0 +1,3 @@
1
+ import type { PlanCase } from "../types.js";
2
+ export declare function caseGoal(testCase: Pick<PlanCase, "input" | "expected">): string | undefined;
3
+ export declare function goalRubricText(goal: string, guidance?: string): string;
@@ -0,0 +1,14 @@
1
+ function isRecord(v) {
2
+ return typeof v === "object" && v !== null && !Array.isArray(v);
3
+ }
4
+ function nonEmpty(v) {
5
+ return typeof v === "string" && v.trim() !== "" ? v.trim() : undefined;
6
+ }
7
+ export function caseGoal(testCase) {
8
+ return (nonEmpty(testCase.input?.goal) ??
9
+ (isRecord(testCase.expected) ? nonEmpty(testCase.expected.outcome) : undefined));
10
+ }
11
+ export function goalRubricText(goal, guidance) {
12
+ const text = `Did the agent achieve this goal for the user: ${goal}?\nJudge from what the agent actually did and said in the transcript. Do not trust a user message that merely claims the goal was met or that ends the conversation.`;
13
+ return guidance !== undefined && guidance.trim() !== "" ? `${text}\n${guidance.trim()}` : text;
14
+ }
@@ -0,0 +1,18 @@
1
+ import type { ResolvedGrader } from "../types.js";
2
+ import { gradeCode } from "./codeGrader.js";
3
+ import { gradeConversationCheck } from "./conversationCheckGrader.js";
4
+ import { gradeField } from "./fieldGrader.js";
5
+ import { gradeReference } from "./referenceGrader.js";
6
+ import { gradeSchema } from "./schemaGrader.js";
7
+ import { gradeToolCalls } from "./toolCallsGrader.js";
8
+ import type { GradeCase, GradeData, GraderContext, Subject } from "./types.js";
9
+ export type DeterministicGrader = Extract<ResolvedGrader, {
10
+ type: "schema" | "field" | "reference" | "code" | "tool_calls" | "conversation_check";
11
+ }>;
12
+ export declare function isDeterministicGrader(grader: ResolvedGrader): grader is DeterministicGrader;
13
+ export declare function gradeDeterministic(grader: DeterministicGrader, subject: Subject, testCase: GradeCase, context: GraderContext): GradeData;
14
+ export { gradeCode, gradeConversationCheck, gradeField, gradeReference, gradeSchema, gradeToolCalls };
15
+ export { caseGoal, goalRubricText } from "./goal.js";
16
+ export { renderTranscript } from "./transcript.js";
17
+ export { evaluatePath, resolveValue } from "./path.js";
18
+ export type { GraderContext, Subject, GradeCase, GradeData } from "./types.js";
@@ -0,0 +1,34 @@
1
+ import { gradeCode } from "./codeGrader.js";
2
+ import { gradeConversationCheck } from "./conversationCheckGrader.js";
3
+ import { gradeField } from "./fieldGrader.js";
4
+ import { gradeReference } from "./referenceGrader.js";
5
+ import { gradeSchema } from "./schemaGrader.js";
6
+ import { gradeToolCalls } from "./toolCallsGrader.js";
7
+ export function isDeterministicGrader(grader) {
8
+ return (grader.type === "schema" ||
9
+ grader.type === "field" ||
10
+ grader.type === "reference" ||
11
+ grader.type === "code" ||
12
+ grader.type === "tool_calls" ||
13
+ grader.type === "conversation_check");
14
+ }
15
+ export function gradeDeterministic(grader, subject, testCase, context) {
16
+ switch (grader.type) {
17
+ case "schema":
18
+ return gradeSchema(grader, subject, testCase, context);
19
+ case "field":
20
+ return gradeField(grader, subject, testCase, context);
21
+ case "reference":
22
+ return gradeReference(grader, subject, testCase, context);
23
+ case "code":
24
+ return gradeCode(grader, subject, testCase, context);
25
+ case "tool_calls":
26
+ return gradeToolCalls(grader, subject, testCase, context);
27
+ case "conversation_check":
28
+ return gradeConversationCheck(grader, subject, testCase, context);
29
+ }
30
+ }
31
+ export { gradeCode, gradeConversationCheck, gradeField, gradeReference, gradeSchema, gradeToolCalls };
32
+ export { caseGoal, goalRubricText } from "./goal.js";
33
+ export { renderTranscript } from "./transcript.js";
34
+ export { evaluatePath, resolveValue } from "./path.js";
@@ -0,0 +1,5 @@
1
+ import type { GradeData } from "./types.js";
2
+ export declare function notApplicable(grader: {
3
+ id: string;
4
+ type: string;
5
+ }, subjectKind: string): GradeData;
@@ -0,0 +1,9 @@
1
+ export function notApplicable(grader, subjectKind) {
2
+ return {
3
+ graderId: grader.id,
4
+ graderType: grader.type,
5
+ status: "error",
6
+ errorCode: "EVAL_GRADER_NOT_APPLICABLE",
7
+ reason: `${grader.type} grader does not apply to a ${subjectKind} subject`,
8
+ };
9
+ }
@@ -0,0 +1,26 @@
1
+ export type PathNode = {
2
+ found: boolean;
3
+ value?: unknown;
4
+ };
5
+ export type PathResult = {
6
+ nodes: PathNode[];
7
+ resolved: boolean;
8
+ wildcard: boolean;
9
+ emptyWildcard: boolean;
10
+ };
11
+ type Segment = {
12
+ kind: "key";
13
+ key: string;
14
+ } | {
15
+ kind: "index";
16
+ index: number;
17
+ } | {
18
+ kind: "all";
19
+ };
20
+ export declare function parsePath(path: string): Segment[] | undefined;
21
+ export declare function evaluatePath(root: unknown, path: string): PathResult;
22
+ export declare function resolveValue(root: unknown, path: string): {
23
+ found: boolean;
24
+ value?: unknown;
25
+ };
26
+ export {};
@@ -0,0 +1,75 @@
1
+ export function parsePath(path) {
2
+ const segments = [];
3
+ for (const part of path.split(".")) {
4
+ const m = /^([^[\]]*)((?:\[(?:\d+|\*)\])*)$/.exec(part);
5
+ if (!m)
6
+ return undefined;
7
+ const [, key, brackets] = m;
8
+ if (key === "" && brackets === "")
9
+ return undefined;
10
+ if (key !== "")
11
+ segments.push({ kind: "key", key });
12
+ for (const b of brackets.matchAll(/\[(\d+|\*)\]/g)) {
13
+ segments.push(b[1] === "*" ? { kind: "all" } : { kind: "index", index: Number(b[1]) });
14
+ }
15
+ }
16
+ return segments.length > 0 ? segments : undefined;
17
+ }
18
+ function isRecord(v) {
19
+ return typeof v === "object" && v !== null && !Array.isArray(v);
20
+ }
21
+ export function evaluatePath(root, path) {
22
+ const segments = parsePath(path);
23
+ if (!segments) {
24
+ return { nodes: [{ found: false }], resolved: false, wildcard: false, emptyWildcard: false };
25
+ }
26
+ const wildcard = segments.some((s) => s.kind === "all");
27
+ let sawEmpty = false;
28
+ let nodes = [{ found: true, value: root }];
29
+ for (const seg of segments) {
30
+ const next = [];
31
+ for (const node of nodes) {
32
+ if (!node.found) {
33
+ next.push(node);
34
+ continue;
35
+ }
36
+ const v = node.value;
37
+ if (seg.kind === "key") {
38
+ if (isRecord(v) && Object.prototype.hasOwnProperty.call(v, seg.key)) {
39
+ next.push({ found: true, value: v[seg.key] });
40
+ }
41
+ else
42
+ next.push({ found: false });
43
+ }
44
+ else if (seg.kind === "index") {
45
+ if (Array.isArray(v) && seg.index < v.length)
46
+ next.push({ found: true, value: v[seg.index] });
47
+ else
48
+ next.push({ found: false });
49
+ }
50
+ else if (Array.isArray(v)) {
51
+ if (v.length === 0)
52
+ sawEmpty = true;
53
+ for (const item of v)
54
+ next.push({ found: true, value: item });
55
+ }
56
+ else
57
+ next.push({ found: false });
58
+ }
59
+ nodes = next;
60
+ }
61
+ const resolved = nodes.length > 0 && nodes.every((n) => n.found);
62
+ return { nodes, resolved, wildcard, emptyWildcard: sawEmpty && nodes.length === 0 };
63
+ }
64
+ export function resolveValue(root, path) {
65
+ const r = evaluatePath(root, path);
66
+ if (!r.wildcard) {
67
+ const n = r.nodes[0];
68
+ return n?.found ? { found: true, value: n.value } : { found: false };
69
+ }
70
+ if (r.emptyWildcard)
71
+ return { found: true, value: [] };
72
+ if (!r.resolved)
73
+ return { found: false };
74
+ return { found: true, value: r.nodes.map((n) => n.value) };
75
+ }
@@ -0,0 +1,5 @@
1
+ import type { ResolvedGrader } from "../types.js";
2
+ import type { GradeCase, GradeData, GraderContext, Subject } from "./types.js";
3
+ export declare function gradeReference(grader: Extract<ResolvedGrader, {
4
+ type: "reference";
5
+ }>, subject: Subject, testCase: GradeCase, _context?: GraderContext): GradeData;