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
@@ -530,7 +530,7 @@ export class RunManager {
530
530
  */
531
531
  async attachWaitingStages() {
532
532
  const found = [];
533
- const runs = await this.options.store.listRuns();
533
+ const runs = await this.options.store.listRuns({ origin: "any" });
534
534
  for (const summary of runs) {
535
535
  if (summary.status !== "running")
536
536
  continue;
@@ -627,7 +627,7 @@ export class RunManager {
627
627
  }
628
628
  async reconcileOrphanedStages() {
629
629
  const reconciled = [];
630
- const runs = await this.options.store.listRuns();
630
+ const runs = await this.options.store.listRuns({ origin: "any" });
631
631
  for (const summary of runs) {
632
632
  let meta;
633
633
  try {
@@ -806,7 +806,7 @@ export class RunManager {
806
806
  }
807
807
  async resumeStalledSchedules() {
808
808
  const resumed = [];
809
- const runs = await this.options.store.listRuns();
809
+ const runs = await this.options.store.listRuns({ origin: "any" });
810
810
  for (const summary of runs) {
811
811
  if (summary.status !== "running")
812
812
  continue;
@@ -828,7 +828,7 @@ export class RunManager {
828
828
  }
829
829
  /** Rebuild in-memory admission queue from persisted `queued` rows (R27). */
830
830
  async reenqueuePersistedQueuedRuns() {
831
- const queued = await this.options.store.listRuns({ status: "queued" });
831
+ const queued = await this.options.store.listRuns({ status: "queued", origin: "any" });
832
832
  const ordered = [...queued].sort((a, b) => a.created_at.localeCompare(b.created_at));
833
833
  this.admissionQueue.clear();
834
834
  for (const row of ordered) {
@@ -988,7 +988,16 @@ export class RunManager {
988
988
  catch {
989
989
  return { ok: false, reason: `Run not found: ${runId}`, status: 404 };
990
990
  }
991
+ const trimmedReason = reason.trim();
992
+ if (trimmedReason.length === 0) {
993
+ return {
994
+ ok: false,
995
+ reason: "Cancel reason is required",
996
+ status: 400,
997
+ };
998
+ }
991
999
  if (meta.status === "cancelled") {
1000
+ await this.interruptLiveStages(runId);
992
1001
  return { ok: true, runId };
993
1002
  }
994
1003
  if (meta.status === "succeeded" || meta.status === "failed") {
@@ -998,14 +1007,6 @@ export class RunManager {
998
1007
  status: 409,
999
1008
  };
1000
1009
  }
1001
- const trimmedReason = reason.trim();
1002
- if (trimmedReason.length === 0) {
1003
- return {
1004
- ok: false,
1005
- reason: "Cancel reason is required",
1006
- status: 400,
1007
- };
1008
- }
1009
1010
  await this.options.store.updateRunStatus(runId, "cancelled");
1010
1011
  this.notifyGateClosed(runId);
1011
1012
  await this.options.store.setCancelReason(runId, trimmedReason);
@@ -1056,6 +1057,39 @@ export class RunManager {
1056
1057
  }
1057
1058
  return { ok: true, runId };
1058
1059
  }
1060
+ async interruptLiveStages(runId) {
1061
+ const halt = this.schedulingHalts.get(runId);
1062
+ if (halt !== undefined) {
1063
+ halt.halted = true;
1064
+ }
1065
+ if (this.stageProcessLauncher !== undefined) {
1066
+ await this.stageProcessLauncher.cancelRun(runId);
1067
+ }
1068
+ const detail = await this.options.store.readRun(runId);
1069
+ for (const stage of detail.stages) {
1070
+ if (stage.status !== "running" && stage.status !== "waiting_for_input") {
1071
+ continue;
1072
+ }
1073
+ const wasWaiting = stage.status === "waiting_for_input";
1074
+ await markStageInterrupted({
1075
+ store: this.options.store,
1076
+ runId,
1077
+ stageId: stage.stage_id,
1078
+ reason: OPERATOR_CANCEL_REASON,
1079
+ status: "failed",
1080
+ });
1081
+ if (this.retryCoordinator.isActive(runId) &&
1082
+ this.retryCoordinator.getActiveRoots(runId)?.has(stage.stage_id)) {
1083
+ this.retryCoordinator.signalExternalRetryRootTerminal(runId, stage.stage_id);
1084
+ }
1085
+ if (wasWaiting) {
1086
+ this.hitl.clearLiveWait(runId, stage.stage_id);
1087
+ }
1088
+ }
1089
+ if (this.active.has(runId)) {
1090
+ this.removeActiveEntry(runId, false);
1091
+ }
1092
+ }
1059
1093
  setA2aStore(store) {
1060
1094
  this.a2aStore = store;
1061
1095
  }
@@ -1273,7 +1307,7 @@ export class RunManager {
1273
1307
  gitSha: input.gitSha,
1274
1308
  ciPrUrl: input.ciPrUrl,
1275
1309
  ciJobUrl: input.ciJobUrl,
1276
- }, derivedProjectRoot, resolved.kind === "path" ? resolved.taskPath : undefined, submission, undefined, input.callerId, input.skills, input.dispatchKey);
1310
+ }, derivedProjectRoot, resolved.kind === "path" ? resolved.taskPath : undefined, submission, undefined, input.callerId, input.skills, input.dispatchKey, input.origin);
1277
1311
  }
1278
1312
  async rerun(runId, options) {
1279
1313
  if (!this.acceptingWork) {
@@ -1357,8 +1391,8 @@ export class RunManager {
1357
1391
  }
1358
1392
  return this.reserveAndStartPipeline(taskYaml, pipeline, `run ${runId} task`, rerunCwd, undefined, skipGates, ciIdentity, rerunProjectRoot, undefined, undefined, pinned, options?.callerId);
1359
1393
  }
1360
- async retryStage(runId, stageId) {
1361
- return this.retryStageInternal(runId, stageId, true);
1394
+ async retryStage(runId, stageId, options) {
1395
+ return this.retryStageInternal(runId, stageId, options?.awaitRoot !== false);
1362
1396
  }
1363
1397
  async resumeTimedOutStage(runId, stageId, options) {
1364
1398
  if (!this.acceptingWork) {
@@ -1622,6 +1656,14 @@ export class RunManager {
1622
1656
  if (!result.ok || awaitRoot !== false) {
1623
1657
  this.retryInFlight.delete(retryKey);
1624
1658
  }
1659
+ else if (result.done !== undefined) {
1660
+ void result.done.finally(() => {
1661
+ this.retryInFlight.delete(retryKey);
1662
+ });
1663
+ }
1664
+ else {
1665
+ this.retryInFlight.delete(retryKey);
1666
+ }
1625
1667
  return result;
1626
1668
  }
1627
1669
  catch (err) {
@@ -2219,7 +2261,7 @@ export class RunManager {
2219
2261
  this.attachedWaiting.delete(`${runId}\0${stageId}`);
2220
2262
  }
2221
2263
  }
2222
- async reserveAndStartPipeline(taskYaml, pipeline, taskLabel, cwd, checkoutOverride, skipGates, ciIdentity, projectRoot, taskPath, submission, pinned, callerId, skills, dispatchKey) {
2264
+ async reserveAndStartPipeline(taskYaml, pipeline, taskLabel, cwd, checkoutOverride, skipGates, ciIdentity, projectRoot, taskPath, submission, pinned, callerId, skills, dispatchKey, origin) {
2223
2265
  const persistence = pipelinePersistenceForStart(pipeline);
2224
2266
  if (!persistence.ok) {
2225
2267
  return {
@@ -2419,6 +2461,7 @@ export class RunManager {
2419
2461
  ...(callerId !== undefined && callerId !== null
2420
2462
  ? { callerId }
2421
2463
  : {}),
2464
+ ...(origin !== undefined ? { origin } : {}),
2422
2465
  runManifest,
2423
2466
  skipGates,
2424
2467
  });
@@ -2506,6 +2549,7 @@ export class RunManager {
2506
2549
  skipGates,
2507
2550
  schedulingHalt,
2508
2551
  callerId,
2552
+ ...(origin !== undefined ? { origin } : {}),
2509
2553
  ...(hasSkills ? { skills: validatedSkills } : {}),
2510
2554
  });
2511
2555
  if (started.created === false)
@@ -252,7 +252,7 @@ export async function runRetentionSweep(store, a2aStore, options = {}) {
252
252
  const windows = options.windows ?? retentionWindowsFromEnv(env);
253
253
  const artifactMaxBytes = options.artifactMaxBytes ?? slimArtifactMaxBytesFromEnv(env);
254
254
  const bareCacheTtlMs = options.bareCacheTtlMs ?? bareCacheTtlFromEnv(env);
255
- const runs = await store.listRuns();
255
+ const runs = await store.listRuns({ origin: "any" });
256
256
  const slimmed = [];
257
257
  const purged = [];
258
258
  const metas = new Map();
@@ -305,7 +305,7 @@ export async function runRetentionSweep(store, a2aStore, options = {}) {
305
305
  }
306
306
  }
307
307
  // Re-list for bare-cache decisions after PURGE removed rows when execute.
308
- const runsForBare = execute ? await store.listRuns() : runs;
308
+ const runsForBare = execute ? await store.listRuns({ origin: "any" }) : runs;
309
309
  const bareCachesEvicted = await evictBareCaches({
310
310
  runs: runsForBare,
311
311
  now,
@@ -1,5 +1,5 @@
1
1
  import type { StagePort } from "../agent/port.js";
2
- import { type RunDetail, type RunPipelineDagSnapshot, type RunStatus, type RunStore, type StageSnapshot } from "../runstore/port.js";
2
+ import type { RunStatus, RunStore } from "../runstore/port.js";
3
3
  import type { PipelineRunResult } from "./pipelineRunner.js";
4
4
  import { type SchedulerPreparedPipeline } from "./pipelineScheduler.js";
5
5
  import type { StageExecutionMode } from "./stageConcurrency.js";
@@ -7,6 +7,7 @@ import type { StageBrowserSupport } from "../browser/browserHost.js";
7
7
  import type { StageProcessLauncher } from "./stageProcessLauncher.js";
8
8
  import type { StageHitlController } from "./stageHitl.js";
9
9
  import type { OperatorCatalog } from "./stageAttemptBootstrap.js";
10
+ export { assertStageRetryEligible, resumesRunOnStageRetry, succeededStageRetryBlocker, } from "./runActionEligibility.js";
10
11
  export declare class DuplicateRetryRootError extends Error {
11
12
  constructor(runId: string, stageId: string);
12
13
  }
@@ -69,19 +70,6 @@ export type RetryStageRequest = {
69
70
  awaitRoot?: boolean;
70
71
  beforeAttemptStart?: (attempt: number) => Promise<void>;
71
72
  };
72
- export declare function succeededStageRetryBlocker(stageSnap: StageSnapshot): string | undefined;
73
- export declare function assertStageRetryEligible(detail: RunDetail, stageId: string, opts?: {
74
- recoveryActive?: boolean;
75
- persistedStatus?: RunStatus;
76
- dag?: Pick<RunPipelineDagSnapshot, "nodes"> | null;
77
- }): {
78
- ok: true;
79
- } | {
80
- ok: false;
81
- reason: string;
82
- status: number;
83
- code: string;
84
- };
85
73
  export declare function readRetryRootWaitTimeoutMs(): number;
86
74
  export declare class RunRetryCoordinator {
87
75
  private readonly sessions;
@@ -1,7 +1,8 @@
1
- import { findUnhandledFailedStage, } from "../runstore/port.js";
2
1
  import { retryRun, } from "./pipelineScheduler.js";
3
2
  import { loadRunContext } from "./resumeReconstruct.js";
4
3
  import { syncRunStatusFromStages } from "./stageRecovery.js";
4
+ import { assertStageRetryEligible, resumesRunOnStageRetry, } from "./runActionEligibility.js";
5
+ export { assertStageRetryEligible, resumesRunOnStageRetry, succeededStageRetryBlocker, } from "./runActionEligibility.js";
5
6
  export class DuplicateRetryRootError extends Error {
6
7
  constructor(runId, stageId) {
7
8
  super(`Retry already in progress for run ${runId} stage ${stageId}`);
@@ -20,71 +21,6 @@ export class RetryRootWaitTimeoutError extends Error {
20
21
  this.name = "RetryRootWaitTimeoutError";
21
22
  }
22
23
  }
23
- export function succeededStageRetryBlocker(stageSnap) {
24
- if (stageSnap.definition_id !== undefined &&
25
- stageSnap.definition_id !== stageSnap.stage_id) {
26
- return `Cannot re-run a succeeded clone instance stage (stage=${stageSnap.stage_id}, definition=${stageSnap.definition_id}): clone instances are created by upstream fan-out and cannot be rebuilt in place. Use rerun to start a new run.`;
27
- }
28
- if (stageSnap.envelope?.fork_choice !== undefined) {
29
- return `Cannot re-run a succeeded fork stage (stage=${stageSnap.stage_id}): its envelope recorded a fork_choice and skipped branches cannot be restored. Use rerun to start a new run.`;
30
- }
31
- return undefined;
32
- }
33
- export function assertStageRetryEligible(detail, stageId, opts) {
34
- const stageSnap = detail.stages.find((s) => s.stage_id === stageId);
35
- if (!stageSnap) {
36
- return {
37
- ok: false,
38
- reason: `Stage not found: ${stageId}`,
39
- status: 404,
40
- code: "stage_not_found",
41
- };
42
- }
43
- if (stageSnap.status === "waiting_for_input") {
44
- return {
45
- ok: false,
46
- reason: `Stage is waiting for input and cannot be retried`,
47
- status: 409,
48
- code: "hitl_not_retriable",
49
- };
50
- }
51
- const runStatus = opts?.persistedStatus ?? detail.status;
52
- const recoveryActive = opts?.recoveryActive === true;
53
- if (runStatus !== "failed" && runStatus !== "succeeded") {
54
- const acceptedPendingRetry = runStatus === "running" &&
55
- stageSnap.status === "failed" &&
56
- findUnhandledFailedStage(detail.stages, opts?.dag) === undefined &&
57
- detail.stages.some((stage) => stage.status === "pending");
58
- if (!(runStatus === "running" && recoveryActive) && !acceptedPendingRetry) {
59
- return {
60
- ok: false,
61
- reason: `Run is not failed or succeeded (status=${runStatus})`,
62
- status: 409,
63
- code: "run_not_retryable",
64
- };
65
- }
66
- }
67
- if (stageSnap.status !== "failed" && stageSnap.status !== "succeeded") {
68
- return {
69
- ok: false,
70
- reason: `Stage is not failed or succeeded (status=${stageSnap.status})`,
71
- status: 409,
72
- code: "stage_not_failed",
73
- };
74
- }
75
- if (stageSnap.status === "succeeded") {
76
- const blocker = succeededStageRetryBlocker(stageSnap);
77
- if (blocker !== undefined) {
78
- return {
79
- ok: false,
80
- reason: blocker,
81
- status: 409,
82
- code: "run_not_retryable",
83
- };
84
- }
85
- }
86
- return { ok: true };
87
- }
88
24
  function mutationKey(stageId, attempt) {
89
25
  return `${stageId}\0${attempt}`;
90
26
  }
@@ -318,7 +254,7 @@ export class RunRetryCoordinator {
318
254
  };
319
255
  }
320
256
  insertedForResume = tracked.insertedForResume === true;
321
- if (priorRunStatus === "failed" || priorRunStatus === "succeeded") {
257
+ if (resumesRunOnStageRetry(priorRunStatus)) {
322
258
  await store.updateRunStatus(runId, "running");
323
259
  bumpedRunning = true;
324
260
  }
@@ -1,5 +1,7 @@
1
1
  export declare const SANDBOX_CONTAINER_IMAGE_ENV = "STAGEFLOW_STAGE_CONTAINER_IMAGE";
2
2
  export declare const SANDBOX_CONTAINER_DOCKER_BIN_ENV = "STAGEFLOW_STAGE_CONTAINER_DOCKER_BIN";
3
+ /** One host directory bind-mounted read-only into every stage sandbox, at the same path. */
4
+ export declare const STAGE_READONLY_DIR_ENV = "STAGEFLOW_STAGE_READONLY_DIR";
3
5
  /** Docker container names allow only `[a-zA-Z0-9_.-]`. */
4
6
  export declare function sanitizeContainerNameSegment(value: string): string;
5
7
  export declare function buildContainerName(input: {
@@ -18,9 +20,13 @@ export declare function resolveSandboxContainerOptions(env: Record<string, strin
18
20
  /** Fixed path inside the sandbox. The daemon owns the volume; we never pass it a path from this process. */
19
21
  export declare const SANDBOX_MOUNT_PATH = "/workspace";
20
22
  export declare function sandboxVolumeName(containerName: string): string;
23
+ export declare function stageReadOnlyDir(env: Record<string, string | undefined>): string | undefined;
24
+ export declare function assertStageReadOnlyDir(raw: string): string;
25
+ export declare function assertStageReadOnlyDirExists(dir: string): Promise<void>;
21
26
  export declare function buildStartContainerArgs(params: {
22
27
  image: string;
23
28
  containerName: string;
29
+ readOnlyDir?: string;
24
30
  }): string[];
25
31
  export declare function startSandboxContainer(params: {
26
32
  image: string;
@@ -28,6 +34,7 @@ export declare function startSandboxContainer(params: {
28
34
  stageId: string;
29
35
  attempt?: number;
30
36
  dockerBin?: string;
37
+ readOnlyDir?: string;
31
38
  }): Promise<{
32
39
  containerName: string;
33
40
  }>;
@@ -1,8 +1,12 @@
1
1
  import { execFile } from "node:child_process";
2
2
  import { randomUUID } from "node:crypto";
3
+ import { stat } from "node:fs/promises";
4
+ import path from "node:path";
3
5
  import { promisify } from "node:util";
4
6
  export const SANDBOX_CONTAINER_IMAGE_ENV = "STAGEFLOW_STAGE_CONTAINER_IMAGE";
5
7
  export const SANDBOX_CONTAINER_DOCKER_BIN_ENV = "STAGEFLOW_STAGE_CONTAINER_DOCKER_BIN";
8
+ /** One host directory bind-mounted read-only into every stage sandbox, at the same path. */
9
+ export const STAGE_READONLY_DIR_ENV = "STAGEFLOW_STAGE_READONLY_DIR";
6
10
  const execFileAsync = promisify(execFile);
7
11
  /** Docker container names allow only `[a-zA-Z0-9_.-]`. */
8
12
  export function sanitizeContainerNameSegment(value) {
@@ -35,21 +39,55 @@ export function sandboxVolumeName(containerName) {
35
39
  const safe = containerName.replace(/[^A-Za-z0-9_.-]/g, "_");
36
40
  return `sf-bash-${safe}`;
37
41
  }
42
+ export function stageReadOnlyDir(env) {
43
+ const raw = env[STAGE_READONLY_DIR_ENV];
44
+ if (raw === undefined || raw.trim() === "")
45
+ return undefined;
46
+ return assertStageReadOnlyDir(raw);
47
+ }
48
+ export function assertStageReadOnlyDir(raw) {
49
+ const trimmed = raw.trim();
50
+ if (!path.isAbsolute(trimmed)) {
51
+ throw new Error(`${STAGE_READONLY_DIR_ENV} must be an absolute path`);
52
+ }
53
+ if (trimmed.includes("\0") || trimmed.includes(":")) {
54
+ throw new Error(`${STAGE_READONLY_DIR_ENV} contains a character docker cannot mount`);
55
+ }
56
+ const resolved = path.resolve(trimmed);
57
+ const parts = resolved.split(path.sep).filter((part) => part.length > 0);
58
+ if (parts.length < 3) {
59
+ throw new Error(`${STAGE_READONLY_DIR_ENV} is too broad`);
60
+ }
61
+ return resolved;
62
+ }
63
+ export async function assertStageReadOnlyDirExists(dir) {
64
+ let info;
65
+ try {
66
+ info = await stat(dir);
67
+ }
68
+ catch {
69
+ throw new Error(`read-only folder is not available: ${dir}`);
70
+ }
71
+ if (!info.isDirectory()) {
72
+ throw new Error(`read-only folder is not a directory: ${dir}`);
73
+ }
74
+ }
38
75
  export function buildStartContainerArgs(params) {
39
76
  const { image, containerName } = params;
40
- return [
77
+ const args = [
41
78
  "run",
42
79
  "-d",
43
80
  "--name",
44
81
  containerName,
45
82
  "-v",
46
83
  `${sandboxVolumeName(containerName)}:${SANDBOX_MOUNT_PATH}`,
47
- "-w",
48
- SANDBOX_MOUNT_PATH,
49
- image,
50
- "sleep",
51
- "infinity",
52
84
  ];
85
+ if (params.readOnlyDir !== undefined) {
86
+ const dir = assertStageReadOnlyDir(params.readOnlyDir);
87
+ args.push("-v", `${dir}:${dir}:ro`);
88
+ }
89
+ args.push("-w", SANDBOX_MOUNT_PATH, image, "sleep", "infinity");
90
+ return args;
53
91
  }
54
92
  function errorMessage(err) {
55
93
  if (err && typeof err === "object" && "stderr" in err) {
@@ -61,9 +99,13 @@ function errorMessage(err) {
61
99
  }
62
100
  export async function startSandboxContainer(params) {
63
101
  const containerName = buildContainerName({ runId: params.runId, stageId: params.stageId, attempt: params.attempt }, randomUUID().slice(0, 8));
102
+ if (params.readOnlyDir !== undefined) {
103
+ await assertStageReadOnlyDirExists(params.readOnlyDir);
104
+ }
64
105
  const args = buildStartContainerArgs({
65
106
  image: params.image,
66
107
  containerName,
108
+ ...(params.readOnlyDir !== undefined ? { readOnlyDir: params.readOnlyDir } : {}),
67
109
  });
68
110
  try {
69
111
  await execFileAsync(params.dockerBin ?? "docker", args);
@@ -1,3 +1,4 @@
1
+ import type { StageArtifactGrant } from "./stageRoots.js";
1
2
  export type SandboxDeskRole = "artifacts" | "envelope" | "checkout" | "grant" | "work";
2
3
  export type SandboxDeskBinding = {
3
4
  role: SandboxDeskRole;
@@ -14,7 +15,7 @@ export type SandboxDesk = {
14
15
  export declare function buildSandboxDesk(input: {
15
16
  attemptDir: string;
16
17
  checkoutRoot?: string;
17
- grantedPaths?: readonly string[];
18
+ grants?: readonly StageArtifactGrant[];
18
19
  }): SandboxDesk;
19
20
  export declare function populateSandboxDesk(params: {
20
21
  containerName: string;
@@ -37,16 +37,14 @@ export function buildSandboxDesk(input) {
37
37
  optional: false,
38
38
  });
39
39
  }
40
- const grants = input.grantedPaths ?? [];
41
- for (let index = 0; index < grants.length; index += 1) {
42
- const hostPath = grants[index];
40
+ for (const grant of input.grants ?? []) {
43
41
  bindings.push({
44
42
  role: "grant",
45
- hostPath,
46
- containerPath: `${SANDBOX_MOUNT_PATH}/grants/${grantSegment(index, hostPath)}`,
47
- shape: "mirror",
43
+ hostPath: grant.hostPath,
44
+ containerPath: grant.containerPath,
45
+ shape: grant.kind === "directory" ? "directory" : "file",
48
46
  copyIn: true,
49
- copyOut: true,
47
+ copyOut: false,
50
48
  optional: false,
51
49
  });
52
50
  }
@@ -61,11 +59,6 @@ export function buildSandboxDesk(input) {
61
59
  });
62
60
  return { bindings };
63
61
  }
64
- function grantSegment(index, hostPath) {
65
- const base = path.basename(hostPath).replace(/[^A-Za-z0-9_.-]/g, "_");
66
- const safe = base.length > 0 && base !== "." && base !== ".." ? base : "path";
67
- return `${index}-${safe}`;
68
- }
69
62
  async function pathExists(target) {
70
63
  try {
71
64
  await access(target);
@@ -85,6 +78,12 @@ export async function populateSandboxDesk(params) {
85
78
  if (binding.role === "checkout" || binding.shape === "mirror") {
86
79
  dirs.add(binding.containerPath);
87
80
  }
81
+ if (binding.role === "grant" && binding.shape === "file") {
82
+ dirs.add(path.posix.dirname(binding.containerPath));
83
+ }
84
+ if (binding.role === "grant" && binding.shape === "directory") {
85
+ dirs.add(binding.containerPath);
86
+ }
88
87
  }
89
88
  const made = await execInSandboxContainer({
90
89
  containerName: params.containerName,
@@ -28,6 +28,7 @@ export const STAGE_ENV_ALLOWLIST = [
28
28
  "STAGEFLOW_CURSOR_EXTENSION",
29
29
  "STAGEFLOW_STAGE_CONTAINER_IMAGE",
30
30
  "STAGEFLOW_STAGE_CONTAINER_DOCKER_BIN",
31
+ "STAGEFLOW_STAGE_READONLY_DIR",
31
32
  ];
32
33
  export const PROVIDER_AND_CLOUD_NAMES = [
33
34
  "ANTHROPIC_API_KEY",
@@ -2,6 +2,14 @@ import type { RunMeta } from "../runstore/port.js";
2
2
  import type { StageAttemptContext } from "./stageAttemptContext.js";
3
3
  import type { TaskFile, TaskGitIdentity } from "../types/task.js";
4
4
  export type DerivedBindingKind = "repository" | "checkout" | "unbound";
5
+ export type StageArtifactGrant = {
6
+ /** Run-relative path from the prior envelope. */
7
+ listedPath: string;
8
+ hostPath: string;
9
+ /** File or directory inside the sandbox, under /workspace/grants. */
10
+ containerPath: string;
11
+ kind: "file" | "directory";
12
+ };
5
13
  export type StageRoots = {
6
14
  mode: "bound" | "unbound";
7
15
  cwd: string;
@@ -19,6 +27,10 @@ export type StageRoots = {
19
27
  containerName?: string;
20
28
  /** The docker binary the container above was started with (see STAGEFLOW_STAGE_CONTAINER_DOCKER_BIN). */
21
29
  containerDockerBin?: string;
30
+ /** Host folder bind-mounted read-only into the sandbox at this same path. */
31
+ readonlyDir?: string;
32
+ /** Prior artifacts mounted into the sandbox. Empty or omitted when none are granted. */
33
+ artifactGrants?: readonly StageArtifactGrant[];
22
34
  };
23
35
  export declare const STAGEFLOW_CHECKOUT = "STAGEFLOW_CHECKOUT";
24
36
  export declare const STAGEFLOW_RUN_WORKSPACE = "STAGEFLOW_RUN_WORKSPACE";
@@ -1,4 +1,4 @@
1
- import { type StageRoots } from "./stageRoots.js";
1
+ import { type StageArtifactGrant, type StageRoots } from "./stageRoots.js";
2
2
  export type StageSandbox = {
3
3
  roots: StageRoots;
4
4
  beforeVerify?: () => Promise<void>;
@@ -13,4 +13,5 @@ export declare function openStageSandbox(input: {
13
13
  attempt: number;
14
14
  attemptDir: string;
15
15
  checkoutRoot?: string;
16
+ grants?: readonly StageArtifactGrant[];
16
17
  }): Promise<StageSandbox>;
@@ -1,4 +1,4 @@
1
- import { resolveSandboxContainerOptions, startSandboxContainer, stopSandboxContainer, } from "./sandboxContainer.js";
1
+ import { assertStageReadOnlyDirExists, resolveSandboxContainerOptions, stageReadOnlyDir, startSandboxContainer, stopSandboxContainer, } from "./sandboxContainer.js";
2
2
  import { buildSandboxDesk, populateSandboxDesk, syncSandboxDesk, } from "./sandboxDesk.js";
3
3
  import { withContainerName } from "./stageRoots.js";
4
4
  export async function openStageSandbox(input) {
@@ -6,18 +6,34 @@ export async function openStageSandbox(input) {
6
6
  if (!options) {
7
7
  return { roots: input.roots, close: async () => { } };
8
8
  }
9
+ let readOnlyDir;
10
+ try {
11
+ readOnlyDir = stageReadOnlyDir(input.env);
12
+ if (readOnlyDir !== undefined)
13
+ await assertStageReadOnlyDirExists(readOnlyDir);
14
+ }
15
+ catch (err) {
16
+ return {
17
+ roots: input.roots,
18
+ close: async () => { },
19
+ failure: err instanceof Error ? err.message : String(err),
20
+ };
21
+ }
9
22
  const started = await startSandboxContainer({
10
23
  image: options.image,
11
24
  dockerBin: options.dockerBin,
12
25
  runId: input.runId,
13
26
  stageId: input.stageId,
14
27
  attempt: input.attempt,
28
+ ...(readOnlyDir !== undefined ? { readOnlyDir } : {}),
15
29
  });
16
- const roots = withContainerName(input.roots, started.containerName, options.dockerBin);
30
+ const roots = withContainerName(readOnlyDir !== undefined ? { ...input.roots, readonlyDir: readOnlyDir } : input.roots, started.containerName, options.dockerBin);
17
31
  const checkout = input.checkoutRoot?.trim();
32
+ const grants = input.grants ?? [];
18
33
  const desk = buildSandboxDesk({
19
34
  attemptDir: input.attemptDir,
20
35
  ...(checkout ? { checkoutRoot: checkout } : {}),
36
+ ...(grants.length > 0 ? { grants } : {}),
21
37
  });
22
38
  const session = {
23
39
  roots,
@@ -16,6 +16,9 @@ import { runStage, isRunStageWaiting, } from "./stageRunner.js";
16
16
  import { openStageAttempt } from "./stageAttemptBootstrap.js";
17
17
  import { attemptContext } from "./stageAttemptContext.js";
18
18
  import { loadActiveFeedbackLoopContext } from "./feedbackLoopCoordinator.js";
19
+ import { buildCompletedEnvelopesFromRun, resolvePriorEnvelope, } from "./envelopeRouting.js";
20
+ import { assignment } from "./cloneSchedule.js";
21
+ import { artifactGrantsFromPriors } from "./priorArtifactGrants.js";
19
22
  import { outcomeToWorkerResult, SF_STAGE_WORKER, STAGE_WORKER_EXIT, } from "./stageWorkerProtocol.js";
20
23
  export async function runStageWorker(input) {
21
24
  const store = createRunStore({ rootDir: globalStageflowHome() });
@@ -67,6 +70,19 @@ export async function runStageWorker(input) {
67
70
  const eventOptions = { attempt };
68
71
  let roots = withResolvedAuthPath(rootsForStageWorker(workspaceDir, input.stageId, stage.model, checkoutRoot, attemptCtx), input.rootDir);
69
72
  const unbindAgentDir = bindPiAgentDirEnv(roots.agentDir);
73
+ const completedEnvelopes = await buildCompletedEnvelopesFromRun(store, input.runId, undefined, dag);
74
+ const assigned = assignment(dag, input.stageId, definitionId, completedEnvelopes);
75
+ const priorResult = assigned ??
76
+ (await resolvePriorEnvelope({
77
+ dag,
78
+ stageId: input.stageId,
79
+ completedEnvelopes,
80
+ store,
81
+ runId: input.runId,
82
+ }));
83
+ const artifactGrants = priorResult.ok
84
+ ? await artifactGrantsFromPriors(workspaceDir, priorResult)
85
+ : [];
70
86
  const sandbox = await openStageSandbox({
71
87
  env: process.env,
72
88
  roots,
@@ -75,8 +91,12 @@ export async function runStageWorker(input) {
75
91
  attempt,
76
92
  attemptDir,
77
93
  ...(checkoutRoot !== undefined ? { checkoutRoot } : {}),
94
+ ...(artifactGrants.length > 0 ? { grants: artifactGrants } : {}),
78
95
  });
79
96
  roots = sandbox.roots;
97
+ if (artifactGrants.length > 0) {
98
+ roots = { ...roots, artifactGrants };
99
+ }
80
100
  const beforeVerify = sandbox.beforeVerify;
81
101
  let outcome;
82
102
  let thrown;