stageflow 0.40.0 → 0.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/agents/authorChat.d.ts +4 -0
- package/dist/agents/authorChat.js +113 -12
- package/dist/agents/authorSessionStore.d.ts +35 -0
- package/dist/agents/authorSessionStore.js +152 -0
- package/dist/agents/chatTurn.d.ts +2 -0
- package/dist/agents/chatTurn.js +17 -1
- package/dist/agents/errors.d.ts +1 -1
- package/dist/agents/errors.js +1 -0
- package/dist/agents/evalGate.d.ts +61 -0
- package/dist/agents/evalGate.js +103 -0
- package/dist/agents/evalSession.d.ts +26 -0
- package/dist/agents/evalSession.js +29 -0
- package/dist/agents/hostContext.d.ts +3 -0
- package/dist/agents/hostContext.js +4 -1
- package/dist/agents/runtime/piRuntime.d.ts +1 -1
- package/dist/agents/runtime/piRuntime.js +4 -4
- package/dist/agents/runtime/types.d.ts +3 -1
- package/dist/agents/service.d.ts +27 -2
- package/dist/agents/service.js +88 -13
- package/dist/agents/sessions.d.ts +8 -0
- package/dist/agents/sessions.js +50 -10
- package/dist/agents/store.d.ts +14 -3
- package/dist/agents/store.js +45 -7
- package/dist/agents/toolRisk.d.ts +21 -0
- package/dist/agents/toolRisk.js +50 -0
- package/dist/cli/doctorCommand.js +26 -0
- package/dist/cli/evalCommand.d.ts +20 -0
- package/dist/cli/evalCommand.js +720 -0
- package/dist/cli/exportAllCommand.js +1 -1
- package/dist/cli/hostClient.d.ts +60 -0
- package/dist/cli/hostClient.js +71 -0
- package/dist/cli/validateOutput.d.ts +2 -2
- package/dist/cli/validateOutput.js +2 -2
- package/dist/cli.js +10 -0
- package/dist/config/atomicWrite.d.ts +15 -0
- package/dist/config/atomicWrite.js +43 -0
- package/dist/config/browseCatalog.d.ts +2 -0
- package/dist/config/browseCatalog.js +4 -2
- package/dist/config/csv.d.ts +9 -0
- package/dist/config/csv.js +81 -0
- package/dist/config/datasetAgentCheck.d.ts +18 -0
- package/dist/config/datasetAgentCheck.js +109 -0
- package/dist/config/datasetCandidates.d.ts +22 -0
- package/dist/config/datasetCandidates.js +86 -0
- package/dist/config/datasetFromSessions.d.ts +34 -0
- package/dist/config/datasetFromSessions.js +105 -0
- package/dist/config/datasetHash.d.ts +1 -0
- package/dist/config/datasetHash.js +4 -0
- package/dist/config/datasetImport.d.ts +21 -0
- package/dist/config/datasetImport.js +120 -0
- package/dist/config/datasetStageCheck.d.ts +9 -0
- package/dist/config/datasetStageCheck.js +17 -0
- package/dist/config/datasetTypes.d.ts +27 -0
- package/dist/config/datasetTypes.js +1 -0
- package/dist/config/ensureCatalogScanRoot.d.ts +2 -1
- package/dist/config/ensureCatalogScanRoot.js +2 -6
- package/dist/config/evalCatalog.d.ts +22 -0
- package/dist/config/evalCatalog.js +67 -0
- package/dist/config/evalWriteRoots.d.ts +17 -0
- package/dist/config/evalWriteRoots.js +109 -0
- package/dist/config/hostConfig.js +1 -0
- package/dist/config/installEvalSample.d.ts +34 -0
- package/dist/config/installEvalSample.js +182 -0
- package/dist/config/loadDataset.d.ts +16 -0
- package/dist/config/loadDataset.js +318 -0
- package/dist/config/loadEval.d.ts +32 -0
- package/dist/config/loadEval.js +1085 -0
- package/dist/config/loadOutcome.d.ts +5 -0
- package/dist/config/loadStageflowManifest.js +64 -0
- package/dist/config/resolveAgentTarget.d.ts +32 -0
- package/dist/config/resolveAgentTarget.js +118 -0
- package/dist/config/resolveEvalTarget.d.ts +21 -0
- package/dist/config/resolveEvalTarget.js +89 -0
- package/dist/config/scanCatalogPaths.d.ts +1 -1
- package/dist/config/scanCatalogPaths.js +17 -5
- package/dist/config/validateCatalog.d.ts +1 -1
- package/dist/config/validateCatalog.js +9 -1
- package/dist/config/validateEval.d.ts +36 -0
- package/dist/config/validateEval.js +405 -0
- package/dist/config/writeDataset.d.ts +54 -0
- package/dist/config/writeDataset.js +186 -0
- package/dist/config/writeEval.d.ts +25 -0
- package/dist/config/writeEval.js +398 -0
- package/dist/diagnostics/checks.js +1 -1
- package/dist/evals/agentDiff.d.ts +13 -0
- package/dist/evals/agentDiff.js +11 -0
- package/dist/evals/canonical.d.ts +3 -0
- package/dist/evals/canonical.js +24 -0
- package/dist/evals/caseTask.d.ts +3 -0
- package/dist/evals/caseTask.js +9 -0
- package/dist/evals/compare.d.ts +94 -0
- package/dist/evals/compare.js +201 -0
- package/dist/evals/constants.d.ts +60 -0
- package/dist/evals/constants.js +95 -0
- package/dist/evals/engine/FakeEngine.d.ts +33 -0
- package/dist/evals/engine/FakeEngine.js +176 -0
- package/dist/evals/engine/index.d.ts +9 -0
- package/dist/evals/engine/index.js +19 -0
- package/dist/evals/engine/promptfoo/PromptfooEngine.d.ts +52 -0
- package/dist/evals/engine/promptfoo/PromptfooEngine.js +311 -0
- package/dist/evals/engine/promptfoo/errors.d.ts +5 -0
- package/dist/evals/engine/promptfoo/errors.js +8 -0
- package/dist/evals/engine/promptfoo/generate.d.ts +30 -0
- package/dist/evals/engine/promptfoo/generate.js +342 -0
- package/dist/evals/engine/promptfoo/guard.d.ts +10 -0
- package/dist/evals/engine/promptfoo/guard.js +116 -0
- package/dist/evals/engine/promptfoo/install.d.ts +17 -0
- package/dist/evals/engine/promptfoo/install.js +73 -0
- package/dist/evals/engine/promptfoo/judgeProviders.d.ts +2 -0
- package/dist/evals/engine/promptfoo/judgeProviders.js +9 -0
- package/dist/evals/engine/promptfoo/judgeServices.d.ts +6 -0
- package/dist/evals/engine/promptfoo/judgeServices.js +41 -0
- package/dist/evals/engine/promptfoo/locate.d.ts +21 -0
- package/dist/evals/engine/promptfoo/locate.js +68 -0
- package/dist/evals/engine/promptfoo/nodeVersion.d.ts +7 -0
- package/dist/evals/engine/promptfoo/nodeVersion.js +14 -0
- package/dist/evals/engine/promptfoo/normalize.d.ts +66 -0
- package/dist/evals/engine/promptfoo/normalize.js +261 -0
- package/dist/evals/engine/promptfoo/pinned.d.ts +5 -0
- package/dist/evals/engine/promptfoo/pinned.js +5 -0
- package/dist/evals/engine/promptfoo/rubricPrompt.d.ts +14 -0
- package/dist/evals/engine/promptfoo/rubricPrompt.js +103 -0
- package/dist/evals/engine/promptfoo/runTokens.d.ts +18 -0
- package/dist/evals/engine/promptfoo/runTokens.js +31 -0
- package/dist/evals/engine/promptfoo/status.d.ts +13 -0
- package/dist/evals/engine/promptfoo/status.js +16 -0
- package/dist/evals/estimate.d.ts +56 -0
- package/dist/evals/estimate.js +66 -0
- package/dist/evals/graders/codeGrader.d.ts +6 -0
- package/dist/evals/graders/codeGrader.js +85 -0
- package/dist/evals/graders/conversationCheckGrader.d.ts +6 -0
- package/dist/evals/graders/conversationCheckGrader.js +62 -0
- package/dist/evals/graders/fieldGrader.d.ts +11 -0
- package/dist/evals/graders/fieldGrader.js +117 -0
- package/dist/evals/graders/goal.d.ts +3 -0
- package/dist/evals/graders/goal.js +14 -0
- package/dist/evals/graders/index.d.ts +18 -0
- package/dist/evals/graders/index.js +34 -0
- package/dist/evals/graders/notApplicable.d.ts +5 -0
- package/dist/evals/graders/notApplicable.js +9 -0
- package/dist/evals/graders/path.d.ts +26 -0
- package/dist/evals/graders/path.js +75 -0
- package/dist/evals/graders/referenceGrader.d.ts +5 -0
- package/dist/evals/graders/referenceGrader.js +59 -0
- package/dist/evals/graders/schemaGrader.d.ts +5 -0
- package/dist/evals/graders/schemaGrader.js +29 -0
- package/dist/evals/graders/subject.d.ts +6 -0
- package/dist/evals/graders/subject.js +33 -0
- package/dist/evals/graders/toolCallsGrader.d.ts +6 -0
- package/dist/evals/graders/toolCallsGrader.js +100 -0
- package/dist/evals/graders/transcript.d.ts +12 -0
- package/dist/evals/graders/transcript.js +57 -0
- package/dist/evals/graders/types.d.ts +20 -0
- package/dist/evals/graders/types.js +1 -0
- package/dist/evals/judgeProviders.d.ts +16 -0
- package/dist/evals/judgeProviders.js +27 -0
- package/dist/evals/lineDiff.d.ts +5 -0
- package/dist/evals/lineDiff.js +34 -0
- package/dist/evals/listStatus.d.ts +31 -0
- package/dist/evals/listStatus.js +48 -0
- package/dist/evals/manager.d.ts +174 -0
- package/dist/evals/manager.js +787 -0
- package/dist/evals/plan.d.ts +58 -0
- package/dist/evals/plan.js +602 -0
- package/dist/evals/providerKeys.d.ts +1 -0
- package/dist/evals/providerKeys.js +21 -0
- package/dist/evals/read/agentTargets.d.ts +37 -0
- package/dist/evals/read/agentTargets.js +101 -0
- package/dist/evals/read/api.d.ts +196 -0
- package/dist/evals/read/api.js +358 -0
- package/dist/evals/read/compare.d.ts +4 -0
- package/dist/evals/read/compare.js +39 -0
- package/dist/evals/read/datasets.d.ts +105 -0
- package/dist/evals/read/datasets.js +318 -0
- package/dist/evals/read/list.d.ts +66 -0
- package/dist/evals/read/list.js +173 -0
- package/dist/evals/read/results.d.ts +46 -0
- package/dist/evals/read/results.js +107 -0
- package/dist/evals/read/runs.d.ts +149 -0
- package/dist/evals/read/runs.js +289 -0
- package/dist/evals/read/suggestions.d.ts +43 -0
- package/dist/evals/read/suggestions.js +73 -0
- package/dist/evals/runner/FakeAgentBackend.d.ts +40 -0
- package/dist/evals/runner/FakeAgentBackend.js +82 -0
- package/dist/evals/runner/agentCaseRunner.d.ts +24 -0
- package/dist/evals/runner/agentCaseRunner.js +388 -0
- package/dist/evals/runner/caseRunner.d.ts +7 -0
- package/dist/evals/runner/caseRunner.js +17 -0
- package/dist/evals/runner/conversationSubject.d.ts +18 -0
- package/dist/evals/runner/conversationSubject.js +123 -0
- package/dist/evals/runner/simulatorModel.d.ts +51 -0
- package/dist/evals/runner/simulatorModel.js +58 -0
- package/dist/evals/runner/simulatorPrompt.d.ts +29 -0
- package/dist/evals/runner/simulatorPrompt.js +59 -0
- package/dist/evals/runner/stageCaseRunner.d.ts +30 -0
- package/dist/evals/runner/stageCaseRunner.js +279 -0
- package/dist/evals/runner/userDriver.d.ts +71 -0
- package/dist/evals/runner/userDriver.js +104 -0
- package/dist/evals/scoring.d.ts +34 -0
- package/dist/evals/scoring.js +67 -0
- package/dist/evals/snapshot.d.ts +183 -0
- package/dist/evals/snapshot.js +65 -0
- package/dist/evals/stageDiff.d.ts +8 -0
- package/dist/evals/stageDiff.js +48 -0
- package/dist/evals/stats.d.ts +95 -0
- package/dist/evals/stats.js +220 -0
- package/dist/evals/statsAdapter.d.ts +4 -0
- package/dist/evals/statsAdapter.js +30 -0
- package/dist/evals/statsTypes.d.ts +51 -0
- package/dist/evals/statsTypes.js +18 -0
- package/dist/evals/storeError.d.ts +5 -0
- package/dist/evals/storeError.js +8 -0
- package/dist/evals/storeTypes.d.ts +207 -0
- package/dist/evals/storeTypes.js +1 -0
- package/dist/evals/tTable.d.ts +3 -0
- package/dist/evals/tTable.js +15 -0
- package/dist/evals/triage/constants.d.ts +26 -0
- package/dist/evals/triage/constants.js +33 -0
- package/dist/evals/triage/credentials.d.ts +13 -0
- package/dist/evals/triage/credentials.js +20 -0
- package/dist/evals/triage/jevClassifier.d.ts +14 -0
- package/dist/evals/triage/jevClassifier.js +124 -0
- package/dist/evals/triage/judgeClassifier.d.ts +10 -0
- package/dist/evals/triage/judgeClassifier.js +76 -0
- package/dist/evals/triage/prompts.d.ts +16 -0
- package/dist/evals/triage/prompts.js +64 -0
- package/dist/evals/triage/service.d.ts +79 -0
- package/dist/evals/triage/service.js +217 -0
- package/dist/evals/triage/stateBuilder.d.ts +19 -0
- package/dist/evals/triage/stateBuilder.js +125 -0
- package/dist/evals/triage/types.d.ts +60 -0
- package/dist/evals/triage/types.js +8 -0
- package/dist/evals/types.d.ts +347 -0
- package/dist/evals/types.js +1 -0
- package/dist/mcp/deps.d.ts +7 -0
- package/dist/mcp/evalTools.d.ts +3 -0
- package/dist/mcp/evalTools.js +280 -0
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.js +2 -0
- package/dist/models/response.d.ts +7 -2
- package/dist/models/response.js +6 -1
- package/dist/operatorAgent/agentAuthorContext.d.ts +1 -1
- package/dist/operatorAgent/agentAuthorContext.js +1 -1
- package/dist/operatorAgent/piModel.js +17 -4
- package/dist/operatorAgent/profiles/agentAuthor.d.ts +3 -1
- package/dist/operatorAgent/profiles/agentAuthor.js +145 -20
- package/dist/operatorAgent/profiles/agentAuthorPlaybook.d.ts +1 -1
- package/dist/operatorAgent/profiles/agentAuthorPlaybook.js +48 -15
- package/dist/operatorAgent/profiles/authorReadable.d.ts +2 -0
- package/dist/operatorAgent/profiles/authorReadable.js +26 -0
- package/dist/package-meta.d.ts +1 -1
- package/dist/package-meta.js +1 -1
- package/dist/runstore/port.d.ts +43 -0
- package/dist/runstore/sqlite/SqliteRunStore.d.ts +28 -0
- package/dist/runstore/sqlite/SqliteRunStore.js +99 -5
- package/dist/runstore/sqlite/evalStore.d.ts +20 -0
- package/dist/runstore/sqlite/evalStore.js +541 -0
- package/dist/runstore/sqlite/migrations/015-evals.d.ts +12 -0
- package/dist/runstore/sqlite/migrations/015-evals.js +157 -0
- package/dist/runstore/sqlite/migrations/016-eval-subject-ref.d.ts +12 -0
- package/dist/runstore/sqlite/migrations/016-eval-subject-ref.js +20 -0
- package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.d.ts +11 -0
- package/dist/runstore/sqlite/migrations/017-eval-result-suggestions.js +36 -0
- package/dist/runstore/sqlite/migrations/index.js +6 -0
- package/dist/runstore/sqlite/suggestionStore.d.ts +14 -0
- package/dist/runstore/sqlite/suggestionStore.js +132 -0
- package/dist/runtime/pipelineRunner.d.ts +2 -1
- package/dist/runtime/pipelineRunner.js +2 -0
- package/dist/runtime/runManager.d.ts +2 -1
- package/dist/runtime/runManager.js +8 -6
- package/dist/runtime/runRetentionSweep.js +2 -2
- package/dist/server/agentAuthorRoutes.js +50 -1
- package/dist/server/bootstrap.d.ts +8 -0
- package/dist/server/bootstrap.js +56 -0
- package/dist/server/controlToken.js +3 -0
- package/dist/server/evalInternalRoutes.d.ts +14 -0
- package/dist/server/evalInternalRoutes.js +87 -0
- package/dist/server/evalRouteContext.d.ts +46 -0
- package/dist/server/evalRouteContext.js +43 -0
- package/dist/server/evalRoutes.d.ts +5 -0
- package/dist/server/evalRoutes.js +1427 -0
- package/dist/server/evalTriageRoutes.d.ts +2 -0
- package/dist/server/evalTriageRoutes.js +95 -0
- package/dist/server/http.d.ts +5 -0
- package/dist/server/http.js +32 -2
- package/dist/server/mcpHost.js +3 -0
- package/dist/toolkit/meta.d.ts +1 -1
- package/dist/toolkit/meta.js +15 -0
- package/dist/toolkit/profiles.js +1 -1
- package/dist/types/stageflowManifest.d.ts +6 -0
- package/dist/ui/assets/AssistantRuntimeProvider-qIX1xNoH.js +9 -0
- package/dist/ui/assets/{MarkdownText-D7tYaIFO.js → MarkdownText-BTrOqu5J.js} +1 -1
- package/dist/ui/assets/chat-Df_wCpak.js +5 -0
- package/dist/ui/assets/chat-P7KQznHm.css +2 -0
- package/dist/ui/assets/{main-BFo79krC.css → main-CHlmTNJe.css} +1 -1
- package/dist/ui/assets/main-CvVfxmMd.js +271 -0
- package/dist/ui/chat.html +3 -3
- package/dist/ui/index.html +3 -3
- package/examples/README.md +2 -0
- package/examples/document-policy-review/README.md +35 -0
- package/examples/document-policy-review/agents/compliance.agent.yaml +42 -0
- package/examples/document-policy-review/documents/acme-vendor-sow.md +15 -0
- package/examples/document-policy-review/documents/support-runbook.md +13 -0
- package/examples/document-policy-review/policies/acceptable-use.md +13 -0
- package/examples/document-policy-review/policies/data-handling.md +17 -0
- package/examples/document-policy-review/policies/vendor-security.md +17 -0
- package/examples/evals/README.md +123 -0
- package/examples/evals/critique-sample.dataset.jsonl +8 -0
- package/examples/evals/critique-sample.eval.yaml +34 -0
- package/examples/evals/critique-sample.task.yaml +4 -0
- package/examples/evals/eval-sample.pipeline.yaml +35 -0
- package/examples/evals/support-sample.agent.yaml +20 -0
- package/examples/evals/support-sample.dataset.jsonl +6 -0
- package/examples/evals/support-sample.eval.yaml +38 -0
- package/examples/stageflow.yaml +6 -0
- package/package.json +1 -1
- package/skills/stageflow/SKILL.md +5 -2
- package/skills/stageflow/references/control-surface.md +4 -2
- package/skills/stageflow/references/evals.md +68 -0
- package/skills/stageflow-author/SKILL.md +4 -0
- package/skills/stageflow-run/SKILL.md +4 -0
- package/dist/ui/assets/AssistantRuntimeProvider-CsiPFhCT.js +0 -9
- package/dist/ui/assets/chat-BbLukq9W.js +0 -5
- package/dist/ui/assets/chat-zIZU_bP1.css +0 -2
- package/dist/ui/assets/main-CijYMeM0.js +0 -259
package/dist/server/bootstrap.js
CHANGED
|
@@ -14,6 +14,12 @@ import { assertStoreFilesystemSupported } from "../runstore/storeFilesystem.js";
|
|
|
14
14
|
import { assertStoreQuickCheck, isSqliteCorruptError, maybeCheckpointResidualWal, rethrowAsStoreIntegrityFailed, } from "../runstore/sqlite/applyStorePragmas.js";
|
|
15
15
|
import { consoleStageBrowserSupport } from "../browser/stageBrowserEnv.js";
|
|
16
16
|
import { RunManager } from "../runtime/runManager.js";
|
|
17
|
+
import { EvalRunManager } from "../evals/manager.js";
|
|
18
|
+
import { createStageCaseRunner } from "../evals/runner/stageCaseRunner.js";
|
|
19
|
+
import { getEngine } from "../evals/engine/index.js";
|
|
20
|
+
import { RunTokenRegistry } from "../evals/engine/promptfoo/runTokens.js";
|
|
21
|
+
import { EVAL_DEFAULT_ENGINE } from "../evals/manager.js";
|
|
22
|
+
import { PACKAGE_VERSION } from "../package-meta.js";
|
|
17
23
|
import { PI_CODING_AGENT_DIR_ENV } from "../runtime/stageRoots.js";
|
|
18
24
|
import { ScheduleSource, triggerTickIntervalMsFromEnv, } from "../runtime/scheduleSource.js";
|
|
19
25
|
import { GithubPollSource, githubPollIntervalMsFromEnv, } from "../runtime/githubPollSource.js";
|
|
@@ -32,6 +38,9 @@ import { applyPendingRestoreAtBoot, } from "../runstore/restore.js";
|
|
|
32
38
|
import { assertTmpdirUsable } from "../runstore/assertTmpdir.js";
|
|
33
39
|
import { logger as rootLogger } from "../logging/logger.js";
|
|
34
40
|
import { getModelCatalog } from "../models/catalog.js";
|
|
41
|
+
import { createAgentCaseRunner } from "../evals/runner/agentCaseRunner.js";
|
|
42
|
+
import { createEvalCaseRunner } from "../evals/runner/caseRunner.js";
|
|
43
|
+
import { defaultLoadJudgePrices } from "../evals/engine/promptfoo/judgeServices.js";
|
|
35
44
|
import { createAgentHostContext } from "../agents/hostContext.js";
|
|
36
45
|
export const DEFAULT_GC_INTERVAL_MS = 60 * 60 * 1000;
|
|
37
46
|
/** Parse `STAGEFLOW_GC_INTERVAL_MS`; default 1h; `0` disables. */
|
|
@@ -257,6 +266,47 @@ export async function bootstrapStageflowHost(options) {
|
|
|
257
266
|
await manager.autoResumeInterruptedStages();
|
|
258
267
|
await manager.resumeStalledSchedules();
|
|
259
268
|
await manager.reenqueuePersistedQueuedRuns();
|
|
269
|
+
const evalLog = rootLogger.child({ component: "evals" });
|
|
270
|
+
const evalStageRunner = createStageCaseRunner({ manager, store });
|
|
271
|
+
const evalAgentRunner = createAgentCaseRunner({
|
|
272
|
+
host: () => agentHost,
|
|
273
|
+
loadPrices: defaultLoadJudgePrices,
|
|
274
|
+
});
|
|
275
|
+
const evalRunner = createEvalCaseRunner({ stage: evalStageRunner, agent: evalAgentRunner });
|
|
276
|
+
const evalTokens = new RunTokenRegistry();
|
|
277
|
+
let evalCallbackBase = "";
|
|
278
|
+
const evalRunManager = new EvalRunManager({
|
|
279
|
+
store,
|
|
280
|
+
stageRunner: evalRunner,
|
|
281
|
+
agents: () => agentHost?.service,
|
|
282
|
+
engines: (name, engineOptions) => getEngine(name, name === EVAL_DEFAULT_ENGINE
|
|
283
|
+
? {
|
|
284
|
+
tokens: evalTokens,
|
|
285
|
+
callbackUrl: () => `${evalCallbackBase}/api/evals/internal/run-case`,
|
|
286
|
+
home: ctx.globalHome,
|
|
287
|
+
...engineOptions,
|
|
288
|
+
}
|
|
289
|
+
: engineOptions),
|
|
290
|
+
stageflowVersion: PACKAGE_VERSION,
|
|
291
|
+
workDirRoot: path.join(ctx.globalHome, "eval-runs"),
|
|
292
|
+
logger: {
|
|
293
|
+
info: (event, msg) => evalLog.info(event, msg),
|
|
294
|
+
warn: (event, msg) => evalLog.warn(event, msg),
|
|
295
|
+
error: (event, msg) => evalLog.error(event, msg),
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
const recoveredEvalRuns = await evalRunManager.recoverOnBoot().catch((err) => {
|
|
299
|
+
evalLog.warn("eval.recover_failed", err instanceof Error ? err.message : String(err));
|
|
300
|
+
return [];
|
|
301
|
+
});
|
|
302
|
+
const evalServices = {
|
|
303
|
+
tokens: evalTokens,
|
|
304
|
+
runner: evalRunner,
|
|
305
|
+
isRunning: (evalRunId) => evalRunManager.isExecuting(evalRunId),
|
|
306
|
+
};
|
|
307
|
+
const setEvalCallbackBase = (baseUrl) => {
|
|
308
|
+
evalCallbackBase = baseUrl.replace(/\/+$/, "");
|
|
309
|
+
};
|
|
260
310
|
await warnDurableRootDiskIfNeeded(ctx.globalHome, { env });
|
|
261
311
|
const gcInterval = startPeriodicRunGc(manager, gcIntervalMsFromEnv(env));
|
|
262
312
|
const stopGcInterval = () => {
|
|
@@ -355,6 +405,8 @@ export async function bootstrapStageflowHost(options) {
|
|
|
355
405
|
},
|
|
356
406
|
})
|
|
357
407
|
: undefined;
|
|
408
|
+
if (agentHost)
|
|
409
|
+
void evalRunManager.sweepAgentSessions(recoveredEvalRuns);
|
|
358
410
|
const mcpStateless = resolveMcpStateless({
|
|
359
411
|
mcpStateless: options.mcpStateless,
|
|
360
412
|
});
|
|
@@ -366,6 +418,7 @@ export async function bootstrapStageflowHost(options) {
|
|
|
366
418
|
runChangeBus,
|
|
367
419
|
providerAuthContext: options.providerAuthContext,
|
|
368
420
|
projectRoot: rootDir,
|
|
421
|
+
evalRunManager,
|
|
369
422
|
...(agentHost
|
|
370
423
|
? {
|
|
371
424
|
agentService: agentHost.service,
|
|
@@ -389,6 +442,9 @@ export async function bootstrapStageflowHost(options) {
|
|
|
389
442
|
isGitProject,
|
|
390
443
|
store,
|
|
391
444
|
manager,
|
|
445
|
+
evalRunManager,
|
|
446
|
+
evalServices,
|
|
447
|
+
setEvalCallbackBase,
|
|
392
448
|
runChangeBus,
|
|
393
449
|
mcpStateless,
|
|
394
450
|
providerAuthContext: options.providerAuthContext,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash, timingSafeEqual } from "node:crypto";
|
|
2
2
|
import { readSecretFromEnvOrFile } from "../config/secretFromEnvOrFile.js";
|
|
3
3
|
import { isLoopbackHostname } from "./allowedHosts.js";
|
|
4
|
+
import { isEvalInternalPath } from "./evalInternalRoutes.js";
|
|
4
5
|
import { matchLiveViewRoute } from "./liveViewPath.js";
|
|
5
6
|
const CONTROL_TOKEN_PREFIX = "STAGEFLOW_CONTROL_TOKEN_";
|
|
6
7
|
const DEFAULT_CALLER_ID = "default";
|
|
@@ -200,6 +201,8 @@ export function requiredScopeFor(method, pathname) {
|
|
|
200
201
|
return null;
|
|
201
202
|
if (isLiveViewRoute(pathname))
|
|
202
203
|
return null;
|
|
204
|
+
if (isEvalInternalPath(pathname))
|
|
205
|
+
return null;
|
|
203
206
|
if (pathname === "/api/backup" || pathname.startsWith("/api/backup/")) {
|
|
204
207
|
return "drive";
|
|
205
208
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { RunTokenRegistry } from "../evals/engine/promptfoo/runTokens.js";
|
|
3
|
+
import type { StageCaseRunner } from "../evals/runner/stageCaseRunner.js";
|
|
4
|
+
export declare const EVAL_INTERNAL_RUN_CASE_PATH = "/api/evals/internal/run-case";
|
|
5
|
+
export type EvalInternalServices = {
|
|
6
|
+
tokens: Pick<RunTokenRegistry, "verify">;
|
|
7
|
+
runner: Pick<StageCaseRunner, "runCase">;
|
|
8
|
+
isRunning(evalRunId: string): boolean;
|
|
9
|
+
};
|
|
10
|
+
export type EvalServices = EvalInternalServices | (() => EvalInternalServices | undefined);
|
|
11
|
+
type Json = (res: ServerResponse, status: number, body: unknown) => void;
|
|
12
|
+
export declare function isEvalInternalPath(pathname: string): boolean;
|
|
13
|
+
export declare function handleEvalInternalRoutes(req: IncomingMessage, method: string, pathname: string, services: EvalServices | undefined, res: ServerResponse, json: Json): Promise<boolean>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export const EVAL_INTERNAL_RUN_CASE_PATH = "/api/evals/internal/run-case";
|
|
2
|
+
const MAX_BODY_BYTES = 8192;
|
|
3
|
+
export function isEvalInternalPath(pathname) {
|
|
4
|
+
return pathname === EVAL_INTERNAL_RUN_CASE_PATH;
|
|
5
|
+
}
|
|
6
|
+
function resolveServices(services) {
|
|
7
|
+
return typeof services === "function" ? services() : services;
|
|
8
|
+
}
|
|
9
|
+
async function readBody(req) {
|
|
10
|
+
const chunks = [];
|
|
11
|
+
let size = 0;
|
|
12
|
+
for await (const chunk of req) {
|
|
13
|
+
const buffer = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
|
|
14
|
+
size += buffer.length;
|
|
15
|
+
if (size > MAX_BODY_BYTES)
|
|
16
|
+
throw new Error("body too large");
|
|
17
|
+
chunks.push(buffer);
|
|
18
|
+
}
|
|
19
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
20
|
+
}
|
|
21
|
+
function parseRequest(body) {
|
|
22
|
+
if (typeof body !== "object" || body === null)
|
|
23
|
+
return undefined;
|
|
24
|
+
const { eval_run_id: evalRunId, case_id: caseId, repeat_index: repeatIndex } = body;
|
|
25
|
+
if (typeof evalRunId !== "string" || evalRunId.length === 0)
|
|
26
|
+
return undefined;
|
|
27
|
+
if (typeof caseId !== "string" || caseId.length === 0)
|
|
28
|
+
return undefined;
|
|
29
|
+
if (typeof repeatIndex !== "number" || !Number.isInteger(repeatIndex) || repeatIndex < 0)
|
|
30
|
+
return undefined;
|
|
31
|
+
return { evalRunId, caseId, repeatIndex };
|
|
32
|
+
}
|
|
33
|
+
function bearerToken(req) {
|
|
34
|
+
const header = req.headers.authorization;
|
|
35
|
+
const match = typeof header === "string" ? /^Bearer ([^\s]+)$/i.exec(header) : null;
|
|
36
|
+
return match?.[1];
|
|
37
|
+
}
|
|
38
|
+
export async function handleEvalInternalRoutes(req, method, pathname, services, res, json) {
|
|
39
|
+
if (!isEvalInternalPath(pathname))
|
|
40
|
+
return false;
|
|
41
|
+
const deps = resolveServices(services);
|
|
42
|
+
if (deps === undefined || method !== "POST") {
|
|
43
|
+
json(res, 404, { error: "Not found" });
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
const entry = deps.tokens.verify(bearerToken(req));
|
|
47
|
+
if (entry === undefined) {
|
|
48
|
+
json(res, 401, { code: "unauthorized" });
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
let request;
|
|
52
|
+
try {
|
|
53
|
+
request = parseRequest(await readBody(req));
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
request = undefined;
|
|
57
|
+
}
|
|
58
|
+
if (request === undefined) {
|
|
59
|
+
json(res, 400, { code: "invalid_request" });
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
if (request.evalRunId !== entry.evalRunId) {
|
|
63
|
+
json(res, 401, { code: "unauthorized" });
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
if (!deps.isRunning(request.evalRunId)) {
|
|
67
|
+
json(res, 409, { code: "eval_run_not_running" });
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const { binding } = entry;
|
|
72
|
+
const result = binding.runCase
|
|
73
|
+
? await binding.runCase(request)
|
|
74
|
+
: binding.plan
|
|
75
|
+
? await deps.runner.runCase(binding.plan, request)
|
|
76
|
+
: undefined;
|
|
77
|
+
if (result === undefined) {
|
|
78
|
+
json(res, 500, { code: "EVAL_ENGINE_ERROR" });
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
json(res, 200, result);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
json(res, 500, { code: "EVAL_ENGINE_ERROR" });
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { SessionsSource } from "../config/datasetFromSessions.js";
|
|
3
|
+
import type { EvalSampleAgents } from "../config/installEvalSample.js";
|
|
4
|
+
import type { EngineStatus } from "../evals/engine/promptfoo/status.js";
|
|
5
|
+
import type { TokenPrice } from "../evals/estimate.js";
|
|
6
|
+
import type { EvalAgentsPort, EvalRunManager } from "../evals/manager.js";
|
|
7
|
+
import { EvalApiError } from "../evals/read/api.js";
|
|
8
|
+
import type { EvalRunRow } from "../evals/storeTypes.js";
|
|
9
|
+
import type { TriageDeps } from "../evals/triage/service.js";
|
|
10
|
+
import type { Logger } from "../logging/logger.js";
|
|
11
|
+
import type { RunStore } from "../runstore/port.js";
|
|
12
|
+
import type { RunManager } from "../runtime/runManager.js";
|
|
13
|
+
export type EvalRoutesDeps = {
|
|
14
|
+
cwd: string;
|
|
15
|
+
store: RunStore;
|
|
16
|
+
manager: RunManager;
|
|
17
|
+
evalRunManager: EvalRunManager | undefined;
|
|
18
|
+
json: (res: ServerResponse, status: number, body: unknown) => void;
|
|
19
|
+
readJsonBody: (req: IncomingMessage) => Promise<unknown>;
|
|
20
|
+
auditLog: Logger;
|
|
21
|
+
engineStatus: () => EngineStatus;
|
|
22
|
+
isKnownModel?: (id: string) => Promise<boolean>;
|
|
23
|
+
sampleSourceDir?: string;
|
|
24
|
+
now?: () => Date;
|
|
25
|
+
/** Lazy view of the agent service; absent or undefined means agents are unavailable on this host. */
|
|
26
|
+
agents?: () => RouteAgents | undefined;
|
|
27
|
+
/** Model prices (USD per million tokens) for the agent cost estimate; unknown models are simply absent. */
|
|
28
|
+
loadPrices?: (modelIds: string[], projectRoot: string) => Promise<Map<string, TokenPrice>>;
|
|
29
|
+
/** Failure sorting: the Host's agent backend (judge classifier) and test seams (fetch, key lookup, base URL). */
|
|
30
|
+
triage?: Omit<TriageDeps, "store">;
|
|
31
|
+
};
|
|
32
|
+
export type Ctx = EvalRoutesDeps & {
|
|
33
|
+
req: IncomingMessage;
|
|
34
|
+
res: ServerResponse;
|
|
35
|
+
url: URL;
|
|
36
|
+
method: string;
|
|
37
|
+
pathname: string;
|
|
38
|
+
evalRunManager: EvalRunManager;
|
|
39
|
+
};
|
|
40
|
+
export type RouteAgents = EvalAgentsPort & SessionsSource & Partial<Pick<EvalSampleAgents, "create" | "setEnabled">>;
|
|
41
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
42
|
+
export declare function bad(message: string, code?: string): EvalApiError;
|
|
43
|
+
export declare function audit(c: Ctx, action: string, outcome: "ok" | "error", target?: string, code?: string): void;
|
|
44
|
+
export declare function readOptionalBody(c: Ctx): Promise<Record<string, unknown>>;
|
|
45
|
+
export declare function optStringArray(body: Record<string, unknown>, key: string): string[] | undefined;
|
|
46
|
+
export declare function runByIdOr404(c: Ctx, id: string): Promise<EvalRunRow>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { badRequest, runByIdOr404 as runByIdOr404Shared } from "../evals/read/api.js";
|
|
2
|
+
import { writeAudit } from "../logging/audit.js";
|
|
3
|
+
import { callerIdFromRequestAuth, getRequestAuth } from "./requestAuthContext.js";
|
|
4
|
+
export function isRecord(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
export function bad(message, code = "invalid_request") {
|
|
8
|
+
return badRequest(message, code);
|
|
9
|
+
}
|
|
10
|
+
function surface() {
|
|
11
|
+
return getRequestAuth()?.surface ?? "rest";
|
|
12
|
+
}
|
|
13
|
+
export function audit(c, action, outcome, target, code) {
|
|
14
|
+
writeAudit(c.auditLog, {
|
|
15
|
+
caller_id: callerIdFromRequestAuth(),
|
|
16
|
+
surface: surface(),
|
|
17
|
+
action,
|
|
18
|
+
outcome,
|
|
19
|
+
...(target !== undefined ? { target_run_id: target } : {}),
|
|
20
|
+
...(code !== undefined ? { error_code: code } : {}),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export async function readOptionalBody(c) {
|
|
24
|
+
try {
|
|
25
|
+
const body = await c.readJsonBody(c.req);
|
|
26
|
+
return isRecord(body) ? body : {};
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function optStringArray(body, key) {
|
|
33
|
+
const value = body[key];
|
|
34
|
+
if (value === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
if (!Array.isArray(value) || value.some((v) => typeof v !== "string" || v === "")) {
|
|
37
|
+
throw bad(`"${key}" must be an array of non-empty strings`);
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
export async function runByIdOr404(c, id) {
|
|
42
|
+
return runByIdOr404Shared(c.store, id);
|
|
43
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import { type EvalRoutesDeps } from "./evalRouteContext.js";
|
|
3
|
+
export type { EvalRoutesDeps };
|
|
4
|
+
export declare function isEvalRoutePath(pathname: string): boolean;
|
|
5
|
+
export declare function handleEvalRoutes(req: IncomingMessage, res: ServerResponse, deps: EvalRoutesDeps): Promise<boolean>;
|