stageflow 0.42.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 +12 -3
- 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 +1 -0
- package/dist/agents/authorChat.js +7 -0
- package/dist/agents/authorSessionStore.d.ts +3 -0
- package/dist/agents/authorSessionStore.js +17 -2
- package/dist/agents/hostContext.d.ts +1 -1
- package/dist/agents/runtime/piRuntime.d.ts +5 -1
- package/dist/agents/runtime/piRuntime.js +46 -12
- package/dist/agents/service.js +3 -2
- package/dist/agents/sessions.js +3 -1
- 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/createPipeline.js +2 -0
- package/dist/config/createTrigger.js +7 -1
- package/dist/config/ensureCatalogScanRoot.d.ts +2 -0
- package/dist/config/ensureCatalogScanRoot.js +6 -0
- package/dist/config/evalCatalog.js +30 -2
- package/dist/config/githubTriggerAction.d.ts +8 -0
- package/dist/config/githubTriggerAction.js +29 -0
- package/dist/config/hostConfig.js +2 -0
- package/dist/config/loadEval.js +21 -3
- 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/validateCatalog.d.ts +1 -1
- package/dist/config/validateCatalog.js +12 -0
- package/dist/config/validateEval.js +43 -2
- package/dist/config/writeEval.js +2 -2
- 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/constants.d.ts +3 -1
- package/dist/evals/constants.js +3 -1
- package/dist/evals/engine/FakeEngine.d.ts +1 -1
- package/dist/evals/engine/FakeEngine.js +2 -1
- package/dist/evals/engine/promptfoo/PromptfooEngine.d.ts +1 -1
- package/dist/evals/engine/promptfoo/PromptfooEngine.js +2 -1
- package/dist/evals/engine/promptfoo/generate.d.ts +1 -1
- package/dist/evals/engine/promptfoo/generate.js +11 -8
- package/dist/evals/engine/promptfoo/rubricPrompt.d.ts +1 -1
- package/dist/evals/engine/promptfoo/rubricPrompt.js +5 -3
- package/dist/evals/manager.d.ts +13 -0
- package/dist/evals/manager.js +10 -2
- package/dist/evals/plan.d.ts +8 -1
- package/dist/evals/plan.js +28 -9
- package/dist/evals/planInternalAgent.d.ts +19 -0
- package/dist/evals/planInternalAgent.js +205 -0
- package/dist/evals/read/api.d.ts +12 -0
- package/dist/evals/read/api.js +5 -0
- package/dist/evals/read/list.js +10 -1
- package/dist/evals/read/runs.d.ts +5 -0
- package/dist/evals/read/runs.js +7 -1
- package/dist/evals/runner/caseRunner.d.ts +2 -1
- package/dist/evals/runner/caseRunner.js +16 -5
- package/dist/evals/runner/internalAgentCaseRunner.d.ts +6 -0
- package/dist/evals/runner/internalAgentCaseRunner.js +250 -0
- package/dist/evals/snapshot.d.ts +10 -2
- package/dist/evals/snapshot.js +8 -3
- package/dist/evals/types.d.ts +12 -2
- package/dist/evals/types.js +4 -1
- 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 +9 -0
- package/dist/mcp/evalTools.js +684 -21
- 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 +5 -0
- package/dist/mcp/tools.js +6 -0
- package/dist/mcp/triggerTools.js +77 -31
- 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 +15 -10
- package/dist/operatorAgent/profiles/agentAuthor.js +66 -22
- package/dist/operatorAgent/profiles/agentAuthorPlaybook.d.ts +1 -1
- package/dist/operatorAgent/profiles/agentAuthorPlaybook.js +1 -1
- 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/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 +1 -0
- package/dist/runstore/sqlite/SqliteRunStore.js +45 -45
- 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/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 +4 -1
- package/dist/runtime/runManager.js +52 -10
- 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 +12 -3
- package/dist/server/bootstrap.d.ts +5 -0
- package/dist/server/bootstrap.js +14 -1
- package/dist/server/evalRoutes.js +38 -9
- package/dist/server/guideRoutes.d.ts +5 -0
- package/dist/server/guideRoutes.js +166 -0
- package/dist/server/http.d.ts +10 -0
- package/dist/server/http.js +35 -1
- package/dist/server/internalAgentRoutes.d.ts +6 -0
- package/dist/server/internalAgentRoutes.js +12 -0
- package/dist/server/mcpHost.js +2 -0
- package/dist/toolkit/meta.d.ts +1 -1
- package/dist/toolkit/meta.js +39 -1
- package/dist/toolkit/profiles.d.ts +5 -0
- package/dist/toolkit/profiles.js +12 -0
- 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/ui/assets/{MarkdownText-BTrOqu5J.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-CHlmTNJe.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/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/evals/README.md +18 -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/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/package.json +1 -1
- package/dist/ui/assets/AssistantRuntimeProvider-qIX1xNoH.js +0 -9
- package/dist/ui/assets/ReadonlyStore-BfXqHykm.js +0 -6
- package/dist/ui/assets/chat-Df_wCpak.js +0 -5
- package/dist/ui/assets/chat-P7KQznHm.css +0 -2
- package/dist/ui/assets/main-CvVfxmMd.js +0 -271
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export const pipelinesTopic = {
|
|
2
|
+
id: "pipelines",
|
|
3
|
+
title: "Pipelines: wiring, contracts, checks, gates and envelopes",
|
|
4
|
+
summary: "Pipeline YAML, route/entry wiring and DAG rules, io schemas between stages, verify and on_verify_fail, feedback loops, clone chains, HITL gates, envelopes and artifacts, and validation.",
|
|
5
|
+
body: `# Pipelines
|
|
6
|
+
|
|
7
|
+
A pipeline file is \`<id>.pipeline.yaml\`. Required: \`id\` (should match the file name) and \`stages\` (a non-empty list of objects). Optional top level: \`model\` (default model for stages), \`agent\` (backend: \`pi\` or Claude), \`schemas\` (named JSON Schemas for \`$ref\`), \`browser\`, \`requires\` (tools on PATH), \`channels\` (default channel inherited by every stage), \`memories\` (memory ids every stage gets), \`include\` (merge stage lists from fragment files).
|
|
8
|
+
|
|
9
|
+
## Where Guide saves them
|
|
10
|
+
|
|
11
|
+
Every pipeline the Guide creates is \`pipelines/<id>/<id>.pipeline.yaml\`. Stage files for that pipeline (\`uses: ./<stage>.yaml\`) go in the same \`pipelines/<id>/\` folder. A folder the person names is input for a stage to read, not a place to write these files. The host writes them under \`pipelines/<id>\` even when a tool call passes another directory. Leave \`project_root\` unset. An existing pipeline is edited at the path already on disk.
|
|
12
|
+
|
|
13
|
+
## Stage entries
|
|
14
|
+
|
|
15
|
+
Each entry is either inline (\`system_prompt\`, \`io\`, …) or \`uses: ./stage.yaml\` (path relative to the pipeline file). On a \`uses:\` wrapper you may add only wiring (\`route\`, \`entry\`, \`on_verify_fail\`, \`replay_safe\`, and for a clone emitter \`clone_cap\`/\`clone_mode\`) plus \`mcp\`, \`secrets\`, \`requires\`, \`browser\`. Any other body key beside \`uses:\` fails (\`pipeline.stage_uses_inline_conflict\`). \`skill\` and \`channels\` are body-only.
|
|
16
|
+
|
|
17
|
+
## Wiring: \`route\` and \`entry\`
|
|
18
|
+
|
|
19
|
+
Wiring lives on the **source** stage. \`needs\`, \`fork\`, \`feedback_loop\` (top level), \`route_select\` and \`allow_none\` are rejected with a hard error. Do not write them.
|
|
20
|
+
|
|
21
|
+
\`\`\`yaml
|
|
22
|
+
stages:
|
|
23
|
+
- id: clarify
|
|
24
|
+
uses: ./clarify.yaml
|
|
25
|
+
entry: true
|
|
26
|
+
route:
|
|
27
|
+
- to: research
|
|
28
|
+
- to: validation
|
|
29
|
+
- id: research
|
|
30
|
+
uses: ./research.yaml
|
|
31
|
+
route:
|
|
32
|
+
- to: synthesize
|
|
33
|
+
- id: validation
|
|
34
|
+
uses: ./validation.yaml
|
|
35
|
+
route:
|
|
36
|
+
- to: synthesize
|
|
37
|
+
- id: synthesize
|
|
38
|
+
uses: ./synthesize.yaml
|
|
39
|
+
\`\`\`
|
|
40
|
+
|
|
41
|
+
- Mark at least one root \`entry: true\`.
|
|
42
|
+
- Several \`to:\` entries fan out; every listed target stays on the graph and runs after the source succeeds. The agent does not pick which ones run.
|
|
43
|
+
- \`if\` on a route entry skips that target unless a condition on the source's output payload holds. Leaf: \`{ field, op, value }\`; composition: \`all\`, \`any\`, \`not\`. Operators: \`eq\`, \`ne\`, \`gt\`, \`gte\`, \`lt\`, \`lte\`, \`in\`, \`not_in\`. The \`field\` path must be a **required** property in the source \`io.output.schema\` (no arrays, no optional fields). There is no \`exists\` operator and no else branch. Bad \`if\` is \`pipeline.route_if_invalid\`.
|
|
44
|
+
- \`on:\` (\`succeeded\`, \`failed\`, \`skipped\`) only stops skip-cascade. Write \`succeeded\`, not \`success\` (envelope status). It does **not** launch a stage after a failure. A child always needs a succeeded parent. For branching, use \`if\` on a succeeded payload.
|
|
45
|
+
- A stage with two or more parents is a **join**. It waits until every parent is finished, runs if at least one succeeded, stays pending (run fails) if any parent failed, and is skipped if all parents skipped. It receives every succeeded parent's envelope.
|
|
46
|
+
- Cycles and backward edges are \`pipeline.dag_error\`. Going back is only possible with a loop entry.
|
|
47
|
+
|
|
48
|
+
## Contracts: \`io\`
|
|
49
|
+
|
|
50
|
+
Every stage body must have \`io.input.schema\` and \`io.output.schema\` (both required; missing is \`stage.invalid_io\`). The root must be \`type: object\`. Supported: \`object\`, \`string\`, \`number\`, \`integer\`, \`boolean\`, \`array\`, with \`properties\`, \`required\`, \`items\`, \`additionalProperties\` (boolean), \`minItems\`, \`maxItems\`, \`enum\`, \`minimum\`, \`maximum\`, \`pattern\`, \`minLength\`, \`maxLength\`, \`nullable\` on nested nodes. On each edge the child's input schema must be a structural subset of the parent's output schema, or load fails with \`pipeline.io_incompatible\`. The entry stage's input is matched against the task's \`input\` (missing \`input\` counts as \`{}\`).
|
|
51
|
+
|
|
52
|
+
## Checks: \`verify\` and \`on_verify_fail\`
|
|
53
|
+
|
|
54
|
+
\`verify\` is one list on the stage body. Each item has \`id\`, \`type\`, and \`when\` (\`[emit]\`, \`[after]\` or both).
|
|
55
|
+
- Emit-phase (soft, in the same session; the agent can fix and retry): \`gate\` (the last \`ask_operator\` exchange of that kind this attempt must be accepted), \`artifact\` with \`basename\` (the name must be in the envelope's artifacts list).
|
|
56
|
+
- After-phase (Stageflow checks after the agent claims success): \`command\` (runs \`bash -c\`, needs exit 0), \`artifact\` with \`path\` and optional \`nonempty\`, \`checklist\` (agent attestation, not proof), \`payload_schema\`, \`checkout_changes\` (the checkout really changed), \`browser_login\`.
|
|
57
|
+
- Defaults: \`gate\` is emit; \`command\`, \`checklist\`, \`payload_schema\`, \`checkout_changes\` are after; \`artifact\` must set \`when\`.
|
|
58
|
+
|
|
59
|
+
\`on_verify_fail\` sits on the pipeline entry and needs at least one after-phase check:
|
|
60
|
+
- \`mode: repair\` with \`max_attempts\`, \`retry_safety: idempotent\`, \`include_failed_checks\` starts fresh attempts automatically.
|
|
61
|
+
- \`mode: manual\` with \`retry_safety\` leaves the stage failed until a person chooses Retry with guidance or Stop recovery. Use manual for anything with side effects (publishing, payments, sending).
|
|
62
|
+
|
|
63
|
+
## Feedback loops
|
|
64
|
+
|
|
65
|
+
A \`route\` entry \`{ type: loop, to, max_replays, on_max_replays, replay_session }\` lets a later stage send work back to an earlier ancestor. \`on_max_replays\` is \`require_continue\` or \`wait_for_human\` (a person decides extend / continue / abandon). \`replay_session\` is \`resume\` or \`new_session\`. One loop entry per stage, no \`if\` on it. Mark one-shot stages \`replay_safe: false\`; a loop whose path crosses one fails validation. The source must emit \`feedback_loop: { action: continue }\` or \`{ action: send_back, target }\` on success.
|
|
66
|
+
|
|
67
|
+
## Clone chain (one run per list item)
|
|
68
|
+
|
|
69
|
+
Emitter → clone child → join. The emitter's output has exactly one array property whose items are \`{ $ref: "#/schemas/<Name>" }\`; the child's whole input schema is that same \`$ref\`. The emitter entry needs \`clone_cap\` (≥ 1) and \`clone_mode\` (\`parallel\` or \`sequential\`). An empty array or more items than the cap fails the emitter's emit; gate the zero-item case earlier. Every clone must succeed for the join to run. \`clonable\`, \`clone_actions\` and \`clone_forks\` are rejected.
|
|
70
|
+
|
|
71
|
+
## Questions to a person (HITL)
|
|
72
|
+
|
|
73
|
+
A stage with a non-empty \`gate_kinds\` list (\`free_text\`, \`confirm\`, \`multi_question\`, \`artifact_backed\`) gets the \`ask_operator\` tool. Omitted or \`[]\` means no tool. The run waits until a person answers in the Inbox or the run page. To make the approval binding, add a \`verify\` item \`{ type: gate, kind: ... }\`; otherwise the agent could emit success without waiting.
|
|
74
|
+
|
|
75
|
+
## Envelopes and artifacts
|
|
76
|
+
|
|
77
|
+
A stage ends only when the agent calls \`emit_stage_envelope\` with \`status\` (\`success\`/\`failure\`), a non-empty \`summary\`, \`artifacts\` (list, may be empty) and \`payload\` (validated against \`io.output.schema\` on success). If the agent stops without emitting, Stageflow sends up to two reminders, then fails the stage (\`missing emit_stage_envelope\`). A \`failure\` envelope skip-cascades single-parent children.
|
|
78
|
+
|
|
79
|
+
### Artifact contract
|
|
80
|
+
|
|
81
|
+
Cross-stage **file** handoff is declared artifacts plus the envelope — not checkout edits and not \`work/\`.
|
|
82
|
+
|
|
83
|
+
1. **Durable writes only via \`write_stage_artifact\`.** The tool writes under the current attempt's artifacts directory and returns a run-relative path for the envelope list. Bash/\`cp\` into a sandbox desk path (for example \`/workspace/artifacts\`) does not persist as a host handoff file.
|
|
84
|
+
2. **Emit list ≠ disk until emit checks pass.** Listing a path in \`artifacts\` is a claim. On success emit, a non-empty list is accepted only when each path is an existing regular file under **this** attempt's artifacts dir (emit disk-truth). Empty \`artifacts: []\` stays valid. Optional after-phase \`verify\` \`type: artifact\` is separate hard proof; do not add it on every new stage by default.
|
|
85
|
+
3. **Facts travel in \`payload\`.** Put required fields the next stage needs in \`io.output.schema\`. Use artifacts for files; put pointers or basenames in payload when useful.
|
|
86
|
+
4. **Sandbox consumers read grants (or payload), not host attempt paths.** Under a stage container, each prior file is copied read-only to the sandbox path listed in the stage assignment (a file grant is that file, under \`/workspace/grants/<stage>/…\`). Do not author prompts that \`read stages/<id>/attempts/…/artifacts/…\` as the handoff. Unbound (no container) stages can still open run-relative artifact paths on the host.
|
|
87
|
+
5. **\`/workspace/work\` is never handoff.** Scratch only; it is not copied into the next stage's desk as an artifact grant.
|
|
88
|
+
|
|
89
|
+
## Validation
|
|
90
|
+
|
|
91
|
+
\`validate\` (tool) or \`sf validate\` checks shape, \`uses:\` paths, wiring, \`io\` compatibility, verify rules, model resolution, MCP names, channels and memories. It does not check provider keys, env vars or a live MCP connection; those fail at run start.
|
|
92
|
+
`,
|
|
93
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export const stagesTopic = {
|
|
2
|
+
id: "stages",
|
|
3
|
+
title: "Stage fields, what each one costs and risks",
|
|
4
|
+
summary: "Every stage field (system_prompt, model, io, verify, gate_kinds, skill, mcp, browser, channels, secrets, requires, timeout_ms) with what it does, where it goes, and its cost or risk.",
|
|
5
|
+
body: `# Stages
|
|
6
|
+
|
|
7
|
+
A stage is one step. Each attempt runs in a fresh agent session on the Host. A stage body lives inline in the pipeline or in its own YAML file (\`uses: ./name.yaml\`). An external stage file must have \`id\` equal to the file name stem and must not contain wiring (\`route\`, \`entry\`, \`on_verify_fail\`, \`clone_cap\`, \`clone_mode\`). The Guide stores that file in the same \`pipelines/<id>/\` folder as its pipeline. A path the person names does not change that folder.
|
|
8
|
+
|
|
9
|
+
## Body fields
|
|
10
|
+
|
|
11
|
+
| Field | Required | What it does | Cost / risk |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| \`system_prompt\` | yes | The stage's instructions. | Vague prompts cause wrong envelopes and repair loops. Say exactly what to put in \`payload\`. |
|
|
14
|
+
| \`model\` | no if a default exists | \`provider/model\` id. Resolved as stage, then pipeline \`model\`, then \`stageflow.yaml\` \`model\`. None at all fails load. | Bigger models cost more per attempt. Cheap models fail structured output more often. |
|
|
15
|
+
| \`io\` | yes | \`io.input.schema\` and \`io.output.schema\`, both required. Output is checked on every success emit. | A strict output schema rejects bad envelopes early. Over-strict schemas make the agent retry. |
|
|
16
|
+
| \`verify\` | no | Checks at emit time or after the agent claims success. | \`command\` runs a shell command on the Host with the stage's environment: same trust level as running the command yourself. |
|
|
17
|
+
| \`gate_kinds\` | no | Non-empty list turns on \`ask_operator\` (\`free_text\`, \`confirm\`, \`multi_question\`, \`artifact_backed\`). | The run stops until a person answers. Evals cannot answer gates. \`sf run --skip-gates\` fails the stage at the first wait. |
|
|
18
|
+
| \`skill\` | no | Binds one installed skill; its instructions are added to the prompt. Body only (not on a \`uses:\` wrapper). | A skill that is not installed fails the stage before the agent starts. |
|
|
19
|
+
| \`mcp\` | no | List of MCP server names the stage may use. | Each server is a process or remote service; tools can act outside Stageflow. Connect failures or unset variables fail the stage at run time. |
|
|
20
|
+
| \`secrets\` | no | Host secret names the stage may receive (for example \`GITHUB_TOKEN\`, or \`{ name: NPM_TOKEN, as: env }\`), or console MCP secrets used only to fill MCP placeholders. | Every secret granted widens what the agent can do. Grant only what the step needs. |
|
|
21
|
+
| \`requires\` | no | \`[{ tool, version? }]\` binaries that must be on PATH. Checked before the run starts. | Stageflow never installs tools. |
|
|
22
|
+
| \`browser\` | no | A real browser session (\`profile\`, \`headed\`, \`allow_domains\`, \`login_url\`, \`check\`). Adds an \`agent-browser\` requirement. | The agent drives a logged-in browser. \`allow_domains\` is not enforced for profile stages. Sites may forbid automation. |
|
|
23
|
+
| \`channels\` | no | One send channel: \`connection\`, pinned \`to\`, \`operations: [send]\`. Gives the \`send_message\` tool. Body only. | Sends real messages. Only one channel per stage. Pi backend only. |
|
|
24
|
+
| \`timeout_ms\` | no | Wall-clock budget per attempt. Default 3600000 (60 minutes). | On timeout the attempt fails but the session is kept so a person can Resume. |
|
|
25
|
+
|
|
26
|
+
Pipeline-entry wiring (not body): \`route\`, \`entry\`, \`on_verify_fail\`, \`replay_safe\`, \`clone_cap\`, \`clone_mode\`. \`memories\` is pipeline-level only; a stage cannot list its own.
|
|
27
|
+
|
|
28
|
+
## Tools every stage has
|
|
29
|
+
|
|
30
|
+
\`emit_stage_envelope\` (ends the stage), \`write_stage_artifact\` (durable files under the attempt artifacts folder — the only durable handoff write) and, when \`gate_kinds\` is non-empty, \`ask_operator\`. On Pi, stages also have the Pi coding agent's own file and shell tools (for example \`read\` and \`bash\`). With memories attached, Pi stages get \`read_memory\`, \`replace_memory\`, \`add_memory_card\`, \`update_memory_card\`, \`read_memory_card\`, \`search_memory_cards\`. With a channel, Pi stages get \`send_message\`.
|
|
31
|
+
|
|
32
|
+
Artifact handoff: list paths from \`write_stage_artifact\` on emit (non-empty lists must exist on disk). Under a stage sandbox, a later stage reads each prior file at the sandbox path in its assignment (a file grant is the file itself, under \`/workspace/grants/<stage>/…\`) or takes facts from \`payload\` — not host \`stages/…/artifacts\` paths and not \`/workspace/work\`. \`create_stage\` does not auto-add after-phase artifact \`verify\`; add that only when you need hard proof of a named file.
|
|
33
|
+
|
|
34
|
+
## Stage environment
|
|
35
|
+
|
|
36
|
+
A stage never gets the Host's raw environment. It gets an allowlist (PATH, locale, proxy, \`STAGEFLOW_HOME\`, …) plus the secrets it declares. Provider API keys are never put in the stage environment; model auth goes through the Host's credential file.
|
|
37
|
+
|
|
38
|
+
## Backends
|
|
39
|
+
|
|
40
|
+
The default backend is Pi. The Claude backend (pipeline or manifest \`agent\`) does not provide \`send_message\` or the memory tools, so a stage with \`channels:\` or a pipeline with \`memories:\` fails at stage start there.
|
|
41
|
+
|
|
42
|
+
## Creating stages with tools
|
|
43
|
+
|
|
44
|
+
- \`create_stage\` adds a file-backed stage (\`uses: ./<id>.yaml\`) to a pipeline. If you pass no \`model\`, it writes the Host's current default model into the stage file. If you pass no \`io\`, it writes a minimal object/object \`io\`.
|
|
45
|
+
- \`edit_stage\` changes body fields (via \`patch\`, \`body\`, \`system_prompt\`, \`model\`, \`io\`) and/or the pipeline entry (\`route\`, \`entry\`, \`uses\`, \`pipeline_entry\`).
|
|
46
|
+
- \`create_stage_file\` writes a standalone stage file that is not wired into any pipeline (\`id\`, \`system_prompt\`, optional \`model\`, \`gate_kinds\`, \`skill\`).
|
|
47
|
+
- \`write_catalog_file\` overwrites an existing stage file; an invalid write is restored.
|
|
48
|
+
- Each pipeline tool validates and writes nothing when invalid, unless \`allow_invalid\` is set to build up step by step.
|
|
49
|
+
|
|
50
|
+
## Recovering a stage in a run
|
|
51
|
+
|
|
52
|
+
Retry (new attempt), Resume (same session, for interrupted or timed-out attempts), Abandon (stop a running stage), and for manual recovery Retry with guidance or Stop recovery. Tools: \`retry_stage\`, \`resume_stage\`, \`abandon_stage\`, \`recover_manual_stage\`, \`stop_manual_recovery\`.
|
|
53
|
+
`,
|
|
54
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export const tasksTopic = {
|
|
2
|
+
id: "tasks",
|
|
3
|
+
title: "Tasks: what a run starts from",
|
|
4
|
+
summary: "Task file fields (id, goal, context, constraints, input, checkout, repository, ref), how input meets the entry stage, standalone vs pipeline tasks, and dynamic tasks built by triggers.",
|
|
5
|
+
body: `# Tasks
|
|
6
|
+
|
|
7
|
+
A task file is \`<id>.task.yaml\`. Every run is one pipeline plus one task. The task says what this run should do; the pipeline says how.
|
|
8
|
+
|
|
9
|
+
## Fields
|
|
10
|
+
|
|
11
|
+
| Field | Required | Meaning |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| \`id\` | yes | Task identifier. Tools expect lowercase kebab-case, 1 to 64 characters. |
|
|
14
|
+
| \`goal\` | yes | What the run should accomplish. Every stage sees it. |
|
|
15
|
+
| \`context\` | no | Background for the agents. |
|
|
16
|
+
| \`constraints\` | no | Boundaries the agents must respect. |
|
|
17
|
+
| \`input\` | no | Structured object matched against each entry stage's \`io.input.schema\`. Omitted means \`{}\`. |
|
|
18
|
+
| \`checkout\` | no | Path (relative or absolute) to an existing working folder. Conflicts with \`repository\`. |
|
|
19
|
+
| \`repository\` | no | GitHub \`owner/repo\`; the Host creates its own worktree. Requires \`ref\`. |
|
|
20
|
+
| \`ref\` | with \`repository\` | Branch, tag or SHA. |
|
|
21
|
+
|
|
22
|
+
Do not set both \`checkout\` and \`repository\`. The loader also accepts \`checkout: { branch, base }\` (Stageflow creates or reuses a git worktree), \`run_branch_template\` and \`git_identity\`; these are not in the public field table, so prefer the documented forms.
|
|
23
|
+
|
|
24
|
+
## How \`input\` meets the pipeline
|
|
25
|
+
|
|
26
|
+
- If an entry stage's \`io.input.schema\` requires fields, the task must provide them under \`input\`. A missing or wrong \`input\` makes run start fail with \`task.invalid_shape\`, even though validating the task file alone succeeds.
|
|
27
|
+
- A prose-only task (no \`input\`) is fine when the entry stage's input schema is an empty object.
|
|
28
|
+
- Non-entry stages also see the whole task in their prompt, plus their parents' envelopes.
|
|
29
|
+
|
|
30
|
+
## Standalone task vs pipeline task
|
|
31
|
+
|
|
32
|
+
- \`create_task_file\` writes a standalone catalog task (\`directory\`, \`id\`, \`goal\`, optional \`context\`, \`constraints\`, \`checkout\`, \`repository\`, \`ref\`). It is not tied to a pipeline; any pipeline can run with it. \`update_task_file\` replaces it by id (\`goal\` required; pass \`null\` or empty to drop an optional field).
|
|
33
|
+
- \`create_task\` / \`edit_task\` write the task that sits beside a pipeline package (same folder).
|
|
34
|
+
- \`import_task_file\` turns a GitHub issue into a task (title becomes goal and id). It calls GitHub.
|
|
35
|
+
- Neither tool set writes \`input\` as a named argument on standalone tasks; to set \`input\` on a pipeline task pass it inside \`body\` of \`create_task\` / \`edit_task\`.
|
|
36
|
+
|
|
37
|
+
## Tasks and triggers
|
|
38
|
+
|
|
39
|
+
- A trigger with \`task: <id>\` (catalog mode) always runs that catalog task. Supplying a different task at fire time is refused (\`trigger.task_override_not_allowed\`).
|
|
40
|
+
- A trigger without \`task\` (dynamic mode) needs a task at every fire. GitHub pull request triggers build one from the PR (\`goal\` summarizes it, \`input\` holds \`action\`, \`number\`, \`title\`, \`url\`, \`author\`, \`repo\`, \`updatedAt\`). Webhook triggers put the JSON body in \`input\`. Email triggers put \`from\`, \`subject\`, \`date\`, \`text\` in \`input\`. A manual fire must pass a task inline, otherwise \`trigger.task_required\`.
|
|
41
|
+
- A schedule trigger has nothing to build a task from, so it needs a catalog task.
|
|
42
|
+
- When the task is built from an event, design the entry stage's \`io.input.schema\` around that event shape.
|
|
43
|
+
|
|
44
|
+
## Repository-bound tasks
|
|
45
|
+
|
|
46
|
+
With \`repository\` + \`ref\`, the stage works in a Host-owned worktree. Repository-bound stages read the repository's own \`.mcp.json\` and \`.pi/skills\` as untrusted workspace content and never see console MCP servers or console secrets. Evals cannot use a checkout or repository: eval cases run with neither.
|
|
47
|
+
|
|
48
|
+
## Starting a run
|
|
49
|
+
|
|
50
|
+
The console's Start a run picks a task and a pipeline (\`#/new\`). Tools: \`start_run\` (pipeline and task), \`run_stage\` (one stage), \`rerun\`. The CLI is \`sf run --pipeline <path> --task <path>\` (paths, not ids).
|
|
51
|
+
`,
|
|
52
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const triggersTopic = {
|
|
2
|
+
id: "triggers",
|
|
3
|
+
title: "Triggers: manual, schedule and event",
|
|
4
|
+
summary: "Trigger YAML, catalog vs dynamic task mode, manual / schedule (cron) / event (GitHub pull requests, signed webhook, email) adapters, which combinations work, and the trigger tools.",
|
|
5
|
+
body: `# Triggers
|
|
6
|
+
|
|
7
|
+
A trigger file is \`<id>.trigger.yaml\`. It binds one id to an existing pipeline (and usually a task) so a run can start without someone picking files. Agent schedules are different: an agent's own \`schedule\` field starts an agent turn, not a pipeline run.
|
|
8
|
+
|
|
9
|
+
## Fields
|
|
10
|
+
|
|
11
|
+
| Field | Required | Meaning |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| \`id\` | yes | Trigger id, unique in the project. |
|
|
14
|
+
| \`pipeline\` | yes | Id of a catalog pipeline. |
|
|
15
|
+
| \`task\` | no | Id of a catalog task. Its presence is the mode switch (below). |
|
|
16
|
+
| \`kind\` | yes | \`manual\`, \`schedule\` or \`event\`. |
|
|
17
|
+
| \`enabled\` | yes in the file | A disabled trigger refuses to fire (409). \`create_trigger\` defaults it to \`true\`. |
|
|
18
|
+
| \`schedule\` | for \`schedule\` | \`{ cron, timezone? }\`. Cron is checked when created. |
|
|
19
|
+
| \`event\` | for \`event\` | \`{ source, match?, config? }\`. |
|
|
20
|
+
|
|
21
|
+
The pipeline and task ids must exist in the catalog; \`create_trigger\` refuses unknown ids (422) and \`validate\` reports \`trigger.unknown_pipeline\` / \`trigger.unknown_task\`.
|
|
22
|
+
|
|
23
|
+
## Catalog mode vs dynamic mode
|
|
24
|
+
|
|
25
|
+
- **\`task\` set (catalog mode).** Every fire runs that task. Passing a task at fire time is refused (\`trigger.task_override_not_allowed\`).
|
|
26
|
+
- **\`task\` absent (dynamic mode).** Every fire must supply a task. GitHub, webhook and email adapters build one from the event. A manual fire must pass one inline (\`fire_trigger\` with \`task\`, or \`sf trigger fire --task-inline\`), else \`trigger.task_required\`. The console's Fire button is disabled for dynamic triggers.
|
|
27
|
+
|
|
28
|
+
## Kinds
|
|
29
|
+
|
|
30
|
+
**manual.** Fires only when asked: console Fire, \`fire_trigger\`, \`sf trigger fire\`, \`POST /api/triggers/<id>/fire\`.
|
|
31
|
+
|
|
32
|
+
**schedule.** While a Host is running, a scheduler checks about every 30 seconds and fires when the cron time passes. If the Host was down, it fires **once** for the latest missed time, not once per missed slot. A schedule trigger needs a catalog task: in dynamic mode the timer has no task, so every automatic fire fails with \`trigger.task_required\`. The console blocks that combination on save; \`create_trigger\` does not, so check it yourself.
|
|
33
|
+
|
|
34
|
+
**event, \`source\` starting with \`github.\`** (console tile uses \`github.pull_request\`). Polls the GitHub pull request list of \`event.config.repo\` (\`owner/repo\`) about every 60 seconds, with a token from \`event.config.secretRef\` (default \`GITHUB_TOKEN\`). Only pull requests, not issues or repo pushes outside a PR. The first poll of a repo only records a cursor (and per-PR head SHAs) and fires nothing for old PRs; the same quiet baseline runs when a cursor already exists but heads were never written (upgrade). \`match.action\` is **required** for github sources — \`create_trigger\` / validate reject omit-match. Actions: \`opened\` (brand-new PR: equal created/updated timestamps, or created after the cursor), \`synchronize\` (head SHA changed — use this for every push), \`updated\` (other activity, same head; also aged PRs with no prior SHA), \`merged\`, \`closed\`. \`match\` can also filter \`author\` and the other normalized fields; exact equality only.
|
|
35
|
+
|
|
36
|
+
**event, \`source: webhook\`.** Gets its own endpoint \`POST /api/triggers/<id>/webhook\`, verified by HMAC-SHA256 over the raw body. \`event.config\`: \`secretRef\` (required, name of the Host secret), \`header\` (required, for example \`x-hub-signature-256\`), \`scheme\` (\`hex\` default or \`base64\`). Wrong signature is 401. A body that does not match \`match\` returns 200 with \`fired: false\`. The Host listens on loopback by default, so an outside sender needs a tunnel or an exposed deployment.
|
|
37
|
+
|
|
38
|
+
**event, \`source\` starting with \`email.\`** (console uses \`email.message\`). Holds an IMAP IDLE connection to a mailbox the user supplies. \`event.config\`: \`host\`, \`port\`, \`user\`, \`secretRef\` (password or app password). \`match\` compares \`from\`, \`subject\`, \`date\`, \`text\` by exact equality (a subject filter must equal the whole subject). No attachments. After creating or changing an email trigger, restart the Host if the mailbox does not connect.
|
|
39
|
+
|
|
40
|
+
**Any other \`event.source\`** loads and validates but nothing watches it. It can only be fired manually.
|
|
41
|
+
|
|
42
|
+
## What works end to end
|
|
43
|
+
|
|
44
|
+
| Setup | Works automatically |
|
|
45
|
+
|---|---|
|
|
46
|
+
| manual + catalog task | fires when asked |
|
|
47
|
+
| schedule + catalog task | yes |
|
|
48
|
+
| schedule + no task | no, every tick fails |
|
|
49
|
+
| GitHub PR + catalog or dynamic | yes |
|
|
50
|
+
| webhook + catalog or dynamic | yes, if reachable and the secret is set |
|
|
51
|
+
| email + catalog or dynamic | yes, with a real mailbox and the secret set |
|
|
52
|
+
| other event source | no, manual fire only |
|
|
53
|
+
|
|
54
|
+
All automatic triggers need a running Host (\`sf ui\`, \`sf mcp\` or Docker). They do not run from the CLI alone.
|
|
55
|
+
|
|
56
|
+
## Secrets
|
|
57
|
+
|
|
58
|
+
Trigger secrets are referenced by name (\`secretRef\`) and read from the Host environment or a \`_FILE\` variant. Never put a token or password in trigger YAML.
|
|
59
|
+
|
|
60
|
+
## Tools
|
|
61
|
+
|
|
62
|
+
\`list_triggers\`, \`get_trigger\`, \`create_trigger\` (\`directory\`, \`id\`, \`pipeline\`, optional \`task\`, \`kind\`, \`schedule\`, \`event\`, \`enabled\`), \`update_trigger\` (replaces the whole definition; the id cannot change), \`set_trigger_enabled\`, \`fire_trigger\`. There is no delete tool: to stop a trigger, disable it; removing it means deleting the file by hand.
|
|
63
|
+
|
|
64
|
+
## Before you add a trigger
|
|
65
|
+
|
|
66
|
+
Run the pipeline once by hand with the same task and confirm it succeeds. A trigger repeats whatever the pipeline does, including its cost and any messages it sends.
|
|
67
|
+
`,
|
|
68
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export const troubleshootingTopic = {
|
|
2
|
+
id: "troubleshooting",
|
|
3
|
+
title: "Troubleshooting: common findings and errors",
|
|
4
|
+
summary: "What common validation finding codes and run, trigger, channel, agent and eval errors mean, and how to fix each one.",
|
|
5
|
+
body: `# Troubleshooting
|
|
6
|
+
|
|
7
|
+
Run \`validate\` (or \`validate_catalog_draft\` for a draft, \`validate_agent\`, \`validate_eval\`) first. Findings have a \`code\`; errors block, warnings do not.
|
|
8
|
+
|
|
9
|
+
## Pipelines and stages
|
|
10
|
+
|
|
11
|
+
| Code or message | Meaning and fix |
|
|
12
|
+
|---|---|
|
|
13
|
+
| "model is required (set on stage, pipeline, or stageflow.yaml)" | No model anywhere in the chain. Set pipeline \`model\` or \`stageflow.yaml\` \`model\`. |
|
|
14
|
+
| \`stage.invalid_io\` | A stage body lacks \`io.input.schema\` or \`io.output.schema\`. Both are required. |
|
|
15
|
+
| \`pipeline.io_incompatible\` | A child's input schema is not a subset of a parent's output schema. Make the child require only fields the parent's output declares. |
|
|
16
|
+
| \`pipeline.route_if_invalid\` | Bad \`if\`: unknown operator, field not required in the source output, array path, mixed shape, or \`if\` on a loop entry. |
|
|
17
|
+
| \`pipeline.route_all_gated\` (warning) | Every forward route has \`if\`; the run may skip all successors. |
|
|
18
|
+
| \`pipeline.model_applies\` (warning) | The pipeline \`model\` fills stages. Informational. |
|
|
19
|
+
| \`pipeline.dag_error\` | A cycle, or a backward or circular edge without a \`type: loop\` entry. |
|
|
20
|
+
| \`"needs" is no longer supported …\` (also \`fork\`, \`feedback_loop\`, \`route_select\`, \`allow_none\`) | Old wiring. Put \`route: [{ to: child }]\` on the parent and \`entry: true\` on roots; loops become a \`type: loop\` route entry. |
|
|
21
|
+
| \`pipeline.stage_uses_inline_conflict\` | Body keys beside \`uses:\`. Move them into the stage file. |
|
|
22
|
+
| \`pipeline.stage_wrapper_skill_rejected\` | \`skill\` on a \`uses:\` wrapper. Put it in the stage file. |
|
|
23
|
+
| \`stage.unresolved_schema_ref\` | A \`$ref\` stage validated alone; validate the pipeline that defines \`schemas\`. |
|
|
24
|
+
| \`catalog.legacy_yaml\` (warning) | Old contract keys (\`payload_schema:\`, \`pre_emit_checks\`, \`completion\`, \`recovery\`). Convert with \`sf migrate-yaml --write\`. |
|
|
25
|
+
| \`pipeline.invalid_memories\` / \`pipeline.memory_unavailable\` | Duplicate memory id, or a memory that does not exist on this Host. Create it first. |
|
|
26
|
+
| \`pipeline.invalid_shape\` | Wrong structure, including \`memories\` on a stage entry. |
|
|
27
|
+
| \`stage.invalid_channels\` / \`pipeline.invalid_channels\` | Bad \`channels\` shape, or more than one channel on a stage. |
|
|
28
|
+
| \`stage.channel_unavailable\` | Connection missing or disabled, operation unsupported, or recipient invalid for the provider. |
|
|
29
|
+
| \`stage.invalid_browser\` | Unknown \`browser\` key, or \`path\`, \`scope\`, \`secret\`, launch options in YAML. |
|
|
30
|
+
| \`stage.invalid_requires\` / \`pipeline.invalid_requires\` / \`pipeline.requires_conflict\` | Bad \`requires\` entries, or version ranges that cannot both hold. |
|
|
31
|
+
| \`stage.unknown_secret\` | A \`secrets\` name that is neither a console MCP secret nor a registered Host secret. |
|
|
32
|
+
| "Unknown MCP server" | A stage \`mcp\` name in neither \`.mcp.json\` nor the console list. |
|
|
33
|
+
| Clone chain errors | Extra routes on emitter or child, \`if\` on chain edges, extra join parents, inline array items, \`clone_cap\`/\`clone_mode\` on the wrong stage. |
|
|
34
|
+
|
|
35
|
+
## Running
|
|
36
|
+
|
|
37
|
+
| Symptom | Meaning and fix |
|
|
38
|
+
|---|---|
|
|
39
|
+
| \`task.invalid_shape\` at run start | The task's \`input\` does not match the entry stage's \`io.input.schema\` (missing \`input\` counts as \`{}\`). |
|
|
40
|
+
| \`channel_check_failed: <connection>: <reason>\` | Live connection check failed. Fix the key or recipient; \`test_connection\`. |
|
|
41
|
+
| \`missing emit_stage_envelope\` | The agent ended without a valid envelope after two reminders. Make the prompt name the payload fields; check \`io.output.schema\` is achievable. |
|
|
42
|
+
| \`provider error: …\` | Usually a missing or invalid provider key or an unavailable model. Check Settings → Providers. |
|
|
43
|
+
| \`stage timed out after …ms\` | Raise \`timeout_ms\` or simplify; the session is kept, so Resume works. |
|
|
44
|
+
| Run waiting | A stage asked a person. Answer in the Inbox. |
|
|
45
|
+
| Stage failed after-phase verify | See the stage's verification history (\`get_stage_verification\`). With \`mode: manual\`, use Retry with guidance or Stop recovery; plain retry is refused. |
|
|
46
|
+
| Join never runs | One parent failed. A join does not run on a failed parent. |
|
|
47
|
+
| "waiting for browser profile" | Another run holds the browser profile until it ends. |
|
|
48
|
+
|
|
49
|
+
## Triggers
|
|
50
|
+
|
|
51
|
+
| Code | Meaning |
|
|
52
|
+
|---|---|
|
|
53
|
+
| \`trigger.invalid_shape\` | Missing or wrong \`id\`, \`pipeline\`, \`kind\`, \`enabled\`. |
|
|
54
|
+
| \`trigger.unknown_pipeline\` / \`trigger.unknown_task\` | The id is not in the catalog. |
|
|
55
|
+
| \`trigger.task_required\` | Dynamic trigger fired without a task (always the case for a schedule without \`task\`). |
|
|
56
|
+
| \`trigger.task_override_not_allowed\` | A task was passed to a catalog-mode trigger. |
|
|
57
|
+
| 409 on fire | The trigger is disabled. |
|
|
58
|
+
| Webhook 401 | Signature does not match the secret and header. |
|
|
59
|
+
|
|
60
|
+
## Channels
|
|
61
|
+
|
|
62
|
+
\`CHANNEL_AUTH_FAILED\` (bad credential), \`CHANNEL_UNAUTHORIZED\` (missing scope, or stage did not declare the channel), \`CHANNEL_SECRET_UNAVAILABLE\` (env secret not set on this Host), \`CHANNEL_TARGET_INVALID\`, \`CHANNEL_RECIPIENT_REJECTED\` (bot not added, user did not start the bot or text the line), \`CHANNEL_WINDOW_CLOSED\` (WhatsApp 24-hour window; pin a template), \`CHANNEL_RATE_LIMIT\`/\`CHANNEL_TIMEOUT\`/\`CHANNEL_CONNECTION_FAILED\` (retryable), \`CHANNEL_PROVIDER_UNSUPPORTED\` (optional iMessage/WhatsApp packages missing), \`CHANNEL_SEND_OUTCOME_UNKNOWN\` (do not resend), \`CHANNEL_OPERATION_CONFLICT\` (same key, different content).
|
|
63
|
+
|
|
64
|
+
## Agents
|
|
65
|
+
|
|
66
|
+
| Code | Meaning |
|
|
67
|
+
|---|---|
|
|
68
|
+
| \`agent.invalid\` | Issues block the save; each has a field \`path\`. |
|
|
69
|
+
| \`agent.unknown_field\`, \`agent.required\` | Typo or missing field. |
|
|
70
|
+
| \`agent.ask_first_not_granted\` | \`ask_first\` names a tool the agent does not hold. |
|
|
71
|
+
| \`agent.stageflow_operator_only\` | Tried to grant \`gates.decide\` or \`get_started\`. |
|
|
72
|
+
| \`agent.channel_in_use\` | That connection (or its inbox) already belongs to another agent. |
|
|
73
|
+
| \`agent.memory_unavailable\` | A memory id does not exist. |
|
|
74
|
+
| \`agent.conflict\` | Saved from an old revision; reload and reapply. |
|
|
75
|
+
| \`agent.disabled\`, \`agent.limit_reached\`, \`agent.session_busy\` | Turn refused: disabled, a limit hit, or a turn/approval already pending. |
|
|
76
|
+
| \`agent.guardrail_blocked\` | A \`block_patterns\` regex matched the reply. |
|
|
77
|
+
| \`agent.model_timeout\` | The model sent nothing for 180 s. |
|
|
78
|
+
| \`agent.reply_undelivered\` | A channel reply failed or its outcome is unknown; Resend or Mark as delivered on the run page. |
|
|
79
|
+
| Warnings: \`agent.mcp_server_unknown\`, \`agent.skill_unknown\`, \`agent.model_unknown\`, \`agent.connection_unknown\`, \`agent.channel_nobody_allowed\`, \`agent.channel_open_to_anyone\`, \`agent.shell_not_path_confined\`, \`agent.web_chat_reads_conversations\` | Advice; the agent still saves. |
|
|
80
|
+
|
|
81
|
+
## Evals
|
|
82
|
+
|
|
83
|
+
\`eval.target_unresolved\` (target does not load, often no default model), \`eval.grader_not_applicable\`, \`eval.judge_missing\`, \`eval.schema_grader_without_output_schema\`, \`eval.no_valid_cases\`, \`eval.cases_skipped\`, \`eval.real_tools_not_allowed\`, \`eval.user_model_missing\`, \`eval.simulator_unsupported\`, \`eval.agent_not_found\`, \`eval.agent_archived\`. At run: \`EVAL_ENGINE_UNAVAILABLE\` (install the engine), \`EVAL_NODE_TOO_OLD\`, \`EVAL_RUN_ACTIVE\`, \`EVAL_REAL_TOOLS_NOT_CONFIRMED\`, \`EVAL_INVALID\` (including an unsupported judge provider), \`budget_stopped\` (raise \`max_cost_usd\` or run fewer cases). On results: \`EVAL_STAGE_NEEDS_INPUT\`, \`EVAL_STAGE_TIMEOUT\`, \`EVAL_JUDGE_ERROR\` (judge key missing or non-JSON reply), \`EVAL_CASE_MISSING_EXPECTED\`, \`EVAL_AGENT_EMPTY_REPLY\` (provider rate limit or outage). Saving: \`FILE_CHANGED\` (reload and reapply).
|
|
84
|
+
`,
|
|
85
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { findGuideKnowledge, GUIDE_KNOWLEDGE_TOPICS, searchGuideKnowledge } from "./knowledge/index.js";
|
|
3
|
+
const SEARCH_LIMIT = 3;
|
|
4
|
+
function textArg(args, key) {
|
|
5
|
+
const value = args[key];
|
|
6
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
7
|
+
}
|
|
8
|
+
function failure(error, content = {}) {
|
|
9
|
+
return { ok: false, content: { error, ...content }, error };
|
|
10
|
+
}
|
|
11
|
+
export function createGuideKnowledgeTools() {
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
name: "list_guide_topics",
|
|
15
|
+
description: "List the Stageflow knowledge topics (id, title, summary). Read a topic with read_guide_topic before you explain how a part of Stageflow works, recommend a design, or say whether something is possible.",
|
|
16
|
+
parameters: Type.Object({}, { additionalProperties: false }),
|
|
17
|
+
handler: () => ({
|
|
18
|
+
ok: true,
|
|
19
|
+
content: {
|
|
20
|
+
topics: GUIDE_KNOWLEDGE_TOPICS.map(({ id, title, summary }) => ({ id, title, summary })),
|
|
21
|
+
},
|
|
22
|
+
}),
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "read_guide_topic",
|
|
26
|
+
description: "Read Stageflow knowledge. Pass { id } to get a topic's full text (ids from list_guide_topics), or { query } to get the best matching topics with a short excerpt. Prefer the limitations topic before promising a feature.",
|
|
27
|
+
parameters: Type.Union([
|
|
28
|
+
Type.Object({ id: Type.String({ minLength: 1 }) }, { additionalProperties: false }),
|
|
29
|
+
Type.Object({ query: Type.String({ minLength: 1 }) }, { additionalProperties: false }),
|
|
30
|
+
]),
|
|
31
|
+
handler: (args) => {
|
|
32
|
+
const id = textArg(args, "id");
|
|
33
|
+
if (id !== undefined) {
|
|
34
|
+
const topic = findGuideKnowledge(id);
|
|
35
|
+
if (!topic) {
|
|
36
|
+
return failure("guide.topic_not_found", {
|
|
37
|
+
id,
|
|
38
|
+
topics: GUIDE_KNOWLEDGE_TOPICS.map((entry) => entry.id),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return { ok: true, content: { id: topic.id, title: topic.title, body: topic.body } };
|
|
42
|
+
}
|
|
43
|
+
const query = textArg(args, "query");
|
|
44
|
+
if (query !== undefined) {
|
|
45
|
+
const matches = searchGuideKnowledge(query, SEARCH_LIMIT).map(({ topic, excerpt }) => ({
|
|
46
|
+
id: topic.id,
|
|
47
|
+
title: topic.title,
|
|
48
|
+
excerpt,
|
|
49
|
+
}));
|
|
50
|
+
return { ok: true, content: { query, matches } };
|
|
51
|
+
}
|
|
52
|
+
return failure("guide.id_or_query_required");
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { McpToolDeps } from "../mcp/deps.js";
|
|
2
|
+
import type { OperatorAgentTool, OperatorAgentToolResult } from "../operatorAgent/types.js";
|
|
3
|
+
export declare const GUIDE_UI_TOOL_NAMES: readonly ["show_ui"];
|
|
4
|
+
export { GUIDE_LINK_KINDS, GUIDE_RESOURCE_KINDS, type GuideLink, type GuideLinkKind, type GuidePipelineStage, type GuideUi, } from "./cardContract.js";
|
|
5
|
+
export declare function buildGuideUi(deps: McpToolDeps, args: Record<string, unknown>): Promise<OperatorAgentToolResult>;
|
|
6
|
+
export declare function createShowUiTool(deps: McpToolDeps): OperatorAgentTool;
|