stageflow 0.40.0 → 0.44.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 (519) hide show
  1. package/README.md +15 -4
  2. package/dist/agent/activity.d.ts +18 -0
  3. package/dist/agent/claudeAdapter.js +7 -0
  4. package/dist/agent/claudeTools.d.ts +27 -18
  5. package/dist/agent/claudeTools.js +54 -15
  6. package/dist/agent/compactionEvents.d.ts +34 -0
  7. package/dist/agent/compactionEvents.js +37 -0
  8. package/dist/agent/openRouterRouting.d.ts +7 -0
  9. package/dist/agent/openRouterRouting.js +23 -0
  10. package/dist/agent/piAdapter.d.ts +6 -0
  11. package/dist/agent/piAdapter.js +128 -27
  12. package/dist/agent/piSettings.d.ts +7 -0
  13. package/dist/agent/piSettings.js +9 -0
  14. package/dist/agent/sandboxPiTools.d.ts +3 -1
  15. package/dist/agent/sandboxPiTools.js +8 -2
  16. package/dist/agent/stageTurnDriver.d.ts +11 -2
  17. package/dist/agent/stageTurnDriver.js +45 -4
  18. package/dist/agent/toolOutputBudget.d.ts +15 -1
  19. package/dist/agent/toolOutputBudget.js +18 -0
  20. package/dist/agent/toolOutputBudgetExtension.d.ts +2 -0
  21. package/dist/agent/toolOutputBudgetExtension.js +40 -3
  22. package/dist/agents/authorChat.d.ts +5 -0
  23. package/dist/agents/authorChat.js +120 -12
  24. package/dist/agents/authorSessionStore.d.ts +38 -0
  25. package/dist/agents/authorSessionStore.js +167 -0
  26. package/dist/agents/chatTurn.d.ts +2 -0
  27. package/dist/agents/chatTurn.js +17 -1
  28. package/dist/agents/errors.d.ts +1 -1
  29. package/dist/agents/errors.js +1 -0
  30. package/dist/agents/evalGate.d.ts +61 -0
  31. package/dist/agents/evalGate.js +103 -0
  32. package/dist/agents/evalSession.d.ts +26 -0
  33. package/dist/agents/evalSession.js +29 -0
  34. package/dist/agents/hostContext.d.ts +4 -1
  35. package/dist/agents/hostContext.js +4 -1
  36. package/dist/agents/runtime/piRuntime.d.ts +6 -2
  37. package/dist/agents/runtime/piRuntime.js +50 -16
  38. package/dist/agents/runtime/types.d.ts +3 -1
  39. package/dist/agents/service.d.ts +27 -2
  40. package/dist/agents/service.js +91 -15
  41. package/dist/agents/sessions.d.ts +8 -0
  42. package/dist/agents/sessions.js +53 -11
  43. package/dist/agents/store.d.ts +14 -3
  44. package/dist/agents/store.js +45 -7
  45. package/dist/agents/toolRisk.d.ts +21 -0
  46. package/dist/agents/toolRisk.js +50 -0
  47. package/dist/cli/doctorCommand.js +26 -0
  48. package/dist/cli/evalCommand.d.ts +20 -0
  49. package/dist/cli/evalCommand.js +720 -0
  50. package/dist/cli/exportAllCommand.js +1 -1
  51. package/dist/cli/hostClient.d.ts +60 -0
  52. package/dist/cli/hostClient.js +71 -0
  53. package/dist/cli/validateOutput.d.ts +2 -2
  54. package/dist/cli/validateOutput.js +2 -2
  55. package/dist/cli.js +10 -0
  56. package/dist/compaction/directives.d.ts +18 -0
  57. package/dist/compaction/directives.js +119 -0
  58. package/dist/compaction/extension.d.ts +20 -0
  59. package/dist/compaction/extension.js +78 -0
  60. package/dist/compaction/mask.d.ts +18 -0
  61. package/dist/compaction/mask.js +155 -0
  62. package/dist/compaction/pin.d.ts +21 -0
  63. package/dist/compaction/pin.js +270 -0
  64. package/dist/compaction/scrub.d.ts +7 -0
  65. package/dist/compaction/scrub.js +26 -0
  66. package/dist/compaction/sessionWiring.d.ts +22 -0
  67. package/dist/compaction/sessionWiring.js +26 -0
  68. package/dist/compaction/summarize.d.ts +79 -0
  69. package/dist/compaction/summarize.js +171 -0
  70. package/dist/compaction/toolPolicy.d.ts +3 -0
  71. package/dist/compaction/toolPolicy.js +33 -0
  72. package/dist/compaction/types.d.ts +45 -0
  73. package/dist/compaction/types.js +7 -0
  74. package/dist/compaction/workingState.d.ts +56 -0
  75. package/dist/compaction/workingState.js +198 -0
  76. package/dist/config/atomicWrite.d.ts +15 -0
  77. package/dist/config/atomicWrite.js +43 -0
  78. package/dist/config/browseCatalog.d.ts +2 -0
  79. package/dist/config/browseCatalog.js +4 -2
  80. package/dist/config/createPipeline.js +2 -0
  81. package/dist/config/createTrigger.js +7 -1
  82. package/dist/config/csv.d.ts +9 -0
  83. package/dist/config/csv.js +81 -0
  84. package/dist/config/datasetAgentCheck.d.ts +18 -0
  85. package/dist/config/datasetAgentCheck.js +109 -0
  86. package/dist/config/datasetCandidates.d.ts +22 -0
  87. package/dist/config/datasetCandidates.js +86 -0
  88. package/dist/config/datasetFromSessions.d.ts +34 -0
  89. package/dist/config/datasetFromSessions.js +105 -0
  90. package/dist/config/datasetHash.d.ts +1 -0
  91. package/dist/config/datasetHash.js +4 -0
  92. package/dist/config/datasetImport.d.ts +21 -0
  93. package/dist/config/datasetImport.js +120 -0
  94. package/dist/config/datasetStageCheck.d.ts +9 -0
  95. package/dist/config/datasetStageCheck.js +17 -0
  96. package/dist/config/datasetTypes.d.ts +27 -0
  97. package/dist/config/datasetTypes.js +1 -0
  98. package/dist/config/ensureCatalogScanRoot.d.ts +4 -1
  99. package/dist/config/ensureCatalogScanRoot.js +8 -6
  100. package/dist/config/evalCatalog.d.ts +22 -0
  101. package/dist/config/evalCatalog.js +95 -0
  102. package/dist/config/evalWriteRoots.d.ts +17 -0
  103. package/dist/config/evalWriteRoots.js +109 -0
  104. package/dist/config/githubTriggerAction.d.ts +8 -0
  105. package/dist/config/githubTriggerAction.js +29 -0
  106. package/dist/config/hostConfig.js +3 -0
  107. package/dist/config/installEvalSample.d.ts +34 -0
  108. package/dist/config/installEvalSample.js +182 -0
  109. package/dist/config/loadDataset.d.ts +16 -0
  110. package/dist/config/loadDataset.js +318 -0
  111. package/dist/config/loadEval.d.ts +32 -0
  112. package/dist/config/loadEval.js +1103 -0
  113. package/dist/config/loadOutcome.d.ts +5 -0
  114. package/dist/config/loadStageflowManifest.js +64 -0
  115. package/dist/config/pipelineNeeds.d.ts +2 -0
  116. package/dist/config/pipelineNeeds.js +16 -3
  117. package/dist/config/pipelineRoute.js +5 -4
  118. package/dist/config/resolveAgentTarget.d.ts +32 -0
  119. package/dist/config/resolveAgentTarget.js +118 -0
  120. package/dist/config/resolveEvalTarget.d.ts +21 -0
  121. package/dist/config/resolveEvalTarget.js +89 -0
  122. package/dist/config/scanCatalogPaths.d.ts +1 -1
  123. package/dist/config/scanCatalogPaths.js +17 -5
  124. package/dist/config/validateCatalog.d.ts +2 -2
  125. package/dist/config/validateCatalog.js +21 -1
  126. package/dist/config/validateEval.d.ts +36 -0
  127. package/dist/config/validateEval.js +446 -0
  128. package/dist/config/writeDataset.d.ts +54 -0
  129. package/dist/config/writeDataset.js +186 -0
  130. package/dist/config/writeEval.d.ts +25 -0
  131. package/dist/config/writeEval.js +398 -0
  132. package/dist/diagnostics/checks.js +1 -1
  133. package/dist/envelope/assertEmittedArtifacts.d.ts +12 -0
  134. package/dist/envelope/assertEmittedArtifacts.js +43 -0
  135. package/dist/envelope/preEmitChecks.d.ts +3 -0
  136. package/dist/evals/agentDiff.d.ts +13 -0
  137. package/dist/evals/agentDiff.js +11 -0
  138. package/dist/evals/canonical.d.ts +3 -0
  139. package/dist/evals/canonical.js +24 -0
  140. package/dist/evals/caseTask.d.ts +3 -0
  141. package/dist/evals/caseTask.js +9 -0
  142. package/dist/evals/compare.d.ts +94 -0
  143. package/dist/evals/compare.js +201 -0
  144. package/dist/evals/constants.d.ts +62 -0
  145. package/dist/evals/constants.js +97 -0
  146. package/dist/evals/engine/FakeEngine.d.ts +33 -0
  147. package/dist/evals/engine/FakeEngine.js +177 -0
  148. package/dist/evals/engine/index.d.ts +9 -0
  149. package/dist/evals/engine/index.js +19 -0
  150. package/dist/evals/engine/promptfoo/PromptfooEngine.d.ts +52 -0
  151. package/dist/evals/engine/promptfoo/PromptfooEngine.js +312 -0
  152. package/dist/evals/engine/promptfoo/errors.d.ts +5 -0
  153. package/dist/evals/engine/promptfoo/errors.js +8 -0
  154. package/dist/evals/engine/promptfoo/generate.d.ts +30 -0
  155. package/dist/evals/engine/promptfoo/generate.js +345 -0
  156. package/dist/evals/engine/promptfoo/guard.d.ts +10 -0
  157. package/dist/evals/engine/promptfoo/guard.js +116 -0
  158. package/dist/evals/engine/promptfoo/install.d.ts +17 -0
  159. package/dist/evals/engine/promptfoo/install.js +73 -0
  160. package/dist/evals/engine/promptfoo/judgeProviders.d.ts +2 -0
  161. package/dist/evals/engine/promptfoo/judgeProviders.js +9 -0
  162. package/dist/evals/engine/promptfoo/judgeServices.d.ts +6 -0
  163. package/dist/evals/engine/promptfoo/judgeServices.js +41 -0
  164. package/dist/evals/engine/promptfoo/locate.d.ts +21 -0
  165. package/dist/evals/engine/promptfoo/locate.js +68 -0
  166. package/dist/evals/engine/promptfoo/nodeVersion.d.ts +7 -0
  167. package/dist/evals/engine/promptfoo/nodeVersion.js +14 -0
  168. package/dist/evals/engine/promptfoo/normalize.d.ts +66 -0
  169. package/dist/evals/engine/promptfoo/normalize.js +261 -0
  170. package/dist/evals/engine/promptfoo/pinned.d.ts +5 -0
  171. package/dist/evals/engine/promptfoo/pinned.js +5 -0
  172. package/dist/evals/engine/promptfoo/rubricPrompt.d.ts +14 -0
  173. package/dist/evals/engine/promptfoo/rubricPrompt.js +105 -0
  174. package/dist/evals/engine/promptfoo/runTokens.d.ts +18 -0
  175. package/dist/evals/engine/promptfoo/runTokens.js +31 -0
  176. package/dist/evals/engine/promptfoo/status.d.ts +13 -0
  177. package/dist/evals/engine/promptfoo/status.js +16 -0
  178. package/dist/evals/estimate.d.ts +56 -0
  179. package/dist/evals/estimate.js +66 -0
  180. package/dist/evals/graders/codeGrader.d.ts +6 -0
  181. package/dist/evals/graders/codeGrader.js +85 -0
  182. package/dist/evals/graders/conversationCheckGrader.d.ts +6 -0
  183. package/dist/evals/graders/conversationCheckGrader.js +62 -0
  184. package/dist/evals/graders/fieldGrader.d.ts +11 -0
  185. package/dist/evals/graders/fieldGrader.js +117 -0
  186. package/dist/evals/graders/goal.d.ts +3 -0
  187. package/dist/evals/graders/goal.js +14 -0
  188. package/dist/evals/graders/index.d.ts +18 -0
  189. package/dist/evals/graders/index.js +34 -0
  190. package/dist/evals/graders/notApplicable.d.ts +5 -0
  191. package/dist/evals/graders/notApplicable.js +9 -0
  192. package/dist/evals/graders/path.d.ts +26 -0
  193. package/dist/evals/graders/path.js +75 -0
  194. package/dist/evals/graders/referenceGrader.d.ts +5 -0
  195. package/dist/evals/graders/referenceGrader.js +59 -0
  196. package/dist/evals/graders/schemaGrader.d.ts +5 -0
  197. package/dist/evals/graders/schemaGrader.js +29 -0
  198. package/dist/evals/graders/subject.d.ts +6 -0
  199. package/dist/evals/graders/subject.js +33 -0
  200. package/dist/evals/graders/toolCallsGrader.d.ts +6 -0
  201. package/dist/evals/graders/toolCallsGrader.js +100 -0
  202. package/dist/evals/graders/transcript.d.ts +12 -0
  203. package/dist/evals/graders/transcript.js +57 -0
  204. package/dist/evals/graders/types.d.ts +20 -0
  205. package/dist/evals/graders/types.js +1 -0
  206. package/dist/evals/judgeProviders.d.ts +16 -0
  207. package/dist/evals/judgeProviders.js +27 -0
  208. package/dist/evals/lineDiff.d.ts +5 -0
  209. package/dist/evals/lineDiff.js +34 -0
  210. package/dist/evals/listStatus.d.ts +31 -0
  211. package/dist/evals/listStatus.js +48 -0
  212. package/dist/evals/manager.d.ts +187 -0
  213. package/dist/evals/manager.js +795 -0
  214. package/dist/evals/plan.d.ts +65 -0
  215. package/dist/evals/plan.js +621 -0
  216. package/dist/evals/planInternalAgent.d.ts +19 -0
  217. package/dist/evals/planInternalAgent.js +205 -0
  218. package/dist/evals/providerKeys.d.ts +1 -0
  219. package/dist/evals/providerKeys.js +21 -0
  220. package/dist/evals/read/agentTargets.d.ts +37 -0
  221. package/dist/evals/read/agentTargets.js +101 -0
  222. package/dist/evals/read/api.d.ts +208 -0
  223. package/dist/evals/read/api.js +363 -0
  224. package/dist/evals/read/compare.d.ts +4 -0
  225. package/dist/evals/read/compare.js +39 -0
  226. package/dist/evals/read/datasets.d.ts +105 -0
  227. package/dist/evals/read/datasets.js +318 -0
  228. package/dist/evals/read/list.d.ts +66 -0
  229. package/dist/evals/read/list.js +182 -0
  230. package/dist/evals/read/results.d.ts +46 -0
  231. package/dist/evals/read/results.js +107 -0
  232. package/dist/evals/read/runs.d.ts +154 -0
  233. package/dist/evals/read/runs.js +295 -0
  234. package/dist/evals/read/suggestions.d.ts +43 -0
  235. package/dist/evals/read/suggestions.js +73 -0
  236. package/dist/evals/runner/FakeAgentBackend.d.ts +40 -0
  237. package/dist/evals/runner/FakeAgentBackend.js +82 -0
  238. package/dist/evals/runner/agentCaseRunner.d.ts +24 -0
  239. package/dist/evals/runner/agentCaseRunner.js +388 -0
  240. package/dist/evals/runner/caseRunner.d.ts +8 -0
  241. package/dist/evals/runner/caseRunner.js +28 -0
  242. package/dist/evals/runner/conversationSubject.d.ts +18 -0
  243. package/dist/evals/runner/conversationSubject.js +123 -0
  244. package/dist/evals/runner/internalAgentCaseRunner.d.ts +6 -0
  245. package/dist/evals/runner/internalAgentCaseRunner.js +250 -0
  246. package/dist/evals/runner/simulatorModel.d.ts +51 -0
  247. package/dist/evals/runner/simulatorModel.js +58 -0
  248. package/dist/evals/runner/simulatorPrompt.d.ts +29 -0
  249. package/dist/evals/runner/simulatorPrompt.js +59 -0
  250. package/dist/evals/runner/stageCaseRunner.d.ts +30 -0
  251. package/dist/evals/runner/stageCaseRunner.js +279 -0
  252. package/dist/evals/runner/userDriver.d.ts +71 -0
  253. package/dist/evals/runner/userDriver.js +104 -0
  254. package/dist/evals/scoring.d.ts +34 -0
  255. package/dist/evals/scoring.js +67 -0
  256. package/dist/evals/snapshot.d.ts +191 -0
  257. package/dist/evals/snapshot.js +70 -0
  258. package/dist/evals/stageDiff.d.ts +8 -0
  259. package/dist/evals/stageDiff.js +48 -0
  260. package/dist/evals/stats.d.ts +95 -0
  261. package/dist/evals/stats.js +220 -0
  262. package/dist/evals/statsAdapter.d.ts +4 -0
  263. package/dist/evals/statsAdapter.js +30 -0
  264. package/dist/evals/statsTypes.d.ts +51 -0
  265. package/dist/evals/statsTypes.js +18 -0
  266. package/dist/evals/storeError.d.ts +5 -0
  267. package/dist/evals/storeError.js +8 -0
  268. package/dist/evals/storeTypes.d.ts +207 -0
  269. package/dist/evals/storeTypes.js +1 -0
  270. package/dist/evals/tTable.d.ts +3 -0
  271. package/dist/evals/tTable.js +15 -0
  272. package/dist/evals/triage/constants.d.ts +26 -0
  273. package/dist/evals/triage/constants.js +33 -0
  274. package/dist/evals/triage/credentials.d.ts +13 -0
  275. package/dist/evals/triage/credentials.js +20 -0
  276. package/dist/evals/triage/jevClassifier.d.ts +14 -0
  277. package/dist/evals/triage/jevClassifier.js +124 -0
  278. package/dist/evals/triage/judgeClassifier.d.ts +10 -0
  279. package/dist/evals/triage/judgeClassifier.js +76 -0
  280. package/dist/evals/triage/prompts.d.ts +16 -0
  281. package/dist/evals/triage/prompts.js +64 -0
  282. package/dist/evals/triage/service.d.ts +79 -0
  283. package/dist/evals/triage/service.js +217 -0
  284. package/dist/evals/triage/stateBuilder.d.ts +19 -0
  285. package/dist/evals/triage/stateBuilder.js +125 -0
  286. package/dist/evals/triage/types.d.ts +60 -0
  287. package/dist/evals/triage/types.js +8 -0
  288. package/dist/evals/types.d.ts +357 -0
  289. package/dist/evals/types.js +4 -0
  290. package/dist/guide/cardContract.d.ts +133 -0
  291. package/dist/guide/cardContract.js +156 -0
  292. package/dist/guide/chat.d.ts +45 -0
  293. package/dist/guide/chat.js +378 -0
  294. package/dist/guide/knowledge/index.d.ts +14 -0
  295. package/dist/guide/knowledge/index.js +109 -0
  296. package/dist/guide/knowledge/topics/agents.d.ts +2 -0
  297. package/dist/guide/knowledge/topics/agents.js +58 -0
  298. package/dist/guide/knowledge/topics/bestPractices.d.ts +2 -0
  299. package/dist/guide/knowledge/topics/bestPractices.js +67 -0
  300. package/dist/guide/knowledge/topics/connections.d.ts +2 -0
  301. package/dist/guide/knowledge/topics/connections.js +66 -0
  302. package/dist/guide/knowledge/topics/consoleMap.d.ts +2 -0
  303. package/dist/guide/knowledge/topics/consoleMap.js +55 -0
  304. package/dist/guide/knowledge/topics/evals.d.ts +2 -0
  305. package/dist/guide/knowledge/topics/evals.js +72 -0
  306. package/dist/guide/knowledge/topics/limitations.d.ts +2 -0
  307. package/dist/guide/knowledge/topics/limitations.js +84 -0
  308. package/dist/guide/knowledge/topics/mcpSkillsBrowser.d.ts +2 -0
  309. package/dist/guide/knowledge/topics/mcpSkillsBrowser.js +57 -0
  310. package/dist/guide/knowledge/topics/memories.d.ts +2 -0
  311. package/dist/guide/knowledge/topics/memories.js +63 -0
  312. package/dist/guide/knowledge/topics/modelsAndProviders.d.ts +2 -0
  313. package/dist/guide/knowledge/topics/modelsAndProviders.js +56 -0
  314. package/dist/guide/knowledge/topics/overview.d.ts +2 -0
  315. package/dist/guide/knowledge/topics/overview.js +56 -0
  316. package/dist/guide/knowledge/topics/pipelines.d.ts +2 -0
  317. package/dist/guide/knowledge/topics/pipelines.js +93 -0
  318. package/dist/guide/knowledge/topics/stages.d.ts +2 -0
  319. package/dist/guide/knowledge/topics/stages.js +54 -0
  320. package/dist/guide/knowledge/topics/tasks.d.ts +2 -0
  321. package/dist/guide/knowledge/topics/tasks.js +52 -0
  322. package/dist/guide/knowledge/topics/triggers.d.ts +2 -0
  323. package/dist/guide/knowledge/topics/triggers.js +68 -0
  324. package/dist/guide/knowledge/topics/troubleshooting.d.ts +2 -0
  325. package/dist/guide/knowledge/topics/troubleshooting.js +85 -0
  326. package/dist/guide/knowledgeTools.d.ts +2 -0
  327. package/dist/guide/knowledgeTools.js +56 -0
  328. package/dist/guide/showUi.d.ts +6 -0
  329. package/dist/guide/showUi.js +546 -0
  330. package/dist/guide/threadStore.d.ts +48 -0
  331. package/dist/guide/threadStore.js +189 -0
  332. package/dist/guide/writeRoot.d.ts +11 -0
  333. package/dist/guide/writeRoot.js +70 -0
  334. package/dist/hosted/translate.js +2 -0
  335. package/dist/mcp/agentTools.js +12 -0
  336. package/dist/mcp/catalogTools.js +18 -20
  337. package/dist/mcp/catalogWriteTools.d.ts +8 -0
  338. package/dist/mcp/catalogWriteTools.js +225 -0
  339. package/dist/mcp/connectionTools.d.ts +3 -0
  340. package/dist/mcp/connectionTools.js +85 -0
  341. package/dist/mcp/controlTools.js +34 -1
  342. package/dist/mcp/deps.d.ts +16 -0
  343. package/dist/mcp/evalTools.d.ts +3 -0
  344. package/dist/mcp/evalTools.js +943 -0
  345. package/dist/mcp/memoryHostTools.d.ts +3 -0
  346. package/dist/mcp/memoryHostTools.js +72 -0
  347. package/dist/mcp/pipelineAuthorTools.js +14 -1
  348. package/dist/mcp/server.js +6 -0
  349. package/dist/mcp/tools.js +8 -0
  350. package/dist/mcp/triggerTools.js +77 -31
  351. package/dist/models/response.d.ts +7 -2
  352. package/dist/models/response.js +6 -1
  353. package/dist/operatorAgent/agentAuthorContext.d.ts +1 -1
  354. package/dist/operatorAgent/agentAuthorContext.js +1 -1
  355. package/dist/operatorAgent/evalGate.d.ts +22 -0
  356. package/dist/operatorAgent/evalGate.js +77 -0
  357. package/dist/operatorAgent/fakeHost.js +10 -2
  358. package/dist/operatorAgent/host.js +18 -2
  359. package/dist/operatorAgent/index.d.ts +1 -0
  360. package/dist/operatorAgent/index.js +1 -0
  361. package/dist/operatorAgent/internalAgents.d.ts +11 -0
  362. package/dist/operatorAgent/internalAgents.js +13 -0
  363. package/dist/operatorAgent/piModel.d.ts +5 -1
  364. package/dist/operatorAgent/piModel.js +32 -14
  365. package/dist/operatorAgent/profiles/agentAuthor.d.ts +3 -1
  366. package/dist/operatorAgent/profiles/agentAuthor.js +201 -32
  367. package/dist/operatorAgent/profiles/agentAuthorPlaybook.d.ts +1 -1
  368. package/dist/operatorAgent/profiles/agentAuthorPlaybook.js +48 -15
  369. package/dist/operatorAgent/profiles/authorReadable.d.ts +2 -0
  370. package/dist/operatorAgent/profiles/authorReadable.js +26 -0
  371. package/dist/operatorAgent/profiles/guideConfirm.d.ts +21 -0
  372. package/dist/operatorAgent/profiles/guideConfirm.js +100 -0
  373. package/dist/operatorAgent/profiles/guideTools.d.ts +7 -0
  374. package/dist/operatorAgent/profiles/guideTools.js +123 -0
  375. package/dist/operatorAgent/profiles/stageflowGuide.d.ts +7 -0
  376. package/dist/operatorAgent/profiles/stageflowGuide.js +132 -0
  377. package/dist/operatorAgent/profiles/workshopAuthor.js +23 -0
  378. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +1 -1
  379. package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +9 -1
  380. package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +2 -0
  381. package/dist/operatorAgent/profiles/workshopAuthorTools.js +197 -9
  382. package/dist/operatorAgent/types.d.ts +23 -0
  383. package/dist/package-meta.d.ts +1 -1
  384. package/dist/package-meta.js +1 -1
  385. package/dist/runstore/port.d.ts +43 -0
  386. package/dist/runstore/retention.d.ts +2 -1
  387. package/dist/runstore/retention.js +3 -7
  388. package/dist/runstore/runStatusClock.d.ts +17 -0
  389. package/dist/runstore/runStatusClock.js +19 -0
  390. package/dist/runstore/sqlite/SqliteRunStore.d.ts +29 -0
  391. package/dist/runstore/sqlite/SqliteRunStore.js +144 -50
  392. package/dist/runstore/sqlite/evalStore.d.ts +20 -0
  393. package/dist/runstore/sqlite/evalStore.js +541 -0
  394. package/dist/runstore/sqlite/migrations/015-evals.d.ts +12 -0
  395. package/dist/runstore/sqlite/migrations/015-evals.js +157 -0
  396. package/dist/runstore/sqlite/migrations/016-eval-subject-ref.d.ts +12 -0
  397. package/dist/runstore/sqlite/migrations/016-eval-subject-ref.js +20 -0
  398. package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.d.ts +11 -0
  399. package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.js +36 -0
  400. package/dist/runstore/sqlite/migrations/index.js +6 -0
  401. package/dist/runstore/sqlite/suggestionStore.d.ts +14 -0
  402. package/dist/runstore/sqlite/suggestionStore.js +132 -0
  403. package/dist/runstore/workspaceLayout.js +6 -1
  404. package/dist/runtime/artifactDiskInspect.d.ts +14 -0
  405. package/dist/runtime/artifactDiskInspect.js +52 -0
  406. package/dist/runtime/artifactPath.d.ts +24 -0
  407. package/dist/runtime/artifactPath.js +84 -0
  408. package/dist/runtime/completionCheckRunner.js +15 -43
  409. package/dist/runtime/githubPollSource.d.ts +22 -4
  410. package/dist/runtime/githubPollSource.js +93 -8
  411. package/dist/runtime/pipelineRunner.d.ts +2 -1
  412. package/dist/runtime/pipelineRunner.js +2 -0
  413. package/dist/runtime/priorArtifactGrants.d.ts +8 -0
  414. package/dist/runtime/priorArtifactGrants.js +105 -0
  415. package/dist/runtime/runActionEligibility.d.ts +46 -0
  416. package/dist/runtime/runActionEligibility.js +123 -0
  417. package/dist/runtime/runManager.d.ts +6 -2
  418. package/dist/runtime/runManager.js +60 -16
  419. package/dist/runtime/runRetentionSweep.js +2 -2
  420. package/dist/runtime/runRetryCoordinator.d.ts +2 -14
  421. package/dist/runtime/runRetryCoordinator.js +3 -67
  422. package/dist/runtime/sandboxContainer.d.ts +7 -0
  423. package/dist/runtime/sandboxContainer.js +48 -6
  424. package/dist/runtime/sandboxDesk.d.ts +2 -1
  425. package/dist/runtime/sandboxDesk.js +11 -12
  426. package/dist/runtime/stageEnvironment.js +1 -0
  427. package/dist/runtime/stageRoots.d.ts +12 -0
  428. package/dist/runtime/stageSandbox.d.ts +2 -1
  429. package/dist/runtime/stageSandbox.js +18 -2
  430. package/dist/runtime/stageWorker.js +20 -0
  431. package/dist/server/agentAuthorRoutes.js +59 -1
  432. package/dist/server/bootstrap.d.ts +13 -0
  433. package/dist/server/bootstrap.js +69 -0
  434. package/dist/server/controlToken.js +3 -0
  435. package/dist/server/evalInternalRoutes.d.ts +14 -0
  436. package/dist/server/evalInternalRoutes.js +87 -0
  437. package/dist/server/evalRouteContext.d.ts +46 -0
  438. package/dist/server/evalRouteContext.js +43 -0
  439. package/dist/server/evalRoutes.d.ts +5 -0
  440. package/dist/server/evalRoutes.js +1456 -0
  441. package/dist/server/evalTriageRoutes.d.ts +2 -0
  442. package/dist/server/evalTriageRoutes.js +95 -0
  443. package/dist/server/guideRoutes.d.ts +5 -0
  444. package/dist/server/guideRoutes.js +166 -0
  445. package/dist/server/http.d.ts +15 -0
  446. package/dist/server/http.js +67 -3
  447. package/dist/server/internalAgentRoutes.d.ts +6 -0
  448. package/dist/server/internalAgentRoutes.js +12 -0
  449. package/dist/server/mcpHost.js +5 -0
  450. package/dist/toolkit/meta.d.ts +1 -1
  451. package/dist/toolkit/meta.js +53 -0
  452. package/dist/toolkit/profiles.d.ts +5 -0
  453. package/dist/toolkit/profiles.js +13 -1
  454. package/dist/tools/askOperator.js +2 -1
  455. package/dist/tools/emitStageEnvelope.d.ts +17 -16
  456. package/dist/tools/emitStageEnvelope.js +46 -32
  457. package/dist/tools/stageToolNames.d.ts +4 -0
  458. package/dist/tools/stageToolNames.js +4 -0
  459. package/dist/tools/workingState.d.ts +40 -0
  460. package/dist/tools/workingState.js +108 -0
  461. package/dist/tools/writeStageArtifact.d.ts +0 -9
  462. package/dist/tools/writeStageArtifact.js +2 -1
  463. package/dist/types/stageflowManifest.d.ts +6 -0
  464. package/dist/ui/assets/{MarkdownText-D7tYaIFO.js → MarkdownText-S5C_vemc.js} +2 -2
  465. package/dist/ui/assets/adapters-C0l4ruiR.js +17 -0
  466. package/dist/ui/assets/chat-CjnsmvqR.js +2 -0
  467. package/dist/ui/assets/chat-DFDd4UjS.css +2 -0
  468. package/dist/ui/assets/{main-BFo79krC.css → main-Del1GeLf.css} +1 -1
  469. package/dist/ui/assets/main-_yXVqcW9.js +277 -0
  470. package/dist/ui/chat.html +3 -4
  471. package/dist/ui/index.html +3 -4
  472. package/dist/workshop/chatTurn.js +1 -1
  473. package/dist/workshop/workshopPin.d.ts +3 -3
  474. package/dist/workshop/workshopPin.js +16 -15
  475. package/examples/README.md +2 -0
  476. package/examples/compaction-stress/README.md +30 -0
  477. package/examples/compaction-stress/check-run.mjs +53 -0
  478. package/examples/compaction-stress/collect-evidence.yaml +60 -0
  479. package/examples/compaction-stress/compaction-stress.pipeline.yaml +141 -0
  480. package/examples/compaction-stress/compaction-stress.task.yaml +15 -0
  481. package/examples/compaction-stress/generate-evidence.mjs +110 -0
  482. package/examples/compaction-stress/root-cause.yaml +26 -0
  483. package/examples/compaction-stress/stageflow.yaml +9 -0
  484. package/examples/compaction-stress/write-postmortem.yaml +40 -0
  485. package/examples/document-policy-review/README.md +35 -0
  486. package/examples/document-policy-review/agents/compliance.agent.yaml +42 -0
  487. package/examples/document-policy-review/documents/acme-vendor-sow.md +15 -0
  488. package/examples/document-policy-review/documents/support-runbook.md +13 -0
  489. package/examples/document-policy-review/policies/acceptable-use.md +13 -0
  490. package/examples/document-policy-review/policies/data-handling.md +17 -0
  491. package/examples/document-policy-review/policies/vendor-security.md +17 -0
  492. package/examples/evals/README.md +141 -0
  493. package/examples/evals/critique-sample.dataset.jsonl +8 -0
  494. package/examples/evals/critique-sample.eval.yaml +34 -0
  495. package/examples/evals/critique-sample.task.yaml +4 -0
  496. package/examples/evals/eval-sample.pipeline.yaml +35 -0
  497. package/examples/evals/guide-behavior.dataset.jsonl +15 -0
  498. package/examples/evals/guide-behavior.eval.yaml +35 -0
  499. package/examples/evals/guide-depth.dataset.jsonl +35 -0
  500. package/examples/evals/guide-depth.eval.yaml +169 -0
  501. package/examples/evals/support-sample.agent.yaml +20 -0
  502. package/examples/evals/support-sample.dataset.jsonl +6 -0
  503. package/examples/evals/support-sample.eval.yaml +38 -0
  504. package/examples/memory/evals/guide-behavior.dataset.jsonl +15 -0
  505. package/examples/memory/evals/guide-behavior.eval.yaml +35 -0
  506. package/examples/memory/evals/guide-depth.dataset.jsonl +35 -0
  507. package/examples/memory/evals/guide-depth.eval.yaml +169 -0
  508. package/examples/stageflow.yaml +6 -0
  509. package/package.json +1 -1
  510. package/skills/stageflow/SKILL.md +5 -2
  511. package/skills/stageflow/references/control-surface.md +4 -2
  512. package/skills/stageflow/references/evals.md +68 -0
  513. package/skills/stageflow-author/SKILL.md +4 -0
  514. package/skills/stageflow-run/SKILL.md +4 -0
  515. package/dist/ui/assets/AssistantRuntimeProvider-CsiPFhCT.js +0 -9
  516. package/dist/ui/assets/ReadonlyStore-BfXqHykm.js +0 -6
  517. package/dist/ui/assets/chat-BbLukq9W.js +0 -5
  518. package/dist/ui/assets/chat-zIZU_bP1.css +0 -2
  519. package/dist/ui/assets/main-CijYMeM0.js +0 -259
@@ -26,6 +26,11 @@ export type LoadIssue = ({
26
26
  message: string;
27
27
  category: "trigger";
28
28
  triggerId?: string;
29
+ } & LoadIssueLocation) | ({
30
+ code: string;
31
+ message: string;
32
+ category: "eval";
33
+ severity?: "error" | "warning";
29
34
  } & LoadIssueLocation) | ({
30
35
  code: ValidationFindingCode | string;
31
36
  message: string;
@@ -8,6 +8,8 @@ import { parseModelField } from "./modelField.js";
8
8
  const DEFAULT_PIPELINE_PATTERN = "*.pipeline.yaml";
9
9
  const DEFAULT_TASK_PATTERN = "*.task.yaml";
10
10
  const DEFAULT_TRIGGER_PATTERN = "*.trigger.yaml";
11
+ const DEFAULT_EVAL_PATTERN = "*.eval.yaml";
12
+ const DEFAULT_DATASET_PATTERNS = ["*.dataset.jsonl", "*.dataset.json", "*.dataset.csv"];
11
13
  export function manifestPathForProject(projectRoot) {
12
14
  return path.join(projectRoot, "stageflow.yaml");
13
15
  }
@@ -37,11 +39,27 @@ function parseStringArray(raw, field, issues) {
37
39
  }
38
40
  return entries;
39
41
  }
42
+ function parseDatasetPattern(raw) {
43
+ const entries = typeof raw === "string" ? [raw] : Array.isArray(raw) ? raw : null;
44
+ if (entries === null || entries.length === 0) {
45
+ return null;
46
+ }
47
+ const parsed = [];
48
+ for (const entry of entries) {
49
+ if (typeof entry !== "string" || entry.trim().length === 0) {
50
+ return null;
51
+ }
52
+ parsed.push(entry.trim());
53
+ }
54
+ return parsed;
55
+ }
40
56
  function parsePatterns(raw, issues) {
41
57
  const defaults = {
42
58
  pipeline: DEFAULT_PIPELINE_PATTERN,
43
59
  task: DEFAULT_TASK_PATTERN,
44
60
  trigger: DEFAULT_TRIGGER_PATTERN,
61
+ eval: DEFAULT_EVAL_PATTERN,
62
+ dataset: DEFAULT_DATASET_PATTERNS,
45
63
  };
46
64
  if (raw === undefined || raw === null) {
47
65
  return defaults;
@@ -66,6 +84,12 @@ function parsePatterns(raw, issues) {
66
84
  : typeof record.trigger === "string" && record.trigger.trim().length > 0
67
85
  ? record.trigger.trim()
68
86
  : null;
87
+ const evalPattern = record.eval === undefined
88
+ ? defaults.eval
89
+ : typeof record.eval === "string" && record.eval.trim().length > 0
90
+ ? record.eval.trim()
91
+ : null;
92
+ const dataset = record.dataset === undefined ? defaults.dataset : parseDatasetPattern(record.dataset);
69
93
  if (pipeline === null) {
70
94
  issues.push(catalogIssue("catalog.manifest_invalid", "catalog.patterns.pipeline must be a string"));
71
95
  }
@@ -75,10 +99,18 @@ function parsePatterns(raw, issues) {
75
99
  if (trigger === null) {
76
100
  issues.push(catalogIssue("catalog.manifest_invalid", "catalog.patterns.trigger must be a string"));
77
101
  }
102
+ if (evalPattern === null) {
103
+ issues.push(catalogIssue("catalog.manifest_invalid", "catalog.patterns.eval must be a string"));
104
+ }
105
+ if (dataset === null) {
106
+ issues.push(catalogIssue("catalog.manifest_invalid", "catalog.patterns.dataset must be a non-empty string or an array of non-empty strings"));
107
+ }
78
108
  return {
79
109
  pipeline: pipeline ?? defaults.pipeline,
80
110
  task: task ?? defaults.task,
81
111
  trigger: trigger ?? defaults.trigger,
112
+ eval: evalPattern ?? defaults.eval,
113
+ dataset: dataset ?? defaults.dataset,
82
114
  };
83
115
  }
84
116
  export function parseStageflowManifestOutcome(yamlText, manifestPath, projectRoot) {
@@ -131,6 +163,22 @@ export function parseStageflowManifestOutcome(yamlText, manifestPath, projectRoo
131
163
  triggers = parsed;
132
164
  }
133
165
  }
166
+ const evalsRaw = catalogRecord.evals;
167
+ let evals;
168
+ if (evalsRaw !== undefined) {
169
+ const parsed = parseStringArray(evalsRaw, "evals", issues);
170
+ if (parsed !== null) {
171
+ evals = parsed;
172
+ }
173
+ }
174
+ const datasetsRaw = catalogRecord.datasets;
175
+ let datasets;
176
+ if (datasetsRaw !== undefined) {
177
+ const parsed = parseStringArray(datasetsRaw, "datasets", issues);
178
+ if (parsed !== null) {
179
+ datasets = parsed;
180
+ }
181
+ }
134
182
  const patterns = parsePatterns(catalogRecord.patterns, issues);
135
183
  let agent;
136
184
  const agentField = parseAgentField(record.agent);
@@ -161,6 +209,12 @@ export function parseStageflowManifestOutcome(yamlText, manifestPath, projectRoo
161
209
  if (triggers !== undefined) {
162
210
  catalog.triggers = triggers;
163
211
  }
212
+ if (evals !== undefined) {
213
+ catalog.evals = evals;
214
+ }
215
+ if (datasets !== undefined) {
216
+ catalog.datasets = datasets;
217
+ }
164
218
  if (catalogRecord.patterns !== undefined) {
165
219
  catalog.patterns = {};
166
220
  if (typeof catalogRecord.patterns.pipeline === "string") {
@@ -172,6 +226,16 @@ export function parseStageflowManifestOutcome(yamlText, manifestPath, projectRoo
172
226
  if (typeof catalogRecord.patterns.trigger === "string") {
173
227
  catalog.patterns.trigger = patterns.trigger;
174
228
  }
229
+ if (typeof catalogRecord.patterns.eval === "string") {
230
+ catalog.patterns.eval = patterns.eval;
231
+ }
232
+ const datasetRaw = catalogRecord.patterns.dataset;
233
+ if (typeof datasetRaw === "string") {
234
+ catalog.patterns.dataset = patterns.dataset[0];
235
+ }
236
+ else if (Array.isArray(datasetRaw)) {
237
+ catalog.patterns.dataset = patterns.dataset;
238
+ }
175
239
  }
176
240
  const manifest = {
177
241
  version: 1,
@@ -1,6 +1,8 @@
1
1
  import type { NeedTerminalState, PipelineNeedEdge, PipelineNeedItem, PipelineNeeds, PipelineRoute, PipelineRouteForwardEntry, ResolvedPipelineStageNode } from "../types/pipeline.js";
2
2
  export declare const NEED_TERMINAL_STATES: readonly NeedTerminalState[];
3
3
  export declare function isNeedTerminalState(value: unknown): value is NeedTerminalState;
4
+ /** Map known aliases; return undefined if not a terminal state or known alias. */
5
+ export declare function canonicalizeNeedTerminalState(value: unknown): NeedTerminalState | undefined;
4
6
  export declare function parsePipelineNeeds(raw: unknown, stageId: string): {
5
7
  ok: true;
6
8
  value: PipelineNeeds;
@@ -5,9 +5,21 @@ export const NEED_TERMINAL_STATES = [
5
5
  "skipped",
6
6
  ];
7
7
  const NEED_TERMINAL_STATE_SET = new Set(NEED_TERMINAL_STATES);
8
+ const NEED_TERMINAL_ALIASES = {
9
+ success: "succeeded",
10
+ failure: "failed",
11
+ };
8
12
  export function isNeedTerminalState(value) {
9
13
  return typeof value === "string" && NEED_TERMINAL_STATE_SET.has(value);
10
14
  }
15
+ /** Map known aliases; return undefined if not a terminal state or known alias. */
16
+ export function canonicalizeNeedTerminalState(value) {
17
+ if (typeof value !== "string")
18
+ return undefined;
19
+ if (isNeedTerminalState(value))
20
+ return value;
21
+ return NEED_TERMINAL_ALIASES[value];
22
+ }
11
23
  function isPlainObject(value) {
12
24
  return typeof value === "object" && value !== null && !Array.isArray(value);
13
25
  }
@@ -21,14 +33,15 @@ function parseNeedOn(raw, stageId, parentId) {
21
33
  const seen = new Set();
22
34
  const on = [];
23
35
  for (const item of raw) {
24
- if (typeof item !== "string" || !NEED_TERMINAL_STATE_SET.has(item) || seen.has(item)) {
36
+ const canonical = canonicalizeNeedTerminalState(item);
37
+ if (canonical === undefined || seen.has(canonical)) {
25
38
  return {
26
39
  ok: false,
27
40
  message: `stage "${stageId}": needs "${parentId}": on must be a non-empty unique subset of succeeded, failed, skipped`,
28
41
  };
29
42
  }
30
- seen.add(item);
31
- on.push(item);
43
+ seen.add(canonical);
44
+ on.push(canonical);
32
45
  }
33
46
  return { ok: true, value: on };
34
47
  }
@@ -1,4 +1,4 @@
1
- import { isNeedTerminalState } from "./pipelineNeeds.js";
1
+ import { canonicalizeNeedTerminalState } from "./pipelineNeeds.js";
2
2
  import { parseRouteIf } from "./routeIf.js";
3
3
  function isPlainObject(value) {
4
4
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -81,14 +81,15 @@ function parseRouteOn(raw, stageId, targetId) {
81
81
  const seen = new Set();
82
82
  const on = [];
83
83
  for (const item of items) {
84
- if (typeof item !== "string" || !isNeedTerminalState(item) || seen.has(item)) {
84
+ const canonical = canonicalizeNeedTerminalState(item);
85
+ if (canonical === undefined || seen.has(canonical)) {
85
86
  return {
86
87
  ok: false,
87
88
  message: `stage "${stageId}": route "${targetId}": on must be a non-empty unique subset of succeeded, failed, skipped`,
88
89
  };
89
90
  }
90
- seen.add(item);
91
- on.push(item);
91
+ seen.add(canonical);
92
+ on.push(canonical);
92
93
  }
93
94
  return { ok: true, value: on };
94
95
  }
@@ -0,0 +1,32 @@
1
+ import type { AgentDetail, AgentSummary } from "../agents/service.js";
2
+ import type { EvalFile } from "../evals/types.js";
3
+ import { type AgentDefinition } from "./loadAgent.js";
4
+ import { type LoadIssue, type LoadOutcome } from "./loadOutcome.js";
5
+ export type AgentToolRisk = "read" | "write" | "shell" | "destructive" | "external" | "mcp_unknown" | "sub_agent" | "browser";
6
+ export type AgentToolGrant = {
7
+ id: string;
8
+ risk: AgentToolRisk;
9
+ };
10
+ export type ResolvedAgentTarget = {
11
+ agentId: string;
12
+ /** The revision read now; null when resolved offline from the file alone. */
13
+ revision: number | null;
14
+ definitionHash: string;
15
+ /** The definition after the eval's `defaults.model` override. */
16
+ definition: AgentDefinition;
17
+ modelResolved: string | undefined;
18
+ tools: AgentToolGrant[];
19
+ askFirst: string[];
20
+ issues: LoadIssue[];
21
+ };
22
+ /** The slice of `AgentService` that eval resolution reads. */
23
+ export type AgentCatalogPort = {
24
+ get(projectRoot: string, agentId: string): Promise<AgentDetail>;
25
+ list(projectRoot: string): Promise<AgentSummary[]>;
26
+ };
27
+ export declare function agentToolGrants(definition: AgentDefinition): AgentToolGrant[];
28
+ /** sha256 of the canonical JSON of the definition after the eval's `defaults.model` override. */
29
+ export declare function agentDefinitionHash(definition: AgentDefinition): string;
30
+ export declare function resolveAgentTarget(file: EvalFile, projectRoot: string, agents: AgentCatalogPort): Promise<LoadOutcome<ResolvedAgentTarget>>;
31
+ /** Offline resolution (`sf eval validate` without an agent service): parses `agents/<id>.agent.yaml` only. */
32
+ export declare function resolveAgentTargetFromFile(file: EvalFile, projectRoot: string): Promise<LoadOutcome<ResolvedAgentTarget>>;
@@ -0,0 +1,118 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { isAgentError } from "../agents/errors.js";
4
+ import { effectiveAskFirst } from "../agents/policy.js";
5
+ import { canonicalJson, sha256Hex } from "../evals/canonical.js";
6
+ import { grantedToolIds, parseAgentYaml } from "./loadAgent.js";
7
+ import { loadFailure, loadSuccess } from "./loadOutcome.js";
8
+ import { TOOL_META, STAGEFLOW_GRANT_PREFIX } from "../toolkit/meta.js";
9
+ const BUILTIN_RISK = {
10
+ read: "read",
11
+ grep: "read",
12
+ find: "read",
13
+ ls: "read",
14
+ write: "write",
15
+ edit: "write",
16
+ bash: "shell",
17
+ };
18
+ function agentIssue(code, message, severity = "error") {
19
+ return { code, message, category: "eval", severity };
20
+ }
21
+ function grantRisk(id) {
22
+ if (id in BUILTIN_RISK)
23
+ return BUILTIN_RISK[id];
24
+ if (id.startsWith("agent:"))
25
+ return "sub_agent";
26
+ if (id.startsWith(STAGEFLOW_GRANT_PREFIX)) {
27
+ return TOOL_META[id.slice(STAGEFLOW_GRANT_PREFIX.length)]?.risk ?? "mcp_unknown";
28
+ }
29
+ return "mcp_unknown";
30
+ }
31
+ export function agentToolGrants(definition) {
32
+ const grants = [...grantedToolIds(definition)].sort().map((id) => ({ id, risk: grantRisk(id) }));
33
+ if (definition.tools.browser)
34
+ grants.push({ id: "browser", risk: "browser" });
35
+ return grants;
36
+ }
37
+ /** sha256 of the canonical JSON of the definition after the eval's `defaults.model` override. */
38
+ export function agentDefinitionHash(definition) {
39
+ return sha256Hex(canonicalJson(definition));
40
+ }
41
+ function withModelOverride(definition, model) {
42
+ return model === undefined ? definition : { ...definition, model: { ...definition.model, id: model } };
43
+ }
44
+ function firstIssue(issues) {
45
+ const issue = issues[0];
46
+ if (!issue)
47
+ return "the definition does not load";
48
+ return issue.path ? `${issue.path}: ${issue.message}` : issue.message;
49
+ }
50
+ function resolved(agentId, revision, base, file, warnings) {
51
+ const definition = withModelOverride(base, file.defaults?.model);
52
+ const issues = [...warnings];
53
+ if (!definition.enabled) {
54
+ issues.push(agentIssue("eval.agent_disabled", `Agent "${agentId}" is disabled; eval sessions run anyway`, "warning"));
55
+ }
56
+ return loadSuccess({
57
+ agentId,
58
+ revision,
59
+ definitionHash: agentDefinitionHash(definition),
60
+ definition,
61
+ modelResolved: definition.model.id,
62
+ tools: agentToolGrants(definition),
63
+ askFirst: effectiveAskFirst(definition),
64
+ issues,
65
+ }, issues);
66
+ }
67
+ export async function resolveAgentTarget(file, projectRoot, agents) {
68
+ if (file.target.kind !== "agent") {
69
+ return loadFailure([agentIssue("eval.target_unresolved", "Not an agent target")]);
70
+ }
71
+ const agentId = file.target.agent;
72
+ let detail;
73
+ try {
74
+ detail = await agents.get(projectRoot, agentId);
75
+ }
76
+ catch (err) {
77
+ if (isAgentError(err) && err.code === "agent.not_found") {
78
+ return loadFailure([agentIssue("eval.agent_not_found", `Agent "${agentId}" was not found`)]);
79
+ }
80
+ throw err;
81
+ }
82
+ const listed = await agents.list(projectRoot);
83
+ if (!listed.some((agent) => agent.id === agentId)) {
84
+ return loadFailure([agentIssue("eval.agent_archived", `Agent "${agentId}" is archived`)]);
85
+ }
86
+ if (detail.agent.issues.length > 0 || detail.definition === null) {
87
+ return loadFailure([
88
+ agentIssue("eval.agent_invalid", `Agent "${agentId}" has problems in its definition: ${firstIssue(detail.agent.issues)}`),
89
+ ]);
90
+ }
91
+ return resolved(agentId, detail.agent.revision, detail.definition, file, []);
92
+ }
93
+ /** Offline resolution (`sf eval validate` without an agent service): parses `agents/<id>.agent.yaml` only. */
94
+ export async function resolveAgentTargetFromFile(file, projectRoot) {
95
+ if (file.target.kind !== "agent") {
96
+ return loadFailure([agentIssue("eval.target_unresolved", "Not an agent target")]);
97
+ }
98
+ const agentId = file.target.agent;
99
+ let text;
100
+ try {
101
+ text = await readFile(path.join(projectRoot, "agents", `${agentId}.agent.yaml`), "utf8");
102
+ }
103
+ catch {
104
+ return loadFailure([agentIssue("eval.agent_not_found", `Agent "${agentId}" was not found`)]);
105
+ }
106
+ const parsed = parseAgentYaml(text);
107
+ if (!parsed.ok) {
108
+ return loadFailure([
109
+ agentIssue("eval.agent_invalid", `Agent "${agentId}" has problems in its definition: ${firstIssue(parsed.issues)}`),
110
+ ]);
111
+ }
112
+ if (parsed.value.id !== agentId) {
113
+ return loadFailure([
114
+ agentIssue("eval.agent_invalid", `Agent "${agentId}" has problems in its definition: id must match the file name`),
115
+ ]);
116
+ }
117
+ return resolved(agentId, null, parsed.value, file, []);
118
+ }
@@ -0,0 +1,21 @@
1
+ import type { EvalFile } from "../evals/types.js";
2
+ import type { CompletionContract } from "../types/completion.js";
3
+ import type { LoadedStageConfig } from "../types/stage.js";
4
+ import { type LoadOutcome } from "./loadOutcome.js";
5
+ export type ResolvedEvalTarget = {
6
+ stageConfig: LoadedStageConfig;
7
+ pipelinePath?: string;
8
+ stageId?: string;
9
+ file?: string;
10
+ stageVersionHash: string;
11
+ completion?: CompletionContract;
12
+ inputSchema?: unknown;
13
+ outputSchema?: unknown;
14
+ modelResolved: string;
15
+ modelTier: "stage" | "pipeline" | "global";
16
+ };
17
+ /** The exact object the stage version hash is computed from. */
18
+ export declare function stageDefinition(stage: LoadedStageConfig, completion: CompletionContract | undefined): Record<string, unknown>;
19
+ /** sha256 of the canonical JSON of the materialized stage config plus its after-phase verify contract. */
20
+ export declare function stageVersionHash(stage: LoadedStageConfig, completion: CompletionContract | undefined): string;
21
+ export declare function resolveEvalTarget(file: EvalFile, evalAbsPath: string, projectRoot: string): Promise<LoadOutcome<ResolvedEvalTarget>>;
@@ -0,0 +1,89 @@
1
+ import path from "node:path";
2
+ import { canonicalJson, sha256Hex } from "../evals/canonical.js";
3
+ import { resolveEvalPaths } from "./loadEval.js";
4
+ import { loadFailure, loadSuccess } from "./loadOutcome.js";
5
+ import { loadPipelineOutcome } from "./loadPipeline.js";
6
+ import { afterCompletionForStage, loadStageOutcome } from "./loadStage.js";
7
+ import { materializeStageModels } from "./materializeStageModels.js";
8
+ function unresolved(message) {
9
+ return { code: "eval.target_unresolved", message, category: "eval" };
10
+ }
11
+ function describeIssues(issues) {
12
+ return issues.map((issue) => issue.message).join("; ");
13
+ }
14
+ /** The exact object the stage version hash is computed from. */
15
+ export function stageDefinition(stage, completion) {
16
+ const { model_tier: _tier, ...config } = stage;
17
+ return { ...config, ...(completion !== undefined ? { completion } : {}) };
18
+ }
19
+ /** sha256 of the canonical JSON of the materialized stage config plus its after-phase verify contract. */
20
+ export function stageVersionHash(stage, completion) {
21
+ return sha256Hex(canonicalJson(stageDefinition(stage, completion)));
22
+ }
23
+ export async function resolveEvalTarget(file, evalAbsPath, projectRoot) {
24
+ if (file.target.kind !== "stage") {
25
+ return loadFailure([unresolved("Agent targets are resolved by resolveAgentTarget")]);
26
+ }
27
+ const paths = resolveEvalPaths(file, evalAbsPath);
28
+ const rel = (abs) => path.relative(projectRoot, abs).split(path.sep).join("/");
29
+ if (paths.pipelinePath !== undefined) {
30
+ const pipelineRel = rel(paths.pipelinePath);
31
+ const outcome = await loadPipelineOutcome(paths.pipelinePath, { cwd: projectRoot, projectRoot, requireIo: false });
32
+ if (!outcome.ok) {
33
+ return loadFailure([
34
+ unresolved(`Target pipeline ${pipelineRel} does not load: ${describeIssues(outcome.issues)}`),
35
+ ]);
36
+ }
37
+ const { value } = outcome;
38
+ const stageId = file.target.stage;
39
+ const stage = value.stages.find((s) => s.id === stageId);
40
+ if (!stage) {
41
+ const known = value.stages.map((s) => s.id).join(", ");
42
+ return loadFailure([
43
+ unresolved(`Target stage "${stageId}" not found in pipeline ${pipelineRel} (stages: ${known})`),
44
+ ]);
45
+ }
46
+ const completion = value.dag.nodes.find((node) => node.id === stageId)?.completion;
47
+ return loadSuccess({
48
+ stageConfig: stage,
49
+ pipelinePath: paths.pipelinePath,
50
+ stageId,
51
+ stageVersionHash: stageVersionHash(stage, completion),
52
+ ...(completion !== undefined ? { completion } : {}),
53
+ inputSchema: stage.clone_input_schema,
54
+ outputSchema: stage.payload_schema,
55
+ modelResolved: stage.model,
56
+ modelTier: stage.model_tier ?? "global",
57
+ });
58
+ }
59
+ const stageFile = paths.stageFile;
60
+ const fileRel = rel(stageFile);
61
+ const loaded = await loadStageOutcome(stageFile, { requireIo: false });
62
+ if (!loaded.ok) {
63
+ return loadFailure([
64
+ unresolved(`Target stage file ${fileRel} does not load: ${describeIssues(loaded.issues)}`),
65
+ ]);
66
+ }
67
+ const materialized = await materializeStageModels([loaded.value], {
68
+ pipelineId: `standalone-${loaded.value.id}`,
69
+ projectRoot,
70
+ });
71
+ if (!materialized.ok) {
72
+ return loadFailure([
73
+ unresolved(`Target stage file ${fileRel} has no resolvable model: ${describeIssues(materialized.issues)}`),
74
+ ]);
75
+ }
76
+ const stage = materialized.value[0];
77
+ const fileCompletion = afterCompletionForStage(loaded.value);
78
+ return loadSuccess({
79
+ stageConfig: stage,
80
+ file: stageFile,
81
+ stageId: stage.id,
82
+ stageVersionHash: stageVersionHash(stage, fileCompletion),
83
+ ...(fileCompletion !== undefined ? { completion: fileCompletion } : {}),
84
+ inputSchema: stage.clone_input_schema,
85
+ outputSchema: stage.payload_schema,
86
+ modelResolved: stage.model,
87
+ modelTier: stage.model_tier ?? "global",
88
+ });
89
+ }
@@ -1,4 +1,4 @@
1
1
  import type { LoadedManifest } from "../types/stageflowManifest.js";
2
- export type CatalogPathKind = "pipeline" | "task" | "trigger";
2
+ export type CatalogPathKind = "pipeline" | "task" | "trigger" | "eval" | "dataset";
3
3
  export declare function isExcluded(repoRelPath: string, exclude: string[] | undefined): boolean;
4
4
  export declare function scanCatalogPaths(manifest: LoadedManifest, kind: CatalogPathKind): Promise<string[]>;
@@ -40,7 +40,7 @@ async function walkDirectory(absDir) {
40
40
  }
41
41
  return files;
42
42
  }
43
- async function expandCatalogEntry(projectRoot, entry, kind, pattern) {
43
+ async function expandCatalogEntry(projectRoot, entry, patterns) {
44
44
  const absPath = path.join(projectRoot, entry);
45
45
  let entryStat;
46
46
  try {
@@ -56,7 +56,7 @@ async function expandCatalogEntry(projectRoot, entry, kind, pattern) {
56
56
  return [];
57
57
  }
58
58
  const files = await walkDirectory(absPath);
59
- return files.filter((filePath) => matchesPattern(path.basename(filePath), pattern));
59
+ return files.filter((filePath) => patterns.some((pattern) => matchesPattern(path.basename(filePath), pattern)));
60
60
  }
61
61
  export async function scanCatalogPaths(manifest, kind) {
62
62
  const { projectRoot, manifest: doc, patterns } = manifest;
@@ -64,13 +64,25 @@ export async function scanCatalogPaths(manifest, kind) {
64
64
  ? doc.catalog.pipelines
65
65
  : kind === "task"
66
66
  ? doc.catalog.tasks
67
- : (doc.catalog.triggers ?? []);
68
- const pattern = kind === "pipeline" ? patterns.pipeline : kind === "task" ? patterns.task : patterns.trigger;
67
+ : kind === "trigger"
68
+ ? (doc.catalog.triggers ?? [])
69
+ : kind === "eval"
70
+ ? (doc.catalog.evals ?? ["evals"])
71
+ : (doc.catalog.datasets ?? ["datasets"]);
72
+ const matchPatterns = kind === "pipeline"
73
+ ? [patterns.pipeline]
74
+ : kind === "task"
75
+ ? [patterns.task]
76
+ : kind === "trigger"
77
+ ? [patterns.trigger]
78
+ : kind === "eval"
79
+ ? [patterns.eval]
80
+ : patterns.dataset;
69
81
  const exclude = doc.catalog.exclude;
70
82
  const seen = new Set();
71
83
  const resolved = [];
72
84
  for (const entry of entries) {
73
- const absPaths = await expandCatalogEntry(projectRoot, entry, kind, pattern);
85
+ const absPaths = await expandCatalogEntry(projectRoot, entry, matchPatterns);
74
86
  for (const absPath of absPaths) {
75
87
  const normalized = path.resolve(absPath);
76
88
  if (seen.has(normalized))
@@ -3,8 +3,8 @@ import type { TriggerFile } from "../types/trigger.js";
3
3
  import type { LoadIssue } from "./loadOutcome.js";
4
4
  import type { AnyChannelProvider } from "../channels/types.js";
5
5
  export type ValidationSeverity = "error" | "warning";
6
- export type ValidationCategory = "pipeline" | "stage" | "catalog" | "task" | "trigger";
7
- export type ValidationFindingCode = "pipeline.invalid_shape" | "pipeline.dag_error" | "pipeline.missing_stage" | "pipeline.load_error" | "pipeline.string_stage_ref" | "pipeline.stage_uses_inline_conflict" | "pipeline.stage_missing_body" | "pipeline.stage_id_mismatch" | "pipeline.stage_wrapper_skill_rejected" | "pipeline.invalid_completion" | "catalog.path_case_mismatch" | "pipeline.invalid_recovery" | "pipeline.include_cycle" | "pipeline.include_invalid" | "pipeline.include_duplicate_stage" | "pipeline.invalid_agent" | "pipeline.invalid_model" | "pipeline.invalid_verify" | "pipeline.io_incompatible" | "pipeline.model_applies" | "pipeline.route_if_invalid" | "pipeline.route_all_gated" | "pipeline.invalid_requires" | "pipeline.requires_conflict" | "pipeline.invalid_channels" | "pipeline.invalid_memories" | "pipeline.memory_unavailable" | "stage.invalid_shape" | "stage.invalid_model" | "stage.missing_model" | "stage.invalid_payload_schema" | "stage.invalid_clone_input_schema" | "stage.unresolved_schema_ref" | "stage.invalid_clone_actions" | "stage.invalid_gate_kinds" | "stage.invalid_pre_emit_checks" | "stage.invalid_timeout_ms" | "stage.invalid_skill" | "stage.invalid_mcp" | "stage.invalid_channels" | "stage.channel_unavailable" | "stage.invalid_browser" | "stage.invalid_secrets" | "stage.unknown_secret" | "stage.denied_secret" | "stage.invalid_requires" | "stage.invalid_agent" | "stage.invalid_io" | "stage.load_error" | "stage.id_filename_mismatch" | "task.invalid_shape" | "task.load_error" | "task.entry_input_unmet" | "task.binding_conflict" | "task.repository_ref_required" | "task.ref_without_repository" | "task.repository_invalid" | "trigger.invalid_shape" | "trigger.load_error" | "trigger.unknown_pipeline" | "trigger.unknown_task" | "catalog.duplicate_pipeline_id" | "catalog.manifest_missing" | "catalog.manifest_invalid" | "catalog.empty_catalog" | "catalog.manifest_load_error" | "catalog.invalid_mcp" | "catalog.mcp_command_missing" | "catalog.mixed_yaml_dialect" | "catalog.legacy_yaml" | "catalog.stageflow_home_absolute_path";
6
+ export type ValidationCategory = "pipeline" | "stage" | "catalog" | "task" | "trigger" | "eval" | "dataset";
7
+ export type ValidationFindingCode = "pipeline.invalid_shape" | "pipeline.dag_error" | "pipeline.missing_stage" | "pipeline.load_error" | "pipeline.string_stage_ref" | "pipeline.stage_uses_inline_conflict" | "pipeline.stage_missing_body" | "pipeline.stage_id_mismatch" | "pipeline.stage_wrapper_skill_rejected" | "pipeline.invalid_completion" | "catalog.path_case_mismatch" | "pipeline.invalid_recovery" | "pipeline.include_cycle" | "pipeline.include_invalid" | "pipeline.include_duplicate_stage" | "pipeline.invalid_agent" | "pipeline.invalid_model" | "pipeline.invalid_verify" | "pipeline.io_incompatible" | "pipeline.model_applies" | "pipeline.route_if_invalid" | "pipeline.route_all_gated" | "pipeline.invalid_requires" | "pipeline.requires_conflict" | "pipeline.invalid_channels" | "pipeline.invalid_memories" | "pipeline.memory_unavailable" | "stage.invalid_shape" | "stage.invalid_model" | "stage.missing_model" | "stage.invalid_payload_schema" | "stage.invalid_clone_input_schema" | "stage.unresolved_schema_ref" | "stage.invalid_clone_actions" | "stage.invalid_gate_kinds" | "stage.invalid_pre_emit_checks" | "stage.invalid_timeout_ms" | "stage.invalid_skill" | "stage.invalid_mcp" | "stage.invalid_channels" | "stage.channel_unavailable" | "stage.invalid_browser" | "stage.invalid_secrets" | "stage.unknown_secret" | "stage.denied_secret" | "stage.invalid_requires" | "stage.invalid_agent" | "stage.invalid_io" | "stage.load_error" | "stage.id_filename_mismatch" | "task.invalid_shape" | "task.load_error" | "task.entry_input_unmet" | "task.binding_conflict" | "task.repository_ref_required" | "task.ref_without_repository" | "task.repository_invalid" | "trigger.invalid_shape" | "trigger.load_error" | "trigger.unknown_pipeline" | "trigger.unknown_task" | "trigger.github_action_required" | "trigger.invalid_github_action" | "catalog.duplicate_pipeline_id" | "catalog.manifest_missing" | "catalog.manifest_invalid" | "catalog.empty_catalog" | "catalog.manifest_load_error" | "catalog.invalid_mcp" | "catalog.mcp_command_missing" | "catalog.mixed_yaml_dialect" | "catalog.legacy_yaml" | "catalog.stageflow_home_absolute_path";
8
8
  export type ValidationFinding = {
9
9
  severity: ValidationSeverity;
10
10
  code: ValidationFindingCode | string;
@@ -6,6 +6,9 @@ import { INLINE_PIPELINE_PATH, loadPipelineFromObjectOutcome, loadPipelineOutcom
6
6
  import { loadStageOutcome } from "./loadStage.js";
7
7
  import { loadTaskOutcome } from "./loadTask.js";
8
8
  import { loadTriggerOutcome } from "./loadTrigger.js";
9
+ import { githubMatchActionError, isGithubTriggerAction } from "./githubTriggerAction.js";
10
+ import { loadEvalCatalog } from "./evalCatalog.js";
11
+ import { evalFindingsFromIssues } from "./validateEval.js";
9
12
  import { readYamlObject } from "./readYamlObject.js";
10
13
  import { resolveCatalogContext } from "./resolveCatalogContext.js";
11
14
  import { getCatalogScanPaths } from "./browseCatalog.js";
@@ -46,7 +49,7 @@ function sortFindings(findings) {
46
49
  export function effectiveSeverity(finding, strict) {
47
50
  if (strict &&
48
51
  finding.severity === "warning" &&
49
- STRICT_CATALOG_WARNINGS.has(finding.code)) {
52
+ (STRICT_CATALOG_WARNINGS.has(finding.code) || finding.category === "eval")) {
50
53
  return "error";
51
54
  }
52
55
  return finding.severity;
@@ -172,6 +175,9 @@ export function findingsFromLoadIssues(cwd, absPath, issues) {
172
175
  withIssueLocation(findingTriggerError(cwd, absPath, issue.message, issue.code), issue),
173
176
  ];
174
177
  }
178
+ if (issue.category === "eval") {
179
+ return evalFindingsFromIssues(relPath(cwd, absPath), [issue]);
180
+ }
175
181
  if (issue.category === "catalog") {
176
182
  const code = issue.code;
177
183
  const severity = code === "catalog.manifest_missing" ||
@@ -647,6 +653,9 @@ async function validateManifestAll(invocationCwd) {
647
653
  }));
648
654
  }
649
655
  }
656
+ for (const entry of await loadEvalCatalog(manifest)) {
657
+ findings.push(...entry.findings);
658
+ }
650
659
  return findings;
651
660
  }
652
661
  /** Confirms a trigger's `pipeline`/`task` refs resolve against known catalog ids. */
@@ -658,6 +667,17 @@ export function findingsForTriggerRefs(cwd, absPath, trigger, refs) {
658
667
  if (trigger.task !== undefined && !refs.taskIds.has(trigger.task)) {
659
668
  findings.push(findingTriggerError(cwd, absPath, `Trigger "${trigger.id}" references unknown task "${trigger.task}"`, "trigger.unknown_task"));
660
669
  }
670
+ const source = trigger.event?.source;
671
+ if (typeof source === "string" && source.startsWith("github.")) {
672
+ const action = trigger.event?.match?.action;
673
+ if (action === undefined) {
674
+ findings.push(findingTriggerError(cwd, absPath, `Trigger "${trigger.id}" requires event.match.action for github.* sources`, "trigger.github_action_required"));
675
+ }
676
+ else if (!isGithubTriggerAction(action)) {
677
+ findings.push(findingTriggerError(cwd, absPath, githubMatchActionError(source, trigger.event?.match) ??
678
+ `Trigger "${trigger.id}" has an invalid event.match.action`, "trigger.invalid_github_action"));
679
+ }
680
+ }
661
681
  return findings;
662
682
  }
663
683
  async function validateSingleTask(invocationCwd, taskArg) {
@@ -0,0 +1,36 @@
1
+ import { type LoadedEval } from "./loadEval.js";
2
+ import type { LoadIssue } from "./loadOutcome.js";
3
+ import { type AgentCatalogPort } from "./resolveAgentTarget.js";
4
+ import type { ValidationFinding, ValidationSeverity } from "./validateCatalog.js";
5
+ export declare const EVAL_LARGE_RUN = 500;
6
+ export declare const EVAL_TOO_LARGE_RUN = 5000;
7
+ /** The slice of the dataset loader's report that eval validation reads. */
8
+ export type DatasetReport = {
9
+ path: string;
10
+ relPath: string;
11
+ cases: Array<{
12
+ id: string;
13
+ input: Record<string, unknown>;
14
+ expected?: unknown;
15
+ tags?: string[];
16
+ }>;
17
+ findings: ValidationFinding[];
18
+ contentHash: string;
19
+ };
20
+ export type ValidateEvalContext = {
21
+ projectRoot: string;
22
+ evals?: ReadonlyArray<{
23
+ id: string;
24
+ absPath: string;
25
+ }>;
26
+ datasetReport?: DatasetReport;
27
+ datasetInline?: boolean;
28
+ isKnownModel?: (id: string) => Promise<boolean>;
29
+ agents?: AgentCatalogPort;
30
+ };
31
+ export declare function evalFinding(relPath: string, severity: ValidationSeverity, code: string, message: string, location?: {
32
+ line?: number;
33
+ column?: number;
34
+ }): ValidationFinding;
35
+ export declare function evalFindingsFromIssues(relPath: string, issues: LoadIssue[]): ValidationFinding[];
36
+ export declare function validateEval(loaded: LoadedEval, ctx: ValidateEvalContext): Promise<ValidationFinding[]>;