stageflow 0.42.0 → 0.46.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/evalGate.js +1 -0
- 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/cli/evalCommand.d.ts +1 -1
- package/dist/cli/evalCommand.js +39 -2
- package/dist/cli/hostClient.d.ts +6 -0
- package/dist/cli/hostClient.js +4 -0
- package/dist/compaction/directives.d.ts +18 -0
- package/dist/compaction/directives.js +119 -0
- package/dist/compaction/extension.d.ts +20 -0
- package/dist/compaction/extension.js +78 -0
- package/dist/compaction/mask.d.ts +18 -0
- package/dist/compaction/mask.js +155 -0
- package/dist/compaction/pin.d.ts +21 -0
- package/dist/compaction/pin.js +270 -0
- package/dist/compaction/scrub.d.ts +7 -0
- package/dist/compaction/scrub.js +26 -0
- package/dist/compaction/sessionWiring.d.ts +22 -0
- package/dist/compaction/sessionWiring.js +26 -0
- package/dist/compaction/summarize.d.ts +79 -0
- package/dist/compaction/summarize.js +171 -0
- package/dist/compaction/toolPolicy.d.ts +3 -0
- package/dist/compaction/toolPolicy.js +33 -0
- package/dist/compaction/types.d.ts +45 -0
- package/dist/compaction/types.js +7 -0
- package/dist/compaction/workingState.d.ts +56 -0
- package/dist/compaction/workingState.js +198 -0
- package/dist/config/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.d.ts +3 -1
- package/dist/config/loadEval.js +96 -10
- 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 +60 -3
- 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/calibration.d.ts +21 -0
- package/dist/evals/calibration.js +69 -0
- package/dist/evals/calibrationSuggest.d.ts +29 -0
- package/dist/evals/calibrationSuggest.js +72 -0
- package/dist/evals/calibrator.d.ts +46 -0
- package/dist/evals/calibrator.js +148 -0
- package/dist/evals/compare.d.ts +1 -1
- package/dist/evals/compare.js +3 -0
- package/dist/evals/constants.d.ts +7 -3
- package/dist/evals/constants.js +7 -1
- package/dist/evals/engine/FakeEngine.d.ts +2 -1
- package/dist/evals/engine/FakeEngine.js +9 -3
- package/dist/evals/engine/promptfoo/PromptfooEngine.d.ts +1 -1
- package/dist/evals/engine/promptfoo/PromptfooEngine.js +4 -2
- package/dist/evals/engine/promptfoo/generate.d.ts +3 -1
- package/dist/evals/engine/promptfoo/generate.js +43 -23
- package/dist/evals/engine/promptfoo/judgeProviders.js +2 -1
- package/dist/evals/engine/promptfoo/normalize.d.ts +4 -1
- package/dist/evals/engine/promptfoo/normalize.js +16 -3
- package/dist/evals/engine/promptfoo/rubricPrompt.d.ts +3 -1
- package/dist/evals/engine/promptfoo/rubricPrompt.js +15 -5
- package/dist/evals/errors.d.ts +7 -0
- package/dist/evals/errors.js +10 -0
- package/dist/evals/judgeProviders.d.ts +6 -0
- package/dist/evals/judgeProviders.js +14 -0
- package/dist/evals/judged.d.ts +7 -0
- package/dist/evals/judged.js +7 -0
- package/dist/evals/manager.d.ts +27 -8
- package/dist/evals/manager.js +73 -12
- package/dist/evals/plan.d.ts +10 -1
- package/dist/evals/plan.js +33 -13
- package/dist/evals/planInternalAgent.d.ts +19 -0
- package/dist/evals/planInternalAgent.js +201 -0
- package/dist/evals/read/api.d.ts +18 -0
- package/dist/evals/read/api.js +10 -1
- package/dist/evals/read/labelQueue.d.ts +45 -0
- package/dist/evals/read/labelQueue.js +83 -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/stats.d.ts +40 -0
- package/dist/evals/stats.js +69 -0
- package/dist/evals/storeTypes.d.ts +42 -0
- package/dist/evals/types.d.ts +25 -2
- package/dist/evals/types.js +4 -1
- package/dist/evals/votes.d.ts +10 -0
- package/dist/evals/votes.js +60 -0
- package/dist/guide/cardContract.d.ts +133 -0
- package/dist/guide/cardContract.js +156 -0
- package/dist/guide/chat.d.ts +45 -0
- package/dist/guide/chat.js +378 -0
- package/dist/guide/knowledge/index.d.ts +14 -0
- package/dist/guide/knowledge/index.js +109 -0
- package/dist/guide/knowledge/topics/agents.d.ts +2 -0
- package/dist/guide/knowledge/topics/agents.js +58 -0
- package/dist/guide/knowledge/topics/bestPractices.d.ts +2 -0
- package/dist/guide/knowledge/topics/bestPractices.js +67 -0
- package/dist/guide/knowledge/topics/connections.d.ts +2 -0
- package/dist/guide/knowledge/topics/connections.js +66 -0
- package/dist/guide/knowledge/topics/consoleMap.d.ts +2 -0
- package/dist/guide/knowledge/topics/consoleMap.js +55 -0
- package/dist/guide/knowledge/topics/evals.d.ts +2 -0
- package/dist/guide/knowledge/topics/evals.js +72 -0
- package/dist/guide/knowledge/topics/limitations.d.ts +2 -0
- package/dist/guide/knowledge/topics/limitations.js +84 -0
- package/dist/guide/knowledge/topics/mcpSkillsBrowser.d.ts +2 -0
- package/dist/guide/knowledge/topics/mcpSkillsBrowser.js +57 -0
- package/dist/guide/knowledge/topics/memories.d.ts +2 -0
- package/dist/guide/knowledge/topics/memories.js +63 -0
- package/dist/guide/knowledge/topics/modelsAndProviders.d.ts +2 -0
- package/dist/guide/knowledge/topics/modelsAndProviders.js +56 -0
- package/dist/guide/knowledge/topics/overview.d.ts +2 -0
- package/dist/guide/knowledge/topics/overview.js +56 -0
- package/dist/guide/knowledge/topics/pipelines.d.ts +2 -0
- package/dist/guide/knowledge/topics/pipelines.js +93 -0
- package/dist/guide/knowledge/topics/stages.d.ts +2 -0
- package/dist/guide/knowledge/topics/stages.js +54 -0
- package/dist/guide/knowledge/topics/tasks.d.ts +2 -0
- package/dist/guide/knowledge/topics/tasks.js +52 -0
- package/dist/guide/knowledge/topics/triggers.d.ts +2 -0
- package/dist/guide/knowledge/topics/triggers.js +68 -0
- package/dist/guide/knowledge/topics/troubleshooting.d.ts +2 -0
- package/dist/guide/knowledge/topics/troubleshooting.js +85 -0
- package/dist/guide/knowledgeTools.d.ts +2 -0
- package/dist/guide/knowledgeTools.js +56 -0
- package/dist/guide/showUi.d.ts +6 -0
- package/dist/guide/showUi.js +546 -0
- package/dist/guide/threadStore.d.ts +48 -0
- package/dist/guide/threadStore.js +189 -0
- package/dist/guide/writeRoot.d.ts +11 -0
- package/dist/guide/writeRoot.js +70 -0
- package/dist/hosted/translate.js +2 -0
- package/dist/mcp/agentTools.js +12 -0
- package/dist/mcp/catalogTools.js +18 -20
- package/dist/mcp/catalogWriteTools.d.ts +8 -0
- package/dist/mcp/catalogWriteTools.js +225 -0
- package/dist/mcp/connectionTools.d.ts +3 -0
- package/dist/mcp/connectionTools.js +85 -0
- package/dist/mcp/controlTools.js +34 -1
- package/dist/mcp/deps.d.ts +9 -0
- package/dist/mcp/evalTools.js +723 -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 +133 -0
- package/dist/operatorAgent/profiles/workshopAuthor.js +23 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +1 -1
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +9 -1
- package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +2 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.js +197 -9
- package/dist/operatorAgent/types.d.ts +23 -0
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/runstore/port.d.ts +13 -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 +11 -1
- package/dist/runstore/sqlite/SqliteRunStore.js +70 -45
- package/dist/runstore/sqlite/calibrationStore.d.ts +10 -0
- package/dist/runstore/sqlite/calibrationStore.js +106 -0
- package/dist/runstore/sqlite/evalStore.d.ts +5 -0
- package/dist/runstore/sqlite/evalStore.js +7 -0
- package/dist/runstore/sqlite/migrations/018-eval-grader-labels.d.ts +11 -0
- package/dist/runstore/sqlite/migrations/018-eval-grader-labels.js +43 -0
- package/dist/runstore/sqlite/migrations/index.js +2 -0
- package/dist/runstore/workspaceLayout.js +6 -1
- package/dist/runtime/artifactDiskInspect.d.ts +14 -0
- package/dist/runtime/artifactDiskInspect.js +52 -0
- package/dist/runtime/artifactPath.d.ts +24 -0
- package/dist/runtime/artifactPath.js +84 -0
- package/dist/runtime/completionCheckRunner.js +15 -43
- package/dist/runtime/githubPollSource.d.ts +22 -4
- package/dist/runtime/githubPollSource.js +93 -8
- package/dist/runtime/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 +251 -12
- 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 +41 -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-BS2BBbCx.js} +2 -2
- package/dist/ui/assets/adapters-DPD-cAsy.js +17 -0
- package/dist/ui/assets/chat-BD1-VTT6.js +2 -0
- package/dist/ui/assets/chat-DXnQv9st.css +2 -0
- package/dist/ui/assets/main-AX5XNLtX.js +278 -0
- package/dist/ui/assets/{main-CHlmTNJe.css → main-CFX0_n8J.css} +1 -1
- 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/skills/stageflow/references/control-surface.md +1 -1
- package/skills/stageflow/references/evals.md +1 -0
- 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,12 @@
|
|
|
1
|
+
import { describeInternalAgents, internalAgentsVisible } from "../operatorAgent/internalAgents.js";
|
|
2
|
+
export const INTERNAL_AGENTS_PATH = "/api/internal-agents";
|
|
3
|
+
export function handleInternalAgentRoutes(method, pathname, host, res, json, env = process.env) {
|
|
4
|
+
if (pathname !== INTERNAL_AGENTS_PATH || method !== "GET")
|
|
5
|
+
return false;
|
|
6
|
+
if (!internalAgentsVisible(env)) {
|
|
7
|
+
json(res, 200, { visible: false, agents: [] });
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
json(res, 200, { visible: true, agents: describeInternalAgents(host) });
|
|
11
|
+
return true;
|
|
12
|
+
}
|
package/dist/server/mcpHost.js
CHANGED
|
@@ -30,6 +30,8 @@ export async function startMcpServer(options) {
|
|
|
30
30
|
...(boot.agentHost ? { agentHost: boot.agentHost } : {}),
|
|
31
31
|
...(boot.evalRunManager ? { evalRunManager: boot.evalRunManager } : {}),
|
|
32
32
|
...(boot.evalServices ? { evalServices: boot.evalServices } : {}),
|
|
33
|
+
...(boot.channels ? { channels: boot.channels } : {}),
|
|
34
|
+
...(boot.memories ? { memories: boot.memories } : {}),
|
|
33
35
|
});
|
|
34
36
|
const envelope = await createHttpHost({
|
|
35
37
|
boot,
|
package/dist/toolkit/meta.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* can import it without pulling in the runtime.
|
|
5
5
|
*/
|
|
6
6
|
export type ToolRisk = "read" | "write" | "destructive" | "external";
|
|
7
|
-
export type ToolGroupId = "discover" | "runs.read" | "runs.control" | "runs.cleanup" | "gates.read" | "gates.decide" | "triggers" | "agents.read" | "agents.manage" | "agents.cleanup" | "agents.converse" | "evals.read" | "evals.run" | "pipelines.author";
|
|
7
|
+
export type ToolGroupId = "discover" | "runs.read" | "runs.control" | "runs.cleanup" | "gates.read" | "gates.decide" | "triggers" | "agents.read" | "agents.manage" | "agents.cleanup" | "agents.converse" | "evals.read" | "evals.run" | "evals.write" | "evals.cleanup" | "pipelines.author" | "connections" | "connections.cleanup" | "memories" | "memories.cleanup";
|
|
8
8
|
export type ToolGroup = {
|
|
9
9
|
id: ToolGroupId;
|
|
10
10
|
title: string;
|
package/dist/toolkit/meta.js
CHANGED
|
@@ -16,8 +16,14 @@ export const TOOL_GROUPS = [
|
|
|
16
16
|
{ id: "agents.cleanup", title: "Archive agents", summary: "Archive an agent. Destructive." },
|
|
17
17
|
{ id: "agents.converse", title: "Talk to agents", summary: "Chat with an agent and stop its running turn." },
|
|
18
18
|
{ id: "pipelines.author", title: "Author pipelines and tasks", summary: "Read, create and edit pipelines, stages and tasks directly on disk." },
|
|
19
|
+
{ id: "connections", title: "Connections", summary: "List, create, test and update host connections. Secret values are stored and never returned." },
|
|
20
|
+
{ id: "connections.cleanup", title: "Remove connections", summary: "Remove a connection and its stored secrets. Destructive." },
|
|
21
|
+
{ id: "memories", title: "Memories", summary: "List, create and edit host memories and their cards." },
|
|
22
|
+
{ id: "memories.cleanup", title: "Delete memory cards", summary: "Delete one card from a host memory. Destructive." },
|
|
19
23
|
{ id: "evals.read", title: "Read evals", summary: "List evals, runs and results; validate and compare. Free." },
|
|
20
|
-
{ id: "evals.run", title: "Run evals", summary: "Start and cancel eval runs. Calls models and costs money." },
|
|
24
|
+
{ id: "evals.run", title: "Run evals", summary: "Start and cancel eval runs, and try one case. Calls models and costs money." },
|
|
25
|
+
{ id: "evals.write", title: "Author evals", summary: "Create and edit evals and datasets, install a sample, and review or sort suggestions." },
|
|
26
|
+
{ id: "evals.cleanup", title: "Delete eval runs", summary: "Delete an eval run and its stored results. Destructive." },
|
|
21
27
|
];
|
|
22
28
|
const t = (group, risk, operatorOnly) => ({ group, risk, ...(operatorOnly ? { operatorOnly } : {}) });
|
|
23
29
|
export const TOOL_META = {
|
|
@@ -70,6 +76,8 @@ export const TOOL_META = {
|
|
|
70
76
|
get_agent: t("agents.read", "read"),
|
|
71
77
|
validate_agent: t("agents.read", "read"),
|
|
72
78
|
list_agent_revisions: t("agents.read", "read"),
|
|
79
|
+
get_agent_revision: t("agents.read", "read"),
|
|
80
|
+
diff_agent_revisions: t("agents.read", "read"),
|
|
73
81
|
get_agent_session: t("agents.read", "read"),
|
|
74
82
|
list_agent_sessions: t("agents.read", "read"),
|
|
75
83
|
create_agent: t("agents.manage", "write"),
|
|
@@ -89,6 +97,24 @@ export const TOOL_META = {
|
|
|
89
97
|
edit_stage: t("pipelines.author", "write"),
|
|
90
98
|
create_task: t("pipelines.author", "write"),
|
|
91
99
|
edit_task: t("pipelines.author", "write"),
|
|
100
|
+
create_task_file: t("pipelines.author", "write"),
|
|
101
|
+
update_task_file: t("pipelines.author", "write"),
|
|
102
|
+
import_task_file: t("pipelines.author", "external"),
|
|
103
|
+
create_stage_file: t("pipelines.author", "write"),
|
|
104
|
+
write_catalog_file: t("pipelines.author", "write"),
|
|
105
|
+
validate_catalog_draft: t("pipelines.author", "read"),
|
|
106
|
+
list_connections: t("connections", "read"),
|
|
107
|
+
create_connection: t("connections", "write"),
|
|
108
|
+
update_connection: t("connections", "write"),
|
|
109
|
+
test_connection: t("connections", "external"),
|
|
110
|
+
validate_connection_target: t("connections", "read"),
|
|
111
|
+
remove_connection: t("connections.cleanup", "destructive"),
|
|
112
|
+
list_memories: t("memories", "read"),
|
|
113
|
+
get_memory: t("memories", "read"),
|
|
114
|
+
create_memory: t("memories", "write"),
|
|
115
|
+
write_memory: t("memories", "write"),
|
|
116
|
+
write_memory_card: t("memories", "write"),
|
|
117
|
+
delete_memory_card: t("memories.cleanup", "destructive"),
|
|
92
118
|
list_evals: t("evals.read", "read"),
|
|
93
119
|
get_eval: t("evals.read", "read"),
|
|
94
120
|
validate_eval: t("evals.read", "read"),
|
|
@@ -99,9 +125,23 @@ export const TOOL_META = {
|
|
|
99
125
|
compare_eval_runs: t("evals.read", "read"),
|
|
100
126
|
get_eval_failure_suggestions: t("evals.read", "read"),
|
|
101
127
|
get_eval_failure_sort_status: t("evals.read", "read"),
|
|
128
|
+
get_eval_run_export: t("evals.read", "read"),
|
|
102
129
|
run_eval: t("evals.run", "external"),
|
|
103
130
|
sort_eval_failures: t("evals.run", "external"),
|
|
131
|
+
list_grader_calibrations: t("evals.read", "read"),
|
|
132
|
+
calibrate_eval_grader: t("evals.run", "external"),
|
|
104
133
|
cancel_eval_run: t("evals.run", "write"),
|
|
134
|
+
try_eval_case: t("evals.run", "external"),
|
|
135
|
+
create_eval: t("evals.write", "write"),
|
|
136
|
+
update_eval: t("evals.write", "write"),
|
|
137
|
+
create_dataset: t("evals.write", "write"),
|
|
138
|
+
update_dataset_cases: t("evals.write", "write"),
|
|
139
|
+
convert_dataset: t("evals.write", "write"),
|
|
140
|
+
install_eval_sample: t("evals.write", "write"),
|
|
141
|
+
put_eval_review: t("evals.write", "write"),
|
|
142
|
+
accept_eval_failure_suggestions: t("evals.write", "write"),
|
|
143
|
+
dismiss_eval_failure_suggestions: t("evals.write", "write"),
|
|
144
|
+
delete_eval_run: t("evals.cleanup", "destructive"),
|
|
105
145
|
};
|
|
106
146
|
/** The grant id the policy gate and `approvals.ask_first` use for a Stageflow tool. */
|
|
107
147
|
export const STAGEFLOW_GRANT_PREFIX = "stageflow.";
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
* Their tools are checked through the same grant-id check as any agent's tools,
|
|
4
4
|
* so there is one permission layer. The lists are literals so this module has no
|
|
5
5
|
* dependency on the profiles; tests keep them equal to the profiles' tool names.
|
|
6
|
+
* Guide is the exception: it may call every Stageflow tool a person could grant,
|
|
7
|
+
* except the ones only a person may decide.
|
|
6
8
|
*/
|
|
9
|
+
export declare const GUIDE_OWN_TOOL_NAMES: readonly ["confirm_action", "show_ui", "list_guide_topics", "read_guide_topic"];
|
|
10
|
+
/** Tool names Guide may call. Operator-only decisions stay out. */
|
|
11
|
+
export declare function stageflowGuideToolNames(): readonly string[];
|
|
7
12
|
export declare const PROFILE_GRANTS: Readonly<Record<string, {
|
|
8
13
|
prefix: string;
|
|
9
14
|
tools: readonly string[];
|
package/dist/toolkit/profiles.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import { isOperatorOnlyTool, TOOL_META } from "./meta.js";
|
|
1
2
|
/**
|
|
2
3
|
* The Workshop and Agent-author profiles are agents with a fixed grant list.
|
|
3
4
|
* Their tools are checked through the same grant-id check as any agent's tools,
|
|
4
5
|
* so there is one permission layer. The lists are literals so this module has no
|
|
5
6
|
* dependency on the profiles; tests keep them equal to the profiles' tool names.
|
|
7
|
+
* Guide is the exception: it may call every Stageflow tool a person could grant,
|
|
8
|
+
* except the ones only a person may decide.
|
|
6
9
|
*/
|
|
10
|
+
export const GUIDE_OWN_TOOL_NAMES = ["confirm_action", "show_ui", "list_guide_topics", "read_guide_topic"];
|
|
11
|
+
/** Tool names Guide may call. Operator-only decisions stay out. */
|
|
12
|
+
export function stageflowGuideToolNames() {
|
|
13
|
+
return [...Object.keys(TOOL_META).filter((name) => !isOperatorOnlyTool(name)), ...GUIDE_OWN_TOOL_NAMES];
|
|
14
|
+
}
|
|
7
15
|
export const PROFILE_GRANTS = {
|
|
8
16
|
"workshop-author": {
|
|
9
17
|
prefix: "workshop.",
|
|
@@ -13,6 +21,10 @@ export const PROFILE_GRANTS = {
|
|
|
13
21
|
prefix: "agent_author.",
|
|
14
22
|
tools: ["read_agent_draft", "read_project_file", "list_project_files", "list_mcp_servers", "list_author_catalog", "update_agent_draft"],
|
|
15
23
|
},
|
|
24
|
+
"stageflow-guide": {
|
|
25
|
+
prefix: "guide.",
|
|
26
|
+
tools: stageflowGuideToolNames(),
|
|
27
|
+
},
|
|
16
28
|
};
|
|
17
29
|
export function profileGrantIds(profileId) {
|
|
18
30
|
const grants = PROFILE_GRANTS[profileId];
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Do not abort the session from inside `execute`: the tool Promise is the
|
|
8
8
|
* live blocking surface until the operator answers (or stage teardown).
|
|
9
9
|
*/
|
|
10
|
+
import { ASK_OPERATOR_TOOL_NAME } from "./stageToolNames.js";
|
|
10
11
|
import { randomUUID } from "node:crypto";
|
|
11
12
|
import { Type } from "typebox";
|
|
12
13
|
import { prepareAskOperatorArguments } from "./prepareToolArguments.js";
|
|
@@ -399,7 +400,7 @@ export function createAskOperatorTool(options) {
|
|
|
399
400
|
? [...allowed].join(", ")
|
|
400
401
|
: ASK_OPERATOR_KINDS.join(", ");
|
|
401
402
|
return {
|
|
402
|
-
name:
|
|
403
|
+
name: ASK_OPERATOR_TOOL_NAME,
|
|
403
404
|
label: "Ask operator",
|
|
404
405
|
description: `Ask the operator a question and wait for their answer. Supports ${kindList} prompts. Does not complete the stage — call emit_stage_envelope when finished.`,
|
|
405
406
|
parameters: askOperatorParamsSchemaFor(allowedKinds),
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom Pi tool the stage agent must call once when finished.
|
|
3
|
-
*
|
|
4
|
-
* Parameter schemas use `typebox` (Pi's `defineTool` TSchema), not
|
|
5
|
-
* `@sinclair/typebox`. An accepted emit returns `terminate: true` so Pi
|
|
6
|
-
* ends the turn instead of asking the model to continue.
|
|
7
|
-
*
|
|
8
|
-
* Do not abort the session from inside `execute`: providers that bridge tools
|
|
9
|
-
* (e.g. MCP) may still be waiting for this result, and abort-while-running
|
|
10
|
-
* deadlocks waitForIdle so later pipeline stages never start.
|
|
11
|
-
*/
|
|
12
1
|
import { Type } from "typebox";
|
|
13
2
|
import type { TSchema } from "typebox/type";
|
|
14
3
|
import { type PreEmitCheckOptions } from "../envelope/preEmitChecks.js";
|
|
@@ -23,20 +12,32 @@ export declare function createEmitStageEnvelopeTool(capture: EmitCapture, payloa
|
|
|
23
12
|
name: string;
|
|
24
13
|
label: string;
|
|
25
14
|
description: string;
|
|
26
|
-
parameters: Type.TObject<{
|
|
27
|
-
status: Type.TUnion<[Type.TLiteral<"success">, Type.TLiteral<"failure">]>;
|
|
15
|
+
parameters: Type.TUnion<[Type.TObject<{
|
|
28
16
|
summary: Type.TString;
|
|
29
17
|
artifacts: Type.TArray<Type.TString>;
|
|
30
|
-
|
|
18
|
+
checklist_attestations: Type.TOptional<Type.TArray<Type.TObject<{
|
|
19
|
+
check_id: Type.TString;
|
|
20
|
+
items: Type.TArray<Type.TString>;
|
|
21
|
+
}>>>;
|
|
22
|
+
stage_id: Type.TOptional<Type.TString>;
|
|
23
|
+
notes: Type.TOptional<Type.TString>;
|
|
24
|
+
status: Type.TLiteral<"success">;
|
|
25
|
+
payload: TSchema;
|
|
31
26
|
fork_choice: Type.TArray<Type.TString>;
|
|
32
|
-
feedback_loop?:
|
|
27
|
+
feedback_loop?: TSchema | undefined;
|
|
28
|
+
}>, Type.TObject<{
|
|
29
|
+
summary: Type.TString;
|
|
30
|
+
artifacts: Type.TArray<Type.TString>;
|
|
33
31
|
checklist_attestations: Type.TOptional<Type.TArray<Type.TObject<{
|
|
34
32
|
check_id: Type.TString;
|
|
35
33
|
items: Type.TArray<Type.TString>;
|
|
36
34
|
}>>>;
|
|
37
35
|
stage_id: Type.TOptional<Type.TString>;
|
|
38
36
|
notes: Type.TOptional<Type.TString>;
|
|
39
|
-
|
|
37
|
+
status: Type.TLiteral<"failure">;
|
|
38
|
+
payload: Type.TOptional<TSchema>;
|
|
39
|
+
fork_choice: Type.TOptional<Type.TArray<Type.TString>>;
|
|
40
|
+
}>]>;
|
|
40
41
|
prepareArguments: (args: unknown) => never;
|
|
41
42
|
execute: (_toolCallId: string, params: unknown) => Promise<{
|
|
42
43
|
content: {
|
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
* (e.g. MCP) may still be waiting for this result, and abort-while-running
|
|
10
10
|
* deadlocks waitForIdle so later pipeline stages never start.
|
|
11
11
|
*/
|
|
12
|
+
import { EMIT_STAGE_ENVELOPE_TOOL_NAME } from "./stageToolNames.js";
|
|
12
13
|
import { Type } from "typebox";
|
|
13
14
|
import { assertRequiredEnvelope, isAdvancingEnvelope, } from "../envelope/check.js";
|
|
14
15
|
import { assertFeedbackLoopAction } from "../envelope/feedbackLoop.js";
|
|
15
16
|
import { normalizeForkChoice } from "../envelope/forkChoice.js";
|
|
16
17
|
import { assertEnvelopePayload, compilePayloadSchema, } from "../envelope/payloadSchema.js";
|
|
18
|
+
import { assertEmittedArtifactsOnDisk } from "../envelope/assertEmittedArtifacts.js";
|
|
17
19
|
import { assertPreEmitChecks, } from "../envelope/preEmitChecks.js";
|
|
18
20
|
import { prepareEmitStageEnvelopeArguments } from "./prepareToolArguments.js";
|
|
19
21
|
function stringLiteralsSchema(values) {
|
|
@@ -22,16 +24,6 @@ function stringLiteralsSchema(values) {
|
|
|
22
24
|
}
|
|
23
25
|
return Type.Union(values.map((value) => Type.Literal(value)));
|
|
24
26
|
}
|
|
25
|
-
function stageEnvelopeSchema(payloadSchema) {
|
|
26
|
-
return Type.Object({
|
|
27
|
-
status: Type.Union([Type.Literal("success"), Type.Literal("failure")]),
|
|
28
|
-
summary: Type.String({ minLength: 1 }),
|
|
29
|
-
artifacts: Type.Array(Type.String()),
|
|
30
|
-
payload: Type.Optional(payloadSchema !== undefined
|
|
31
|
-
? payloadSchema
|
|
32
|
-
: Type.Record(Type.String(), Type.Unknown())),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
27
|
function feedbackLoopActionSchema(context) {
|
|
36
28
|
return Type.Union([
|
|
37
29
|
Type.Object({ action: Type.Literal("continue") }, { additionalProperties: false }),
|
|
@@ -41,6 +33,44 @@ function feedbackLoopActionSchema(context) {
|
|
|
41
33
|
}, { additionalProperties: false }),
|
|
42
34
|
]);
|
|
43
35
|
}
|
|
36
|
+
const closed = { additionalProperties: false };
|
|
37
|
+
function checklistAttestationsSchema() {
|
|
38
|
+
return Type.Optional(Type.Array(Type.Object({
|
|
39
|
+
check_id: Type.String({ minLength: 1 }),
|
|
40
|
+
items: Type.Array(Type.String()),
|
|
41
|
+
}, closed)));
|
|
42
|
+
}
|
|
43
|
+
function emitStageEnvelopeParameters(input) {
|
|
44
|
+
const freePayload = Type.Record(Type.String(), Type.Unknown());
|
|
45
|
+
const payloadValue = input.compiledPayload ?? freePayload;
|
|
46
|
+
const forkOptional = Type.Optional(Type.Array(Type.String()));
|
|
47
|
+
const forkOnSuccess = input.forkEmitContext !== undefined && input.feedbackLoopEmitContext === undefined
|
|
48
|
+
? Type.Array(Type.String())
|
|
49
|
+
: forkOptional;
|
|
50
|
+
const shared = {
|
|
51
|
+
summary: Type.String({ minLength: 1 }),
|
|
52
|
+
artifacts: Type.Array(Type.String()),
|
|
53
|
+
checklist_attestations: checklistAttestationsSchema(),
|
|
54
|
+
stage_id: Type.Optional(Type.String()),
|
|
55
|
+
notes: Type.Optional(Type.String()),
|
|
56
|
+
};
|
|
57
|
+
const success = Type.Object({
|
|
58
|
+
status: Type.Literal("success"),
|
|
59
|
+
...shared,
|
|
60
|
+
payload: input.compiledPayload !== undefined ? input.compiledPayload : Type.Optional(freePayload),
|
|
61
|
+
fork_choice: forkOnSuccess,
|
|
62
|
+
...(input.feedbackLoopEmitContext !== undefined
|
|
63
|
+
? { feedback_loop: feedbackLoopActionSchema(input.feedbackLoopEmitContext) }
|
|
64
|
+
: {}),
|
|
65
|
+
}, closed);
|
|
66
|
+
const failure = Type.Object({
|
|
67
|
+
status: Type.Literal("failure"),
|
|
68
|
+
...shared,
|
|
69
|
+
payload: Type.Optional(payloadValue),
|
|
70
|
+
fork_choice: forkOptional,
|
|
71
|
+
}, closed);
|
|
72
|
+
return Type.Union([success, failure]);
|
|
73
|
+
}
|
|
44
74
|
function toolResult(text, details, options) {
|
|
45
75
|
return {
|
|
46
76
|
content: [{ type: "text", text }],
|
|
@@ -54,30 +84,13 @@ export function createEmitStageEnvelopeTool(capture, payloadSchema, forkEmitCont
|
|
|
54
84
|
? compilePayloadSchema(payloadSchema)
|
|
55
85
|
: undefined;
|
|
56
86
|
return {
|
|
57
|
-
name:
|
|
87
|
+
name: EMIT_STAGE_ENVELOPE_TOOL_NAME,
|
|
58
88
|
label: "Emit stage envelope",
|
|
59
89
|
description: "Emit the shared stage handoff envelope. Call exactly once when the stage is complete. The pipeline cannot advance until this tool succeeds.",
|
|
60
|
-
parameters:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
payload: Type.Optional(compiledPayload !== undefined
|
|
65
|
-
? compiledPayload
|
|
66
|
-
: Type.Record(Type.String(), Type.Unknown())),
|
|
67
|
-
fork_choice: forkEmitContext !== undefined && feedbackLoopEmitContext === undefined
|
|
68
|
-
? Type.Array(Type.String())
|
|
69
|
-
: Type.Optional(Type.Array(Type.String())),
|
|
70
|
-
...(feedbackLoopEmitContext !== undefined
|
|
71
|
-
? {
|
|
72
|
-
feedback_loop: Type.Optional(feedbackLoopActionSchema(feedbackLoopEmitContext)),
|
|
73
|
-
}
|
|
74
|
-
: {}),
|
|
75
|
-
checklist_attestations: Type.Optional(Type.Array(Type.Object({
|
|
76
|
-
check_id: Type.String({ minLength: 1 }),
|
|
77
|
-
items: Type.Array(Type.String()),
|
|
78
|
-
}))),
|
|
79
|
-
stage_id: Type.Optional(Type.String()),
|
|
80
|
-
notes: Type.Optional(Type.String()),
|
|
90
|
+
parameters: emitStageEnvelopeParameters({
|
|
91
|
+
compiledPayload,
|
|
92
|
+
forkEmitContext,
|
|
93
|
+
feedbackLoopEmitContext,
|
|
81
94
|
}),
|
|
82
95
|
prepareArguments: prepareEmitStageEnvelopeArguments,
|
|
83
96
|
execute: async (_toolCallId, params) => {
|
|
@@ -96,6 +109,7 @@ export function createEmitStageEnvelopeTool(capture, payloadSchema, forkEmitCont
|
|
|
96
109
|
assertEnvelopePayload(envelope, payloadSchema);
|
|
97
110
|
if (envelope.status !== "failure") {
|
|
98
111
|
await assertPreEmitChecks(envelope, preEmitCheckOptions);
|
|
112
|
+
await assertEmittedArtifactsOnDisk(envelope.artifacts, preEmitCheckOptions?.artifactPresence);
|
|
99
113
|
}
|
|
100
114
|
capture.envelope = envelope;
|
|
101
115
|
const advancing = isAdvancingEnvelope(envelope);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Names of the tools every stage session shares. The tools register under these names; consumers read them from here. */
|
|
2
|
+
export declare const EMIT_STAGE_ENVELOPE_TOOL_NAME = "emit_stage_envelope";
|
|
3
|
+
export declare const ASK_OPERATOR_TOOL_NAME = "ask_operator";
|
|
4
|
+
export declare const WRITE_STAGE_ARTIFACT_TOOL_NAME = "write_stage_artifact";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Names of the tools every stage session shares. The tools register under these names; consumers read them from here. */
|
|
2
|
+
export const EMIT_STAGE_ENVELOPE_TOOL_NAME = "emit_stage_envelope";
|
|
3
|
+
export const ASK_OPERATOR_TOOL_NAME = "ask_operator";
|
|
4
|
+
export const WRITE_STAGE_ARTIFACT_TOOL_NAME = "write_stage_artifact";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
import { WorkingStateStore, type WorkingStateEvent } from "../compaction/workingState.js";
|
|
4
|
+
export type WorkingStateToolOptions = {
|
|
5
|
+
store: WorkingStateStore;
|
|
6
|
+
persist: (event: WorkingStateEvent) => void;
|
|
7
|
+
now?: () => string;
|
|
8
|
+
};
|
|
9
|
+
type ToolResult = {
|
|
10
|
+
content: {
|
|
11
|
+
type: "text";
|
|
12
|
+
text: string;
|
|
13
|
+
}[];
|
|
14
|
+
details: unknown;
|
|
15
|
+
isError?: boolean;
|
|
16
|
+
};
|
|
17
|
+
export declare function createWorkingStateTool(options: WorkingStateToolOptions): {
|
|
18
|
+
name: string;
|
|
19
|
+
label: string;
|
|
20
|
+
description: string;
|
|
21
|
+
parameters: Type.TUnion<[Type.TObject<{
|
|
22
|
+
operation: Type.TLiteral<"set">;
|
|
23
|
+
key: Type.TString;
|
|
24
|
+
kind: Type.TUnion<[Type.TLiteral<Type.TLiteralValue>, Type.TLiteral<Type.TLiteralValue>, ...Type.TLiteral<Type.TLiteralValue>[]]>;
|
|
25
|
+
value: Type.TString;
|
|
26
|
+
}>, Type.TObject<{
|
|
27
|
+
operation: Type.TLiteral<"delete">;
|
|
28
|
+
key: Type.TString;
|
|
29
|
+
}>, Type.TObject<{
|
|
30
|
+
operation: Type.TLiteral<"list">;
|
|
31
|
+
}>]>;
|
|
32
|
+
execute(_toolCallId: string, input: unknown): Promise<ToolResult>;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Inline Pi extension: registers the tool, persists each change as a custom
|
|
36
|
+
* session entry and rebuilds the store from the session file on first use,
|
|
37
|
+
* so state survives process restarts and resume.
|
|
38
|
+
*/
|
|
39
|
+
export declare function createWorkingStateExtension(): ExtensionFactory;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { WORKING_STATE_CUSTOM_TYPE, WORKING_STATE_KINDS, WORKING_STATE_MAX_KEY, WORKING_STATE_MAX_VALUE, WorkingStateStore, workingStateEventsFromEntries, } from "../compaction/workingState.js";
|
|
3
|
+
import { WORKING_STATE_TOOL_NAME } from "../compaction/types.js";
|
|
4
|
+
const closed = { additionalProperties: false };
|
|
5
|
+
function workingStateKindSchema() {
|
|
6
|
+
return Type.Union(WORKING_STATE_KINDS.map((k) => Type.Literal(k)));
|
|
7
|
+
}
|
|
8
|
+
function workingStateParameters() {
|
|
9
|
+
return Type.Union([
|
|
10
|
+
Type.Object({
|
|
11
|
+
operation: Type.Literal("set"),
|
|
12
|
+
key: Type.String({ maxLength: WORKING_STATE_MAX_KEY }),
|
|
13
|
+
kind: workingStateKindSchema(),
|
|
14
|
+
value: Type.String({ maxLength: WORKING_STATE_MAX_VALUE }),
|
|
15
|
+
}, closed),
|
|
16
|
+
Type.Object({
|
|
17
|
+
operation: Type.Literal("delete"),
|
|
18
|
+
key: Type.String({ maxLength: WORKING_STATE_MAX_KEY }),
|
|
19
|
+
}, closed),
|
|
20
|
+
Type.Object({ operation: Type.Literal("list") }, closed),
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
function result(text, isError = false) {
|
|
24
|
+
return {
|
|
25
|
+
content: [{ type: "text", text }],
|
|
26
|
+
details: { isError },
|
|
27
|
+
...(isError ? { isError: true } : {}),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function createWorkingStateTool(options) {
|
|
31
|
+
const { store, persist } = options;
|
|
32
|
+
const now = options.now ?? (() => new Date().toISOString());
|
|
33
|
+
return {
|
|
34
|
+
name: WORKING_STATE_TOOL_NAME,
|
|
35
|
+
label: "Working state",
|
|
36
|
+
description: "Keep your own structured working state. Older messages and tool results are trimmed automatically, but this state is kept and shown to you again after every trim. Use `set` as soon as you know something you will need later: exact values and identifiers (fact), choices and reasons (decision), what is finished (progress), what remains (todo), what is stuck (blocker). Keep entries short (one or two lines). Reuse a key to update an entry instead of adding a duplicate; use `delete` when an entry no longer matters; `list` shows everything. Never store secrets.",
|
|
37
|
+
parameters: workingStateParameters(),
|
|
38
|
+
async execute(_toolCallId, input) {
|
|
39
|
+
const params = (input ?? {});
|
|
40
|
+
if (params.operation === "list") {
|
|
41
|
+
const rendered = store.render();
|
|
42
|
+
return result(rendered === "" ? "Working state is empty." : rendered);
|
|
43
|
+
}
|
|
44
|
+
if (params.operation === "delete") {
|
|
45
|
+
if (typeof params.key !== "string" || params.key.trim() === "") {
|
|
46
|
+
return result("delete requires key", true);
|
|
47
|
+
}
|
|
48
|
+
if (!store.delete(params.key)) {
|
|
49
|
+
return result(`No entry "${params.key}".`, true);
|
|
50
|
+
}
|
|
51
|
+
persist({ op: "delete", key: params.key.trim(), at: now() });
|
|
52
|
+
return result(`Deleted ${params.key.trim()}.`);
|
|
53
|
+
}
|
|
54
|
+
if (params.operation === "set") {
|
|
55
|
+
const at = now();
|
|
56
|
+
const outcome = store.set({
|
|
57
|
+
key: params.key ?? "",
|
|
58
|
+
kind: params.kind,
|
|
59
|
+
value: params.value ?? "",
|
|
60
|
+
updatedAt: at,
|
|
61
|
+
});
|
|
62
|
+
if (!outcome.ok)
|
|
63
|
+
return result(outcome.error, true);
|
|
64
|
+
persist({
|
|
65
|
+
op: "set",
|
|
66
|
+
key: outcome.entry.key,
|
|
67
|
+
kind: outcome.entry.kind,
|
|
68
|
+
value: outcome.entry.value,
|
|
69
|
+
at,
|
|
70
|
+
});
|
|
71
|
+
const dropped = outcome.dropped.length > 0
|
|
72
|
+
? ` State was full; dropped oldest progress: ${outcome.dropped.join(", ")}.`
|
|
73
|
+
: "";
|
|
74
|
+
const redacted = outcome.redacted
|
|
75
|
+
? " Part of it looked like a secret and was redacted; reword the entry if that removed a fact you need."
|
|
76
|
+
: "";
|
|
77
|
+
return result(`${outcome.replaced ? "Updated" : "Saved"} ${outcome.entry.key} (${store.size} entries).${dropped}${redacted}`);
|
|
78
|
+
}
|
|
79
|
+
return result("operation must be set, delete or list", true);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Inline Pi extension: registers the tool, persists each change as a custom
|
|
85
|
+
* session entry and rebuilds the store from the session file on first use,
|
|
86
|
+
* so state survives process restarts and resume.
|
|
87
|
+
*/
|
|
88
|
+
export function createWorkingStateExtension() {
|
|
89
|
+
return (pi) => {
|
|
90
|
+
const store = new WorkingStateStore();
|
|
91
|
+
let restored = false;
|
|
92
|
+
const tool = createWorkingStateTool({
|
|
93
|
+
store,
|
|
94
|
+
persist: (event) => pi.appendEntry(WORKING_STATE_CUSTOM_TYPE, event),
|
|
95
|
+
});
|
|
96
|
+
pi.registerTool({
|
|
97
|
+
...tool,
|
|
98
|
+
constrainedSampling: { type: "json_schema", strict: "prefer" },
|
|
99
|
+
async execute(toolCallId, params, _signal, _onUpdate, ctx) {
|
|
100
|
+
if (!restored) {
|
|
101
|
+
restored = true;
|
|
102
|
+
store.load(workingStateEventsFromEntries(ctx.sessionManager.getEntries()));
|
|
103
|
+
}
|
|
104
|
+
return tool.execute(toolCallId, params);
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom Pi tool for writing factory stage artifact files under the run
|
|
3
|
-
* workspace. Paths are relative to
|
|
4
|
-
* `stages/<stageId>/attempts/<attempt>/artifacts/` and must resolve inside
|
|
5
|
-
* that directory.
|
|
6
|
-
*
|
|
7
|
-
* Parameter schemas use `typebox` (Pi's `defineTool` TSchema), not
|
|
8
|
-
* `@sinclair/typebox`. Unlike emit, this tool does not terminate the turn.
|
|
9
|
-
*/
|
|
10
1
|
import { Type } from "typebox";
|
|
11
2
|
export type WriteStageArtifactOptions = {
|
|
12
3
|
runWorkspaceDir: string;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Parameter schemas use `typebox` (Pi's `defineTool` TSchema), not
|
|
8
8
|
* `@sinclair/typebox`. Unlike emit, this tool does not terminate the turn.
|
|
9
9
|
*/
|
|
10
|
+
import { WRITE_STAGE_ARTIFACT_TOOL_NAME } from "./stageToolNames.js";
|
|
10
11
|
import { Type } from "typebox";
|
|
11
12
|
import { resolveArtifactTarget } from "../runstore/workspaceLayout.js";
|
|
12
13
|
import { writeContainedArtifact } from "../runstore/writeContainedArtifact.js";
|
|
@@ -20,7 +21,7 @@ function toolResult(text, details, options) {
|
|
|
20
21
|
export function createWriteStageArtifactTool(options) {
|
|
21
22
|
const { runWorkspaceDir, stageId, attempt } = options;
|
|
22
23
|
return {
|
|
23
|
-
name:
|
|
24
|
+
name: WRITE_STAGE_ARTIFACT_TOOL_NAME,
|
|
24
25
|
label: "Write stage artifact",
|
|
25
26
|
description: "Write a factory artifact file under this stage attempt's artifacts directory in the run workspace. Pass a path relative to stages/<stageId>/attempts/<attempt>/artifacts/ and the file content. Returns the run-relative path to include in emit_stage_envelope artifacts.",
|
|
26
27
|
parameters: Type.Object({
|