stageflow 0.39.0 → 0.42.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 +46 -19
- package/dist/agent/claudeAdapter.js +15 -1
- package/dist/agent/claudeTools.d.ts +13 -0
- package/dist/agent/claudeTools.js +98 -0
- package/dist/agent/piAdapter.js +38 -16
- package/dist/agent/sandboxPiTools.d.ts +99 -0
- package/dist/agent/sandboxPiTools.js +109 -0
- package/dist/agents/authorChat.d.ts +4 -0
- package/dist/agents/authorChat.js +113 -12
- package/dist/agents/authorSessionStore.d.ts +35 -0
- package/dist/agents/authorSessionStore.js +152 -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 +3 -0
- package/dist/agents/hostContext.js +4 -1
- package/dist/agents/runtime/piRuntime.d.ts +1 -1
- package/dist/agents/runtime/piRuntime.js +4 -4
- package/dist/agents/runtime/types.d.ts +3 -1
- package/dist/agents/service.d.ts +27 -2
- package/dist/agents/service.js +88 -13
- package/dist/agents/sessions.d.ts +8 -0
- package/dist/agents/sessions.js +50 -10
- 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/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/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 +2 -1
- package/dist/config/ensureCatalogScanRoot.js +2 -6
- package/dist/config/evalCatalog.d.ts +22 -0
- package/dist/config/evalCatalog.js +67 -0
- package/dist/config/evalWriteRoots.d.ts +17 -0
- package/dist/config/evalWriteRoots.js +109 -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 +1085 -0
- package/dist/config/loadOutcome.d.ts +5 -0
- package/dist/config/loadStageflowManifest.js +64 -0
- package/dist/config/loadTask.js +34 -1
- 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 +1 -1
- package/dist/config/validateCatalog.js +9 -1
- package/dist/config/validateEval.d.ts +36 -0
- package/dist/config/validateEval.js +405 -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/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 +60 -0
- package/dist/evals/constants.js +95 -0
- package/dist/evals/engine/FakeEngine.d.ts +33 -0
- package/dist/evals/engine/FakeEngine.js +176 -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 +311 -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 +342 -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 +103 -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 +174 -0
- package/dist/evals/manager.js +787 -0
- package/dist/evals/plan.d.ts +58 -0
- package/dist/evals/plan.js +602 -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 +196 -0
- package/dist/evals/read/api.js +358 -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 +173 -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 +149 -0
- package/dist/evals/read/runs.js +289 -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 +7 -0
- package/dist/evals/runner/caseRunner.js +17 -0
- package/dist/evals/runner/conversationSubject.d.ts +18 -0
- package/dist/evals/runner/conversationSubject.js +123 -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 +183 -0
- package/dist/evals/snapshot.js +65 -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 +347 -0
- package/dist/evals/types.js +1 -0
- package/dist/mcp/catalogTools.js +11 -1
- package/dist/mcp/deps.d.ts +7 -0
- package/dist/mcp/evalTools.d.ts +3 -0
- package/dist/mcp/evalTools.js +280 -0
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.js +2 -0
- 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/piModel.js +17 -4
- package/dist/operatorAgent/profiles/agentAuthor.d.ts +3 -1
- package/dist/operatorAgent/profiles/agentAuthor.js +145 -20
- 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/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/runstore/port.d.ts +43 -0
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +28 -0
- package/dist/runstore/sqlite/SqliteRunStore.js +99 -5
- 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/runtime/gitCheckoutCapability.d.ts +1 -0
- package/dist/runtime/gitCheckoutCapability.js +1 -1
- package/dist/runtime/gitWorktreeCheckout.d.ts +22 -0
- package/dist/runtime/gitWorktreeCheckout.js +120 -0
- package/dist/runtime/pipelineRunner.d.ts +2 -1
- package/dist/runtime/pipelineRunner.js +2 -0
- package/dist/runtime/runManager.d.ts +2 -1
- package/dist/runtime/runManager.js +8 -6
- package/dist/runtime/runRetentionSweep.js +2 -2
- package/dist/runtime/sandboxContainer.d.ts +62 -0
- package/dist/runtime/sandboxContainer.js +151 -0
- package/dist/runtime/sandboxDesk.d.ts +28 -0
- package/dist/runtime/sandboxDesk.js +242 -0
- package/dist/runtime/sandboxFiles.d.ts +20 -0
- package/dist/runtime/sandboxFiles.js +150 -0
- package/dist/runtime/stageEnvironment.js +2 -0
- package/dist/runtime/stageRoots.d.ts +9 -0
- package/dist/runtime/stageRoots.js +14 -0
- package/dist/runtime/stageRunner.d.ts +5 -0
- package/dist/runtime/stageRunner.js +38 -4
- package/dist/runtime/stageSandbox.d.ts +16 -0
- package/dist/runtime/stageSandbox.js +54 -0
- package/dist/runtime/stageWorker.js +138 -105
- package/dist/runtime/workspaceBinding.d.ts +2 -1
- package/dist/runtime/workspaceBinding.js +20 -4
- package/dist/server/agentAuthorRoutes.js +50 -1
- package/dist/server/bootstrap.d.ts +8 -0
- package/dist/server/bootstrap.js +56 -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 +1427 -0
- package/dist/server/evalTriageRoutes.d.ts +2 -0
- package/dist/server/evalTriageRoutes.js +95 -0
- package/dist/server/http.d.ts +5 -0
- package/dist/server/http.js +32 -2
- package/dist/server/mcpHost.js +3 -0
- package/dist/toolkit/meta.d.ts +1 -1
- package/dist/toolkit/meta.js +15 -0
- package/dist/toolkit/profiles.js +1 -1
- package/dist/tools/readEmail.d.ts +3 -3
- package/dist/types/stageflowManifest.d.ts +6 -0
- package/dist/types/task.d.ts +11 -1
- package/dist/ui/assets/AssistantRuntimeProvider-qIX1xNoH.js +9 -0
- package/dist/ui/assets/{MarkdownText-D7tYaIFO.js → MarkdownText-BTrOqu5J.js} +1 -1
- package/dist/ui/assets/chat-Df_wCpak.js +5 -0
- package/dist/ui/assets/chat-P7KQznHm.css +2 -0
- package/dist/ui/assets/{main-BFo79krC.css → main-CHlmTNJe.css} +1 -1
- package/dist/ui/assets/main-CvVfxmMd.js +271 -0
- package/dist/ui/chat.html +3 -3
- package/dist/ui/index.html +3 -3
- package/examples/README.md +2 -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 +123 -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/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/README.md +2 -0
- package/examples/memory/probe-bash.task.yaml +3 -0
- package/examples/memory/sandbox-memory-bash.pipeline.yaml +28 -0
- package/examples/ship-feature/README.md +15 -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/chat-BbLukq9W.js +0 -5
- package/dist/ui/assets/chat-zIZU_bP1.css +0 -2
- package/dist/ui/assets/main-CijYMeM0.js +0 -259
package/dist/mcp/server.js
CHANGED
|
@@ -49,6 +49,7 @@ function toolDepsFrom(deps) {
|
|
|
49
49
|
...(deps.agentConversationBackend !== undefined
|
|
50
50
|
? { agentConversationBackend: deps.agentConversationBackend }
|
|
51
51
|
: {}),
|
|
52
|
+
...(deps.evalRunManager !== undefined ? { evalRunManager: deps.evalRunManager } : {}),
|
|
52
53
|
};
|
|
53
54
|
}
|
|
54
55
|
function attachBusNotifications(server, bus) {
|
package/dist/mcp/tools.js
CHANGED
|
@@ -5,6 +5,7 @@ import { registerControlTools } from "./controlTools.js";
|
|
|
5
5
|
import { registerProjectMcpTools } from "./projectMcpTools.js";
|
|
6
6
|
import { registerPipelineAuthorTools } from "./pipelineAuthorTools.js";
|
|
7
7
|
import { registerProviderTools } from "./providerTools.js";
|
|
8
|
+
import { registerEvalTools } from "./evalTools.js";
|
|
8
9
|
import { registerTriggerTools } from "./triggerTools.js";
|
|
9
10
|
import { textResult } from "./toolResults.js";
|
|
10
11
|
import { DEFAULT_TIMEOUT_MS, waitRun } from "./waitRun.js";
|
|
@@ -19,6 +20,7 @@ export function registerMcpTools(server, deps) {
|
|
|
19
20
|
registerProviderTools(server, deps);
|
|
20
21
|
registerProjectMcpTools(server, deps);
|
|
21
22
|
registerTriggerTools(server, deps);
|
|
23
|
+
registerEvalTools(server, deps);
|
|
22
24
|
registerPipelineAuthorTools(server, deps);
|
|
23
25
|
registerAgentTools(server, deps);
|
|
24
26
|
server.registerTool("wait_run", {
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { RunStore } from "../runstore/port.js";
|
|
2
2
|
import { listModelsMultiProject } from "../config/multiProjectCatalog.js";
|
|
3
|
-
import { type CatalogProvider } from "./catalog.js";
|
|
3
|
+
import { type CatalogModel, type CatalogProvider } from "./catalog.js";
|
|
4
|
+
export type ModelsResponseProvider = Omit<CatalogProvider, "models"> & {
|
|
5
|
+
models: Array<CatalogModel & {
|
|
6
|
+
judge_capable: boolean;
|
|
7
|
+
}>;
|
|
8
|
+
};
|
|
4
9
|
export type ModelsResponse = {
|
|
5
10
|
/** Catalog ids plus ids pipelines already use, sorted. Back-compatible with the old flat list. */
|
|
6
11
|
models: string[];
|
|
7
12
|
/** Connected providers with their models. */
|
|
8
|
-
providers:
|
|
13
|
+
providers: ModelsResponseProvider[];
|
|
9
14
|
/** The model a new chat, stage or agent starts on. */
|
|
10
15
|
default: string;
|
|
11
16
|
fetchedAt: string;
|
package/dist/models/response.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { listModelsMultiProject } from "../config/multiProjectCatalog.js";
|
|
2
|
+
import { judgeCapableModels } from "../evals/judgeProviders.js";
|
|
2
3
|
import { getModelCatalog } from "./catalog.js";
|
|
3
4
|
/** The shared answer for GET /api/models, the MCP `list_models` tool and every picker. */
|
|
4
5
|
export async function buildModelsResponse(options) {
|
|
@@ -9,12 +10,16 @@ export async function buildModelsResponse(options) {
|
|
|
9
10
|
catalog.defaultModel(),
|
|
10
11
|
]);
|
|
11
12
|
const listed = new Set(snapshot.models);
|
|
13
|
+
const judgeCapable = new Set(judgeCapableModels(snapshot.providers.flatMap((p) => p.models.map((m) => m.id))));
|
|
12
14
|
const unlisted = used.models.filter((id) => !listed.has(id));
|
|
13
15
|
return {
|
|
14
16
|
used,
|
|
15
17
|
response: {
|
|
16
18
|
models: [...new Set([...snapshot.models, ...used.models])].sort((a, b) => a.localeCompare(b)),
|
|
17
|
-
providers: snapshot.providers
|
|
19
|
+
providers: snapshot.providers.map((provider) => ({
|
|
20
|
+
...provider,
|
|
21
|
+
models: provider.models.map((model) => ({ ...model, judge_capable: judgeCapable.has(model.id) })),
|
|
22
|
+
})),
|
|
18
23
|
default: defaultModel,
|
|
19
24
|
fetchedAt: snapshot.fetchedAt,
|
|
20
25
|
unlisted,
|
|
@@ -10,7 +10,7 @@ export type AgentAuthorContext = {
|
|
|
10
10
|
projectRoot?: string;
|
|
11
11
|
draft: AgentAuthorDraft;
|
|
12
12
|
};
|
|
13
|
-
export declare const AGENT_AUTHOR_GREETING = "
|
|
13
|
+
export declare const AGENT_AUTHOR_GREETING = "Who is this agent for, and what does a good result look like? I'll ask a few questions before I fill the config.";
|
|
14
14
|
export declare function emptyAgentAuthorDraft(): AgentAuthorDraft;
|
|
15
15
|
export declare function isAgentAuthorContext(value: unknown): value is AgentAuthorContext;
|
|
16
16
|
export declare function readAgentAuthorDraft(context: unknown): AgentAuthorDraft;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const AGENT_AUTHOR_GREETING = "
|
|
1
|
+
export const AGENT_AUTHOR_GREETING = "Who is this agent for, and what does a good result look like? I'll ask a few questions before I fill the config.";
|
|
2
2
|
export function emptyAgentAuthorDraft() {
|
|
3
3
|
return {};
|
|
4
4
|
}
|
|
@@ -11,7 +11,7 @@ import path from "node:path";
|
|
|
11
11
|
import { defineTool, ModelRuntime, resolveCliModel, SessionManager, SettingsManager, } from "@earendil-works/pi-coding-agent";
|
|
12
12
|
import { Type } from "typebox";
|
|
13
13
|
import { createPiAgentSession, createSealedResourceLoader, resolveWorkshopToolNames, } from "../agent/piSessionFactory.js";
|
|
14
|
-
import { bindCursorApiKey, cursorBridgePrompt } from "../agent/cursorProvider.js";
|
|
14
|
+
import { bindCursorApiKey, cursorBridgePrompt, isCursorModelRef } from "../agent/cursorProvider.js";
|
|
15
15
|
import { findProviderSupport } from "../agent/providerSupport.js";
|
|
16
16
|
import "../agent/cursorProvider.js";
|
|
17
17
|
import { logger as rootLogger } from "../logging/logger.js";
|
|
@@ -19,7 +19,7 @@ import { globalStageflowHome } from "../project/globalHome.js";
|
|
|
19
19
|
import { isUsableAuthFile, resolveCredentialBinding, } from "../runtime/credentialBinding.js";
|
|
20
20
|
import { resolveWorkshopModel } from "../workshop/modelSettings.js";
|
|
21
21
|
import { createOperatorAgentHost, invokeProfileTool, } from "./host.js";
|
|
22
|
-
import { createAgentAuthorProfile } from "./profiles/agentAuthor.js";
|
|
22
|
+
import { AGENT_AUTHOR_PROFILE_ID, agentAuthorBridgeHint, createAgentAuthorProfile, formatAgentAuthorTurnPrompt, } from "./profiles/agentAuthor.js";
|
|
23
23
|
import { createWorkshopAuthorProfile, } from "./profiles/workshopAuthor.js";
|
|
24
24
|
import { readDraftFromContext } from "./draftContext.js";
|
|
25
25
|
export function sessionNeedsExtensionReload(loaded, needed) {
|
|
@@ -434,7 +434,7 @@ export function createPiOperatorAgentModel(options) {
|
|
|
434
434
|
syncAgentMessages(state.handle.session, state.handle.sessionManager);
|
|
435
435
|
state.replayed = true;
|
|
436
436
|
},
|
|
437
|
-
async complete({ profile, message, tools, onDelta, onActivity, modelId }) {
|
|
437
|
+
async complete({ profile, message, contextSnapshot, tools, onDelta, onActivity, modelId }) {
|
|
438
438
|
let state;
|
|
439
439
|
try {
|
|
440
440
|
state = await ensureBound(profile, tools, modelId);
|
|
@@ -472,8 +472,21 @@ export function createPiOperatorAgentModel(options) {
|
|
|
472
472
|
}
|
|
473
473
|
}
|
|
474
474
|
});
|
|
475
|
+
const toolNames = profile.tools.map((tool) => tool.name);
|
|
476
|
+
let prompt = message;
|
|
477
|
+
if (profile.id === AGENT_AUTHOR_PROFILE_ID) {
|
|
478
|
+
prompt = formatAgentAuthorTurnPrompt(message, contextSnapshot);
|
|
479
|
+
prompt = `${prompt}\n\n${agentAuthorBridgeHint(toolNames)}`;
|
|
480
|
+
if (modelId && isCursorModelRef(modelId) && toolNames.length > 0) {
|
|
481
|
+
const aliasLines = toolNames.map((name) => `- pi__${name} (playbook name: ${name})`);
|
|
482
|
+
prompt = `${prompt}\n${aliasLines.join("\n")}`;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
prompt = cursorBridgePrompt(prompt, modelId, toolNames);
|
|
487
|
+
}
|
|
475
488
|
try {
|
|
476
|
-
await state.handle.session.prompt(
|
|
489
|
+
await state.handle.session.prompt(prompt);
|
|
477
490
|
}
|
|
478
491
|
catch (err) {
|
|
479
492
|
unsubscribe();
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type AgentAuthorContext, type AgentAuthorDraft } from "../agentAuthorContext.js";
|
|
2
2
|
import type { OperatorAgentProfile } from "../types.js";
|
|
3
3
|
export declare const AGENT_AUTHOR_PROFILE_ID = "agent-author";
|
|
4
|
+
export declare function formatAgentAuthorTurnPrompt(message: string, contextSnapshot: unknown): string;
|
|
5
|
+
export declare function agentAuthorBridgeHint(toolNames: readonly string[]): string;
|
|
4
6
|
/** Objects merge key by key; arrays and scalars replace; `null` removes the key. */
|
|
5
7
|
export declare function mergeDraftPatch(draft: AgentAuthorDraft, patch: Record<string, unknown>): AgentAuthorDraft;
|
|
6
|
-
export declare const AGENT_AUTHOR_TOOL_NAMES: readonly ["read_project_file", "list_project_files", "list_mcp_servers", "update_agent_draft"];
|
|
8
|
+
export declare const AGENT_AUTHOR_TOOL_NAMES: readonly ["read_agent_draft", "read_project_file", "list_project_files", "list_mcp_servers", "list_author_catalog", "update_agent_draft"];
|
|
7
9
|
export declare function createAgentAuthorProfile(): OperatorAgentProfile;
|
|
8
10
|
export declare function createAgentAuthorContext(input: {
|
|
9
11
|
projectRoot: string;
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { readdir, readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { parse as parseYaml } from "yaml";
|
|
3
4
|
import { agentAuthorContextAdapter, emptyAgentAuthorDraft, isAgentAuthorContext, readAgentAuthorDraft, } from "../agentAuthorContext.js";
|
|
4
5
|
import { AGENT_ID_PATTERN, parseAgentDefinition } from "../../config/loadAgent.js";
|
|
5
6
|
import { listProjectMcpCatalog } from "../../config/resolveStageMcpServers.js";
|
|
6
7
|
import { AGENT_AUTHOR_PLAYBOOK } from "./agentAuthorPlaybook.js";
|
|
8
|
+
import { authorReadRefusal } from "./authorReadable.js";
|
|
9
|
+
import { connectionsFilePath } from "../../channels/registry.js";
|
|
10
|
+
import { loadConnectionsFile } from "../../channels/config.js";
|
|
11
|
+
import { listSkills } from "../../config/listSkills.js";
|
|
12
|
+
import { globalStageflowHome } from "../../project/globalHome.js";
|
|
7
13
|
export const AGENT_AUTHOR_PROFILE_ID = "agent-author";
|
|
8
14
|
const MAX_READ_CHARS = 32_000;
|
|
9
15
|
let proposalSeq = 0;
|
|
@@ -38,6 +44,60 @@ function stringArg(args, key) {
|
|
|
38
44
|
function isPlainObject(value) {
|
|
39
45
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
40
46
|
}
|
|
47
|
+
function coercePlainObject(value) {
|
|
48
|
+
if (isPlainObject(value))
|
|
49
|
+
return value;
|
|
50
|
+
if (typeof value !== "string")
|
|
51
|
+
return null;
|
|
52
|
+
const trimmed = value.trim();
|
|
53
|
+
if (!trimmed)
|
|
54
|
+
return null;
|
|
55
|
+
try {
|
|
56
|
+
const parsed = JSON.parse(trimmed);
|
|
57
|
+
if (isPlainObject(parsed))
|
|
58
|
+
return parsed;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
/* not JSON */
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const parsed = parseYaml(trimmed);
|
|
65
|
+
if (isPlainObject(parsed))
|
|
66
|
+
return parsed;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
/* not YAML */
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
export function formatAgentAuthorTurnPrompt(message, contextSnapshot) {
|
|
74
|
+
const draft = readAgentAuthorDraft(contextSnapshot);
|
|
75
|
+
const draftJson = JSON.stringify(draft, null, 2);
|
|
76
|
+
return [
|
|
77
|
+
"Current agent draft JSON. Ask until the job is clear. Call update_agent_draft only when you draft or revise; do not reply with YAML instead:",
|
|
78
|
+
draftJson,
|
|
79
|
+
"",
|
|
80
|
+
"Operator message:",
|
|
81
|
+
message.trim(),
|
|
82
|
+
].join("\n");
|
|
83
|
+
}
|
|
84
|
+
export function agentAuthorBridgeHint(toolNames) {
|
|
85
|
+
return [
|
|
86
|
+
"Agent author: a thin first request is not a spec. Ask what you still need, or offer one suggestion when the answer is vague. Do not call update_agent_draft until they confirm the job or tell you to go ahead.",
|
|
87
|
+
"When you do change the draft, call update_agent_draft before you finish. Chat YAML does not update the panel.",
|
|
88
|
+
"You may read only docs/, policies/, AGENTS.md, and README.md. Do not grant a connection, MCP server, or skill that list_author_catalog or list_mcp_servers did not return. Do not set tools.browser.",
|
|
89
|
+
`Tools: ${toolNames.join(", ")}`,
|
|
90
|
+
].join("\n");
|
|
91
|
+
}
|
|
92
|
+
function patchFromToolArgs(args) {
|
|
93
|
+
const patch = coercePlainObject(args.patch);
|
|
94
|
+
if (patch)
|
|
95
|
+
return patch;
|
|
96
|
+
const { summary: _summary, patch: _patch, ...rest } = args;
|
|
97
|
+
if (Object.keys(rest).length === 0)
|
|
98
|
+
return null;
|
|
99
|
+
return coercePlainObject(rest) ?? (isPlainObject(rest) ? rest : null);
|
|
100
|
+
}
|
|
41
101
|
/** Objects merge key by key; arrays and scalars replace; `null` removes the key. */
|
|
42
102
|
export function mergeDraftPatch(draft, patch) {
|
|
43
103
|
const next = structuredClone(draft);
|
|
@@ -75,6 +135,9 @@ const readProjectFile = {
|
|
|
75
135
|
const rejected = rejectEscape(root, rel);
|
|
76
136
|
if (rejected)
|
|
77
137
|
return { ok: false, content: null, error: rejected };
|
|
138
|
+
const docsOnly = authorReadRefusal(rel);
|
|
139
|
+
if (docsOnly)
|
|
140
|
+
return { ok: false, content: null, error: docsOnly };
|
|
78
141
|
try {
|
|
79
142
|
const bytes = await readFile(path.resolve(root, rel));
|
|
80
143
|
if (bytes.includes(0))
|
|
@@ -95,32 +158,61 @@ const readProjectFile = {
|
|
|
95
158
|
};
|
|
96
159
|
const listProjectFiles = {
|
|
97
160
|
name: "list_project_files",
|
|
98
|
-
description: "List
|
|
161
|
+
description: "List documentation the author may read: docs/ and policies/ (.md and .txt), plus AGENTS.md and README.md at the project root. Does not list source code.",
|
|
99
162
|
async handler(_args, ctx) {
|
|
100
163
|
const root = projectRootOf(ctx);
|
|
101
164
|
if (!root)
|
|
102
165
|
return { ok: false, content: null, error: "project root is not set" };
|
|
103
166
|
const files = [];
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
167
|
+
for (const name of ["AGENTS.md", "README.md"]) {
|
|
168
|
+
try {
|
|
169
|
+
await readFile(path.join(root, name));
|
|
170
|
+
files.push(name);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
/* absent */
|
|
174
|
+
}
|
|
110
175
|
}
|
|
111
|
-
|
|
112
|
-
|
|
176
|
+
async function walk(rel) {
|
|
177
|
+
let entries;
|
|
178
|
+
try {
|
|
179
|
+
entries = await readdir(path.join(root, rel), { withFileTypes: true });
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
113
184
|
for (const entry of entries) {
|
|
114
|
-
if (entry.
|
|
115
|
-
|
|
185
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
186
|
+
continue;
|
|
187
|
+
const child = `${rel}/${entry.name}`;
|
|
188
|
+
if (entry.isDirectory())
|
|
189
|
+
await walk(child);
|
|
190
|
+
else if (!authorReadRefusal(child))
|
|
191
|
+
files.push(child);
|
|
116
192
|
}
|
|
117
193
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
194
|
+
await walk("docs");
|
|
195
|
+
await walk("policies");
|
|
196
|
+
files.sort();
|
|
121
197
|
return { ok: true, content: { files } };
|
|
122
198
|
},
|
|
123
199
|
};
|
|
200
|
+
const readAgentDraft = {
|
|
201
|
+
name: "read_agent_draft",
|
|
202
|
+
description: "Read the current unsaved agent draft (agents/<id>.agent.yaml shape). Use before update_agent_draft when you need the latest fields.",
|
|
203
|
+
handler(_args, ctx) {
|
|
204
|
+
const draft = readAgentAuthorDraft(ctx.getContext());
|
|
205
|
+
const context = ctx.getContext();
|
|
206
|
+
const projectRoot = isAgentAuthorContext(context) ? context.projectRoot : undefined;
|
|
207
|
+
return {
|
|
208
|
+
ok: true,
|
|
209
|
+
content: {
|
|
210
|
+
...(projectRoot ? { projectRoot } : {}),
|
|
211
|
+
draft,
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
},
|
|
215
|
+
};
|
|
124
216
|
const listMcpServers = {
|
|
125
217
|
name: "list_mcp_servers",
|
|
126
218
|
description: "List MCP server names declared in the project's .mcp.json. Use these names under tools.mcp. Does not connect.",
|
|
@@ -132,6 +224,32 @@ const listMcpServers = {
|
|
|
132
224
|
return { ok: true, content: { status: catalog.status, servers: catalog.servers.map((server) => server.name) } };
|
|
133
225
|
},
|
|
134
226
|
};
|
|
227
|
+
const listAuthorCatalog = {
|
|
228
|
+
name: "list_author_catalog",
|
|
229
|
+
description: "List host connections (id and provider only) and installed skill names. No secrets. Use these ids in channel.connection_id and tools.skills. If a name is not listed, do not grant it.",
|
|
230
|
+
async handler(_args, ctx) {
|
|
231
|
+
const root = projectRootOf(ctx);
|
|
232
|
+
if (!root)
|
|
233
|
+
return { ok: false, content: null, error: "project root is not set" };
|
|
234
|
+
let connections = [];
|
|
235
|
+
try {
|
|
236
|
+
const loaded = loadConnectionsFile(connectionsFilePath(root));
|
|
237
|
+
connections = loaded.connections.map((entry) => ({ id: entry.id, provider: entry.provider }));
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
connections = [];
|
|
241
|
+
}
|
|
242
|
+
let skills = [];
|
|
243
|
+
try {
|
|
244
|
+
const catalog = await listSkills({ cwd: root, agentDir: path.join(globalStageflowHome(), "workshop", "agent") });
|
|
245
|
+
skills = catalog.skills.map((skill) => skill.name);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
skills = [];
|
|
249
|
+
}
|
|
250
|
+
return { ok: true, content: { connections, skills } };
|
|
251
|
+
},
|
|
252
|
+
};
|
|
135
253
|
const updateAgentDraft = {
|
|
136
254
|
name: "update_agent_draft",
|
|
137
255
|
description: [
|
|
@@ -140,9 +258,9 @@ const updateAgentDraft = {
|
|
|
140
258
|
"The result lists validation issues; fix them in a follow-up patch. Does not write YAML.",
|
|
141
259
|
].join(" "),
|
|
142
260
|
handler(args, ctx) {
|
|
143
|
-
const patch = args
|
|
144
|
-
if (!
|
|
145
|
-
return { ok: false, content: null, error: "patch must be an object" };
|
|
261
|
+
const patch = patchFromToolArgs(args);
|
|
262
|
+
if (!patch)
|
|
263
|
+
return { ok: false, content: null, error: "patch must be an object (JSON or YAML)" };
|
|
146
264
|
const currentContext = ctx.getContext();
|
|
147
265
|
const current = readAgentAuthorDraft(currentContext);
|
|
148
266
|
const next = mergeDraftPatch(current, patch);
|
|
@@ -172,14 +290,21 @@ const updateAgentDraft = {
|
|
|
172
290
|
};
|
|
173
291
|
},
|
|
174
292
|
};
|
|
175
|
-
export const AGENT_AUTHOR_TOOL_NAMES = [
|
|
293
|
+
export const AGENT_AUTHOR_TOOL_NAMES = [
|
|
294
|
+
"read_agent_draft",
|
|
295
|
+
"read_project_file",
|
|
296
|
+
"list_project_files",
|
|
297
|
+
"list_mcp_servers",
|
|
298
|
+
"list_author_catalog",
|
|
299
|
+
"update_agent_draft",
|
|
300
|
+
];
|
|
176
301
|
export function createAgentAuthorProfile() {
|
|
177
302
|
return {
|
|
178
303
|
id: AGENT_AUTHOR_PROFILE_ID,
|
|
179
304
|
title: "Agent author",
|
|
180
305
|
playbook: AGENT_AUTHOR_PLAYBOOK,
|
|
181
|
-
greeting: "
|
|
182
|
-
tools: [readProjectFile, listProjectFiles, listMcpServers, updateAgentDraft],
|
|
306
|
+
greeting: "Who is this agent for, and what does a good result look like? I'll ask a few questions before I fill the config.",
|
|
307
|
+
tools: [readAgentDraft, readProjectFile, listProjectFiles, listMcpServers, listAuthorCatalog, updateAgentDraft],
|
|
183
308
|
contextAdapter: agentAuthorContextAdapter(),
|
|
184
309
|
};
|
|
185
310
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_AUTHOR_PLAYBOOK = "You are the Stageflow Agent author. You
|
|
1
|
+
export declare const AGENT_AUTHOR_PLAYBOOK = "You are the Stageflow Agent author. You help an operator design one sealed project agent that will actually be useful. You are not a task runner, and you do not write files.\n\nA first message is a starting point, not a spec. Your job is to understand the use case before you fill the config.\n\n## How you talk\n- Short turns, plain words, present tense.\n- Two or three questions a turn. Do not dump a questionnaire.\n- Do not narrate tool names.\n- The config panel shows the draft. The operator can edit it directly; your next patch builds on what they changed.\n\n## Understand the job first\nDo not call update_agent_draft while the brief is still thin. Asking questions is a complete turn.\n\nLearn, in whatever order the gaps are:\n- Who uses it, and in what situation (a person in chat, a schedule, a channel).\n- What a good result looks like, and what a bad one looks like.\n- What it may read, and what it may change.\n- What it must never do without asking.\n- Where the source of truth lives. You may read only documentation: docs/, policies/, AGENTS.md, and README.md (.md and .txt). You cannot read source code. If they point at code, say you only read documentation and ask which doc describes the behavior.\n\nUse what they already said. Ask only what would change the draft.\n\nWhen an answer is vague, confused, or contradicts an earlier one:\n- Restate what you heard in one sentence.\n- Offer one concrete suggestion they can accept or correct (a name, a boundary, a tool grant, or a refusal).\n- Ask which part is wrong.\n\nWhen you can describe the job in two or three sentences, say that summary and ask them to confirm or correct it. Do not draft before they confirm, unless they tell you to go ahead anyway.\n\nWhen the brief is thin, offer one concrete agent: a name, what it will do, what it will not do, and which tools. When they accept that suggestion, call update_agent_draft in that same turn. Do not wait for another question.\n\nIf they say \"just build it\" before the brief is solid:\n- State the assumptions in one or two sentences.\n- Offer the narrowest useful version.\n- Draft only after they accept those assumptions, or if they insist a second time. Name every assumption in the reply after you draft.\n\n## When you draft\n- Call update_agent_draft in that turn. Chat text does not update the panel. Do not paste YAML unless they ask to see it.\n- instructions must describe this job: who it serves, how it decides, what it refuses, and what a good reply contains. Do not write a generic \"be helpful\" prompt.\n- Grant only the tools the job needs. A new agent stays sealed: read only, until the job needs write or shell.\n- Anything that sends, posts, writes, merges, or deletes goes in approvals.ask_first.\n- Leave model.id unset unless they name a model, and say you did that.\n- Capture stays metadata unless they ask for full content.\n- If update_agent_draft reports issues, fix them with another patch before you finish.\n\nAfter the patch, one sentence on what the agent will do. Then one sentence naming anything they asked for that you did not turn on: a doc you could not read, a channel or skill that list_author_catalog or list_mcp_servers did not return, or browsing. Do not set tools.browser. Do not invent a connection id, MCP server, or skill name.\n\n## Tools\n- read_agent_draft returns the current unsaved draft JSON. Each turn also includes that draft in the operator message.\n- read_project_file and list_project_files are read-only and documentation only: docs/, policies/, AGENTS.md, and README.md, and only .md or .txt. A refused path means you tell them you cannot read code or other files.\n- list_mcp_servers names the servers in .mcp.json. list_author_catalog names host connections (id and provider) and installed skills. Grant only names those tools return. If they want one that is not listed, say it is not connected or not installed.\n- update_agent_draft applies a patch immediately. Objects merge key by key, arrays replace, null removes a key. Do not wait for Keep.\n- Never use bash, write, or edit. Save is the operator's button, not a tool.\n\n## The draft (agents/<id>.agent.yaml schema)\n- id (snake_case, starts with a letter; derived from name when omitted), name, description, greeting, instructions (required).\n- model: { backend: pi | claude, id?: \"provider/model\", thinking: low | medium | high }.\n- tools: { builtin: [read | write | shell] (whole groups), builtin_tools: [read | grep | find | ls | write | edit | bash] (single tools), stageflow: { groups: [...], tools: [...] }, mcp: { <server>: [tool names] or [\"*\"] }, skills: [names], browser: bool }.\n- approvals: { ask_first: [tool ids], approvers: { operators: bool, channel_ids: [] }, timeout_minutes, on_timeout: skip | deny }.\n Tool ids: builtin names (read, grep, find, ls, write, edit, bash), \"<server>.<tool>\" for MCP, \"agent:<id>\" for sub-agents. ask_first may only name granted tools.\n- sub_agents: [agent ids], observability: { capture: off | metadata | full }, limits: { session_minutes, max_turns, cost_usd | null, long_context: summarize | truncate }, guardrails: { block_patterns: [JavaScript regex] }, schedule: { cron, timezone?, message? }.\n";
|
|
@@ -1,29 +1,62 @@
|
|
|
1
|
-
export const AGENT_AUTHOR_PLAYBOOK = `You are the Stageflow Agent author. You
|
|
1
|
+
export const AGENT_AUTHOR_PLAYBOOK = `You are the Stageflow Agent author. You help an operator design one sealed project agent that will actually be useful. You are not a task runner, and you do not write files.
|
|
2
|
+
|
|
3
|
+
A first message is a starting point, not a spec. Your job is to understand the use case before you fill the config.
|
|
2
4
|
|
|
3
5
|
## How you talk
|
|
4
|
-
- Short turns, plain words, present tense.
|
|
5
|
-
-
|
|
6
|
+
- Short turns, plain words, present tense.
|
|
7
|
+
- Two or three questions a turn. Do not dump a questionnaire.
|
|
8
|
+
- Do not narrate tool names.
|
|
6
9
|
- The config panel shows the draft. The operator can edit it directly; your next patch builds on what they changed.
|
|
7
10
|
|
|
11
|
+
## Understand the job first
|
|
12
|
+
Do not call update_agent_draft while the brief is still thin. Asking questions is a complete turn.
|
|
13
|
+
|
|
14
|
+
Learn, in whatever order the gaps are:
|
|
15
|
+
- Who uses it, and in what situation (a person in chat, a schedule, a channel).
|
|
16
|
+
- What a good result looks like, and what a bad one looks like.
|
|
17
|
+
- What it may read, and what it may change.
|
|
18
|
+
- What it must never do without asking.
|
|
19
|
+
- Where the source of truth lives. You may read only documentation: docs/, policies/, AGENTS.md, and README.md (.md and .txt). You cannot read source code. If they point at code, say you only read documentation and ask which doc describes the behavior.
|
|
20
|
+
|
|
21
|
+
Use what they already said. Ask only what would change the draft.
|
|
22
|
+
|
|
23
|
+
When an answer is vague, confused, or contradicts an earlier one:
|
|
24
|
+
- Restate what you heard in one sentence.
|
|
25
|
+
- Offer one concrete suggestion they can accept or correct (a name, a boundary, a tool grant, or a refusal).
|
|
26
|
+
- Ask which part is wrong.
|
|
27
|
+
|
|
28
|
+
When you can describe the job in two or three sentences, say that summary and ask them to confirm or correct it. Do not draft before they confirm, unless they tell you to go ahead anyway.
|
|
29
|
+
|
|
30
|
+
When the brief is thin, offer one concrete agent: a name, what it will do, what it will not do, and which tools. When they accept that suggestion, call update_agent_draft in that same turn. Do not wait for another question.
|
|
31
|
+
|
|
32
|
+
If they say "just build it" before the brief is solid:
|
|
33
|
+
- State the assumptions in one or two sentences.
|
|
34
|
+
- Offer the narrowest useful version.
|
|
35
|
+
- Draft only after they accept those assumptions, or if they insist a second time. Name every assumption in the reply after you draft.
|
|
36
|
+
|
|
37
|
+
## When you draft
|
|
38
|
+
- Call update_agent_draft in that turn. Chat text does not update the panel. Do not paste YAML unless they ask to see it.
|
|
39
|
+
- instructions must describe this job: who it serves, how it decides, what it refuses, and what a good reply contains. Do not write a generic "be helpful" prompt.
|
|
40
|
+
- Grant only the tools the job needs. A new agent stays sealed: read only, until the job needs write or shell.
|
|
41
|
+
- Anything that sends, posts, writes, merges, or deletes goes in approvals.ask_first.
|
|
42
|
+
- Leave model.id unset unless they name a model, and say you did that.
|
|
43
|
+
- Capture stays metadata unless they ask for full content.
|
|
44
|
+
- If update_agent_draft reports issues, fix them with another patch before you finish.
|
|
45
|
+
|
|
46
|
+
After the patch, one sentence on what the agent will do. Then one sentence naming anything they asked for that you did not turn on: a doc you could not read, a channel or skill that list_author_catalog or list_mcp_servers did not return, or browsing. Do not set tools.browser. Do not invent a connection id, MCP server, or skill name.
|
|
47
|
+
|
|
8
48
|
## Tools
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
49
|
+
- read_agent_draft returns the current unsaved draft JSON. Each turn also includes that draft in the operator message.
|
|
50
|
+
- read_project_file and list_project_files are read-only and documentation only: docs/, policies/, AGENTS.md, and README.md, and only .md or .txt. A refused path means you tell them you cannot read code or other files.
|
|
51
|
+
- list_mcp_servers names the servers in .mcp.json. list_author_catalog names host connections (id and provider) and installed skills. Grant only names those tools return. If they want one that is not listed, say it is not connected or not installed.
|
|
52
|
+
- update_agent_draft applies a patch immediately. Objects merge key by key, arrays replace, null removes a key. Do not wait for Keep.
|
|
12
53
|
- Never use bash, write, or edit. Save is the operator's button, not a tool.
|
|
13
54
|
|
|
14
55
|
## The draft (agents/<id>.agent.yaml schema)
|
|
15
56
|
- id (snake_case, starts with a letter; derived from name when omitted), name, description, greeting, instructions (required).
|
|
16
|
-
- model: { backend: pi | claude, id?: "provider/model", thinking: low | medium | high }.
|
|
57
|
+
- model: { backend: pi | claude, id?: "provider/model", thinking: low | medium | high }.
|
|
17
58
|
- tools: { builtin: [read | write | shell] (whole groups), builtin_tools: [read | grep | find | ls | write | edit | bash] (single tools), stageflow: { groups: [...], tools: [...] }, mcp: { <server>: [tool names] or ["*"] }, skills: [names], browser: bool }.
|
|
18
59
|
- approvals: { ask_first: [tool ids], approvers: { operators: bool, channel_ids: [] }, timeout_minutes, on_timeout: skip | deny }.
|
|
19
60
|
Tool ids: builtin names (read, grep, find, ls, write, edit, bash), "<server>.<tool>" for MCP, "agent:<id>" for sub-agents. ask_first may only name granted tools.
|
|
20
61
|
- sub_agents: [agent ids], observability: { capture: off | metadata | full }, limits: { session_minutes, max_turns, cost_usd | null, long_context: summarize | truncate }, guardrails: { block_patterns: [JavaScript regex] }, schedule: { cron, timezone?, message? }.
|
|
21
|
-
|
|
22
|
-
## Defaults
|
|
23
|
-
- A new agent saves disabled and starts sealed: read only. Write and shell stay off unless the job needs them.
|
|
24
|
-
- Anything that sends, posts, writes, merges or deletes goes in approvals.ask_first.
|
|
25
|
-
- Capture stays metadata unless they ask for full content.
|
|
26
|
-
|
|
27
|
-
## After an edit
|
|
28
|
-
- One sentence on what the agent will do now. Mention any assumption or open question. Do not paste YAML unless they ask.
|
|
29
62
|
`;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const DOC_ROOTS = new Set(["docs", "policies"]);
|
|
2
|
+
const ROOT_FILES = new Set(["AGENTS.md", "README.md"]);
|
|
3
|
+
/** Relative project path the agent author may read. Null when it is documentation. */
|
|
4
|
+
export function authorReadRefusal(rel) {
|
|
5
|
+
const normalized = rel.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
6
|
+
if (!normalized || normalized.startsWith("/") || normalized.split("/").includes("..")) {
|
|
7
|
+
return "path is outside the readable project surface";
|
|
8
|
+
}
|
|
9
|
+
const segments = normalized.split("/").filter(Boolean);
|
|
10
|
+
if (segments.some((part) => part === ".git" || part === "node_modules" || part.startsWith("."))) {
|
|
11
|
+
return "path is outside the readable project surface";
|
|
12
|
+
}
|
|
13
|
+
if (ROOT_FILES.has(normalized))
|
|
14
|
+
return null;
|
|
15
|
+
const [head, ...rest] = segments;
|
|
16
|
+
if (!head || !DOC_ROOTS.has(head)) {
|
|
17
|
+
return "only documentation under docs/ and policies/, plus AGENTS.md and README.md, can be read";
|
|
18
|
+
}
|
|
19
|
+
if (rest.length === 0)
|
|
20
|
+
return "path must be a documentation file";
|
|
21
|
+
const base = rest[rest.length - 1] ?? "";
|
|
22
|
+
if (!base.endsWith(".md") && !base.endsWith(".txt")) {
|
|
23
|
+
return "only .md and .txt documentation can be read";
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
package/dist/package-meta.d.ts
CHANGED
package/dist/package-meta.js
CHANGED
package/dist/runstore/port.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { StageLogLine } from "../agent/activity.js";
|
|
2
|
+
import type { EvalTargetKind } from "../evals/constants.js";
|
|
2
3
|
import type { ConfigOriginRecord } from "../config/configOrigin.js";
|
|
3
4
|
import type { RunSubmission, RunSubmissionRecord } from "./submission.js";
|
|
4
5
|
import type { AskOperatorPrompt } from "../tools/askOperator.js";
|
|
@@ -8,6 +9,9 @@ import type { CompletionCheck } from "../types/completion.js";
|
|
|
8
9
|
import type { StageGateKind } from "../types/stage.js";
|
|
9
10
|
import type { StageUsage } from "../types/usage.js";
|
|
10
11
|
import type { OverviewRunRow } from "./overviewSummary.js";
|
|
12
|
+
import type { CreateEvalRunInput, EvalCaseInput, EvalCaseRow, EvalGraderVersionInput, EvalResultInput, EvalResultWithGrades, EvalReviewPatch, EvalReviewRow, EvalRunPage, EvalRunProgress, EvalRunRow, FinishEvalRunInput, ListEvalRunsQuery } from "../evals/storeTypes.js";
|
|
13
|
+
import type { SuggestionStatus } from "../evals/triage/constants.js";
|
|
14
|
+
import type { SuggestionInput, SuggestionRow } from "../evals/triage/types.js";
|
|
11
15
|
export type { ConfigOriginRecord };
|
|
12
16
|
export type RunStatus = "created" | "queued" | "running" | "succeeded" | "failed" | "cancelled";
|
|
13
17
|
export type RunPipelineDagSnapshot = ResolvedPipelineDag & {
|
|
@@ -40,6 +44,7 @@ export type PipelineTrackProjection = {
|
|
|
40
44
|
nodes: PipelineTrackNode[];
|
|
41
45
|
edges: PipelineTrackEdge[];
|
|
42
46
|
};
|
|
47
|
+
export type RunOrigin = "eval";
|
|
43
48
|
export type RunMeta = {
|
|
44
49
|
run_id: string;
|
|
45
50
|
pipeline_id: string;
|
|
@@ -69,6 +74,8 @@ export type RunMeta = {
|
|
|
69
74
|
config_origins?: ConfigOriginRecord[];
|
|
70
75
|
pipeline_source?: "inline" | "path";
|
|
71
76
|
caller_id?: string;
|
|
77
|
+
/** `eval` for stage runs started by an eval run; absent for normal runs. */
|
|
78
|
+
origin?: RunOrigin;
|
|
72
79
|
run_manifest?: unknown;
|
|
73
80
|
skip_gates?: boolean;
|
|
74
81
|
/**
|
|
@@ -372,6 +379,7 @@ export type CreateRunInput = {
|
|
|
372
379
|
*/
|
|
373
380
|
inlinePipeline?: InlinePipelineDefinition;
|
|
374
381
|
callerId?: string;
|
|
382
|
+
origin?: RunOrigin;
|
|
375
383
|
runManifest?: unknown;
|
|
376
384
|
skipGates?: boolean;
|
|
377
385
|
};
|
|
@@ -382,6 +390,8 @@ export type ListRunsFilter = {
|
|
|
382
390
|
/** Match pipeline_id or pipeline_path */
|
|
383
391
|
pipeline?: string;
|
|
384
392
|
caller_id?: string;
|
|
393
|
+
/** Default (undefined) hides eval stage runs; `"any"` includes them; `"eval"` returns only them. */
|
|
394
|
+
origin?: RunOrigin | "any";
|
|
385
395
|
};
|
|
386
396
|
/**
|
|
387
397
|
* Persistence port for pipeline run state.
|
|
@@ -466,6 +476,39 @@ export interface RunStore {
|
|
|
466
476
|
listRuns(filter?: ListRunsFilter): Promise<RunSummary[]>;
|
|
467
477
|
/** One light row per run created at or after `since` (ISO), newest first, with summed stage cost. No stages are loaded. */
|
|
468
478
|
listRunOverviewRows(since: string): Promise<OverviewRunRow[]>;
|
|
479
|
+
createEvalRun(input: CreateEvalRunInput): Promise<EvalRunRow>;
|
|
480
|
+
insertEvalCases(evalRunId: string, cases: EvalCaseInput[]): Promise<void>;
|
|
481
|
+
/** Result row and its grade rows in one transaction; replaces any earlier grades for the same result. */
|
|
482
|
+
upsertEvalResult(result: EvalResultInput): Promise<void>;
|
|
483
|
+
updateEvalRunProgress(evalRunId: string, progress: EvalRunProgress): Promise<void>;
|
|
484
|
+
finishEvalRun(evalRunId: string, input: FinishEvalRunInput): Promise<void>;
|
|
485
|
+
getEvalRun(evalRunId: string): Promise<EvalRunRow | null>;
|
|
486
|
+
getEvalRunByNumber(projectRoot: string, evalId: string, runNumber: number): Promise<EvalRunRow | null>;
|
|
487
|
+
listEvalRuns(query: ListEvalRunsQuery): Promise<EvalRunPage>;
|
|
488
|
+
listEvalResults(evalRunId: string): Promise<EvalResultWithGrades[]>;
|
|
489
|
+
getEvalResultsForCase(evalRunId: string, caseId: string): Promise<EvalResultWithGrades[]>;
|
|
490
|
+
getEvalCases(evalRunId: string): Promise<EvalCaseRow[]>;
|
|
491
|
+
/** `tags` replaces the tag set and is accepted only for results with `passed = 0`. */
|
|
492
|
+
putEvalReview(evalRunId: string, caseId: string, repeatIndex: number, patch: EvalReviewPatch): Promise<EvalReviewRow>;
|
|
493
|
+
getEvalReviews(evalRunId: string): Promise<EvalReviewRow[]>;
|
|
494
|
+
/** The eval's failure-type vocabulary, most recently used first. */
|
|
495
|
+
listFailureTypes(projectRoot: string, evalId: string): Promise<string[]>;
|
|
496
|
+
/** Inserts unseen grader hashes with the next ordinal per grader id; returns grader id to ordinal. */
|
|
497
|
+
recordGraderVersions(projectRoot: string, evalId: string, graders: EvalGraderVersionInput[]): Promise<Record<string, number>>;
|
|
498
|
+
/** Deletes the eval run and its rows; returns the stage run ids it started so the caller can delete those runs. */
|
|
499
|
+
deleteEvalRun(evalRunId: string): Promise<string[]>;
|
|
500
|
+
/** Distinct non-null result subject refs (stage run ids or agent session ids) when the run's target kind matches. */
|
|
501
|
+
listEvalSubjectRefs(evalRunId: string, targetKind: EvalTargetKind): Promise<string[]>;
|
|
502
|
+
/** Inserts or replaces pending suggestions (accepted and dismissed are kept); returns the rows written. */
|
|
503
|
+
upsertEvalSuggestions(evalRunId: string, inputs: SuggestionInput[]): Promise<SuggestionRow[]>;
|
|
504
|
+
listEvalSuggestions(evalRunId: string, status?: SuggestionStatus): Promise<SuggestionRow[]>;
|
|
505
|
+
/** Pending only; returns how many changed. */
|
|
506
|
+
dismissEvalSuggestions(evalRunId: string, ids: string[]): Promise<number>;
|
|
507
|
+
/** Pending only; adds the failure type and `bucket:` tags through the review write path. */
|
|
508
|
+
acceptEvalSuggestions(evalRunId: string, ids: string[]): Promise<{
|
|
509
|
+
accepted: number;
|
|
510
|
+
tagged: number;
|
|
511
|
+
}>;
|
|
469
512
|
/** Idempotent upsert; returns the realpath/resolve-normalized absolute key. */
|
|
470
513
|
ensureProject(absPath: string): Promise<string>;
|
|
471
514
|
/** Absolute roots from the durable projects registry. */
|