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
@@ -0,0 +1,378 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { logger as rootLogger } from "../logging/logger.js";
3
+ import { STAGEFLOW_GUIDE_GREETING, STAGEFLOW_GUIDE_PROFILE_ID, createStageflowGuideProfile, } from "../operatorAgent/index.js";
4
+ import { redactString } from "../logging/redact.js";
5
+ import { buildWorkshopChatPrompt, parseWorkshopChatAttachments } from "../workshop/chatAttachments.js";
6
+ import { resolveWorkshopModel } from "../workshop/modelSettings.js";
7
+ import { advanceGuideTurn } from "../operatorAgent/profiles/guideConfirm.js";
8
+ import { GUIDE_UI_TOOL_NAMES } from "./showUi.js";
9
+ import { guideTitleFrom, readGuideThread, saveGuideThread, } from "./threadStore.js";
10
+ const log = rootLogger.child({ component: "guide" });
11
+ export const GUIDE_MAX_MESSAGE_CHARS = 8000;
12
+ export class GuideError extends Error {
13
+ code;
14
+ status;
15
+ constructor(code, status) {
16
+ super(code);
17
+ this.code = code;
18
+ this.status = status;
19
+ this.name = "GuideError";
20
+ }
21
+ }
22
+ export const GUIDE_TOOL_RESULT_MAX_BYTES = 20_000;
23
+ const GUIDE_TOOL_ERROR_MAX_CHARS = 300;
24
+ const GUIDE_KEPT_RESULT_TOOLS = new Set(GUIDE_UI_TOOL_NAMES);
25
+ const SECRET_KEY = /secret|password|passwd|token|api_?key/i;
26
+ const sessions = new Map();
27
+ const running = new Set();
28
+ const turnAborts = new Map();
29
+ export function resetGuideSessionsForTests() {
30
+ for (const controller of turnAborts.values())
31
+ controller.abort();
32
+ turnAborts.clear();
33
+ for (const session of sessions.values())
34
+ session.close();
35
+ sessions.clear();
36
+ running.clear();
37
+ }
38
+ export function guideAgentInfo(host) {
39
+ const profile = host.getProfile(STAGEFLOW_GUIDE_PROFILE_ID);
40
+ return {
41
+ name: profile?.title ?? createStageflowGuideProfile().title,
42
+ greeting: profile?.greeting ?? STAGEFLOW_GUIDE_GREETING,
43
+ };
44
+ }
45
+ export function isGuideThreadRunning(threadId) {
46
+ return running.has(threadId);
47
+ }
48
+ export function abortGuideTurn(threadId) {
49
+ const controller = turnAborts.get(threadId);
50
+ if (!controller)
51
+ return false;
52
+ controller.abort();
53
+ return true;
54
+ }
55
+ async function openGuideSession(host, record) {
56
+ const existing = sessions.get(record.id);
57
+ if (existing)
58
+ return existing;
59
+ const profile = host.getProfile(STAGEFLOW_GUIDE_PROFILE_ID);
60
+ if (!profile)
61
+ throw new GuideError("guide.unavailable", 503);
62
+ const session = host.openSession({
63
+ profileId: STAGEFLOW_GUIDE_PROFILE_ID,
64
+ context: { kind: "stageflow_guide" },
65
+ });
66
+ sessions.set(record.id, session);
67
+ if (record.messages.length > 0) {
68
+ await session.prepareRestart?.(record.messages.map((message) => ({ role: message.role, text: message.text })));
69
+ }
70
+ return session;
71
+ }
72
+ function assistantText(events) {
73
+ return events
74
+ .filter((event) => event.type === "message" && event.role === "assistant" && typeof event.text === "string")
75
+ .map((event) => event.text ?? "")
76
+ .filter(Boolean)
77
+ .join("\n\n");
78
+ }
79
+ export async function* streamGuideTurn(input) {
80
+ const text = input.text.trim();
81
+ const parsedAttachments = parseWorkshopChatAttachments(input.attachments);
82
+ if (!parsedAttachments.ok)
83
+ throw new GuideError("guide.attachment", 400);
84
+ const attachments = parsedAttachments.attachments;
85
+ if (!text && attachments.length === 0)
86
+ throw new GuideError("guide.invalid", 400);
87
+ if (text.length > GUIDE_MAX_MESSAGE_CHARS)
88
+ throw new GuideError("guide.message_too_long", 413);
89
+ const record = readGuideThread(input.threadId, input.storeRoot);
90
+ if (!record)
91
+ throw new GuideError("guide.not_found", 404);
92
+ if (running.has(record.id))
93
+ throw new GuideError("guide.busy", 409);
94
+ if (input.signal?.aborted)
95
+ return;
96
+ const turnAbort = new AbortController();
97
+ const onExternalAbort = () => turnAbort.abort();
98
+ if (input.signal) {
99
+ input.signal.addEventListener("abort", onExternalAbort);
100
+ }
101
+ turnAborts.set(record.id, turnAbort);
102
+ running.add(record.id);
103
+ let live;
104
+ try {
105
+ const now = new Date().toISOString();
106
+ const attachmentMeta = attachments.map(({ name, size, mediaType }) => ({ name, size, mediaType }));
107
+ const userMessage = {
108
+ id: randomUUID(),
109
+ role: "user",
110
+ text,
111
+ createdAt: now,
112
+ ...(attachmentMeta.length > 0 ? { attachments: attachmentMeta } : {}),
113
+ };
114
+ const titled = record.title.trim() ? record : { ...record, title: guideTitleFrom(text || attachments[0]?.name || "") };
115
+ const incoming = typeof input.model === "string" && input.model.trim() ? input.model.trim() : undefined;
116
+ const sessionModel = incoming ?? record.model;
117
+ saveGuideThread({
118
+ ...titled,
119
+ updatedAt: now,
120
+ messages: [...titled.messages, userMessage],
121
+ ...(sessionModel ? { model: sessionModel } : {}),
122
+ }, input.storeRoot);
123
+ const queue = createFrameQueue();
124
+ live = queue;
125
+ let streamed = "";
126
+ const parts = createPartsRecorder();
127
+ const session = await openGuideSession(input.host, titled);
128
+ const onAbort = () => {
129
+ void session.abort();
130
+ };
131
+ turnAbort.signal.addEventListener("abort", onAbort);
132
+ if (turnAbort.signal.aborted)
133
+ onAbort();
134
+ const prompt = buildWorkshopChatPrompt(text || "Please look at the attached files.", attachments, null);
135
+ const modelId = resolveWorkshopModel({ sessionOverride: sessionModel });
136
+ session.setContext(advanceGuideTurn(session.getContext()));
137
+ const finished = session
138
+ .send(prompt, {
139
+ modelId,
140
+ onDelta: (delta) => {
141
+ streamed += delta;
142
+ parts.text(delta);
143
+ queue.push({ type: "delta", text: delta });
144
+ },
145
+ onActivity: (update) => {
146
+ queue.push(parts.tool(update));
147
+ },
148
+ })
149
+ .then((events) => ({ ok: true, events }))
150
+ .catch((err) => ({ ok: false, err }))
151
+ .finally(() => queue.close());
152
+ for await (const frame of queue.frames()) {
153
+ yield frame;
154
+ if (turnAbort.signal.aborted)
155
+ break;
156
+ }
157
+ const result = await finished;
158
+ turnAbort.signal.removeEventListener("abort", onAbort);
159
+ if (turnAbort.signal.aborted) {
160
+ persistAssistant(input.threadId, input.storeRoot, streamed, parts.finish());
161
+ return;
162
+ }
163
+ if (!result.ok) {
164
+ if (result.err instanceof GuideError)
165
+ throw result.err;
166
+ persistAssistant(input.threadId, input.storeRoot, streamed, parts.finish());
167
+ log.warn("guide.turn.failed", "turn failed", { threadId: record.id });
168
+ yield { type: "error", code: "guide.failed", message: "" };
169
+ return;
170
+ }
171
+ const reply = assistantText(result.events) || streamed;
172
+ const failed = result.events.some((event) => event.type === "error");
173
+ if (failed && !reply) {
174
+ log.warn("guide.turn.failed", "turn failed", { threadId: record.id });
175
+ yield { type: "error", code: "guide.failed", message: "" };
176
+ return;
177
+ }
178
+ if (reply.startsWith(streamed)) {
179
+ const rest = reply.slice(streamed.length);
180
+ if (rest) {
181
+ parts.text(rest);
182
+ yield { type: "delta", text: rest };
183
+ }
184
+ }
185
+ else if (reply && reply !== streamed) {
186
+ parts.replaceText(reply);
187
+ yield { type: "delta", text: reply };
188
+ }
189
+ const saved = persistAssistant(input.threadId, input.storeRoot, reply, parts.finish());
190
+ if (saved)
191
+ yield { type: "done", message: saved };
192
+ else
193
+ yield { type: "error", code: "guide.failed", message: "" };
194
+ }
195
+ catch (err) {
196
+ if (turnAbort.signal.aborted)
197
+ return;
198
+ if (err instanceof GuideError)
199
+ throw err;
200
+ log.warn("guide.turn.failed", "turn failed", { threadId: record.id });
201
+ yield { type: "error", code: "guide.failed", message: "" };
202
+ }
203
+ finally {
204
+ input.signal?.removeEventListener("abort", onExternalAbort);
205
+ live?.close();
206
+ turnAborts.delete(record.id);
207
+ running.delete(record.id);
208
+ }
209
+ }
210
+ function createFrameQueue() {
211
+ const items = [];
212
+ let pending = null;
213
+ let closed = false;
214
+ return {
215
+ push(frame) {
216
+ if (closed)
217
+ return;
218
+ if (pending) {
219
+ const resolve = pending;
220
+ pending = null;
221
+ resolve(frame);
222
+ }
223
+ else {
224
+ items.push(frame);
225
+ }
226
+ },
227
+ close() {
228
+ closed = true;
229
+ pending?.(null);
230
+ pending = null;
231
+ },
232
+ async *frames() {
233
+ while (true) {
234
+ const next = await new Promise((resolve) => {
235
+ if (items.length > 0) {
236
+ resolve(items.shift() ?? null);
237
+ return;
238
+ }
239
+ if (closed) {
240
+ resolve(null);
241
+ return;
242
+ }
243
+ pending = resolve;
244
+ });
245
+ if (!next)
246
+ return;
247
+ yield next;
248
+ }
249
+ },
250
+ };
251
+ }
252
+ function scrubSecrets(value) {
253
+ if (typeof value === "string")
254
+ return redactString(value);
255
+ if (Array.isArray(value))
256
+ return value.map(scrubSecrets);
257
+ if (value !== null && typeof value === "object") {
258
+ const out = {};
259
+ for (const [key, child] of Object.entries(value)) {
260
+ out[key] = key === "secrets" || (SECRET_KEY.test(key) && typeof child === "string")
261
+ ? "[redacted]"
262
+ : scrubSecrets(child);
263
+ }
264
+ return out;
265
+ }
266
+ return value;
267
+ }
268
+ function boundedResult(name, result) {
269
+ const scrubbed = scrubSecrets(result);
270
+ if (GUIDE_KEPT_RESULT_TOOLS.has(name))
271
+ return scrubbed;
272
+ let bytes;
273
+ try {
274
+ bytes = Buffer.byteLength(JSON.stringify(scrubbed) ?? "");
275
+ }
276
+ catch {
277
+ return { truncated: true };
278
+ }
279
+ return bytes > GUIDE_TOOL_RESULT_MAX_BYTES ? { truncated: true } : scrubbed;
280
+ }
281
+ function boundedArgs(args) {
282
+ const scrubbed = scrubSecrets(args);
283
+ let bytes;
284
+ try {
285
+ bytes = Buffer.byteLength(JSON.stringify(scrubbed));
286
+ }
287
+ catch {
288
+ return { truncated: true };
289
+ }
290
+ return bytes > GUIDE_TOOL_RESULT_MAX_BYTES ? { truncated: true } : scrubbed;
291
+ }
292
+ function shortError(message) {
293
+ const text = redactString((message ?? "").trim()) || "tool_failed";
294
+ return text.length > GUIDE_TOOL_ERROR_MAX_CHARS ? `${text.slice(0, GUIDE_TOOL_ERROR_MAX_CHARS - 1)}…` : text;
295
+ }
296
+ function createPartsRecorder() {
297
+ let parts = [];
298
+ let pending = "";
299
+ const flush = () => {
300
+ if (!pending)
301
+ return;
302
+ parts.push({ type: "text", text: pending });
303
+ pending = "";
304
+ };
305
+ return {
306
+ text(delta) {
307
+ pending += delta;
308
+ },
309
+ replaceText(text) {
310
+ parts = parts.filter((part) => part.type !== "text");
311
+ pending = text;
312
+ },
313
+ tool(update) {
314
+ const base = { type: "tool", id: update.id, name: update.name };
315
+ let frame;
316
+ if (update.status === "running") {
317
+ frame = { ...base, status: "running", ...(update.args ? { args: boundedArgs(update.args) } : {}) };
318
+ }
319
+ else if (update.status === "complete") {
320
+ frame = { ...base, status: "complete", ...(update.result !== undefined ? { result: boundedResult(update.name, update.result) } : {}) };
321
+ }
322
+ else {
323
+ frame = { ...base, status: "error", error: shortError(update.errorMessage) };
324
+ }
325
+ const index = parts.findIndex((part) => part.type === "tool" && part.id === update.id && part.status === "running");
326
+ if (frame.status === "running") {
327
+ if (index !== -1)
328
+ return frame;
329
+ flush();
330
+ parts.push({ ...base, status: "running", ...(frame.args ? { args: frame.args } : {}) });
331
+ return frame;
332
+ }
333
+ const started = index === -1 ? undefined : parts[index];
334
+ const done = {
335
+ ...base,
336
+ status: frame.status,
337
+ ...(started?.args ? { args: started.args } : {}),
338
+ ...(frame.result !== undefined ? { result: frame.result } : {}),
339
+ ...(frame.error !== undefined ? { error: frame.error } : {}),
340
+ };
341
+ if (index === -1) {
342
+ flush();
343
+ parts.push(done);
344
+ }
345
+ else {
346
+ parts[index] = done;
347
+ }
348
+ return frame;
349
+ },
350
+ finish() {
351
+ flush();
352
+ return parts.map((part) => part.type === "tool" && part.status === "running"
353
+ ? { ...part, status: "error", error: "guide.tool_interrupted" }
354
+ : part);
355
+ },
356
+ };
357
+ }
358
+ function persistAssistant(threadId, storeRoot, text, parts = []) {
359
+ const reply = text.trim();
360
+ if (!reply && !parts.some((part) => part.type === "tool"))
361
+ return null;
362
+ const latest = readGuideThread(threadId, storeRoot);
363
+ if (!latest)
364
+ return null;
365
+ const message = {
366
+ id: randomUUID(),
367
+ role: "assistant",
368
+ text: reply,
369
+ createdAt: new Date().toISOString(),
370
+ ...(parts.length > 0 ? { parts } : {}),
371
+ };
372
+ saveGuideThread({
373
+ ...latest,
374
+ updatedAt: message.createdAt,
375
+ messages: [...latest.messages, message],
376
+ }, storeRoot);
377
+ return message;
378
+ }
@@ -0,0 +1,14 @@
1
+ export type GuideKnowledgeTopic = {
2
+ id: string;
3
+ title: string;
4
+ summary: string;
5
+ body: string;
6
+ };
7
+ export type GuideKnowledgeMatch = {
8
+ topic: GuideKnowledgeTopic;
9
+ score: number;
10
+ excerpt: string;
11
+ };
12
+ export declare const GUIDE_KNOWLEDGE_TOPICS: readonly GuideKnowledgeTopic[];
13
+ export declare function findGuideKnowledge(id: string): GuideKnowledgeTopic | undefined;
14
+ export declare function searchGuideKnowledge(query: string, limit?: number): GuideKnowledgeMatch[];
@@ -0,0 +1,109 @@
1
+ import { agentsTopic } from "./topics/agents.js";
2
+ import { bestPracticesTopic } from "./topics/bestPractices.js";
3
+ import { connectionsTopic } from "./topics/connections.js";
4
+ import { consoleMapTopic } from "./topics/consoleMap.js";
5
+ import { evalsTopic } from "./topics/evals.js";
6
+ import { limitationsTopic } from "./topics/limitations.js";
7
+ import { mcpSkillsBrowserTopic } from "./topics/mcpSkillsBrowser.js";
8
+ import { memoriesTopic } from "./topics/memories.js";
9
+ import { modelsAndProvidersTopic } from "./topics/modelsAndProviders.js";
10
+ import { overviewTopic } from "./topics/overview.js";
11
+ import { pipelinesTopic } from "./topics/pipelines.js";
12
+ import { stagesTopic } from "./topics/stages.js";
13
+ import { tasksTopic } from "./topics/tasks.js";
14
+ import { triggersTopic } from "./topics/triggers.js";
15
+ import { troubleshootingTopic } from "./topics/troubleshooting.js";
16
+ export const GUIDE_KNOWLEDGE_TOPICS = [
17
+ overviewTopic,
18
+ pipelinesTopic,
19
+ stagesTopic,
20
+ tasksTopic,
21
+ agentsTopic,
22
+ triggersTopic,
23
+ connectionsTopic,
24
+ memoriesTopic,
25
+ evalsTopic,
26
+ modelsAndProvidersTopic,
27
+ mcpSkillsBrowserTopic,
28
+ bestPracticesTopic,
29
+ limitationsTopic,
30
+ troubleshootingTopic,
31
+ consoleMapTopic,
32
+ ];
33
+ const STOP_WORDS = new Set([
34
+ "a", "an", "and", "are", "as", "at", "be", "by", "can", "do", "does", "for", "from", "how", "i", "if",
35
+ "in", "is", "it", "me", "my", "of", "on", "or", "should", "that", "the", "this", "to", "what", "when",
36
+ "where", "which", "who", "why", "with", "you", "your",
37
+ ]);
38
+ const EXCERPT_CHARS = 240;
39
+ export function findGuideKnowledge(id) {
40
+ const key = id.trim().toLowerCase();
41
+ return GUIDE_KNOWLEDGE_TOPICS.find((topic) => topic.id === key);
42
+ }
43
+ function tokenize(text) {
44
+ return text
45
+ .toLowerCase()
46
+ .split(/[^a-z0-9_.-]+/)
47
+ .map((token) => token.replace(/^[.-]+|[.-]+$/g, ""))
48
+ .filter((token) => token.length >= 2 && !STOP_WORDS.has(token));
49
+ }
50
+ function countOccurrences(haystack, needle) {
51
+ let count = 0;
52
+ let index = haystack.indexOf(needle);
53
+ while (index !== -1) {
54
+ count += 1;
55
+ index = haystack.indexOf(needle, index + needle.length);
56
+ }
57
+ return count;
58
+ }
59
+ function scoreTopic(topic, tokens, phrase) {
60
+ const id = topic.id.toLowerCase();
61
+ const title = topic.title.toLowerCase();
62
+ const summary = topic.summary.toLowerCase();
63
+ const body = topic.body.toLowerCase();
64
+ let score = 0;
65
+ for (const token of tokens) {
66
+ if (id === token || id.split("_").includes(token))
67
+ score += 8;
68
+ score += 5 * Math.min(countOccurrences(title, token), 2);
69
+ score += 3 * Math.min(countOccurrences(summary, token), 3);
70
+ score += Math.min(countOccurrences(body, token), 6);
71
+ }
72
+ if (tokens.length > 1 && phrase.length > 0) {
73
+ if (title.includes(phrase) || summary.includes(phrase))
74
+ score += 6;
75
+ else if (body.includes(phrase))
76
+ score += 4;
77
+ }
78
+ return score;
79
+ }
80
+ function excerptFor(body, tokens) {
81
+ const lower = body.toLowerCase();
82
+ let at = -1;
83
+ for (const token of tokens) {
84
+ const index = lower.indexOf(token);
85
+ if (index !== -1 && (at === -1 || index < at))
86
+ at = index;
87
+ }
88
+ const start = Math.max(0, at === -1 ? 0 : at - EXCERPT_CHARS / 3);
89
+ let slice = body.slice(start, start + EXCERPT_CHARS);
90
+ if (start > 0)
91
+ slice = slice.replace(/^\S*\s/, "");
92
+ if (start + EXCERPT_CHARS < body.length)
93
+ slice = slice.replace(/\s\S*$/, "");
94
+ const text = slice.replace(/\s+/g, " ").trim();
95
+ return `${start > 0 ? "…" : ""}${text}${start + EXCERPT_CHARS < body.length ? "…" : ""}`;
96
+ }
97
+ export function searchGuideKnowledge(query, limit = 3) {
98
+ const tokens = [...new Set(tokenize(query))];
99
+ if (tokens.length === 0)
100
+ return [];
101
+ const phrase = tokens.join(" ");
102
+ const max = Math.max(1, Math.floor(limit));
103
+ return GUIDE_KNOWLEDGE_TOPICS
104
+ .map((topic, order) => ({ topic, order, score: scoreTopic(topic, tokens, phrase) }))
105
+ .filter((entry) => entry.score > 0)
106
+ .sort((a, b) => b.score - a.score || a.order - b.order)
107
+ .slice(0, max)
108
+ .map(({ topic, score }) => ({ topic, score, excerpt: excerptFor(topic.body, tokens) }));
109
+ }
@@ -0,0 +1,2 @@
1
+ import type { GuideKnowledgeTopic } from "../index.js";
2
+ export declare const agentsTopic: GuideKnowledgeTopic;
@@ -0,0 +1,58 @@
1
+ export const agentsTopic = {
2
+ id: "agents",
3
+ title: "Project agents: definition, tools, approvals, reach and limits",
4
+ summary: "Agent YAML fields, tool grants, ask-first approvals, memories, one inbound channel, schedule, web chat, limits, sub-agents, revisions, and the rules that an agent cannot grant beyond what it holds or edit itself.",
5
+ body: `# Project agents
6
+
7
+ An agent is one file, \`agents/<id>.agent.yaml\`. It is a configured assistant that talks over many turns. It is not the stage \`agent:\` field (that picks the Pi or Claude backend for stages).
8
+
9
+ Minimum: \`id\`, \`name\`, \`instructions\`. Unknown keys are rejected (\`agent.unknown_field\`).
10
+
11
+ ## Fields
12
+
13
+ - \`id\`: \`^[a-z][a-z0-9_]{0,63}$\`, must match the file name, fixed after create. Made from \`name\` when omitted. \`sessions\`, \`approvals\`, \`new\` are reserved.
14
+ - \`name\` (1–120), \`description\` (≤ 500), \`greeting\` (≤ 500, shown on web chat), \`instructions\` (the system prompt).
15
+ - \`enabled\`: default \`false\`. **A new agent is always created disabled**; enabling is a separate step (\`enable_agent\`) and its own revision. Enabling is refused while the file has issues.
16
+ - \`project_context\`: adds the project's \`AGENTS.md\` (or \`CLAUDE.md\`) to the prompt, first 20,000 characters.
17
+ - \`model\`: \`{ backend: pi|claude, id?, thinking: off|low|medium|high }\`. Only \`pi\` runs; \`claude\` saves with a warning and sessions fail. \`id\` defaults to the project default model.
18
+ - \`execution\`: \`trusted-local\` (default). \`sandbox\` is not installed yet; sessions fail.
19
+ - \`tools\`: \`builtin\` groups (\`read\` = read, grep, find, ls; \`write\` = write, edit; \`shell\` = bash), \`builtin_tools\` (single tools), \`mcp\` (\`{ server: [tool names] }\` or \`["*"]\`), \`skills\`, \`stageflow\` (\`{ groups, tools }\`), \`browser\` (stored, not wired to anything yet).
20
+ - \`approvals\`: \`ask_first\` (tool ids the agent holds: \`edit\`, \`bash\`, \`stageflow.<tool>\`, \`<server>.<tool>\`, \`agent:<id>\`), \`approvers.operators\` (default true), \`timeout_minutes\` (default 30), \`on_timeout\` (\`skip\` default, or \`deny\`). \`approvers.channel_ids\` is reserved and ignored; never set \`operators: false\`.
21
+ - \`sub_agents\` (agent ids, not itself) and \`sub_agent_depth\` (1–5, default 1).
22
+ - \`guardrails.block_patterns\`: regexes checked on the finished reply; a match fails the turn and the reply is not sent. Streaming is held back for agents with patterns.
23
+ - \`evals.groundedness\`, \`observability\` (\`capture: off|metadata|full\`, \`otlp\`).
24
+ - \`channel\`: \`{ connection_id, allow_from }\`. One connection per agent and one agent per connection (\`agent.channel_in_use\`). Empty \`allow_from\` lets nobody in; \`*\` lets anyone in. Entries: email, \`@domain\` (AgentMail), \`+E164\` phone (iMessage), Slack user id \`U…\`/\`W…\`, Telegram \`@username\`.
25
+ - \`memories\`: memory ids every session can use. Must already exist (\`agent.memory_unavailable\` blocks save and enable). Sub-agents do not inherit them.
26
+ - \`web_chat\`: \`{ enabled, slug, rate_limit_per_minute (1–120, default 10), max_message_chars (1–20000, default 4000) }\`. Agents created through console, API, CLI or MCP start with web chat on and a random slug; the link \`/chat/<slug>\` is the credential. It is live only while the agent is enabled.
27
+ - \`schedule\`: \`{ cron, timezone?, message? }\`. The first tick only stores the next run; a missed time fires once.
28
+ - \`limits\`: \`session_minutes\` (default 10), \`max_turns\` (default 40), \`cost_usd\` (default none), \`long_context\` (\`summarize\`/\`truncate\`), \`always_on\` (ignores time and turns; cost counts per 24 hours). Limits are checked when a turn starts, not during it.
29
+
30
+ ## Tools and the gate
31
+
32
+ Every tool call passes one gate: path guard (no writes to \`agents/*.agent.yaml\` or \`$STAGEFLOW_HOME\` through path arguments), then "is it granted", then "ask first". \`bash\` is **always** ask-first when granted and is not path-confined, so an agent with \`bash\` can still change agent files and Stageflow state (\`agent.shell_not_path_confined\` warning). MCP tools appear as \`<server>_<tool>\` with grant id \`<server>.<tool>\`; Stageflow tools as \`stageflow_<tool>\` with grant id \`stageflow.<tool>\`; sub-agents as \`agent_<id>\`.
33
+
34
+ Stageflow tool groups: \`discover\`, \`runs.read\`, \`runs.control\`, \`runs.cleanup\`, \`gates.read\`, \`triggers\`, \`agents.read\`, \`agents.manage\`, \`agents.cleanup\`, \`agents.converse\`, \`evals.read\`, \`evals.run\`, \`evals.write\`, \`evals.cleanup\`, \`pipelines.author\`, \`connections\`, \`connections.cleanup\`, \`memories\`, \`memories.cleanup\`. \`gates.decide\` and \`get_started\` are operator-only and cannot be granted (\`agent.stageflow_operator_only\`). Destructive tools have their own \`*.cleanup\` groups. The console turns on ask-first for every non-read tool when you tick a group.
35
+
36
+ ## Asking first
37
+
38
+ A call to an ask-first tool pauses the turn until a person decides in the Inbox, the session page, \`sf agents\` or MCP. One pending approval per session. An identical call approved once is not asked again in that session. Pending approvals do not survive a Host restart. Channels cannot approve.
39
+
40
+ ## Rules for agents that manage agents
41
+
42
+ - An agent cannot hand out more than it holds: \`create_agent\`, \`save_agent\`, \`restore_agent_revision\` and \`enable_agent\` called by an agent refuse any tool, MCP tool, MCP wildcard, skill or browser grant the caller does not hold, and refuse a definition that drops an ask-first the caller itself must obey.
43
+ - An agent cannot edit, restore or archive its own definition.
44
+ - An agent cannot decide approvals on its own sessions, and no agent can decide approvals at all.
45
+
46
+ ## Revisions and sessions
47
+
48
+ Every valid save is a revision with a source. A save based on an old revision is refused (\`agent.conflict\`). Identical saves are no-ops. Restore saves an old revision as the newest. Removing the file or \`archive_agent\` archives the agent (history kept). A session stays on the revision it started with; edits reach new sessions only.
49
+
50
+ ## Reach
51
+
52
+ Console only by default, plus web chat for agents created through tools. Inbound channels: AgentMail and iMessage (the Host keeps a stream open, no public URL needed), Slack and Telegram (webhook at \`/api/agent-inbound/<connection id>\`, needs an \`inboundSecret\` and a URL the provider can reach). WhatsApp is send-only. On a channel the system sends the reply; an unknown delivery outcome is never resent and fails the turn as \`agent.reply_undelivered\`.
53
+
54
+ ## Tools for agents
55
+
56
+ \`list_agents\`, \`get_agent\`, \`validate_agent\`, \`create_agent\` (always disabled), \`save_agent\`, \`enable_agent\`, \`disable_agent\`, \`restore_agent_revision\`, \`list_agent_revisions\`, \`diff_agent_revisions\`, \`archive_agent\`, \`agent_chat\`, \`get_agent_session\`, \`list_agent_sessions\`, \`stop_agent_session\`.
57
+ `,
58
+ };
@@ -0,0 +1,2 @@
1
+ import type { GuideKnowledgeTopic } from "../index.js";
2
+ export declare const bestPracticesTopic: GuideKnowledgeTopic;
@@ -0,0 +1,67 @@
1
+ export const bestPracticesTopic = {
2
+ id: "best_practices",
3
+ title: "Best practices for building on Stageflow",
4
+ summary: "Opinionated, product-specific advice: small stages with typed io, real verify checks, gates only where a person decides, run once before adding a trigger, evals before relying on a stage or agent, safe agent grants, cost limits.",
5
+ body: `# Best practices
6
+
7
+ Each point follows from how Stageflow behaves.
8
+
9
+ ## Designing pipelines
10
+
11
+ 1. **Start with one or two stages and run them.** Every stage is a fresh model session, so each extra stage costs time and money and adds a handoff. Split a stage only when a step has its own output, needs another model or tools, needs a person's decision, or needs its own check.
12
+ 2. **Make the output schema carry the handoff.** The next stage reads the parent's \`payload\` and \`summary\`, not the transcript. Put every fact the next stage needs into required fields of \`io.output.schema\`. Keep \`io.input.schema\` of the child a subset of the parent's output, or the pipeline will not load (\`pipeline.io_incompatible\`).
13
+ 3. **Make fields you branch on required.** A route \`if\` can only read required, non-array fields. Add an explicit field such as \`severity\` or \`needs_review: boolean\` rather than asking the model to decide successors.
14
+ 4. **Do not use \`on: [failed]\` to build a "failure path".** It does not launch a stage after a failure. Model the decision as a succeeded payload field and branch with \`if\`.
15
+ 5. **Name the payload in the prompt.** Tell the stage exactly which fields to put in \`payload\`, what to write as artifacts, and to call \`emit_stage_envelope\` once at the end.
16
+ 6. **Follow the Artifact contract for file handoff.** Durable files only via \`write_stage_artifact\`; list those returned paths on emit (emit rejects missing files). Prefer required \`payload\` fields for facts. Under a stage sandbox, the assignment lists each prior file's sandbox path under \`/workspace/grants/<stage>/…\` (that path is the file). Teach the consumer to read those paths or payload, never \`stages/…/artifacts\` host paths and never \`/workspace/work\` as handoff. Do not add after-phase \`verify\` \`type: artifact\` on every bare \`create_stage\` — only when an explicit basename needs hard proof.
17
+ 7. **Use the pipeline \`model\` default** so stages follow one setting. When adding stages with tools, pass the model explicitly or the Host default gets written into each stage file.
18
+ 8. **Clone chains for "do this for each item".** Gate the empty-list case before the emitter (an empty array fails the emitter), and set \`clone_cap\` to a real maximum.
19
+
20
+ ## Checks
21
+
22
+ 9. **Back up claims with after-phase \`verify\`.** A \`command\` check (tests, a linter, a script that checks the output) or an \`artifact\` with \`path\` and \`nonempty: true\` is evidence. A \`checklist\` is only the agent's word; pair it with a real check. Emit disk-truth already requires listed files to exist; after-phase artifact verify is optional extra proof, not a default on every stage.
23
+ 10. **Use \`on_verify_fail: repair\` only for repeatable work** (\`retry_safety: idempotent\`) with a small \`max_attempts\` such as 2 or 3. Use \`mode: manual\` for anything that publishes, pays, sends or deploys.
24
+ 11. **Make approvals binding.** \`gate_kinds\` alone lets the agent skip the question. Add \`verify: [{ type: gate, kind: confirm }]\` (or \`artifact_backed\`) so success cannot be emitted without an accepted answer.
25
+
26
+ ## People in the loop
27
+
28
+ 12. **Add a gate only where a person must decide** (approve a plan, confirm a send, choose between options). Every gate stops the run until someone answers, blocks CI unless \`--skip-gates\` (which fails instead), and makes the stage impossible to evaluate (\`EVAL_STAGE_NEEDS_INPUT\`).
29
+ 13. **Put side effects after the decision.** Put the send or publish stage after the gated stage, with \`replay_safe: false\` if a feedback loop could replay it.
30
+
31
+ ## Sending messages
32
+
33
+ 14. **One channel per stage.** Two providers means two stages. Write the message content in the stage before the send, so the send stage stays small.
34
+ 15. **Test the connection before the run** (\`test_connection\`) and check the recipient (\`validate_connection_target\`). Telegram, iMessage and WhatsApp have extra rules (start the bot first, text the line first, 24-hour window).
35
+ 16. **Never resend an unknown outcome.** If a send reports \`CHANNEL_SEND_OUTCOME_UNKNOWN\`, check with the recipient first.
36
+
37
+ ## Triggers
38
+
39
+ 17. **Create a catalog task and run the pipeline by hand once before adding a trigger.** Then add the trigger with that task. Schedules need a catalog task.
40
+ 18. **Start triggers disabled if the pipeline sends messages or costs a lot**, then enable after a manual fire works.
41
+ 19. **For event triggers in dynamic mode, shape the entry stage's input schema around the event's fields** (GitHub: \`action\`, \`number\`, \`title\`, \`url\`, \`author\`, \`repo\`, \`updatedAt\`; email: \`from\`, \`subject\`, \`date\`, \`text\`).
42
+
43
+ ## Agents
44
+
45
+ 20. **Grant the least.** Start with \`read\` tools and the specific Stageflow tools needed. \`bash\` is always ask-first and not path-confined; avoid it for agents that should stay confined.
46
+ 21. **Put risky tools in \`approvals.ask_first\`**, and keep \`approvers.operators: true\` (channel approvers are ignored, so turning operators off leaves nobody able to decide).
47
+ 22. **Set limits.** Keep \`max_turns\`, \`session_minutes\` and \`cost_usd\` for public web chat and channel agents. With \`always_on\`, \`cost_usd\` is per day.
48
+ 23. **Lock down reach.** Use a specific \`allow_from\` list, not \`*\`. Treat the web chat link as a password; rotate it with \`slug: ""\`. A web chat agent that can read agent sessions can read visitors' messages.
49
+ 24. **Enable last.** Agents are created disabled. Validate, try it in the console session page, then enable.
50
+
51
+ ## Memories
52
+
53
+ 25. **Write a clear description** (the session only sees id and description until it calls a tool), use stable card keys (email, ticket id), and keep cards under 64,000 characters and 200 per memory.
54
+
55
+ ## Evals
56
+
57
+ 26. **Add an eval before you rely on a stage or agent, and before changing its prompt, model or tools.** Start with deterministic graders (\`schema\`, \`field\`, \`tool_calls\`, \`conversation_check\`); add \`rubric\` or \`goal_reached\` for what rules cannot say.
58
+ 27. **At least 5 cases, \`repeats: 3\`.** Fewer cases give wide intervals; one repeat hides flakiness. Read reliability (pass on every repeat), not only pass rate.
59
+ 28. **Baseline first, change one thing per run, compare.** Use a judge model different from the target's model.
60
+ 29. **Keep agent evals on \`read_only\`.** Use \`tool_mocks\` for tools that would change things. Use \`real\` only on a throwaway copy of the project.
61
+ 30. **Keep \`max_cost_usd\` and \`concurrency\` low** (defaults 2 and 4 for stages, 1 and 2 for agents) until you know the cost per case.
62
+
63
+ ## Cost control in general
64
+
65
+ Pipelines have no run-level cost cap. Control cost with cheaper models for simple stages, fewer stages, small \`max_attempts\` for repair, \`timeout_ms\` on long stages, agent \`limits.cost_usd\`, and eval \`max_cost_usd\`.
66
+ `,
67
+ };
@@ -0,0 +1,2 @@
1
+ import type { GuideKnowledgeTopic } from "../index.js";
2
+ export declare const connectionsTopic: GuideKnowledgeTopic;