stageflow 0.40.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -4
- package/dist/agent/activity.d.ts +18 -0
- package/dist/agent/claudeAdapter.js +7 -0
- package/dist/agent/claudeTools.d.ts +27 -18
- package/dist/agent/claudeTools.js +54 -15
- package/dist/agent/compactionEvents.d.ts +34 -0
- package/dist/agent/compactionEvents.js +37 -0
- package/dist/agent/openRouterRouting.d.ts +7 -0
- package/dist/agent/openRouterRouting.js +23 -0
- package/dist/agent/piAdapter.d.ts +6 -0
- package/dist/agent/piAdapter.js +128 -27
- package/dist/agent/piSettings.d.ts +7 -0
- package/dist/agent/piSettings.js +9 -0
- package/dist/agent/sandboxPiTools.d.ts +3 -1
- package/dist/agent/sandboxPiTools.js +8 -2
- package/dist/agent/stageTurnDriver.d.ts +11 -2
- package/dist/agent/stageTurnDriver.js +45 -4
- package/dist/agent/toolOutputBudget.d.ts +15 -1
- package/dist/agent/toolOutputBudget.js +18 -0
- package/dist/agent/toolOutputBudgetExtension.d.ts +2 -0
- package/dist/agent/toolOutputBudgetExtension.js +40 -3
- package/dist/agents/authorChat.d.ts +5 -0
- package/dist/agents/authorChat.js +120 -12
- package/dist/agents/authorSessionStore.d.ts +38 -0
- package/dist/agents/authorSessionStore.js +167 -0
- package/dist/agents/chatTurn.d.ts +2 -0
- package/dist/agents/chatTurn.js +17 -1
- package/dist/agents/errors.d.ts +1 -1
- package/dist/agents/errors.js +1 -0
- package/dist/agents/evalGate.d.ts +61 -0
- package/dist/agents/evalGate.js +103 -0
- package/dist/agents/evalSession.d.ts +26 -0
- package/dist/agents/evalSession.js +29 -0
- package/dist/agents/hostContext.d.ts +4 -1
- package/dist/agents/hostContext.js +4 -1
- package/dist/agents/runtime/piRuntime.d.ts +6 -2
- package/dist/agents/runtime/piRuntime.js +50 -16
- package/dist/agents/runtime/types.d.ts +3 -1
- package/dist/agents/service.d.ts +27 -2
- package/dist/agents/service.js +91 -15
- package/dist/agents/sessions.d.ts +8 -0
- package/dist/agents/sessions.js +53 -11
- package/dist/agents/store.d.ts +14 -3
- package/dist/agents/store.js +45 -7
- package/dist/agents/toolRisk.d.ts +21 -0
- package/dist/agents/toolRisk.js +50 -0
- package/dist/cli/doctorCommand.js +26 -0
- package/dist/cli/evalCommand.d.ts +20 -0
- package/dist/cli/evalCommand.js +720 -0
- package/dist/cli/exportAllCommand.js +1 -1
- package/dist/cli/hostClient.d.ts +60 -0
- package/dist/cli/hostClient.js +71 -0
- package/dist/cli/validateOutput.d.ts +2 -2
- package/dist/cli/validateOutput.js +2 -2
- package/dist/cli.js +10 -0
- package/dist/compaction/directives.d.ts +18 -0
- package/dist/compaction/directives.js +119 -0
- package/dist/compaction/extension.d.ts +20 -0
- package/dist/compaction/extension.js +78 -0
- package/dist/compaction/mask.d.ts +18 -0
- package/dist/compaction/mask.js +155 -0
- package/dist/compaction/pin.d.ts +21 -0
- package/dist/compaction/pin.js +270 -0
- package/dist/compaction/scrub.d.ts +7 -0
- package/dist/compaction/scrub.js +26 -0
- package/dist/compaction/sessionWiring.d.ts +22 -0
- package/dist/compaction/sessionWiring.js +26 -0
- package/dist/compaction/summarize.d.ts +79 -0
- package/dist/compaction/summarize.js +171 -0
- package/dist/compaction/toolPolicy.d.ts +3 -0
- package/dist/compaction/toolPolicy.js +33 -0
- package/dist/compaction/types.d.ts +45 -0
- package/dist/compaction/types.js +7 -0
- package/dist/compaction/workingState.d.ts +56 -0
- package/dist/compaction/workingState.js +198 -0
- package/dist/config/atomicWrite.d.ts +15 -0
- package/dist/config/atomicWrite.js +43 -0
- package/dist/config/browseCatalog.d.ts +2 -0
- package/dist/config/browseCatalog.js +4 -2
- package/dist/config/createPipeline.js +2 -0
- package/dist/config/createTrigger.js +7 -1
- package/dist/config/csv.d.ts +9 -0
- package/dist/config/csv.js +81 -0
- package/dist/config/datasetAgentCheck.d.ts +18 -0
- package/dist/config/datasetAgentCheck.js +109 -0
- package/dist/config/datasetCandidates.d.ts +22 -0
- package/dist/config/datasetCandidates.js +86 -0
- package/dist/config/datasetFromSessions.d.ts +34 -0
- package/dist/config/datasetFromSessions.js +105 -0
- package/dist/config/datasetHash.d.ts +1 -0
- package/dist/config/datasetHash.js +4 -0
- package/dist/config/datasetImport.d.ts +21 -0
- package/dist/config/datasetImport.js +120 -0
- package/dist/config/datasetStageCheck.d.ts +9 -0
- package/dist/config/datasetStageCheck.js +17 -0
- package/dist/config/datasetTypes.d.ts +27 -0
- package/dist/config/datasetTypes.js +1 -0
- package/dist/config/ensureCatalogScanRoot.d.ts +4 -1
- package/dist/config/ensureCatalogScanRoot.js +8 -6
- package/dist/config/evalCatalog.d.ts +22 -0
- package/dist/config/evalCatalog.js +95 -0
- package/dist/config/evalWriteRoots.d.ts +17 -0
- package/dist/config/evalWriteRoots.js +109 -0
- package/dist/config/githubTriggerAction.d.ts +8 -0
- package/dist/config/githubTriggerAction.js +29 -0
- package/dist/config/hostConfig.js +3 -0
- package/dist/config/installEvalSample.d.ts +34 -0
- package/dist/config/installEvalSample.js +182 -0
- package/dist/config/loadDataset.d.ts +16 -0
- package/dist/config/loadDataset.js +318 -0
- package/dist/config/loadEval.d.ts +32 -0
- package/dist/config/loadEval.js +1103 -0
- package/dist/config/loadOutcome.d.ts +5 -0
- package/dist/config/loadStageflowManifest.js +64 -0
- package/dist/config/pipelineNeeds.d.ts +2 -0
- package/dist/config/pipelineNeeds.js +16 -3
- package/dist/config/pipelineRoute.js +5 -4
- package/dist/config/resolveAgentTarget.d.ts +32 -0
- package/dist/config/resolveAgentTarget.js +118 -0
- package/dist/config/resolveEvalTarget.d.ts +21 -0
- package/dist/config/resolveEvalTarget.js +89 -0
- package/dist/config/scanCatalogPaths.d.ts +1 -1
- package/dist/config/scanCatalogPaths.js +17 -5
- package/dist/config/validateCatalog.d.ts +2 -2
- package/dist/config/validateCatalog.js +21 -1
- package/dist/config/validateEval.d.ts +36 -0
- package/dist/config/validateEval.js +446 -0
- package/dist/config/writeDataset.d.ts +54 -0
- package/dist/config/writeDataset.js +186 -0
- package/dist/config/writeEval.d.ts +25 -0
- package/dist/config/writeEval.js +398 -0
- package/dist/diagnostics/checks.js +1 -1
- package/dist/envelope/assertEmittedArtifacts.d.ts +12 -0
- package/dist/envelope/assertEmittedArtifacts.js +43 -0
- package/dist/envelope/preEmitChecks.d.ts +3 -0
- package/dist/evals/agentDiff.d.ts +13 -0
- package/dist/evals/agentDiff.js +11 -0
- package/dist/evals/canonical.d.ts +3 -0
- package/dist/evals/canonical.js +24 -0
- package/dist/evals/caseTask.d.ts +3 -0
- package/dist/evals/caseTask.js +9 -0
- package/dist/evals/compare.d.ts +94 -0
- package/dist/evals/compare.js +201 -0
- package/dist/evals/constants.d.ts +62 -0
- package/dist/evals/constants.js +97 -0
- package/dist/evals/engine/FakeEngine.d.ts +33 -0
- package/dist/evals/engine/FakeEngine.js +177 -0
- package/dist/evals/engine/index.d.ts +9 -0
- package/dist/evals/engine/index.js +19 -0
- package/dist/evals/engine/promptfoo/PromptfooEngine.d.ts +52 -0
- package/dist/evals/engine/promptfoo/PromptfooEngine.js +312 -0
- package/dist/evals/engine/promptfoo/errors.d.ts +5 -0
- package/dist/evals/engine/promptfoo/errors.js +8 -0
- package/dist/evals/engine/promptfoo/generate.d.ts +30 -0
- package/dist/evals/engine/promptfoo/generate.js +345 -0
- package/dist/evals/engine/promptfoo/guard.d.ts +10 -0
- package/dist/evals/engine/promptfoo/guard.js +116 -0
- package/dist/evals/engine/promptfoo/install.d.ts +17 -0
- package/dist/evals/engine/promptfoo/install.js +73 -0
- package/dist/evals/engine/promptfoo/judgeProviders.d.ts +2 -0
- package/dist/evals/engine/promptfoo/judgeProviders.js +9 -0
- package/dist/evals/engine/promptfoo/judgeServices.d.ts +6 -0
- package/dist/evals/engine/promptfoo/judgeServices.js +41 -0
- package/dist/evals/engine/promptfoo/locate.d.ts +21 -0
- package/dist/evals/engine/promptfoo/locate.js +68 -0
- package/dist/evals/engine/promptfoo/nodeVersion.d.ts +7 -0
- package/dist/evals/engine/promptfoo/nodeVersion.js +14 -0
- package/dist/evals/engine/promptfoo/normalize.d.ts +66 -0
- package/dist/evals/engine/promptfoo/normalize.js +261 -0
- package/dist/evals/engine/promptfoo/pinned.d.ts +5 -0
- package/dist/evals/engine/promptfoo/pinned.js +5 -0
- package/dist/evals/engine/promptfoo/rubricPrompt.d.ts +14 -0
- package/dist/evals/engine/promptfoo/rubricPrompt.js +105 -0
- package/dist/evals/engine/promptfoo/runTokens.d.ts +18 -0
- package/dist/evals/engine/promptfoo/runTokens.js +31 -0
- package/dist/evals/engine/promptfoo/status.d.ts +13 -0
- package/dist/evals/engine/promptfoo/status.js +16 -0
- package/dist/evals/estimate.d.ts +56 -0
- package/dist/evals/estimate.js +66 -0
- package/dist/evals/graders/codeGrader.d.ts +6 -0
- package/dist/evals/graders/codeGrader.js +85 -0
- package/dist/evals/graders/conversationCheckGrader.d.ts +6 -0
- package/dist/evals/graders/conversationCheckGrader.js +62 -0
- package/dist/evals/graders/fieldGrader.d.ts +11 -0
- package/dist/evals/graders/fieldGrader.js +117 -0
- package/dist/evals/graders/goal.d.ts +3 -0
- package/dist/evals/graders/goal.js +14 -0
- package/dist/evals/graders/index.d.ts +18 -0
- package/dist/evals/graders/index.js +34 -0
- package/dist/evals/graders/notApplicable.d.ts +5 -0
- package/dist/evals/graders/notApplicable.js +9 -0
- package/dist/evals/graders/path.d.ts +26 -0
- package/dist/evals/graders/path.js +75 -0
- package/dist/evals/graders/referenceGrader.d.ts +5 -0
- package/dist/evals/graders/referenceGrader.js +59 -0
- package/dist/evals/graders/schemaGrader.d.ts +5 -0
- package/dist/evals/graders/schemaGrader.js +29 -0
- package/dist/evals/graders/subject.d.ts +6 -0
- package/dist/evals/graders/subject.js +33 -0
- package/dist/evals/graders/toolCallsGrader.d.ts +6 -0
- package/dist/evals/graders/toolCallsGrader.js +100 -0
- package/dist/evals/graders/transcript.d.ts +12 -0
- package/dist/evals/graders/transcript.js +57 -0
- package/dist/evals/graders/types.d.ts +20 -0
- package/dist/evals/graders/types.js +1 -0
- package/dist/evals/judgeProviders.d.ts +16 -0
- package/dist/evals/judgeProviders.js +27 -0
- package/dist/evals/lineDiff.d.ts +5 -0
- package/dist/evals/lineDiff.js +34 -0
- package/dist/evals/listStatus.d.ts +31 -0
- package/dist/evals/listStatus.js +48 -0
- package/dist/evals/manager.d.ts +187 -0
- package/dist/evals/manager.js +795 -0
- package/dist/evals/plan.d.ts +65 -0
- package/dist/evals/plan.js +621 -0
- package/dist/evals/planInternalAgent.d.ts +19 -0
- package/dist/evals/planInternalAgent.js +205 -0
- package/dist/evals/providerKeys.d.ts +1 -0
- package/dist/evals/providerKeys.js +21 -0
- package/dist/evals/read/agentTargets.d.ts +37 -0
- package/dist/evals/read/agentTargets.js +101 -0
- package/dist/evals/read/api.d.ts +208 -0
- package/dist/evals/read/api.js +363 -0
- package/dist/evals/read/compare.d.ts +4 -0
- package/dist/evals/read/compare.js +39 -0
- package/dist/evals/read/datasets.d.ts +105 -0
- package/dist/evals/read/datasets.js +318 -0
- package/dist/evals/read/list.d.ts +66 -0
- package/dist/evals/read/list.js +182 -0
- package/dist/evals/read/results.d.ts +46 -0
- package/dist/evals/read/results.js +107 -0
- package/dist/evals/read/runs.d.ts +154 -0
- package/dist/evals/read/runs.js +295 -0
- package/dist/evals/read/suggestions.d.ts +43 -0
- package/dist/evals/read/suggestions.js +73 -0
- package/dist/evals/runner/FakeAgentBackend.d.ts +40 -0
- package/dist/evals/runner/FakeAgentBackend.js +82 -0
- package/dist/evals/runner/agentCaseRunner.d.ts +24 -0
- package/dist/evals/runner/agentCaseRunner.js +388 -0
- package/dist/evals/runner/caseRunner.d.ts +8 -0
- package/dist/evals/runner/caseRunner.js +28 -0
- package/dist/evals/runner/conversationSubject.d.ts +18 -0
- package/dist/evals/runner/conversationSubject.js +123 -0
- package/dist/evals/runner/internalAgentCaseRunner.d.ts +6 -0
- package/dist/evals/runner/internalAgentCaseRunner.js +250 -0
- package/dist/evals/runner/simulatorModel.d.ts +51 -0
- package/dist/evals/runner/simulatorModel.js +58 -0
- package/dist/evals/runner/simulatorPrompt.d.ts +29 -0
- package/dist/evals/runner/simulatorPrompt.js +59 -0
- package/dist/evals/runner/stageCaseRunner.d.ts +30 -0
- package/dist/evals/runner/stageCaseRunner.js +279 -0
- package/dist/evals/runner/userDriver.d.ts +71 -0
- package/dist/evals/runner/userDriver.js +104 -0
- package/dist/evals/scoring.d.ts +34 -0
- package/dist/evals/scoring.js +67 -0
- package/dist/evals/snapshot.d.ts +191 -0
- package/dist/evals/snapshot.js +70 -0
- package/dist/evals/stageDiff.d.ts +8 -0
- package/dist/evals/stageDiff.js +48 -0
- package/dist/evals/stats.d.ts +95 -0
- package/dist/evals/stats.js +220 -0
- package/dist/evals/statsAdapter.d.ts +4 -0
- package/dist/evals/statsAdapter.js +30 -0
- package/dist/evals/statsTypes.d.ts +51 -0
- package/dist/evals/statsTypes.js +18 -0
- package/dist/evals/storeError.d.ts +5 -0
- package/dist/evals/storeError.js +8 -0
- package/dist/evals/storeTypes.d.ts +207 -0
- package/dist/evals/storeTypes.js +1 -0
- package/dist/evals/tTable.d.ts +3 -0
- package/dist/evals/tTable.js +15 -0
- package/dist/evals/triage/constants.d.ts +26 -0
- package/dist/evals/triage/constants.js +33 -0
- package/dist/evals/triage/credentials.d.ts +13 -0
- package/dist/evals/triage/credentials.js +20 -0
- package/dist/evals/triage/jevClassifier.d.ts +14 -0
- package/dist/evals/triage/jevClassifier.js +124 -0
- package/dist/evals/triage/judgeClassifier.d.ts +10 -0
- package/dist/evals/triage/judgeClassifier.js +76 -0
- package/dist/evals/triage/prompts.d.ts +16 -0
- package/dist/evals/triage/prompts.js +64 -0
- package/dist/evals/triage/service.d.ts +79 -0
- package/dist/evals/triage/service.js +217 -0
- package/dist/evals/triage/stateBuilder.d.ts +19 -0
- package/dist/evals/triage/stateBuilder.js +125 -0
- package/dist/evals/triage/types.d.ts +60 -0
- package/dist/evals/triage/types.js +8 -0
- package/dist/evals/types.d.ts +357 -0
- package/dist/evals/types.js +4 -0
- package/dist/guide/cardContract.d.ts +133 -0
- package/dist/guide/cardContract.js +156 -0
- package/dist/guide/chat.d.ts +45 -0
- package/dist/guide/chat.js +378 -0
- package/dist/guide/knowledge/index.d.ts +14 -0
- package/dist/guide/knowledge/index.js +109 -0
- package/dist/guide/knowledge/topics/agents.d.ts +2 -0
- package/dist/guide/knowledge/topics/agents.js +58 -0
- package/dist/guide/knowledge/topics/bestPractices.d.ts +2 -0
- package/dist/guide/knowledge/topics/bestPractices.js +67 -0
- package/dist/guide/knowledge/topics/connections.d.ts +2 -0
- package/dist/guide/knowledge/topics/connections.js +66 -0
- package/dist/guide/knowledge/topics/consoleMap.d.ts +2 -0
- package/dist/guide/knowledge/topics/consoleMap.js +55 -0
- package/dist/guide/knowledge/topics/evals.d.ts +2 -0
- package/dist/guide/knowledge/topics/evals.js +72 -0
- package/dist/guide/knowledge/topics/limitations.d.ts +2 -0
- package/dist/guide/knowledge/topics/limitations.js +84 -0
- package/dist/guide/knowledge/topics/mcpSkillsBrowser.d.ts +2 -0
- package/dist/guide/knowledge/topics/mcpSkillsBrowser.js +57 -0
- package/dist/guide/knowledge/topics/memories.d.ts +2 -0
- package/dist/guide/knowledge/topics/memories.js +63 -0
- package/dist/guide/knowledge/topics/modelsAndProviders.d.ts +2 -0
- package/dist/guide/knowledge/topics/modelsAndProviders.js +56 -0
- package/dist/guide/knowledge/topics/overview.d.ts +2 -0
- package/dist/guide/knowledge/topics/overview.js +56 -0
- package/dist/guide/knowledge/topics/pipelines.d.ts +2 -0
- package/dist/guide/knowledge/topics/pipelines.js +93 -0
- package/dist/guide/knowledge/topics/stages.d.ts +2 -0
- package/dist/guide/knowledge/topics/stages.js +54 -0
- package/dist/guide/knowledge/topics/tasks.d.ts +2 -0
- package/dist/guide/knowledge/topics/tasks.js +52 -0
- package/dist/guide/knowledge/topics/triggers.d.ts +2 -0
- package/dist/guide/knowledge/topics/triggers.js +68 -0
- package/dist/guide/knowledge/topics/troubleshooting.d.ts +2 -0
- package/dist/guide/knowledge/topics/troubleshooting.js +85 -0
- package/dist/guide/knowledgeTools.d.ts +2 -0
- package/dist/guide/knowledgeTools.js +56 -0
- package/dist/guide/showUi.d.ts +6 -0
- package/dist/guide/showUi.js +546 -0
- package/dist/guide/threadStore.d.ts +48 -0
- package/dist/guide/threadStore.js +189 -0
- package/dist/guide/writeRoot.d.ts +11 -0
- package/dist/guide/writeRoot.js +70 -0
- package/dist/hosted/translate.js +2 -0
- package/dist/mcp/agentTools.js +12 -0
- package/dist/mcp/catalogTools.js +18 -20
- package/dist/mcp/catalogWriteTools.d.ts +8 -0
- package/dist/mcp/catalogWriteTools.js +225 -0
- package/dist/mcp/connectionTools.d.ts +3 -0
- package/dist/mcp/connectionTools.js +85 -0
- package/dist/mcp/controlTools.js +34 -1
- package/dist/mcp/deps.d.ts +16 -0
- package/dist/mcp/evalTools.d.ts +3 -0
- package/dist/mcp/evalTools.js +943 -0
- package/dist/mcp/memoryHostTools.d.ts +3 -0
- package/dist/mcp/memoryHostTools.js +72 -0
- package/dist/mcp/pipelineAuthorTools.js +14 -1
- package/dist/mcp/server.js +6 -0
- package/dist/mcp/tools.js +8 -0
- package/dist/mcp/triggerTools.js +77 -31
- package/dist/models/response.d.ts +7 -2
- package/dist/models/response.js +6 -1
- package/dist/operatorAgent/agentAuthorContext.d.ts +1 -1
- package/dist/operatorAgent/agentAuthorContext.js +1 -1
- package/dist/operatorAgent/evalGate.d.ts +22 -0
- package/dist/operatorAgent/evalGate.js +77 -0
- package/dist/operatorAgent/fakeHost.js +10 -2
- package/dist/operatorAgent/host.js +18 -2
- package/dist/operatorAgent/index.d.ts +1 -0
- package/dist/operatorAgent/index.js +1 -0
- package/dist/operatorAgent/internalAgents.d.ts +11 -0
- package/dist/operatorAgent/internalAgents.js +13 -0
- package/dist/operatorAgent/piModel.d.ts +5 -1
- package/dist/operatorAgent/piModel.js +32 -14
- package/dist/operatorAgent/profiles/agentAuthor.d.ts +3 -1
- package/dist/operatorAgent/profiles/agentAuthor.js +201 -32
- package/dist/operatorAgent/profiles/agentAuthorPlaybook.d.ts +1 -1
- package/dist/operatorAgent/profiles/agentAuthorPlaybook.js +48 -15
- package/dist/operatorAgent/profiles/authorReadable.d.ts +2 -0
- package/dist/operatorAgent/profiles/authorReadable.js +26 -0
- package/dist/operatorAgent/profiles/guideConfirm.d.ts +21 -0
- package/dist/operatorAgent/profiles/guideConfirm.js +100 -0
- package/dist/operatorAgent/profiles/guideTools.d.ts +7 -0
- package/dist/operatorAgent/profiles/guideTools.js +123 -0
- package/dist/operatorAgent/profiles/stageflowGuide.d.ts +7 -0
- package/dist/operatorAgent/profiles/stageflowGuide.js +132 -0
- package/dist/operatorAgent/profiles/workshopAuthor.js +23 -0
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.d.ts +1 -1
- package/dist/operatorAgent/profiles/workshopAuthorPlaybook.js +9 -1
- package/dist/operatorAgent/profiles/workshopAuthorTools.d.ts +2 -0
- package/dist/operatorAgent/profiles/workshopAuthorTools.js +197 -9
- package/dist/operatorAgent/types.d.ts +23 -0
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/runstore/port.d.ts +43 -0
- package/dist/runstore/retention.d.ts +2 -1
- package/dist/runstore/retention.js +3 -7
- package/dist/runstore/runStatusClock.d.ts +17 -0
- package/dist/runstore/runStatusClock.js +19 -0
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +29 -0
- package/dist/runstore/sqlite/SqliteRunStore.js +144 -50
- package/dist/runstore/sqlite/evalStore.d.ts +20 -0
- package/dist/runstore/sqlite/evalStore.js +541 -0
- package/dist/runstore/sqlite/migrations/015-evals.d.ts +12 -0
- package/dist/runstore/sqlite/migrations/015-evals.js +157 -0
- package/dist/runstore/sqlite/migrations/016-eval-subject-ref.d.ts +12 -0
- package/dist/runstore/sqlite/migrations/016-eval-subject-ref.js +20 -0
- package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.d.ts +11 -0
- package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.js +36 -0
- package/dist/runstore/sqlite/migrations/index.js +6 -0
- package/dist/runstore/sqlite/suggestionStore.d.ts +14 -0
- package/dist/runstore/sqlite/suggestionStore.js +132 -0
- package/dist/runstore/workspaceLayout.js +6 -1
- package/dist/runtime/artifactDiskInspect.d.ts +14 -0
- package/dist/runtime/artifactDiskInspect.js +52 -0
- package/dist/runtime/artifactPath.d.ts +24 -0
- package/dist/runtime/artifactPath.js +84 -0
- package/dist/runtime/completionCheckRunner.js +15 -43
- package/dist/runtime/githubPollSource.d.ts +22 -4
- package/dist/runtime/githubPollSource.js +93 -8
- package/dist/runtime/pipelineRunner.d.ts +2 -1
- package/dist/runtime/pipelineRunner.js +2 -0
- package/dist/runtime/priorArtifactGrants.d.ts +8 -0
- package/dist/runtime/priorArtifactGrants.js +105 -0
- package/dist/runtime/runActionEligibility.d.ts +46 -0
- package/dist/runtime/runActionEligibility.js +123 -0
- package/dist/runtime/runManager.d.ts +6 -2
- package/dist/runtime/runManager.js +60 -16
- package/dist/runtime/runRetentionSweep.js +2 -2
- package/dist/runtime/runRetryCoordinator.d.ts +2 -14
- package/dist/runtime/runRetryCoordinator.js +3 -67
- package/dist/runtime/sandboxContainer.d.ts +7 -0
- package/dist/runtime/sandboxContainer.js +48 -6
- package/dist/runtime/sandboxDesk.d.ts +2 -1
- package/dist/runtime/sandboxDesk.js +11 -12
- package/dist/runtime/stageEnvironment.js +1 -0
- package/dist/runtime/stageRoots.d.ts +12 -0
- package/dist/runtime/stageSandbox.d.ts +2 -1
- package/dist/runtime/stageSandbox.js +18 -2
- package/dist/runtime/stageWorker.js +20 -0
- package/dist/server/agentAuthorRoutes.js +59 -1
- package/dist/server/bootstrap.d.ts +13 -0
- package/dist/server/bootstrap.js +69 -0
- package/dist/server/controlToken.js +3 -0
- package/dist/server/evalInternalRoutes.d.ts +14 -0
- package/dist/server/evalInternalRoutes.js +87 -0
- package/dist/server/evalRouteContext.d.ts +46 -0
- package/dist/server/evalRouteContext.js +43 -0
- package/dist/server/evalRoutes.d.ts +5 -0
- package/dist/server/evalRoutes.js +1456 -0
- package/dist/server/evalTriageRoutes.d.ts +2 -0
- package/dist/server/evalTriageRoutes.js +95 -0
- package/dist/server/guideRoutes.d.ts +5 -0
- package/dist/server/guideRoutes.js +166 -0
- package/dist/server/http.d.ts +15 -0
- package/dist/server/http.js +67 -3
- package/dist/server/internalAgentRoutes.d.ts +6 -0
- package/dist/server/internalAgentRoutes.js +12 -0
- package/dist/server/mcpHost.js +5 -0
- package/dist/toolkit/meta.d.ts +1 -1
- package/dist/toolkit/meta.js +53 -0
- package/dist/toolkit/profiles.d.ts +5 -0
- package/dist/toolkit/profiles.js +13 -1
- package/dist/tools/askOperator.js +2 -1
- package/dist/tools/emitStageEnvelope.d.ts +17 -16
- package/dist/tools/emitStageEnvelope.js +46 -32
- package/dist/tools/stageToolNames.d.ts +4 -0
- package/dist/tools/stageToolNames.js +4 -0
- package/dist/tools/workingState.d.ts +40 -0
- package/dist/tools/workingState.js +108 -0
- package/dist/tools/writeStageArtifact.d.ts +0 -9
- package/dist/tools/writeStageArtifact.js +2 -1
- package/dist/types/stageflowManifest.d.ts +6 -0
- package/dist/ui/assets/{MarkdownText-D7tYaIFO.js → MarkdownText-S5C_vemc.js} +2 -2
- package/dist/ui/assets/adapters-C0l4ruiR.js +17 -0
- package/dist/ui/assets/chat-CjnsmvqR.js +2 -0
- package/dist/ui/assets/chat-DFDd4UjS.css +2 -0
- package/dist/ui/assets/{main-BFo79krC.css → main-Del1GeLf.css} +1 -1
- package/dist/ui/assets/main-_yXVqcW9.js +277 -0
- package/dist/ui/chat.html +3 -4
- package/dist/ui/index.html +3 -4
- package/dist/workshop/chatTurn.js +1 -1
- package/dist/workshop/workshopPin.d.ts +3 -3
- package/dist/workshop/workshopPin.js +16 -15
- package/examples/README.md +2 -0
- package/examples/compaction-stress/README.md +30 -0
- package/examples/compaction-stress/check-run.mjs +53 -0
- package/examples/compaction-stress/collect-evidence.yaml +60 -0
- package/examples/compaction-stress/compaction-stress.pipeline.yaml +141 -0
- package/examples/compaction-stress/compaction-stress.task.yaml +15 -0
- package/examples/compaction-stress/generate-evidence.mjs +110 -0
- package/examples/compaction-stress/root-cause.yaml +26 -0
- package/examples/compaction-stress/stageflow.yaml +9 -0
- package/examples/compaction-stress/write-postmortem.yaml +40 -0
- package/examples/document-policy-review/README.md +35 -0
- package/examples/document-policy-review/agents/compliance.agent.yaml +42 -0
- package/examples/document-policy-review/documents/acme-vendor-sow.md +15 -0
- package/examples/document-policy-review/documents/support-runbook.md +13 -0
- package/examples/document-policy-review/policies/acceptable-use.md +13 -0
- package/examples/document-policy-review/policies/data-handling.md +17 -0
- package/examples/document-policy-review/policies/vendor-security.md +17 -0
- package/examples/evals/README.md +141 -0
- package/examples/evals/critique-sample.dataset.jsonl +8 -0
- package/examples/evals/critique-sample.eval.yaml +34 -0
- package/examples/evals/critique-sample.task.yaml +4 -0
- package/examples/evals/eval-sample.pipeline.yaml +35 -0
- package/examples/evals/guide-behavior.dataset.jsonl +15 -0
- package/examples/evals/guide-behavior.eval.yaml +35 -0
- package/examples/evals/guide-depth.dataset.jsonl +35 -0
- package/examples/evals/guide-depth.eval.yaml +169 -0
- package/examples/evals/support-sample.agent.yaml +20 -0
- package/examples/evals/support-sample.dataset.jsonl +6 -0
- package/examples/evals/support-sample.eval.yaml +38 -0
- package/examples/memory/evals/guide-behavior.dataset.jsonl +15 -0
- package/examples/memory/evals/guide-behavior.eval.yaml +35 -0
- package/examples/memory/evals/guide-depth.dataset.jsonl +35 -0
- package/examples/memory/evals/guide-depth.eval.yaml +169 -0
- package/examples/stageflow.yaml +6 -0
- package/package.json +1 -1
- package/skills/stageflow/SKILL.md +5 -2
- package/skills/stageflow/references/control-surface.md +4 -2
- package/skills/stageflow/references/evals.md +68 -0
- package/skills/stageflow-author/SKILL.md +4 -0
- package/skills/stageflow-run/SKILL.md +4 -0
- package/dist/ui/assets/AssistantRuntimeProvider-CsiPFhCT.js +0 -9
- package/dist/ui/assets/ReadonlyStore-BfXqHykm.js +0 -6
- package/dist/ui/assets/chat-BbLukq9W.js +0 -5
- package/dist/ui/assets/chat-zIZU_bP1.css +0 -2
- package/dist/ui/assets/main-CijYMeM0.js +0 -259
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { CompleteInput, CompleteResult, ConversationBackend, RuntimeUsage } from "../../agents/runtime/types.js";
|
|
2
|
+
export type FakeToolStep = {
|
|
3
|
+
tool: string;
|
|
4
|
+
input?: Record<string, unknown>;
|
|
5
|
+
/** What the tool does when the gate lets it run. */
|
|
6
|
+
body?: () => string | Promise<string>;
|
|
7
|
+
/** Report the tool as failed when it ran. */
|
|
8
|
+
fails?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export type FakeTurnScript = {
|
|
11
|
+
text?: string;
|
|
12
|
+
tools?: FakeToolStep[];
|
|
13
|
+
usage?: RuntimeUsage;
|
|
14
|
+
/** Wait before replying; an abort ends the wait early. */
|
|
15
|
+
delayMs?: number;
|
|
16
|
+
/** Never reply until the turn is aborted. */
|
|
17
|
+
hang?: boolean;
|
|
18
|
+
/** Throw this from the backend. */
|
|
19
|
+
error?: Error;
|
|
20
|
+
};
|
|
21
|
+
export type FakeTurnReply = FakeTurnScript | ((input: CompleteInput, index: number) => FakeTurnScript);
|
|
22
|
+
export declare const FAKE_USAGE: RuntimeUsage;
|
|
23
|
+
/**
|
|
24
|
+
* A scriptable conversation backend for eval tests. Each model call takes the next scripted turn; tool calls go
|
|
25
|
+
* through the same gate and hooks the real runtime uses, so tool policy is exercised.
|
|
26
|
+
*/
|
|
27
|
+
export declare class FakeAgentBackend implements ConversationBackend {
|
|
28
|
+
private readonly script;
|
|
29
|
+
readonly id: "pi";
|
|
30
|
+
readonly inputs: CompleteInput[];
|
|
31
|
+
readonly released: string[];
|
|
32
|
+
/** Tool bodies that actually ran, by grant id. */
|
|
33
|
+
readonly executed: string[];
|
|
34
|
+
private index;
|
|
35
|
+
private callSeq;
|
|
36
|
+
constructor(script?: readonly FakeTurnReply[] | ((input: CompleteInput, index: number) => FakeTurnScript));
|
|
37
|
+
complete(input: CompleteInput): Promise<CompleteResult>;
|
|
38
|
+
release(sessionId: string): Promise<void>;
|
|
39
|
+
get calls(): number;
|
|
40
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export const FAKE_USAGE = { inputTokens: 100, outputTokens: 20, costUsd: 0.01 };
|
|
2
|
+
function waitOrAbort(ms, signal) {
|
|
3
|
+
return new Promise((resolve) => {
|
|
4
|
+
if (signal.aborted)
|
|
5
|
+
return resolve();
|
|
6
|
+
const done = () => {
|
|
7
|
+
clearTimeout(timer);
|
|
8
|
+
signal.removeEventListener("abort", done);
|
|
9
|
+
resolve();
|
|
10
|
+
};
|
|
11
|
+
const timer = ms === undefined ? undefined : setTimeout(done, ms);
|
|
12
|
+
signal.addEventListener("abort", done, { once: true });
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A scriptable conversation backend for eval tests. Each model call takes the next scripted turn; tool calls go
|
|
17
|
+
* through the same gate and hooks the real runtime uses, so tool policy is exercised.
|
|
18
|
+
*/
|
|
19
|
+
export class FakeAgentBackend {
|
|
20
|
+
script;
|
|
21
|
+
id = "pi";
|
|
22
|
+
inputs = [];
|
|
23
|
+
released = [];
|
|
24
|
+
/** Tool bodies that actually ran, by grant id. */
|
|
25
|
+
executed = [];
|
|
26
|
+
index = 0;
|
|
27
|
+
callSeq = 0;
|
|
28
|
+
constructor(script = []) {
|
|
29
|
+
this.script = script;
|
|
30
|
+
}
|
|
31
|
+
async complete(input) {
|
|
32
|
+
const index = this.index++;
|
|
33
|
+
this.inputs.push(input);
|
|
34
|
+
const reply = typeof this.script === "function" ? this.script : this.script[index];
|
|
35
|
+
const turn = typeof reply === "function" ? reply(input, index) : (reply ?? { text: `reply ${index + 1}` });
|
|
36
|
+
if (turn.error)
|
|
37
|
+
throw turn.error;
|
|
38
|
+
const usage = turn.usage ?? FAKE_USAGE;
|
|
39
|
+
const toolOutputs = [];
|
|
40
|
+
const startedAt = new Date();
|
|
41
|
+
if (turn.hang)
|
|
42
|
+
await waitOrAbort(undefined, input.signal);
|
|
43
|
+
else if (turn.delayMs !== undefined)
|
|
44
|
+
await waitOrAbort(turn.delayMs, input.signal);
|
|
45
|
+
if (input.signal.aborted)
|
|
46
|
+
return { text: "", usage, toolOutputs };
|
|
47
|
+
for (const step of turn.tools ?? []) {
|
|
48
|
+
const call = { id: `call_${(this.callSeq += 1)}`, tool: step.tool, input: step.input ?? {} };
|
|
49
|
+
const decision = await input.hooks.gate(call);
|
|
50
|
+
if (!decision.allow)
|
|
51
|
+
continue;
|
|
52
|
+
input.hooks.toolStarted(call);
|
|
53
|
+
let output;
|
|
54
|
+
let ok = step.fails !== true;
|
|
55
|
+
if (step.tool.startsWith("agent:")) {
|
|
56
|
+
output = await input.hooks.delegate(step.tool.slice(6), String(call.input.message ?? ""), call.id);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
try {
|
|
60
|
+
this.executed.push(step.tool);
|
|
61
|
+
output = await (step.body ? step.body() : `ran ${step.tool}`);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
ok = false;
|
|
65
|
+
output = error instanceof Error ? error.message : String(error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
toolOutputs.push(output);
|
|
69
|
+
input.hooks.toolFinished(call, { ok, output });
|
|
70
|
+
}
|
|
71
|
+
const text = turn.text ?? `reply ${index + 1}`;
|
|
72
|
+
input.onDelta(text);
|
|
73
|
+
input.hooks.modelFinished({ startedAt, endedAt: new Date(), ...usage });
|
|
74
|
+
return { text, usage, toolOutputs };
|
|
75
|
+
}
|
|
76
|
+
async release(sessionId) {
|
|
77
|
+
this.released.push(sessionId);
|
|
78
|
+
}
|
|
79
|
+
get calls() {
|
|
80
|
+
return this.index;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AgentHostContext } from "../../agents/hostContext.js";
|
|
2
|
+
import type { AgentDefinition } from "../../config/loadAgent.js";
|
|
3
|
+
import { type ModelPrice, type SimulatorModel } from "./simulatorModel.js";
|
|
4
|
+
import type { StageCaseRunner } from "./stageCaseRunner.js";
|
|
5
|
+
export declare const EVAL_CASE_WALL_CLOCK_GRACE_MS = 60000;
|
|
6
|
+
export declare const EVAL_TURN_STOP_GRACE_MS = 10000;
|
|
7
|
+
export type AgentRunnerHost = Pick<AgentHostContext, "service" | "chat" | "evalGates" | "backend">;
|
|
8
|
+
export type AgentCaseRunnerDeps = {
|
|
9
|
+
/** Lazy: the manager is built before the agent host. Undefined means this Host cannot run agents. */
|
|
10
|
+
host: () => AgentRunnerHost | undefined;
|
|
11
|
+
/** Builds the simulated user's model; defaults to the agent backend's one-shot call on `plan.userModel`. */
|
|
12
|
+
simulatorModel?: (input: {
|
|
13
|
+
projectRoot: string;
|
|
14
|
+
definition: AgentDefinition;
|
|
15
|
+
modelId: string;
|
|
16
|
+
host: AgentRunnerHost;
|
|
17
|
+
}) => SimulatorModel;
|
|
18
|
+
/** USD per million tokens by model id, for pricing simulator calls the backend reports no cost for. */
|
|
19
|
+
loadPrices?: (modelIds: readonly string[], projectRoot: string) => Promise<Map<string, ModelPrice>>;
|
|
20
|
+
now?: () => number;
|
|
21
|
+
wallClockGraceMs?: number;
|
|
22
|
+
stopGraceMs?: number;
|
|
23
|
+
};
|
|
24
|
+
export declare function createAgentCaseRunner(deps: AgentCaseRunnerDeps): StageCaseRunner;
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import { isAgentError } from "../../agents/errors.js";
|
|
2
|
+
import { createEvalGate } from "../../agents/evalGate.js";
|
|
3
|
+
import { EVAL_MAX_CONSECUTIVE_PROVIDER_FAILURES } from "../constants.js";
|
|
4
|
+
import { buildConversationSubject } from "./conversationSubject.js";
|
|
5
|
+
import { createBackendSimulatorModel, SimulatorError, } from "./simulatorModel.js";
|
|
6
|
+
import { createDriver, DriverScenarioError, } from "./userDriver.js";
|
|
7
|
+
export const EVAL_CASE_WALL_CLOCK_GRACE_MS = 60_000;
|
|
8
|
+
export const EVAL_TURN_STOP_GRACE_MS = 10_000;
|
|
9
|
+
const SESSION_OVERHEAD_MINUTES = 5;
|
|
10
|
+
function failure(code, message, extra = {}) {
|
|
11
|
+
return {
|
|
12
|
+
ok: false,
|
|
13
|
+
code,
|
|
14
|
+
message,
|
|
15
|
+
...(extra.subjectRef !== undefined ? { subjectRef: extra.subjectRef } : {}),
|
|
16
|
+
...(extra.output !== undefined ? { output: extra.output } : {}),
|
|
17
|
+
...(extra.latencyMs !== undefined ? { latencyMs: extra.latencyMs } : {}),
|
|
18
|
+
...(extra.costUsd !== undefined ? { costUsd: extra.costUsd } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function parseMocks(value) {
|
|
22
|
+
const out = {};
|
|
23
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
24
|
+
return out;
|
|
25
|
+
for (const [tool, mock] of Object.entries(value)) {
|
|
26
|
+
if (typeof mock !== "object" || mock === null)
|
|
27
|
+
continue;
|
|
28
|
+
const { result, error } = mock;
|
|
29
|
+
if (typeof error === "string")
|
|
30
|
+
out[tool] = { error };
|
|
31
|
+
else if ("result" in mock)
|
|
32
|
+
out[tool] = { result };
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
function sumTurns(detail) {
|
|
37
|
+
let costUsd = 0;
|
|
38
|
+
let tokensIn = 0;
|
|
39
|
+
let tokensOut = 0;
|
|
40
|
+
for (const turn of detail.turns) {
|
|
41
|
+
costUsd += turn.costUsd ?? 0;
|
|
42
|
+
tokensIn += turn.inputTokens ?? 0;
|
|
43
|
+
tokensOut += turn.outputTokens ?? 0;
|
|
44
|
+
}
|
|
45
|
+
const modelSpans = detail.spans.filter((span) => span.kind === "model").length;
|
|
46
|
+
return { costUsd, tokensIn, tokensOut, modelCalls: modelSpans > 0 ? modelSpans : detail.turns.length };
|
|
47
|
+
}
|
|
48
|
+
function isEmptyReply(detail, turn) {
|
|
49
|
+
if ((turn.outputTokens ?? 0) > 0)
|
|
50
|
+
return false;
|
|
51
|
+
return !detail.messages.some((m) => m.turnId === turn.id && m.role === "assistant" && m.text.trim() !== "");
|
|
52
|
+
}
|
|
53
|
+
function errorText(error) {
|
|
54
|
+
if (isAgentError(error))
|
|
55
|
+
return error.message === error.code ? error.code : `${error.code}: ${error.message}`;
|
|
56
|
+
return "agent.backend_failed";
|
|
57
|
+
}
|
|
58
|
+
export function createAgentCaseRunner(deps) {
|
|
59
|
+
const clock = deps.now ?? Date.now;
|
|
60
|
+
const wallGraceMs = deps.wallClockGraceMs ?? EVAL_CASE_WALL_CLOCK_GRACE_MS;
|
|
61
|
+
const stopGraceMs = deps.stopGraceMs ?? EVAL_TURN_STOP_GRACE_MS;
|
|
62
|
+
const states = new Map();
|
|
63
|
+
const stateFor = (evalRunId) => {
|
|
64
|
+
let state = states.get(evalRunId);
|
|
65
|
+
if (state === undefined) {
|
|
66
|
+
state = { active: new Map(), spend: 0, cancelled: false, abort: new AbortController(), providerFailures: 0 };
|
|
67
|
+
states.set(evalRunId, state);
|
|
68
|
+
}
|
|
69
|
+
return state;
|
|
70
|
+
};
|
|
71
|
+
async function simulatorFor(plan, host, definition) {
|
|
72
|
+
const modelId = plan.userModel;
|
|
73
|
+
if (deps.simulatorModel)
|
|
74
|
+
return deps.simulatorModel({ projectRoot: plan.projectRoot, definition, modelId, host });
|
|
75
|
+
const prices = (await deps.loadPrices?.([modelId], plan.projectRoot).catch(() => undefined)) ?? new Map();
|
|
76
|
+
return createBackendSimulatorModel({
|
|
77
|
+
backend: host.backend,
|
|
78
|
+
projectRoot: plan.projectRoot,
|
|
79
|
+
definition,
|
|
80
|
+
modelId,
|
|
81
|
+
priceOf: (id) => prices.get(id),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async function runCase(plan, req) {
|
|
85
|
+
const state = stateFor(req.evalRunId);
|
|
86
|
+
if (state.stopReason !== undefined)
|
|
87
|
+
return failure("EVAL_CANCELLED", state.stopReason);
|
|
88
|
+
const result = await runCaseInner(plan, req);
|
|
89
|
+
if (result.ok)
|
|
90
|
+
state.providerFailures = 0;
|
|
91
|
+
else if (result.code === "EVAL_AGENT_EMPTY_REPLY" || result.code === "EVAL_AGENT_FAILED") {
|
|
92
|
+
state.providerFailures += 1;
|
|
93
|
+
if (state.providerFailures >= EVAL_MAX_CONSECUTIVE_PROVIDER_FAILURES && state.stopReason === undefined) {
|
|
94
|
+
state.stopReason = `Stopped after ${EVAL_MAX_CONSECUTIVE_PROVIDER_FAILURES} consecutive provider failures; check your provider key or rate limit`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
async function runCaseInner(plan, req) {
|
|
100
|
+
const state = stateFor(req.evalRunId);
|
|
101
|
+
if (state.cancelled)
|
|
102
|
+
return failure("EVAL_CANCELLED", "Eval run was cancelled");
|
|
103
|
+
if (state.spend >= plan.maxCostUsd) {
|
|
104
|
+
return failure("EVAL_BUDGET_EXCEEDED", `Eval spend reached the $${plan.maxCostUsd} limit`);
|
|
105
|
+
}
|
|
106
|
+
const { agent, conversation, target } = plan;
|
|
107
|
+
if (target.kind !== "agent" || !agent || !conversation) {
|
|
108
|
+
return failure("EVAL_ENGINE_ERROR", "Not an agent plan");
|
|
109
|
+
}
|
|
110
|
+
const host = deps.host();
|
|
111
|
+
if (!host)
|
|
112
|
+
return failure("EVAL_ENGINE_ERROR", "Agents are unavailable on this host");
|
|
113
|
+
const planCase = plan.cases.find((c) => c.id === req.caseId);
|
|
114
|
+
if (planCase === undefined)
|
|
115
|
+
return failure("EVAL_ENGINE_ERROR", `Case "${req.caseId}" is not in the plan`);
|
|
116
|
+
const definition = agent.definition;
|
|
117
|
+
const scenario = planCase.input;
|
|
118
|
+
const mode = scenario.mode === "script" || scenario.mode === "simulated" ? scenario.mode : conversation.mode;
|
|
119
|
+
let driver;
|
|
120
|
+
try {
|
|
121
|
+
let simulatorModel;
|
|
122
|
+
if (mode === "simulated") {
|
|
123
|
+
if (!plan.userModel)
|
|
124
|
+
return failure("EVAL_ENGINE_ERROR", "A simulated case needs a user model");
|
|
125
|
+
simulatorModel = await simulatorFor(plan, host, definition);
|
|
126
|
+
}
|
|
127
|
+
driver = createDriver(mode, scenario, simulatorModel ? { simulatorModel } : {});
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
return failure("EVAL_ENGINE_ERROR", err instanceof DriverScenarioError ? err.message : "Scenario could not be prepared");
|
|
131
|
+
}
|
|
132
|
+
const { service, chat, evalGates } = host;
|
|
133
|
+
const startedAt = clock();
|
|
134
|
+
const sessionMinutes = Math.ceil((conversation.maxTurns * conversation.turnTimeoutMs) / 60_000) + SESSION_OVERHEAD_MINUTES;
|
|
135
|
+
let sessionId;
|
|
136
|
+
try {
|
|
137
|
+
const session = await service.openSession(plan.projectRoot, target.agentId, {
|
|
138
|
+
source: "eval",
|
|
139
|
+
sourceRef: plan.evalRunId,
|
|
140
|
+
title: `eval ${plan.evalId} ${plan.evalRunId} ${req.caseId}.${req.repeatIndex}`,
|
|
141
|
+
eval: {
|
|
142
|
+
...(target.revision !== undefined ? { revision: target.revision } : {}),
|
|
143
|
+
...(plan.modelOverride !== undefined ? { definition: { model: { id: plan.modelOverride } } } : {}),
|
|
144
|
+
limits: { max_turns: conversation.maxTurns + 1, session_minutes: sessionMinutes, cost_usd: null },
|
|
145
|
+
capture: "full",
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
sessionId = session.id;
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
const code = isAgentError(err) && (err.code === "agent.archived" || err.code === "agent.revision_not_found") ? "EVAL_AGENT_FAILED" : "EVAL_ENGINE_ERROR";
|
|
152
|
+
return failure(code, isAgentError(err) ? errorText(err) : "The eval session could not be opened");
|
|
153
|
+
}
|
|
154
|
+
let resolveDone;
|
|
155
|
+
state.active.set(sessionId, { done: new Promise((resolve) => (resolveDone = resolve)) });
|
|
156
|
+
let currentTurn = 0;
|
|
157
|
+
const gate = createEvalGate({
|
|
158
|
+
policy: {
|
|
159
|
+
tools: conversation.tools,
|
|
160
|
+
approvals: conversation.approvals,
|
|
161
|
+
readOnlyTools: conversation.readOnlyTools,
|
|
162
|
+
mocks: parseMocks(scenario.tool_mocks),
|
|
163
|
+
},
|
|
164
|
+
definition,
|
|
165
|
+
projectRoot: plan.projectRoot,
|
|
166
|
+
turn: () => currentTurn,
|
|
167
|
+
});
|
|
168
|
+
evalGates.set(sessionId, gate);
|
|
169
|
+
const usage = { simCost: 0, simIn: 0, simOut: 0, simCalls: 0, simEstimated: false };
|
|
170
|
+
const addSimulator = (u) => {
|
|
171
|
+
if (u === undefined)
|
|
172
|
+
return;
|
|
173
|
+
usage.simCost += u.costUsd;
|
|
174
|
+
usage.simIn += u.tokensIn;
|
|
175
|
+
usage.simOut += u.tokensOut;
|
|
176
|
+
usage.simCalls += 1;
|
|
177
|
+
usage.simEstimated ||= u.estimated === true;
|
|
178
|
+
state.spend += u.costUsd;
|
|
179
|
+
};
|
|
180
|
+
let countedRootCost = 0;
|
|
181
|
+
const syncSpend = (detail) => {
|
|
182
|
+
const cost = sumTurns(detail).costUsd;
|
|
183
|
+
state.spend += cost - countedRootCost;
|
|
184
|
+
countedRootCost = cost;
|
|
185
|
+
};
|
|
186
|
+
const caseCtl = new AbortController();
|
|
187
|
+
let wallExpired = false;
|
|
188
|
+
let stuckTimer;
|
|
189
|
+
let releaseStuck = () => undefined;
|
|
190
|
+
const stuck = new Promise((resolve) => (releaseStuck = () => resolve("stuck")));
|
|
191
|
+
const stopTurn = () => {
|
|
192
|
+
chat.stop(sessionId);
|
|
193
|
+
stuckTimer ??= setTimeout(releaseStuck, stopGraceMs);
|
|
194
|
+
};
|
|
195
|
+
const onCancel = () => {
|
|
196
|
+
caseCtl.abort();
|
|
197
|
+
stopTurn();
|
|
198
|
+
};
|
|
199
|
+
state.abort.signal.addEventListener("abort", onCancel, { once: true });
|
|
200
|
+
const wallMs = conversation.maxTurns * conversation.turnTimeoutMs + wallGraceMs;
|
|
201
|
+
const wallTimer = setTimeout(() => {
|
|
202
|
+
wallExpired = true;
|
|
203
|
+
caseCtl.abort();
|
|
204
|
+
stopTurn();
|
|
205
|
+
}, wallMs);
|
|
206
|
+
let turnsDone = 0;
|
|
207
|
+
const converse = async () => {
|
|
208
|
+
const transcript = [];
|
|
209
|
+
for (let turn = 1; turn <= conversation.maxTurns; turn++) {
|
|
210
|
+
if (state.cancelled)
|
|
211
|
+
return { kind: "cancelled" };
|
|
212
|
+
if (wallExpired)
|
|
213
|
+
return { kind: "failed", code: "EVAL_AGENT_TIMEOUT", message: "Conversation exceeded its time limit", stopReason: "timeout" };
|
|
214
|
+
let step;
|
|
215
|
+
try {
|
|
216
|
+
step = await driver.next({ turn, transcript, signal: caseCtl.signal });
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
if (state.cancelled)
|
|
220
|
+
return { kind: "cancelled" };
|
|
221
|
+
if (wallExpired)
|
|
222
|
+
return { kind: "failed", code: "EVAL_AGENT_TIMEOUT", message: "Conversation exceeded its time limit", stopReason: "timeout" };
|
|
223
|
+
const message = err instanceof SimulatorError ? err.message : "The simulated user failed";
|
|
224
|
+
return { kind: "failed", code: "EVAL_SIMULATOR_ERROR", message, stopReason: "error" };
|
|
225
|
+
}
|
|
226
|
+
addSimulator(step.usage);
|
|
227
|
+
if (step.kind === "end")
|
|
228
|
+
return { kind: "done", stopReason: step.reason };
|
|
229
|
+
currentTurn = turn;
|
|
230
|
+
let turnTimedOut = false;
|
|
231
|
+
const turnTimer = setTimeout(() => {
|
|
232
|
+
turnTimedOut = true;
|
|
233
|
+
stopTurn();
|
|
234
|
+
}, conversation.turnTimeoutMs);
|
|
235
|
+
const sent = chat
|
|
236
|
+
.send({ projectRoot: plan.projectRoot, agentId: target.agentId, sessionId, text: step.text, source: "eval" })
|
|
237
|
+
.then((detail) => ({ ok: true, detail }), (err) => ({ ok: false, err }));
|
|
238
|
+
const outcome = await Promise.race([sent, stuck]);
|
|
239
|
+
clearTimeout(turnTimer);
|
|
240
|
+
turnsDone = turn;
|
|
241
|
+
if (state.cancelled)
|
|
242
|
+
return { kind: "cancelled" };
|
|
243
|
+
if (outcome === "stuck" || turnTimedOut || wallExpired) {
|
|
244
|
+
const message = turnTimedOut ? `Turn ${turn} exceeded ${conversation.turnTimeoutMs} ms` : "Conversation exceeded its time limit";
|
|
245
|
+
return { kind: "failed", code: "EVAL_AGENT_TIMEOUT", message, stopReason: "timeout" };
|
|
246
|
+
}
|
|
247
|
+
if (!outcome.ok) {
|
|
248
|
+
return { kind: "failed", code: "EVAL_AGENT_FAILED", message: errorText(outcome.err), stopReason: "error" };
|
|
249
|
+
}
|
|
250
|
+
const { detail } = outcome;
|
|
251
|
+
syncSpend(detail);
|
|
252
|
+
const latest = detail.turns[detail.turns.length - 1];
|
|
253
|
+
if (latest?.status === "waiting") {
|
|
254
|
+
return { kind: "failed", code: "EVAL_ENGINE_ERROR", message: "A turn is waiting for approval, which an eval cannot give", stopReason: "error" };
|
|
255
|
+
}
|
|
256
|
+
if (latest !== undefined && latest.status !== "succeeded") {
|
|
257
|
+
return { kind: "failed", code: "EVAL_AGENT_FAILED", message: latest.errorCode ?? "agent.backend_failed", stopReason: "error" };
|
|
258
|
+
}
|
|
259
|
+
if (latest !== undefined && isEmptyReply(detail, latest)) {
|
|
260
|
+
return {
|
|
261
|
+
kind: "failed",
|
|
262
|
+
code: "EVAL_AGENT_EMPTY_REPLY",
|
|
263
|
+
message: "The agent returned an empty reply with no output tokens. The model provider may be rate limiting or failing; check your provider key and limits",
|
|
264
|
+
stopReason: "error",
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
transcript.splice(0, transcript.length, ...detail.messages.map((m) => ({ role: m.role, text: m.text })));
|
|
268
|
+
if (step.endAfter !== undefined)
|
|
269
|
+
return { kind: "done", stopReason: step.endAfter };
|
|
270
|
+
}
|
|
271
|
+
return { kind: "done", stopReason: "max_turns" };
|
|
272
|
+
};
|
|
273
|
+
let end;
|
|
274
|
+
try {
|
|
275
|
+
end = await converse();
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
end = { kind: "failed", code: "EVAL_ENGINE_ERROR", message: err instanceof Error ? err.message : "Conversation failed", stopReason: "error" };
|
|
279
|
+
}
|
|
280
|
+
clearTimeout(wallTimer);
|
|
281
|
+
if (stuckTimer)
|
|
282
|
+
clearTimeout(stuckTimer);
|
|
283
|
+
state.abort.signal.removeEventListener("abort", onCancel);
|
|
284
|
+
let result;
|
|
285
|
+
try {
|
|
286
|
+
const detail = await service.getSession(plan.projectRoot, sessionId);
|
|
287
|
+
syncSpend(detail);
|
|
288
|
+
const root = sumTurns(detail);
|
|
289
|
+
let childCost = 0;
|
|
290
|
+
let childIn = 0;
|
|
291
|
+
let childOut = 0;
|
|
292
|
+
let childCalls = 0;
|
|
293
|
+
for (const child of service.listChildSessions(sessionId)) {
|
|
294
|
+
const childDetail = await service.getSession(plan.projectRoot, child.id);
|
|
295
|
+
const sums = sumTurns(childDetail);
|
|
296
|
+
childCost += sums.costUsd;
|
|
297
|
+
childIn += sums.tokensIn;
|
|
298
|
+
childOut += sums.tokensOut;
|
|
299
|
+
childCalls += sums.modelCalls;
|
|
300
|
+
}
|
|
301
|
+
state.spend += childCost;
|
|
302
|
+
const agentCost = root.costUsd + childCost;
|
|
303
|
+
const conversationUsage = {
|
|
304
|
+
cost_usd: agentCost + usage.simCost,
|
|
305
|
+
agent_cost_usd: agentCost,
|
|
306
|
+
simulator_cost_usd: usage.simCost,
|
|
307
|
+
tokens_in: root.tokensIn + childIn,
|
|
308
|
+
tokens_out: root.tokensOut + childOut,
|
|
309
|
+
simulator_tokens_in: usage.simIn,
|
|
310
|
+
simulator_tokens_out: usage.simOut,
|
|
311
|
+
simulator_estimated: usage.simEstimated,
|
|
312
|
+
agent_calls: root.modelCalls + childCalls,
|
|
313
|
+
simulator_calls: usage.simCalls,
|
|
314
|
+
};
|
|
315
|
+
const latencyMs = Math.max(0, clock() - startedAt);
|
|
316
|
+
const costUsd = conversationUsage.cost_usd;
|
|
317
|
+
const subject = (stopReason, failed) => buildConversationSubject({
|
|
318
|
+
detail,
|
|
319
|
+
calls: gate.records(),
|
|
320
|
+
stopReason,
|
|
321
|
+
usage: conversationUsage,
|
|
322
|
+
turns: turnsDone,
|
|
323
|
+
...(failed !== undefined ? { failure: failed } : {}),
|
|
324
|
+
});
|
|
325
|
+
if (end.kind === "done") {
|
|
326
|
+
result = {
|
|
327
|
+
ok: true,
|
|
328
|
+
subjectRef: sessionId,
|
|
329
|
+
output: subject(end.stopReason),
|
|
330
|
+
latencyMs,
|
|
331
|
+
costUsd,
|
|
332
|
+
tokensIn: conversationUsage.tokens_in,
|
|
333
|
+
tokensOut: conversationUsage.tokens_out,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
else if (end.kind === "cancelled") {
|
|
337
|
+
result = failure("EVAL_CANCELLED", "Eval run was cancelled", { subjectRef: sessionId, latencyMs, costUsd });
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
result = failure(end.code, end.message, {
|
|
341
|
+
subjectRef: sessionId,
|
|
342
|
+
output: subject(end.stopReason, end.message),
|
|
343
|
+
latencyMs,
|
|
344
|
+
costUsd,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
catch (err) {
|
|
349
|
+
result = failure("EVAL_ENGINE_ERROR", err instanceof Error ? err.message : "Conversation could not be read", { subjectRef: sessionId });
|
|
350
|
+
}
|
|
351
|
+
finally {
|
|
352
|
+
try {
|
|
353
|
+
const children = service.listChildSessions(sessionId);
|
|
354
|
+
await chat.closeEvalSession(plan.projectRoot, sessionId);
|
|
355
|
+
for (const child of children) {
|
|
356
|
+
await chat.release(child.id);
|
|
357
|
+
service.forgetEvalSession(child.id);
|
|
358
|
+
evalGates.delete(child.id);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
/* the runtime session is dropped with the Host at the latest */
|
|
363
|
+
}
|
|
364
|
+
evalGates.delete(sessionId);
|
|
365
|
+
state.active.delete(sessionId);
|
|
366
|
+
resolveDone();
|
|
367
|
+
}
|
|
368
|
+
return result;
|
|
369
|
+
}
|
|
370
|
+
return {
|
|
371
|
+
runCase,
|
|
372
|
+
async cancelAll(evalRunId) {
|
|
373
|
+
const state = stateFor(evalRunId);
|
|
374
|
+
state.cancelled = true;
|
|
375
|
+
state.abort.abort();
|
|
376
|
+
const host = deps.host();
|
|
377
|
+
await Promise.all([...state.active.entries()].map(async ([sessionId, entry]) => {
|
|
378
|
+
host?.chat.stop(sessionId);
|
|
379
|
+
await entry.done;
|
|
380
|
+
}));
|
|
381
|
+
},
|
|
382
|
+
spend: (evalRunId) => states.get(evalRunId)?.spend ?? 0,
|
|
383
|
+
stopReason: (evalRunId) => states.get(evalRunId)?.stopReason,
|
|
384
|
+
addSpend(evalRunId, usd) {
|
|
385
|
+
stateFor(evalRunId).spend += usd;
|
|
386
|
+
},
|
|
387
|
+
};
|
|
388
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { StageCaseRunner } from "./stageCaseRunner.js";
|
|
2
|
+
export type EvalCaseRunner = StageCaseRunner;
|
|
3
|
+
/** Routes each case to the stage, agent, or internal-agent runner by the plan's target kind. */
|
|
4
|
+
export declare function createEvalCaseRunner(deps: {
|
|
5
|
+
stage: StageCaseRunner;
|
|
6
|
+
agent: StageCaseRunner;
|
|
7
|
+
internalAgent?: StageCaseRunner;
|
|
8
|
+
}): EvalCaseRunner;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { isConversationTarget } from "../types.js";
|
|
2
|
+
/** Routes each case to the stage, agent, or internal-agent runner by the plan's target kind. */
|
|
3
|
+
export function createEvalCaseRunner(deps) {
|
|
4
|
+
const kinds = new Map();
|
|
5
|
+
const runnerOf = (evalRunId) => {
|
|
6
|
+
const kind = kinds.get(evalRunId);
|
|
7
|
+
if (kind === "internal_agent" && deps.internalAgent)
|
|
8
|
+
return deps.internalAgent;
|
|
9
|
+
return kind === "agent" ? deps.agent : deps.stage;
|
|
10
|
+
};
|
|
11
|
+
return {
|
|
12
|
+
runCase(plan, req) {
|
|
13
|
+
const kind = plan.target.kind === "internal_agent" ? "internal_agent" : isConversationTarget(plan.target.kind) ? "agent" : "stage";
|
|
14
|
+
kinds.set(req.evalRunId, kind);
|
|
15
|
+
return runnerOf(req.evalRunId).runCase(plan, req);
|
|
16
|
+
},
|
|
17
|
+
async cancelAll(evalRunId) {
|
|
18
|
+
await Promise.all([
|
|
19
|
+
deps.stage.cancelAll(evalRunId),
|
|
20
|
+
deps.agent.cancelAll(evalRunId),
|
|
21
|
+
deps.internalAgent?.cancelAll(evalRunId),
|
|
22
|
+
]);
|
|
23
|
+
},
|
|
24
|
+
spend: (evalRunId) => deps.stage.spend(evalRunId) + deps.agent.spend(evalRunId) + (deps.internalAgent?.spend(evalRunId) ?? 0),
|
|
25
|
+
addSpend: (evalRunId, usd) => runnerOf(evalRunId).addSpend(evalRunId, usd),
|
|
26
|
+
stopReason: (evalRunId) => runnerOf(evalRunId).stopReason?.(evalRunId),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { EvalToolCallRecord } from "../../agents/evalGate.js";
|
|
2
|
+
import type { AgentSessionDetail } from "../../agents/service.js";
|
|
3
|
+
import type { ConversationOutput, ConversationStopReason, ConversationUsage } from "../types.js";
|
|
4
|
+
export type ConversationSubjectInput = {
|
|
5
|
+
detail: AgentSessionDetail;
|
|
6
|
+
calls: readonly EvalToolCallRecord[];
|
|
7
|
+
stopReason: ConversationStopReason;
|
|
8
|
+
usage: ConversationUsage;
|
|
9
|
+
/** User turns completed (a turn counts once the agent replied or failed). */
|
|
10
|
+
turns: number;
|
|
11
|
+
/** Set for the partial subject of a failed case. */
|
|
12
|
+
failure?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* The normalized subject of an agent result. Every text is redacted before it is capped, because stored agent
|
|
16
|
+
* messages are not redacted.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildConversationSubject(input: ConversationSubjectInput): ConversationOutput;
|