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.
- package/README.md +15 -4
- package/dist/agent/activity.d.ts +18 -0
- package/dist/agent/claudeAdapter.js +7 -0
- package/dist/agent/claudeTools.d.ts +27 -18
- package/dist/agent/claudeTools.js +54 -15
- package/dist/agent/compactionEvents.d.ts +34 -0
- package/dist/agent/compactionEvents.js +37 -0
- package/dist/agent/openRouterRouting.d.ts +7 -0
- package/dist/agent/openRouterRouting.js +23 -0
- package/dist/agent/piAdapter.d.ts +6 -0
- package/dist/agent/piAdapter.js +128 -27
- package/dist/agent/piSettings.d.ts +7 -0
- package/dist/agent/piSettings.js +9 -0
- package/dist/agent/sandboxPiTools.d.ts +3 -1
- package/dist/agent/sandboxPiTools.js +8 -2
- package/dist/agent/stageTurnDriver.d.ts +11 -2
- package/dist/agent/stageTurnDriver.js +45 -4
- package/dist/agent/toolOutputBudget.d.ts +15 -1
- package/dist/agent/toolOutputBudget.js +18 -0
- package/dist/agent/toolOutputBudgetExtension.d.ts +2 -0
- package/dist/agent/toolOutputBudgetExtension.js +40 -3
- package/dist/agents/authorChat.d.ts +5 -0
- package/dist/agents/authorChat.js +120 -12
- package/dist/agents/authorSessionStore.d.ts +38 -0
- package/dist/agents/authorSessionStore.js +167 -0
- package/dist/agents/chatTurn.d.ts +2 -0
- package/dist/agents/chatTurn.js +17 -1
- package/dist/agents/errors.d.ts +1 -1
- package/dist/agents/errors.js +1 -0
- package/dist/agents/evalGate.d.ts +61 -0
- package/dist/agents/evalGate.js +103 -0
- package/dist/agents/evalSession.d.ts +26 -0
- package/dist/agents/evalSession.js +29 -0
- package/dist/agents/hostContext.d.ts +4 -1
- package/dist/agents/hostContext.js +4 -1
- package/dist/agents/runtime/piRuntime.d.ts +6 -2
- package/dist/agents/runtime/piRuntime.js +50 -16
- package/dist/agents/runtime/types.d.ts +3 -1
- package/dist/agents/service.d.ts +27 -2
- package/dist/agents/service.js +91 -15
- package/dist/agents/sessions.d.ts +8 -0
- package/dist/agents/sessions.js +53 -11
- package/dist/agents/store.d.ts +14 -3
- package/dist/agents/store.js +45 -7
- package/dist/agents/toolRisk.d.ts +21 -0
- package/dist/agents/toolRisk.js +50 -0
- package/dist/cli/doctorCommand.js +26 -0
- package/dist/cli/evalCommand.d.ts +20 -0
- package/dist/cli/evalCommand.js +720 -0
- package/dist/cli/exportAllCommand.js +1 -1
- package/dist/cli/hostClient.d.ts +60 -0
- package/dist/cli/hostClient.js +71 -0
- package/dist/cli/validateOutput.d.ts +2 -2
- package/dist/cli/validateOutput.js +2 -2
- package/dist/cli.js +10 -0
- package/dist/compaction/directives.d.ts +18 -0
- package/dist/compaction/directives.js +119 -0
- package/dist/compaction/extension.d.ts +20 -0
- package/dist/compaction/extension.js +78 -0
- package/dist/compaction/mask.d.ts +18 -0
- package/dist/compaction/mask.js +155 -0
- package/dist/compaction/pin.d.ts +21 -0
- package/dist/compaction/pin.js +270 -0
- package/dist/compaction/scrub.d.ts +7 -0
- package/dist/compaction/scrub.js +26 -0
- package/dist/compaction/sessionWiring.d.ts +22 -0
- package/dist/compaction/sessionWiring.js +26 -0
- package/dist/compaction/summarize.d.ts +79 -0
- package/dist/compaction/summarize.js +171 -0
- package/dist/compaction/toolPolicy.d.ts +3 -0
- package/dist/compaction/toolPolicy.js +33 -0
- package/dist/compaction/types.d.ts +45 -0
- package/dist/compaction/types.js +7 -0
- package/dist/compaction/workingState.d.ts +56 -0
- package/dist/compaction/workingState.js +198 -0
- package/dist/config/atomicWrite.d.ts +15 -0
- package/dist/config/atomicWrite.js +43 -0
- package/dist/config/browseCatalog.d.ts +2 -0
- package/dist/config/browseCatalog.js +4 -2
- package/dist/config/createPipeline.js +2 -0
- package/dist/config/createTrigger.js +7 -1
- package/dist/config/csv.d.ts +9 -0
- package/dist/config/csv.js +81 -0
- package/dist/config/datasetAgentCheck.d.ts +18 -0
- package/dist/config/datasetAgentCheck.js +109 -0
- package/dist/config/datasetCandidates.d.ts +22 -0
- package/dist/config/datasetCandidates.js +86 -0
- package/dist/config/datasetFromSessions.d.ts +34 -0
- package/dist/config/datasetFromSessions.js +105 -0
- package/dist/config/datasetHash.d.ts +1 -0
- package/dist/config/datasetHash.js +4 -0
- package/dist/config/datasetImport.d.ts +21 -0
- package/dist/config/datasetImport.js +120 -0
- package/dist/config/datasetStageCheck.d.ts +9 -0
- package/dist/config/datasetStageCheck.js +17 -0
- package/dist/config/datasetTypes.d.ts +27 -0
- package/dist/config/datasetTypes.js +1 -0
- package/dist/config/ensureCatalogScanRoot.d.ts +4 -1
- package/dist/config/ensureCatalogScanRoot.js +8 -6
- package/dist/config/evalCatalog.d.ts +22 -0
- package/dist/config/evalCatalog.js +95 -0
- package/dist/config/evalWriteRoots.d.ts +17 -0
- package/dist/config/evalWriteRoots.js +109 -0
- package/dist/config/githubTriggerAction.d.ts +8 -0
- package/dist/config/githubTriggerAction.js +29 -0
- package/dist/config/hostConfig.js +3 -0
- package/dist/config/installEvalSample.d.ts +34 -0
- package/dist/config/installEvalSample.js +182 -0
- package/dist/config/loadDataset.d.ts +16 -0
- package/dist/config/loadDataset.js +318 -0
- package/dist/config/loadEval.d.ts +32 -0
- package/dist/config/loadEval.js +1103 -0
- package/dist/config/loadOutcome.d.ts +5 -0
- package/dist/config/loadStageflowManifest.js +64 -0
- package/dist/config/pipelineNeeds.d.ts +2 -0
- package/dist/config/pipelineNeeds.js +16 -3
- package/dist/config/pipelineRoute.js +5 -4
- package/dist/config/resolveAgentTarget.d.ts +32 -0
- package/dist/config/resolveAgentTarget.js +118 -0
- package/dist/config/resolveEvalTarget.d.ts +21 -0
- package/dist/config/resolveEvalTarget.js +89 -0
- package/dist/config/scanCatalogPaths.d.ts +1 -1
- package/dist/config/scanCatalogPaths.js +17 -5
- package/dist/config/validateCatalog.d.ts +2 -2
- package/dist/config/validateCatalog.js +21 -1
- package/dist/config/validateEval.d.ts +36 -0
- package/dist/config/validateEval.js +446 -0
- package/dist/config/writeDataset.d.ts +54 -0
- package/dist/config/writeDataset.js +186 -0
- package/dist/config/writeEval.d.ts +25 -0
- package/dist/config/writeEval.js +398 -0
- package/dist/diagnostics/checks.js +1 -1
- package/dist/envelope/assertEmittedArtifacts.d.ts +12 -0
- package/dist/envelope/assertEmittedArtifacts.js +43 -0
- package/dist/envelope/preEmitChecks.d.ts +3 -0
- package/dist/evals/agentDiff.d.ts +13 -0
- package/dist/evals/agentDiff.js +11 -0
- package/dist/evals/canonical.d.ts +3 -0
- package/dist/evals/canonical.js +24 -0
- package/dist/evals/caseTask.d.ts +3 -0
- package/dist/evals/caseTask.js +9 -0
- package/dist/evals/compare.d.ts +94 -0
- package/dist/evals/compare.js +201 -0
- package/dist/evals/constants.d.ts +62 -0
- package/dist/evals/constants.js +97 -0
- package/dist/evals/engine/FakeEngine.d.ts +33 -0
- package/dist/evals/engine/FakeEngine.js +177 -0
- package/dist/evals/engine/index.d.ts +9 -0
- package/dist/evals/engine/index.js +19 -0
- package/dist/evals/engine/promptfoo/PromptfooEngine.d.ts +52 -0
- package/dist/evals/engine/promptfoo/PromptfooEngine.js +312 -0
- package/dist/evals/engine/promptfoo/errors.d.ts +5 -0
- package/dist/evals/engine/promptfoo/errors.js +8 -0
- package/dist/evals/engine/promptfoo/generate.d.ts +30 -0
- package/dist/evals/engine/promptfoo/generate.js +345 -0
- package/dist/evals/engine/promptfoo/guard.d.ts +10 -0
- package/dist/evals/engine/promptfoo/guard.js +116 -0
- package/dist/evals/engine/promptfoo/install.d.ts +17 -0
- package/dist/evals/engine/promptfoo/install.js +73 -0
- package/dist/evals/engine/promptfoo/judgeProviders.d.ts +2 -0
- package/dist/evals/engine/promptfoo/judgeProviders.js +9 -0
- package/dist/evals/engine/promptfoo/judgeServices.d.ts +6 -0
- package/dist/evals/engine/promptfoo/judgeServices.js +41 -0
- package/dist/evals/engine/promptfoo/locate.d.ts +21 -0
- package/dist/evals/engine/promptfoo/locate.js +68 -0
- package/dist/evals/engine/promptfoo/nodeVersion.d.ts +7 -0
- package/dist/evals/engine/promptfoo/nodeVersion.js +14 -0
- package/dist/evals/engine/promptfoo/normalize.d.ts +66 -0
- package/dist/evals/engine/promptfoo/normalize.js +261 -0
- package/dist/evals/engine/promptfoo/pinned.d.ts +5 -0
- package/dist/evals/engine/promptfoo/pinned.js +5 -0
- package/dist/evals/engine/promptfoo/rubricPrompt.d.ts +14 -0
- package/dist/evals/engine/promptfoo/rubricPrompt.js +105 -0
- package/dist/evals/engine/promptfoo/runTokens.d.ts +18 -0
- package/dist/evals/engine/promptfoo/runTokens.js +31 -0
- package/dist/evals/engine/promptfoo/status.d.ts +13 -0
- package/dist/evals/engine/promptfoo/status.js +16 -0
- package/dist/evals/estimate.d.ts +56 -0
- package/dist/evals/estimate.js +66 -0
- package/dist/evals/graders/codeGrader.d.ts +6 -0
- package/dist/evals/graders/codeGrader.js +85 -0
- package/dist/evals/graders/conversationCheckGrader.d.ts +6 -0
- package/dist/evals/graders/conversationCheckGrader.js +62 -0
- package/dist/evals/graders/fieldGrader.d.ts +11 -0
- package/dist/evals/graders/fieldGrader.js +117 -0
- package/dist/evals/graders/goal.d.ts +3 -0
- package/dist/evals/graders/goal.js +14 -0
- package/dist/evals/graders/index.d.ts +18 -0
- package/dist/evals/graders/index.js +34 -0
- package/dist/evals/graders/notApplicable.d.ts +5 -0
- package/dist/evals/graders/notApplicable.js +9 -0
- package/dist/evals/graders/path.d.ts +26 -0
- package/dist/evals/graders/path.js +75 -0
- package/dist/evals/graders/referenceGrader.d.ts +5 -0
- package/dist/evals/graders/referenceGrader.js +59 -0
- package/dist/evals/graders/schemaGrader.d.ts +5 -0
- package/dist/evals/graders/schemaGrader.js +29 -0
- package/dist/evals/graders/subject.d.ts +6 -0
- package/dist/evals/graders/subject.js +33 -0
- package/dist/evals/graders/toolCallsGrader.d.ts +6 -0
- package/dist/evals/graders/toolCallsGrader.js +100 -0
- package/dist/evals/graders/transcript.d.ts +12 -0
- package/dist/evals/graders/transcript.js +57 -0
- package/dist/evals/graders/types.d.ts +20 -0
- package/dist/evals/graders/types.js +1 -0
- package/dist/evals/judgeProviders.d.ts +16 -0
- package/dist/evals/judgeProviders.js +27 -0
- package/dist/evals/lineDiff.d.ts +5 -0
- package/dist/evals/lineDiff.js +34 -0
- package/dist/evals/listStatus.d.ts +31 -0
- package/dist/evals/listStatus.js +48 -0
- package/dist/evals/manager.d.ts +187 -0
- package/dist/evals/manager.js +795 -0
- package/dist/evals/plan.d.ts +65 -0
- package/dist/evals/plan.js +621 -0
- package/dist/evals/planInternalAgent.d.ts +19 -0
- package/dist/evals/planInternalAgent.js +205 -0
- package/dist/evals/providerKeys.d.ts +1 -0
- package/dist/evals/providerKeys.js +21 -0
- package/dist/evals/read/agentTargets.d.ts +37 -0
- package/dist/evals/read/agentTargets.js +101 -0
- package/dist/evals/read/api.d.ts +208 -0
- package/dist/evals/read/api.js +363 -0
- package/dist/evals/read/compare.d.ts +4 -0
- package/dist/evals/read/compare.js +39 -0
- package/dist/evals/read/datasets.d.ts +105 -0
- package/dist/evals/read/datasets.js +318 -0
- package/dist/evals/read/list.d.ts +66 -0
- package/dist/evals/read/list.js +182 -0
- package/dist/evals/read/results.d.ts +46 -0
- package/dist/evals/read/results.js +107 -0
- package/dist/evals/read/runs.d.ts +154 -0
- package/dist/evals/read/runs.js +295 -0
- package/dist/evals/read/suggestions.d.ts +43 -0
- package/dist/evals/read/suggestions.js +73 -0
- package/dist/evals/runner/FakeAgentBackend.d.ts +40 -0
- package/dist/evals/runner/FakeAgentBackend.js +82 -0
- package/dist/evals/runner/agentCaseRunner.d.ts +24 -0
- package/dist/evals/runner/agentCaseRunner.js +388 -0
- package/dist/evals/runner/caseRunner.d.ts +8 -0
- package/dist/evals/runner/caseRunner.js +28 -0
- package/dist/evals/runner/conversationSubject.d.ts +18 -0
- package/dist/evals/runner/conversationSubject.js +123 -0
- package/dist/evals/runner/internalAgentCaseRunner.d.ts +6 -0
- package/dist/evals/runner/internalAgentCaseRunner.js +250 -0
- package/dist/evals/runner/simulatorModel.d.ts +51 -0
- package/dist/evals/runner/simulatorModel.js +58 -0
- package/dist/evals/runner/simulatorPrompt.d.ts +29 -0
- package/dist/evals/runner/simulatorPrompt.js +59 -0
- package/dist/evals/runner/stageCaseRunner.d.ts +30 -0
- package/dist/evals/runner/stageCaseRunner.js +279 -0
- package/dist/evals/runner/userDriver.d.ts +71 -0
- package/dist/evals/runner/userDriver.js +104 -0
- package/dist/evals/scoring.d.ts +34 -0
- package/dist/evals/scoring.js +67 -0
- package/dist/evals/snapshot.d.ts +191 -0
- package/dist/evals/snapshot.js +70 -0
- package/dist/evals/stageDiff.d.ts +8 -0
- package/dist/evals/stageDiff.js +48 -0
- package/dist/evals/stats.d.ts +95 -0
- package/dist/evals/stats.js +220 -0
- package/dist/evals/statsAdapter.d.ts +4 -0
- package/dist/evals/statsAdapter.js +30 -0
- package/dist/evals/statsTypes.d.ts +51 -0
- package/dist/evals/statsTypes.js +18 -0
- package/dist/evals/storeError.d.ts +5 -0
- package/dist/evals/storeError.js +8 -0
- package/dist/evals/storeTypes.d.ts +207 -0
- package/dist/evals/storeTypes.js +1 -0
- package/dist/evals/tTable.d.ts +3 -0
- package/dist/evals/tTable.js +15 -0
- package/dist/evals/triage/constants.d.ts +26 -0
- package/dist/evals/triage/constants.js +33 -0
- package/dist/evals/triage/credentials.d.ts +13 -0
- package/dist/evals/triage/credentials.js +20 -0
- package/dist/evals/triage/jevClassifier.d.ts +14 -0
- package/dist/evals/triage/jevClassifier.js +124 -0
- package/dist/evals/triage/judgeClassifier.d.ts +10 -0
- package/dist/evals/triage/judgeClassifier.js +76 -0
- package/dist/evals/triage/prompts.d.ts +16 -0
- package/dist/evals/triage/prompts.js +64 -0
- package/dist/evals/triage/service.d.ts +79 -0
- package/dist/evals/triage/service.js +217 -0
- package/dist/evals/triage/stateBuilder.d.ts +19 -0
- package/dist/evals/triage/stateBuilder.js +125 -0
- package/dist/evals/triage/types.d.ts +60 -0
- package/dist/evals/triage/types.js +8 -0
- package/dist/evals/types.d.ts +357 -0
- package/dist/evals/types.js +4 -0
- package/dist/guide/cardContract.d.ts +133 -0
- package/dist/guide/cardContract.js +156 -0
- package/dist/guide/chat.d.ts +45 -0
- package/dist/guide/chat.js +378 -0
- package/dist/guide/knowledge/index.d.ts +14 -0
- package/dist/guide/knowledge/index.js +109 -0
- package/dist/guide/knowledge/topics/agents.d.ts +2 -0
- package/dist/guide/knowledge/topics/agents.js +58 -0
- package/dist/guide/knowledge/topics/bestPractices.d.ts +2 -0
- package/dist/guide/knowledge/topics/bestPractices.js +67 -0
- package/dist/guide/knowledge/topics/connections.d.ts +2 -0
- package/dist/guide/knowledge/topics/connections.js +66 -0
- package/dist/guide/knowledge/topics/consoleMap.d.ts +2 -0
- package/dist/guide/knowledge/topics/consoleMap.js +55 -0
- package/dist/guide/knowledge/topics/evals.d.ts +2 -0
- package/dist/guide/knowledge/topics/evals.js +72 -0
- package/dist/guide/knowledge/topics/limitations.d.ts +2 -0
- package/dist/guide/knowledge/topics/limitations.js +84 -0
- package/dist/guide/knowledge/topics/mcpSkillsBrowser.d.ts +2 -0
- package/dist/guide/knowledge/topics/mcpSkillsBrowser.js +57 -0
- package/dist/guide/knowledge/topics/memories.d.ts +2 -0
- package/dist/guide/knowledge/topics/memories.js +63 -0
- package/dist/guide/knowledge/topics/modelsAndProviders.d.ts +2 -0
- package/dist/guide/knowledge/topics/modelsAndProviders.js +56 -0
- package/dist/guide/knowledge/topics/overview.d.ts +2 -0
- package/dist/guide/knowledge/topics/overview.js +56 -0
- package/dist/guide/knowledge/topics/pipelines.d.ts +2 -0
- package/dist/guide/knowledge/topics/pipelines.js +93 -0
- package/dist/guide/knowledge/topics/stages.d.ts +2 -0
- package/dist/guide/knowledge/topics/stages.js +54 -0
- package/dist/guide/knowledge/topics/tasks.d.ts +2 -0
- package/dist/guide/knowledge/topics/tasks.js +52 -0
- package/dist/guide/knowledge/topics/triggers.d.ts +2 -0
- package/dist/guide/knowledge/topics/triggers.js +68 -0
- package/dist/guide/knowledge/topics/troubleshooting.d.ts +2 -0
- package/dist/guide/knowledge/topics/troubleshooting.js +85 -0
- package/dist/guide/knowledgeTools.d.ts +2 -0
- package/dist/guide/knowledgeTools.js +56 -0
- package/dist/guide/showUi.d.ts +6 -0
- package/dist/guide/showUi.js +546 -0
- package/dist/guide/threadStore.d.ts +48 -0
- package/dist/guide/threadStore.js +189 -0
- package/dist/guide/writeRoot.d.ts +11 -0
- package/dist/guide/writeRoot.js +70 -0
- package/dist/hosted/translate.js +2 -0
- package/dist/mcp/agentTools.js +12 -0
- package/dist/mcp/catalogTools.js +18 -20
- package/dist/mcp/catalogWriteTools.d.ts +8 -0
- package/dist/mcp/catalogWriteTools.js +225 -0
- package/dist/mcp/connectionTools.d.ts +3 -0
- package/dist/mcp/connectionTools.js +85 -0
- package/dist/mcp/controlTools.js +34 -1
- package/dist/mcp/deps.d.ts +16 -0
- package/dist/mcp/evalTools.d.ts +3 -0
- package/dist/mcp/evalTools.js +943 -0
- package/dist/mcp/memoryHostTools.d.ts +3 -0
- package/dist/mcp/memoryHostTools.js +72 -0
- package/dist/mcp/pipelineAuthorTools.js +14 -1
- package/dist/mcp/server.js +6 -0
- package/dist/mcp/tools.js +8 -0
- package/dist/mcp/triggerTools.js +77 -31
- package/dist/models/response.d.ts +7 -2
- package/dist/models/response.js +6 -1
- package/dist/operatorAgent/agentAuthorContext.d.ts +1 -1
- package/dist/operatorAgent/agentAuthorContext.js +1 -1
- package/dist/operatorAgent/evalGate.d.ts +22 -0
- package/dist/operatorAgent/evalGate.js +77 -0
- package/dist/operatorAgent/fakeHost.js +10 -2
- package/dist/operatorAgent/host.js +18 -2
- package/dist/operatorAgent/index.d.ts +1 -0
- package/dist/operatorAgent/index.js +1 -0
- package/dist/operatorAgent/internalAgents.d.ts +11 -0
- package/dist/operatorAgent/internalAgents.js +13 -0
- package/dist/operatorAgent/piModel.d.ts +5 -1
- package/dist/operatorAgent/piModel.js +32 -14
- package/dist/operatorAgent/profiles/agentAuthor.d.ts +3 -1
- package/dist/operatorAgent/profiles/agentAuthor.js +201 -32
- package/dist/operatorAgent/profiles/agentAuthorPlaybook.d.ts +1 -1
- package/dist/operatorAgent/profiles/agentAuthorPlaybook.js +48 -15
- package/dist/operatorAgent/profiles/authorReadable.d.ts +2 -0
- package/dist/operatorAgent/profiles/authorReadable.js +26 -0
- package/dist/operatorAgent/profiles/guideConfirm.d.ts +21 -0
- package/dist/operatorAgent/profiles/guideConfirm.js +100 -0
- package/dist/operatorAgent/profiles/guideTools.d.ts +7 -0
- package/dist/operatorAgent/profiles/guideTools.js +123 -0
- package/dist/operatorAgent/profiles/stageflowGuide.d.ts +7 -0
- package/dist/operatorAgent/profiles/stageflowGuide.js +132 -0
- package/dist/operatorAgent/profiles/workshopAuthor.js +23 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +1 -1
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +9 -1
- package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +2 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.js +197 -9
- package/dist/operatorAgent/types.d.ts +23 -0
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/runstore/port.d.ts +43 -0
- package/dist/runstore/retention.d.ts +2 -1
- package/dist/runstore/retention.js +3 -7
- package/dist/runstore/runStatusClock.d.ts +17 -0
- package/dist/runstore/runStatusClock.js +19 -0
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +29 -0
- package/dist/runstore/sqlite/SqliteRunStore.js +144 -50
- package/dist/runstore/sqlite/evalStore.d.ts +20 -0
- package/dist/runstore/sqlite/evalStore.js +541 -0
- package/dist/runstore/sqlite/migrations/015-evals.d.ts +12 -0
- package/dist/runstore/sqlite/migrations/015-evals.js +157 -0
- package/dist/runstore/sqlite/migrations/016-eval-subject-ref.d.ts +12 -0
- package/dist/runstore/sqlite/migrations/016-eval-subject-ref.js +20 -0
- package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.d.ts +11 -0
- package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.js +36 -0
- package/dist/runstore/sqlite/migrations/index.js +6 -0
- package/dist/runstore/sqlite/suggestionStore.d.ts +14 -0
- package/dist/runstore/sqlite/suggestionStore.js +132 -0
- package/dist/runstore/workspaceLayout.js +6 -1
- package/dist/runtime/artifactDiskInspect.d.ts +14 -0
- package/dist/runtime/artifactDiskInspect.js +52 -0
- package/dist/runtime/artifactPath.d.ts +24 -0
- package/dist/runtime/artifactPath.js +84 -0
- package/dist/runtime/completionCheckRunner.js +15 -43
- package/dist/runtime/githubPollSource.d.ts +22 -4
- package/dist/runtime/githubPollSource.js +93 -8
- package/dist/runtime/pipelineRunner.d.ts +2 -1
- package/dist/runtime/pipelineRunner.js +2 -0
- package/dist/runtime/priorArtifactGrants.d.ts +8 -0
- package/dist/runtime/priorArtifactGrants.js +105 -0
- package/dist/runtime/runActionEligibility.d.ts +46 -0
- package/dist/runtime/runActionEligibility.js +123 -0
- package/dist/runtime/runManager.d.ts +6 -2
- package/dist/runtime/runManager.js +60 -16
- package/dist/runtime/runRetentionSweep.js +2 -2
- package/dist/runtime/runRetryCoordinator.d.ts +2 -14
- package/dist/runtime/runRetryCoordinator.js +3 -67
- package/dist/runtime/sandboxContainer.d.ts +7 -0
- package/dist/runtime/sandboxContainer.js +48 -6
- package/dist/runtime/sandboxDesk.d.ts +2 -1
- package/dist/runtime/sandboxDesk.js +11 -12
- package/dist/runtime/stageEnvironment.js +1 -0
- package/dist/runtime/stageRoots.d.ts +12 -0
- package/dist/runtime/stageSandbox.d.ts +2 -1
- package/dist/runtime/stageSandbox.js +18 -2
- package/dist/runtime/stageWorker.js +20 -0
- package/dist/server/agentAuthorRoutes.js +59 -1
- package/dist/server/bootstrap.d.ts +13 -0
- package/dist/server/bootstrap.js +69 -0
- package/dist/server/controlToken.js +3 -0
- package/dist/server/evalInternalRoutes.d.ts +14 -0
- package/dist/server/evalInternalRoutes.js +87 -0
- package/dist/server/evalRouteContext.d.ts +46 -0
- package/dist/server/evalRouteContext.js +43 -0
- package/dist/server/evalRoutes.d.ts +5 -0
- package/dist/server/evalRoutes.js +1456 -0
- package/dist/server/evalTriageRoutes.d.ts +2 -0
- package/dist/server/evalTriageRoutes.js +95 -0
- package/dist/server/guideRoutes.d.ts +5 -0
- package/dist/server/guideRoutes.js +166 -0
- package/dist/server/http.d.ts +15 -0
- package/dist/server/http.js +67 -3
- package/dist/server/internalAgentRoutes.d.ts +6 -0
- package/dist/server/internalAgentRoutes.js +12 -0
- package/dist/server/mcpHost.js +5 -0
- package/dist/toolkit/meta.d.ts +1 -1
- package/dist/toolkit/meta.js +53 -0
- package/dist/toolkit/profiles.d.ts +5 -0
- package/dist/toolkit/profiles.js +13 -1
- package/dist/tools/askOperator.js +2 -1
- package/dist/tools/emitStageEnvelope.d.ts +17 -16
- package/dist/tools/emitStageEnvelope.js +46 -32
- package/dist/tools/stageToolNames.d.ts +4 -0
- package/dist/tools/stageToolNames.js +4 -0
- package/dist/tools/workingState.d.ts +40 -0
- package/dist/tools/workingState.js +108 -0
- package/dist/tools/writeStageArtifact.d.ts +0 -9
- package/dist/tools/writeStageArtifact.js +2 -1
- package/dist/types/stageflowManifest.d.ts +6 -0
- package/dist/ui/assets/{MarkdownText-D7tYaIFO.js → MarkdownText-S5C_vemc.js} +2 -2
- package/dist/ui/assets/adapters-C0l4ruiR.js +17 -0
- package/dist/ui/assets/chat-CjnsmvqR.js +2 -0
- package/dist/ui/assets/chat-DFDd4UjS.css +2 -0
- package/dist/ui/assets/{main-BFo79krC.css → main-Del1GeLf.css} +1 -1
- package/dist/ui/assets/main-_yXVqcW9.js +277 -0
- package/dist/ui/chat.html +3 -4
- package/dist/ui/index.html +3 -4
- package/dist/workshop/chatTurn.js +1 -1
- package/dist/workshop/workshopPin.d.ts +3 -3
- package/dist/workshop/workshopPin.js +16 -15
- package/examples/README.md +2 -0
- package/examples/compaction-stress/README.md +30 -0
- package/examples/compaction-stress/check-run.mjs +53 -0
- package/examples/compaction-stress/collect-evidence.yaml +60 -0
- package/examples/compaction-stress/compaction-stress.pipeline.yaml +141 -0
- package/examples/compaction-stress/compaction-stress.task.yaml +15 -0
- package/examples/compaction-stress/generate-evidence.mjs +110 -0
- package/examples/compaction-stress/root-cause.yaml +26 -0
- package/examples/compaction-stress/stageflow.yaml +9 -0
- package/examples/compaction-stress/write-postmortem.yaml +40 -0
- package/examples/document-policy-review/README.md +35 -0
- package/examples/document-policy-review/agents/compliance.agent.yaml +42 -0
- package/examples/document-policy-review/documents/acme-vendor-sow.md +15 -0
- package/examples/document-policy-review/documents/support-runbook.md +13 -0
- package/examples/document-policy-review/policies/acceptable-use.md +13 -0
- package/examples/document-policy-review/policies/data-handling.md +17 -0
- package/examples/document-policy-review/policies/vendor-security.md +17 -0
- package/examples/evals/README.md +141 -0
- package/examples/evals/critique-sample.dataset.jsonl +8 -0
- package/examples/evals/critique-sample.eval.yaml +34 -0
- package/examples/evals/critique-sample.task.yaml +4 -0
- package/examples/evals/eval-sample.pipeline.yaml +35 -0
- package/examples/evals/guide-behavior.dataset.jsonl +15 -0
- package/examples/evals/guide-behavior.eval.yaml +35 -0
- package/examples/evals/guide-depth.dataset.jsonl +35 -0
- package/examples/evals/guide-depth.eval.yaml +169 -0
- package/examples/evals/support-sample.agent.yaml +20 -0
- package/examples/evals/support-sample.dataset.jsonl +6 -0
- package/examples/evals/support-sample.eval.yaml +38 -0
- package/examples/memory/evals/guide-behavior.dataset.jsonl +15 -0
- package/examples/memory/evals/guide-behavior.eval.yaml +35 -0
- package/examples/memory/evals/guide-depth.dataset.jsonl +35 -0
- package/examples/memory/evals/guide-depth.eval.yaml +169 -0
- package/examples/stageflow.yaml +6 -0
- package/package.json +1 -1
- package/skills/stageflow/SKILL.md +5 -2
- package/skills/stageflow/references/control-surface.md +4 -2
- package/skills/stageflow/references/evals.md +68 -0
- package/skills/stageflow-author/SKILL.md +4 -0
- package/skills/stageflow-run/SKILL.md +4 -0
- package/dist/ui/assets/AssistantRuntimeProvider-CsiPFhCT.js +0 -9
- package/dist/ui/assets/ReadonlyStore-BfXqHykm.js +0 -6
- package/dist/ui/assets/chat-BbLukq9W.js +0 -5
- package/dist/ui/assets/chat-zIZU_bP1.css +0 -2
- 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,
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
47
|
-
shape: "
|
|
43
|
+
hostPath: grant.hostPath,
|
|
44
|
+
containerPath: grant.containerPath,
|
|
45
|
+
shape: grant.kind === "directory" ? "directory" : "file",
|
|
48
46
|
copyIn: true,
|
|
49
|
-
copyOut:
|
|
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,
|
|
@@ -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;
|