@pikku/core 0.12.84 → 0.12.88
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/CHANGELOG.md +503 -0
- package/dist/bootstrap-compat/root.d.ts +20 -0
- package/dist/classification/column-form.d.ts +32 -0
- package/dist/classification/column-form.js +42 -0
- package/dist/classification/data-classification.d.ts +64 -0
- package/dist/classification/index.d.ts +13 -0
- package/dist/classification/index.js +2 -0
- package/dist/classification/secret-value.d.ts +56 -0
- package/dist/classification/secret-value.js +46 -0
- package/dist/crypto-utils.d.ts +1 -1
- package/dist/dev/hot-reload.d.ts +1 -1
- package/dist/dev/hot-reload.js +1 -1
- package/dist/ecosystem/agent-scorer.d.ts +1 -1
- package/dist/ecosystem/agent.d.ts +4 -1
- package/dist/ecosystem/channel/local.d.ts +2 -0
- package/dist/ecosystem/channel/local.js +2 -0
- package/dist/ecosystem/channel/serverless.d.ts +9 -0
- package/dist/ecosystem/channel/serverless.js +1 -0
- package/dist/ecosystem/channel.d.ts +3 -0
- package/dist/ecosystem/channel.js +1 -0
- package/dist/ecosystem/cli.d.ts +1 -1
- package/dist/ecosystem/cli.js +1 -1
- package/dist/ecosystem/credential.d.ts +1 -0
- package/dist/ecosystem/crypto-utils.d.ts +8 -0
- package/dist/ecosystem/crypto-utils.js +1 -0
- package/dist/ecosystem/dev.d.ts +1 -0
- package/dist/ecosystem/dev.js +1 -0
- package/{src/ecosystem/testing.ts → dist/ecosystem/errors.d.ts} +3 -3
- package/dist/ecosystem/errors.js +2 -0
- package/dist/ecosystem/function.d.ts +1 -1
- package/dist/ecosystem/function.js +1 -1
- package/dist/ecosystem/http.d.ts +3 -1
- package/dist/ecosystem/http.js +3 -1
- package/dist/ecosystem/mcp.d.ts +1 -1
- package/dist/ecosystem/mcp.js +1 -1
- package/dist/ecosystem/middleware.d.ts +2 -1
- package/dist/ecosystem/middleware.js +2 -1
- package/dist/ecosystem/persona.d.ts +4 -2
- package/dist/ecosystem/persona.js +2 -1
- package/dist/ecosystem/queue.d.ts +4 -2
- package/dist/ecosystem/queue.js +3 -1
- package/dist/ecosystem/role.d.ts +1 -0
- package/dist/ecosystem/rpc.d.ts +2 -0
- package/dist/ecosystem/rpc.js +1 -0
- package/dist/ecosystem/scenario.d.ts +8 -2
- package/dist/ecosystem/scenario.js +5 -1
- package/dist/ecosystem/scheduler.d.ts +2 -1
- package/dist/ecosystem/scheduler.js +2 -1
- package/dist/ecosystem/schema.d.ts +2 -1
- package/dist/ecosystem/schema.js +1 -1
- package/dist/ecosystem/scope.d.ts +2 -0
- package/dist/ecosystem/scope.js +1 -0
- package/dist/ecosystem/secret.d.ts +2 -0
- package/dist/ecosystem/secret.js +1 -0
- package/dist/ecosystem/services/local-content.d.ts +2 -1
- package/dist/ecosystem/services/local-content.js +1 -1
- package/dist/ecosystem/services/local-meta.d.ts +1 -0
- package/dist/ecosystem/services/local-meta.js +1 -0
- package/dist/ecosystem/services.d.ts +11 -3
- package/dist/ecosystem/services.js +7 -1
- package/dist/ecosystem/trigger.d.ts +1 -0
- package/dist/ecosystem/trigger.js +1 -1
- package/dist/ecosystem/types.d.ts +6 -3
- package/dist/ecosystem/types.js +3 -2
- package/dist/ecosystem/variable.d.ts +1 -0
- package/dist/ecosystem/virtual-user.d.ts +3 -0
- package/dist/ecosystem/virtual-user.js +3 -0
- package/dist/ecosystem/workflow.d.ts +2 -0
- package/dist/ecosystem/workflow.js +2 -0
- package/dist/errors/index.d.ts +8 -0
- package/dist/errors/index.js +1 -0
- package/dist/errors/serialized-error.d.ts +7 -0
- package/dist/function/function-meta.types.d.ts +139 -0
- package/dist/function/function-runner.d.ts +3 -2
- package/dist/function/function-runner.js +31 -11
- package/dist/function/functions.types.d.ts +10 -2
- package/dist/function/index.d.ts +8 -2
- package/dist/function/index.js +4 -1
- package/dist/function/pikku-request.d.ts +8 -0
- package/dist/function/pikku-request.js +15 -0
- package/dist/middleware/auth-apikey.d.ts +2 -10
- package/dist/middleware/auth-apikey.js +1 -1
- package/dist/middleware/auth-bearer.d.ts +2 -10
- package/dist/middleware/auth-bearer.js +1 -1
- package/dist/middleware/auth-cookie.d.ts +2 -10
- package/dist/middleware/auth-cookie.js +1 -1
- package/dist/middleware/cors.d.ts +5 -11
- package/dist/middleware/cors.js +13 -6
- package/dist/middleware/index.d.ts +3 -0
- package/dist/middleware/index.js +1 -0
- package/dist/middleware/middleware-factories.d.ts +9 -0
- package/dist/middleware/middleware-factories.js +19 -0
- package/dist/middleware/middleware.types.d.ts +27 -0
- package/dist/middleware/middleware.types.js +1 -0
- package/dist/middleware/remote-auth.d.ts +2 -2
- package/dist/middleware/remote-auth.js +1 -1
- package/dist/middleware/telemetry.d.ts +4 -20
- package/dist/middleware/telemetry.js +1 -1
- package/dist/middleware-runner.d.ts +2 -1
- package/dist/pikku-state.d.ts +2 -1
- package/dist/services/audit-service.d.ts +1 -1
- package/dist/services/credential-wire-service.js +1 -1
- package/dist/services/email-service.d.ts +1 -1
- package/dist/services/file-scenario-run-store.d.ts +58 -0
- package/dist/services/file-scenario-run-store.js +214 -0
- package/dist/services/in-memory-workflow-service.d.ts +1 -1
- package/dist/services/index.d.ts +5 -1
- package/dist/services/index.js +3 -0
- package/dist/services/local-secrets.d.ts +1 -1
- package/dist/services/local-secrets.js +1 -1
- package/dist/services/logger.d.ts +7 -7
- package/dist/services/meta-service.d.ts +2 -1
- package/dist/services/scoped-secret-service.d.ts +1 -1
- package/dist/services/secret-service.d.ts +1 -1
- package/dist/services/typed-secret-service.d.ts +16 -2
- package/dist/services/typed-secret-service.js +5 -0
- package/dist/services/webhook-service.d.ts +1 -1
- package/dist/services/workflow-service.d.ts +2 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +1 -0
- package/dist/types/core.types.d.ts +30 -180
- package/dist/types/core.types.js +1 -19
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +1 -0
- package/dist/types/state.types.d.ts +3 -1
- package/dist/utils.d.ts +13 -0
- package/dist/utils.js +2 -0
- package/dist/wirings/addon/addon-runner.d.ts +17 -0
- package/dist/wirings/addon/addon-runner.js +150 -0
- package/dist/wirings/addon/index.d.ts +6 -0
- package/dist/wirings/addon/index.js +3 -0
- package/dist/wirings/addon/remote-addon-auth.d.ts +16 -0
- package/dist/wirings/addon/remote-addon-auth.js +39 -0
- package/dist/wirings/addon/wire-addon.d.ts +80 -0
- package/dist/wirings/addon/wire-addon.js +120 -0
- package/dist/wirings/addon/wire-remote-addon.d.ts +22 -0
- package/dist/wirings/addon/wire-remote-addon.js +11 -0
- package/dist/wirings/agent/agent-memory.d.ts +11 -0
- package/dist/wirings/agent/agent-memory.js +17 -2
- package/dist/wirings/agent/agent-prepare.d.ts +3 -3
- package/dist/wirings/agent/agent-prepare.js +1 -1
- package/dist/wirings/agent/agent-runner.js +2 -3
- package/dist/wirings/agent/agent-stream.js +117 -93
- package/dist/wirings/agent/agent-utils.d.ts +13 -0
- package/dist/wirings/agent/agent-utils.js +16 -0
- package/dist/wirings/agent/agent.types.d.ts +12 -10
- package/dist/wirings/agent/index.d.ts +1 -1
- package/dist/wirings/agent/voice-input.js +1 -1
- package/dist/wirings/agent/voice-output.js +1 -1
- package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +13 -0
- package/dist/wirings/agent-scorer/agent-scorer-judge.js +52 -0
- package/dist/wirings/agent-scorer/agent-scorer.d.ts +7 -1
- package/dist/wirings/agent-scorer/agent-scorer.js +1 -0
- package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +20 -0
- package/dist/wirings/agent-scorer/index.d.ts +1 -1
- package/dist/wirings/channel/channel-common.d.ts +2 -1
- package/dist/wirings/channel/channel-middleware-runner.d.ts +2 -1
- package/dist/wirings/channel/channel.types.d.ts +1 -1
- package/dist/wirings/channel/serverless/index.d.ts +1 -0
- package/dist/wirings/cli/channel/index.d.ts +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +2 -1
- package/dist/wirings/cli/cli-runner.js +4 -1
- package/dist/wirings/cli/cli.types.d.ts +21 -2
- package/dist/wirings/cli/command-parser.js +157 -23
- package/dist/wirings/gateway/gateway.types.d.ts +2 -1
- package/dist/wirings/http/http-runner.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +1 -1
- package/dist/wirings/http/http.types.d.ts +2 -2
- package/dist/wirings/http/index.d.ts +1 -0
- package/dist/wirings/http/index.js +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.js +1 -1
- package/dist/wirings/http/pikku-fetch-http-response.js +2 -2
- package/dist/wirings/mcp/mcp.types.d.ts +1 -1
- package/dist/wirings/persona/index.d.ts +1 -1
- package/dist/wirings/persona/index.js +1 -1
- package/dist/wirings/persona/persona.types.d.ts +14 -0
- package/dist/wirings/queue/queue.types.d.ts +1 -1
- package/dist/wirings/queue/signed-queue-service.d.ts +1 -1
- package/dist/wirings/rpc/index.d.ts +0 -6
- package/dist/wirings/rpc/index.js +0 -3
- package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -1
- package/dist/wirings/rpc/remote-addon-auth.js +1 -1
- package/dist/wirings/rpc/rpc-runner.js +2 -2
- package/dist/wirings/rpc/wire-addon.d.ts +1 -1
- package/dist/wirings/scheduler/scheduler.types.d.ts +2 -1
- package/dist/wirings/scope/index.d.ts +1 -0
- package/dist/wirings/scope/index.js +1 -0
- package/dist/wirings/secret/secret.types.d.ts +10 -0
- package/dist/wirings/secret/validate-secret-definitions.js +2 -0
- package/dist/wirings/variable/validate-variable-definitions.js +2 -0
- package/dist/wirings/variable/variable.types.d.ts +15 -0
- package/dist/wirings/virtual-user/index.d.ts +1 -1
- package/dist/wirings/virtual-user/index.js +1 -1
- package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +1 -1
- package/dist/wirings/virtual-user/virtual-user-derive.d.ts +1 -1
- package/dist/wirings/workflow/graph/graph-node.d.ts +9 -2
- package/dist/wirings/workflow/graph/graph-node.js +2 -0
- package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -0
- package/dist/wirings/workflow/graph/graph-runner.js +283 -31
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +16 -1
- package/dist/wirings/workflow/index.d.ts +2 -0
- package/dist/wirings/workflow/index.js +1 -0
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +15 -5
- package/dist/wirings/workflow/pikku-scenario-service.js +44 -16
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +22 -7
- package/dist/wirings/workflow/pikku-workflow-service.js +28 -29
- package/dist/wirings/workflow/run-timeline.d.ts +1 -1
- package/dist/wirings/workflow/scenario-run.types.d.ts +171 -0
- package/dist/wirings/workflow/scenario-run.types.js +1 -0
- package/dist/wirings/workflow/scenario-step-guards.d.ts +1 -2
- package/dist/wirings/workflow/scenario-step-guards.js +0 -8
- package/dist/wirings/workflow/scenario-step.types.d.ts +27 -12
- package/dist/wirings/workflow/workflow-approval.js +2 -1
- package/dist/wirings/workflow/workflow-run-engine.types.d.ts +2 -1
- package/dist/wirings/workflow/workflow-step-claim.d.ts +16 -0
- package/dist/wirings/workflow/workflow-step-claim.js +27 -0
- package/dist/wirings/workflow/workflow.types.d.ts +2 -1
- package/knowledge/decisions/index.md +2 -0
- package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +1 -1
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +1 -1
- package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +2 -2
- package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +6 -6
- package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +1 -1
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +1 -1
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +1 -1
- package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +1 -1
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +1 -1
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +1 -1
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +1 -1
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +1 -1
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +1 -1
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +1 -1
- package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +4 -4
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +1 -1
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +3 -3
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +2 -2
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +2 -2
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +1 -1
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +1 -1
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +3 -3
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +1 -1
- package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +4 -4
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +1 -1
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +1 -1
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +1 -1
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +1 -1
- package/knowledge/decisions/internals/index.md +4 -2
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +1 -1
- package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +1 -1
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +1 -1
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +1 -1
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +1 -1
- package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +2 -2
- package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +5 -5
- package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +1 -1
- package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +1 -1
- package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +43 -19
- package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +1 -1
- package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +1 -1
- package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +3 -3
- package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +1 -1
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +1 -1
- package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +1 -1
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +1 -1
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +1 -1
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +1 -1
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +1 -1
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +1 -1
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +1 -1
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +9 -5
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +2 -2
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +1 -1
- package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +1 -1
- package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +47 -0
- package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +1 -1
- package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +2 -3
- package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +1 -1
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +1 -1
- package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +1 -1
- package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +3 -3
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +4 -3
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +1 -1
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +2 -2
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +1 -1
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +2 -2
- package/knowledge/decisions/security/index.md +4 -1
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +1 -1
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +3 -3
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +1 -1
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +8 -2
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +1 -1
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +2 -2
- package/knowledge/index.md +3 -1
- package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +1 -1
- package/knowledge/questions/index.md +2 -0
- package/package.json +14 -13
- package/run-tests.sh +0 -0
- package/scripts/generate-api-report.d.mts +1 -1
- package/scripts/generate-api-report.mjs +67 -60
- package/scripts/generate-api-report.mts +11 -45
- package/src/api-report.test.ts +70 -1
- package/src/app-alias-surface.test.ts +179 -0
- package/src/app-leaf-surface.test.ts +217 -0
- package/src/bootstrap-compat/root.ts +20 -0
- package/src/{column-form.test.ts → classification/column-form.test.ts} +2 -2
- package/src/{data-classification.ts → classification/data-classification.ts} +1 -5
- package/src/classification/index.ts +38 -0
- package/src/{secret-value.test.ts → classification/secret-value.test.ts} +2 -2
- package/src/{secret-value.ts → classification/secret-value.ts} +1 -6
- package/src/crypto-utils.ts +1 -1
- package/src/dev/hot-reload.ts +1 -1
- package/src/dev/reload-meta.test.ts +1 -1
- package/src/errors/index.ts +9 -0
- package/src/errors/serialized-error.ts +9 -0
- package/src/factory-functions.test.ts +4 -2
- package/src/function/function-meta.types.ts +151 -0
- package/src/function/function-runner.test.ts +4 -2
- package/src/function/function-runner.ts +47 -14
- package/src/function/functions.types.ts +11 -7
- package/src/function/index.ts +24 -5
- package/src/function/list.types.ts +1 -3
- package/src/middleware/auth-apikey.ts +4 -2
- package/src/middleware/auth-bearer.test.ts +1 -1
- package/src/middleware/auth-bearer.ts +4 -2
- package/src/middleware/auth-cookie.ts +4 -1
- package/src/middleware/cors.test.ts +126 -5
- package/src/middleware/cors.ts +19 -8
- package/src/middleware/index.ts +16 -0
- package/src/middleware/middleware-factories.ts +62 -0
- package/src/middleware/middleware.types.ts +61 -0
- package/src/middleware/remote-auth.test.ts +1 -1
- package/src/middleware/remote-auth.ts +1 -1
- package/src/middleware/telemetry.ts +4 -2
- package/src/middleware-runner.test.ts +2 -3
- package/src/middleware-runner.ts +2 -2
- package/src/no-root-barrel.test.ts +114 -0
- package/src/permissions.ts +2 -4
- package/src/pikku-state.ts +3 -1
- package/src/public-surface.json +56 -241
- package/src/public-surface.json.README +3 -3
- package/src/public-surface.test.ts +5 -5
- package/src/remote.test.ts +1 -1
- package/src/removed-legacy-exports.test.ts +5 -1
- package/src/services/audit-service.ts +1 -1
- package/src/services/credential-wire-service.ts +1 -1
- package/src/services/email-service.ts +2 -4
- package/src/services/file-scenario-run-store.test.ts +349 -0
- package/src/services/file-scenario-run-store.ts +282 -0
- package/src/services/in-memory-workflow-service.ts +1 -1
- package/src/services/index.ts +13 -1
- package/src/services/local-content-request-handler.ts +1 -2
- package/src/services/local-secrets.ts +1 -1
- package/src/services/logger.ts +7 -7
- package/src/services/meta-service.ts +2 -2
- package/src/services/queue-webhook-service.test.ts +1 -1
- package/src/services/scoped-secret-service.ts +1 -1
- package/src/services/secret-service.ts +1 -1
- package/src/services/typed-secret-service.test.ts +52 -0
- package/src/services/typed-secret-service.ts +26 -2
- package/src/services/webhook-service.ts +1 -1
- package/src/services/workflow-service.ts +2 -1
- package/src/template-alias-surface.test.ts +240 -0
- package/src/testing/index.ts +1 -0
- package/src/types/core.types.ts +33 -285
- package/src/types/index.ts +25 -0
- package/src/types/state.types.ts +6 -5
- package/src/types/typed-credentials.test.ts +72 -0
- package/src/utils.ts +34 -0
- package/src/wirings/{rpc → addon}/addon-scopes.test.ts +1 -1
- package/src/wirings/addon/index.ts +12 -0
- package/src/wirings/{rpc → addon}/remote-addon-auth.ts +4 -1
- package/src/wirings/{rpc → addon}/wire-addon.ts +37 -2
- package/src/wirings/agent/agent-memory.test.ts +73 -0
- package/src/wirings/agent/agent-memory.ts +16 -2
- package/src/wirings/agent/agent-middleware.types.test.ts +41 -0
- package/src/wirings/agent/agent-prepare.ts +8 -5
- package/src/wirings/agent/agent-runner.ts +2 -3
- package/src/wirings/agent/agent-stream-delegate.test.ts +381 -0
- package/src/wirings/agent/agent-stream.ts +160 -81
- package/src/wirings/agent/agent-utils.ts +19 -0
- package/src/wirings/agent/agent.types.ts +12 -11
- package/src/wirings/agent/index.ts +1 -0
- package/src/wirings/agent/voice-input.ts +1 -1
- package/src/wirings/agent/voice-output.test.ts +2 -4
- package/src/wirings/agent/voice-output.ts +1 -1
- package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +145 -0
- package/src/wirings/agent-scorer/agent-scorer-judge.ts +60 -0
- package/src/wirings/agent-scorer/agent-scorer.ts +8 -0
- package/src/wirings/agent-scorer/agent-scorer.types.ts +21 -0
- package/src/wirings/agent-scorer/index.ts +1 -0
- package/src/wirings/channel/channel-common.ts +4 -2
- package/src/wirings/channel/channel-handler.ts +2 -5
- package/src/wirings/channel/channel-middleware-runner.ts +1 -1
- package/src/wirings/channel/channel-rpc.types.ts +1 -5
- package/src/wirings/channel/channel.types.ts +1 -2
- package/src/wirings/channel/local/local-channel-runner.test.ts +1 -2
- package/src/wirings/channel/serverless/index.ts +1 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +2 -2
- package/src/wirings/cli/channel/index.ts +1 -3
- package/src/wirings/cli/cli-runner.test.ts +1 -1
- package/src/wirings/cli/cli-runner.ts +11 -7
- package/src/wirings/cli/cli.types.ts +24 -3
- package/src/wirings/cli/command-parser.test.ts +388 -1
- package/src/wirings/cli/command-parser.ts +189 -29
- package/src/wirings/gateway/gateway-runner.test.ts +1 -2
- package/src/wirings/gateway/gateway-runner.ts +3 -6
- package/src/wirings/gateway/gateway.types.ts +5 -4
- package/src/wirings/http/http-routes.test.ts +1 -2
- package/src/wirings/http/http-runner-addon-ref.test.ts +238 -0
- package/src/wirings/http/http-runner.test.ts +3 -8
- package/src/wirings/http/http-runner.ts +9 -3
- package/src/wirings/http/http.types.ts +3 -12
- package/src/wirings/http/index.ts +1 -0
- package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +3 -2
- package/src/wirings/mcp/mcp-runner.test.ts +1 -1
- package/src/wirings/mcp/mcp.types.ts +1 -2
- package/src/wirings/persona/index.ts +1 -4
- package/src/wirings/persona/persona.types.ts +14 -0
- package/src/wirings/queue/queue-identity.test.ts +1 -1
- package/src/wirings/queue/queue.types.ts +2 -6
- package/src/wirings/queue/signed-queue-service.ts +1 -1
- package/src/wirings/rpc/index.ts +0 -12
- package/src/wirings/rpc/rpc-runner.test.ts +4 -4
- package/src/wirings/rpc/rpc-runner.ts +3 -3
- package/src/wirings/scheduler/scheduler.types.ts +2 -5
- package/src/wirings/scope/index.ts +1 -0
- package/src/wirings/secret/secret.types.ts +10 -0
- package/src/wirings/secret/validate-secret-definitions.test.ts +23 -0
- package/src/wirings/secret/validate-secret-definitions.ts +2 -0
- package/src/wirings/variable/validate-variable-definitions.test.ts +24 -0
- package/src/wirings/variable/validate-variable-definitions.ts +2 -0
- package/src/wirings/variable/variable.types.ts +15 -0
- package/src/wirings/virtual-user/index.ts +1 -4
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +1 -1
- package/src/wirings/virtual-user/virtual-user-derive.ts +1 -1
- package/src/wirings/virtual-user/virtual-user.types.ts +1 -5
- package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +569 -0
- package/src/wirings/workflow/graph/graph-foreach.test.ts +626 -0
- package/src/wirings/workflow/graph/graph-node.ts +16 -1
- package/src/wirings/workflow/graph/graph-runner.ts +387 -61
- package/src/wirings/workflow/graph/workflow-graph.types.ts +28 -3
- package/src/wirings/workflow/index.ts +8 -0
- package/src/wirings/workflow/pikku-scenario-service.ts +83 -20
- package/src/wirings/workflow/pikku-workflow-service.ts +37 -35
- package/src/wirings/workflow/run-timeline.ts +1 -1
- package/src/wirings/workflow/scenario-expectations.test.ts +28 -13
- package/src/wirings/workflow/scenario-run.types.ts +186 -0
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +32 -7
- package/src/wirings/workflow/scenario-step.types.ts +27 -12
- package/src/wirings/workflow/workflow-approval-policy.test.ts +117 -47
- package/src/wirings/workflow/workflow-approval.ts +2 -1
- package/src/wirings/workflow/workflow-run-engine.types.ts +2 -1
- package/src/wirings/workflow/workflow-step-claim.ts +46 -0
- package/src/wirings/workflow/workflow.types.ts +4 -12
- package/src/wirings-stay-decoupled.test.ts +6 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/tsconfig.type-tests.json +4 -2
- package/dist/ecosystem/ai-agent.d.ts +0 -18
- package/dist/ecosystem/ai-agent.js +0 -6
- package/dist/ecosystem/ai-scorer.d.ts +0 -12
- package/dist/ecosystem/ai-scorer.js +0 -5
- package/dist/services/ai-agent-runner-service.d.ts +0 -220
- package/dist/services/ai-run-state-service.d.ts +0 -29
- package/dist/services/ai-storage-service.d.ts +0 -18
- package/dist/services/in-memory-ai-run-state-service.d.ts +0 -19
- package/dist/services/in-memory-ai-run-state-service.js +0 -54
- package/dist/testing/service-tests/ai-storage-service-tests.d.ts +0 -3
- package/dist/testing/service-tests/ai-storage-service-tests.js +0 -302
- package/dist/wirings/ai-agent/agent-rpc.d.ts +0 -15
- package/dist/wirings/ai-agent/agent-rpc.js +0 -53
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -79
- package/dist/wirings/ai-agent/ai-agent-agui.js +0 -327
- package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +0 -58
- package/dist/wirings/ai-agent/ai-agent-finalize.js +0 -138
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +0 -35
- package/dist/wirings/ai-agent/ai-agent-helpers.js +0 -47
- package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +0 -153
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +0 -257
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +0 -42
- package/dist/wirings/ai-agent/ai-agent-memory.js +0 -333
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -16
- package/dist/wirings/ai-agent/ai-agent-model-config.js +0 -51
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +0 -117
- package/dist/wirings/ai-agent/ai-agent-prepare.js +0 -728
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +0 -16
- package/dist/wirings/ai-agent/ai-agent-registry.js +0 -51
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +0 -7
- package/dist/wirings/ai-agent/ai-agent-runner.js +0 -580
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +0 -41
- package/dist/wirings/ai-agent/ai-agent-stream.js +0 -1029
- package/dist/wirings/ai-agent/ai-agent-turn.d.ts +0 -57
- package/dist/wirings/ai-agent/ai-agent-turn.js +0 -82
- package/dist/wirings/ai-agent/ai-agent-utils.d.ts +0 -1
- package/dist/wirings/ai-agent/ai-agent-utils.js +0 -1
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +0 -625
- package/dist/wirings/ai-agent/index.d.ts +0 -12
- package/dist/wirings/ai-agent/index.js +0 -10
- package/dist/wirings/ai-agent/voice-input.d.ts +0 -69
- package/dist/wirings/ai-agent/voice-input.js +0 -150
- package/dist/wirings/ai-agent/voice-output.d.ts +0 -85
- package/dist/wirings/ai-agent/voice-output.js +0 -196
- package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +0 -26
- package/dist/wirings/ai-scorer/ai-scorer-grade.js +0 -33
- package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +0 -17
- package/dist/wirings/ai-scorer/ai-scorer-judge.js +0 -92
- package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +0 -15
- package/dist/wirings/ai-scorer/ai-scorer-live.js +0 -38
- package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +0 -18
- package/dist/wirings/ai-scorer/ai-scorer-registry.js +0 -46
- package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +0 -8
- package/dist/wirings/ai-scorer/ai-scorer-sampling.js +0 -31
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +0 -10
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +0 -40
- package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +0 -15
- package/dist/wirings/ai-scorer/ai-scorer-worker.js +0 -58
- package/dist/wirings/ai-scorer/ai-scorer.d.ts +0 -39
- package/dist/wirings/ai-scorer/ai-scorer.js +0 -40
- package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +0 -90
- package/dist/wirings/ai-scorer/ai-scorer.types.js +0 -4
- package/dist/wirings/ai-scorer/index.d.ts +0 -6
- package/dist/wirings/ai-scorer/index.js +0 -5
- package/src/ecosystem/agent-scorer.ts +0 -24
- package/src/ecosystem/agent.ts +0 -42
- package/src/ecosystem/channel/local.ts +0 -1
- package/src/ecosystem/channel.ts +0 -22
- package/src/ecosystem/cli/channel.ts +0 -25
- package/src/ecosystem/cli.ts +0 -21
- package/src/ecosystem/credential.ts +0 -10
- package/src/ecosystem/dev.ts +0 -12
- package/src/ecosystem/function.ts +0 -28
- package/src/ecosystem/gateway.ts +0 -4
- package/src/ecosystem/hmac.ts +0 -1
- package/src/ecosystem/http.ts +0 -22
- package/src/ecosystem/mcp.ts +0 -17
- package/src/ecosystem/middleware.ts +0 -27
- package/src/ecosystem/node-host-resolver.ts +0 -1
- package/src/ecosystem/node.ts +0 -5
- package/src/ecosystem/oauth2.ts +0 -4
- package/src/ecosystem/persona.ts +0 -30
- package/src/ecosystem/queue.ts +0 -23
- package/src/ecosystem/remote.ts +0 -9
- package/src/ecosystem/role.ts +0 -13
- package/src/ecosystem/rpc.ts +0 -7
- package/src/ecosystem/safe-fetch.ts +0 -8
- package/src/ecosystem/scenario.ts +0 -32
- package/src/ecosystem/scheduler.ts +0 -5
- package/src/ecosystem/schema.ts +0 -1
- package/src/ecosystem/scope.ts +0 -14
- package/src/ecosystem/secret.ts +0 -15
- package/src/ecosystem/services/istanbul-coverage.ts +0 -1
- package/src/ecosystem/services/local-content-request-handler.ts +0 -16
- package/src/ecosystem/services/local-content.ts +0 -1
- package/src/ecosystem/services/v8-coverage.ts +0 -1
- package/src/ecosystem/services.ts +0 -82
- package/src/ecosystem/trigger.ts +0 -7
- package/src/ecosystem/types.ts +0 -34
- package/src/ecosystem/variable.ts +0 -14
- package/src/ecosystem/virtual-user.ts +0 -48
- package/src/ecosystem/workflow.ts +0 -68
- package/src/ecosystem.ts +0 -40
- package/src/index.ts +0 -244
- /package/dist/{services/ai-agent-runner-service.js → bootstrap-compat/root.js} +0 -0
- /package/dist/{services/ai-run-state-service.js → classification/data-classification.js} +0 -0
- /package/dist/{services/ai-storage-service.js → errors/serialized-error.js} +0 -0
- /package/dist/{wirings/ai-agent/ai-agent.types.js → function/function-meta.types.js} +0 -0
- /package/src/{column-form.ts → classification/column-form.ts} +0 -0
- /package/src/{pikku-request.test.ts → function/pikku-request.test.ts} +0 -0
- /package/src/{pikku-request.ts → function/pikku-request.ts} +0 -0
- /package/src/wirings/{rpc → addon}/addon-auth-tags.test.ts +0 -0
- /package/src/wirings/{rpc → addon}/addon-runner.ts +0 -0
- /package/src/wirings/{rpc → addon}/addon-secrets.test.ts +0 -0
- /package/src/wirings/{rpc → addon}/wire-addon.test.ts +0 -0
- /package/src/wirings/{rpc → addon}/wire-remote-addon.ts +0 -0
|
@@ -36,10 +36,57 @@ import type {
|
|
|
36
36
|
WorkflowExpectErrorOptions,
|
|
37
37
|
WorkflowExpectScoreOptions,
|
|
38
38
|
WorkflowExpectServiceOptions,
|
|
39
|
+
WorkflowStepOptions,
|
|
39
40
|
} from './dsl/workflow-dsl.types.js'
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The retry default for the `expect*` family: none, the same as `given`,
|
|
44
|
+
* `when` and `then` take, and for the same reason — a failed assertion is a
|
|
45
|
+
* result, not a transient fault.
|
|
46
|
+
*
|
|
47
|
+
* Left to the workflow-wide `DEFAULT_STEP_RETRIES` they get six attempts each,
|
|
48
|
+
* which re-runs the RPC behind a failing `expectError`, restarts a whole
|
|
49
|
+
* `expectEventually` poll after it has already spent its own deadline, and
|
|
50
|
+
* lets a live judge re-roll a grade until one lands inside the band. The last
|
|
51
|
+
* of those is how it was found: a judge scored a deliberately useless answer
|
|
52
|
+
* 1, and the scenario went green anyway on the next attempt.
|
|
53
|
+
*
|
|
54
|
+
* A caller that genuinely wants attempts still asks for them.
|
|
55
|
+
*/
|
|
56
|
+
const assertionStep = <T extends WorkflowStepOptions>(
|
|
57
|
+
options?: T
|
|
58
|
+
): T & { retries: number } =>
|
|
59
|
+
({ ...options, retries: options?.retries ?? 0 }) as T & { retries: number }
|
|
60
|
+
|
|
41
61
|
export { addFeature, resolveFeatureScenarios } from './feature.js'
|
|
42
|
-
export type
|
|
62
|
+
export type {
|
|
63
|
+
CoreFeature,
|
|
64
|
+
CoreFeatureScenario,
|
|
65
|
+
FeatureMeta,
|
|
66
|
+
FeaturesMeta,
|
|
67
|
+
PikkuBrowserWire,
|
|
68
|
+
PikkuScenarioWire,
|
|
69
|
+
ScenarioBrowserFailure,
|
|
70
|
+
ScenarioBrowserProvider,
|
|
71
|
+
ScenarioEnvironment,
|
|
72
|
+
ScenarioStepKind,
|
|
73
|
+
ScenarioStepMeta,
|
|
74
|
+
ScenarioStepOptions,
|
|
75
|
+
ScenarioStepPhase,
|
|
76
|
+
ScenarioSurface,
|
|
77
|
+
TestIdSelector,
|
|
78
|
+
} from './scenario.types.js'
|
|
79
|
+
export type {
|
|
80
|
+
ScenarioArtifact,
|
|
81
|
+
ScenarioFailureDetail,
|
|
82
|
+
ScenarioResult,
|
|
83
|
+
ScenarioRunRecord,
|
|
84
|
+
ScenarioRunReport,
|
|
85
|
+
ScenarioRunStatus,
|
|
86
|
+
ScenarioRunStore,
|
|
87
|
+
ScenarioRunSummary,
|
|
88
|
+
ScenarioStepRow,
|
|
89
|
+
} from './scenario-run.types.js'
|
|
43
90
|
export { SCENARIO_SURFACES } from './scenario-step.types.js'
|
|
44
91
|
|
|
45
92
|
// Which of a step's bindings run: one for an action, every witness for a `then`
|
|
@@ -50,7 +97,7 @@ export { createCookieJar } from './scenario-cookie-jar.js'
|
|
|
50
97
|
export type { ScenarioCookieJar } from './scenario-cookie-jar.js'
|
|
51
98
|
export { composeStepProse, renderStepTemplate } from './scenario-prose.js'
|
|
52
99
|
|
|
53
|
-
export {
|
|
100
|
+
export { requireScenarioEnv } from './scenario-step-guards.js'
|
|
54
101
|
|
|
55
102
|
export type {
|
|
56
103
|
ScenarioHttpResponse,
|
|
@@ -171,20 +218,24 @@ addError(ScenarioBrowserUnavailable, {
|
|
|
171
218
|
})
|
|
172
219
|
|
|
173
220
|
/**
|
|
174
|
-
* A
|
|
175
|
-
*
|
|
221
|
+
* A step that is driven by a persona was dispatched without one.
|
|
222
|
+
*
|
|
223
|
+
* Raised before the body runs rather than partway through it: the step declared
|
|
224
|
+
* that it needs an actor — by having a `browser` binding, which cannot be
|
|
225
|
+
* provisioned without a window to open, or by `actor: true` — so a call site
|
|
226
|
+
* that omits one is a mistake at the call site.
|
|
176
227
|
*/
|
|
177
|
-
export class
|
|
228
|
+
export class ScenarioActorRequired extends PikkuError {
|
|
178
229
|
constructor(public readonly stepFunc: string) {
|
|
179
230
|
super(
|
|
180
|
-
`[scenario] step '${stepFunc}'
|
|
181
|
-
`Pass { actor: actors.<name> } so
|
|
231
|
+
`[scenario] step '${stepFunc}' is driven by a persona but was called without an actor. ` +
|
|
232
|
+
`Pass { actor: actors.<name> } so it runs as that persona.`
|
|
182
233
|
)
|
|
183
234
|
}
|
|
184
235
|
}
|
|
185
|
-
addError(
|
|
236
|
+
addError(ScenarioActorRequired, {
|
|
186
237
|
status: 500,
|
|
187
|
-
message: '
|
|
238
|
+
message: 'This step needs an actor.',
|
|
188
239
|
})
|
|
189
240
|
|
|
190
241
|
/**
|
|
@@ -480,8 +531,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
480
531
|
let wireServices: Record<string, unknown> | undefined
|
|
481
532
|
try {
|
|
482
533
|
wireServices = (await createWireServices?.(singletonServices, wire)) as
|
|
483
|
-
|
|
484
|
-
| undefined
|
|
534
|
+
Record<string, unknown> | undefined
|
|
485
535
|
const services =
|
|
486
536
|
wireServices && Object.keys(wireServices).length > 0
|
|
487
537
|
? { ...singletonServices, ...wireServices }
|
|
@@ -602,7 +652,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
602
652
|
await new Promise((resolve) => setTimeout(resolve, interval))
|
|
603
653
|
}
|
|
604
654
|
},
|
|
605
|
-
options
|
|
655
|
+
assertionStep(options)
|
|
606
656
|
)
|
|
607
657
|
},
|
|
608
658
|
|
|
@@ -645,7 +695,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
645
695
|
`[workflow] expectError '${stepName}' ('${resolvedRpcName}') expected an error but the call succeeded: ${JSON.stringify(result)?.slice(0, 300)}`
|
|
646
696
|
)
|
|
647
697
|
},
|
|
648
|
-
options
|
|
698
|
+
assertionStep(options)
|
|
649
699
|
)
|
|
650
700
|
},
|
|
651
701
|
|
|
@@ -700,7 +750,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
700
750
|
)
|
|
701
751
|
}
|
|
702
752
|
},
|
|
703
|
-
options
|
|
753
|
+
assertionStep(options)
|
|
704
754
|
)
|
|
705
755
|
},
|
|
706
756
|
|
|
@@ -745,7 +795,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
745
795
|
}
|
|
746
796
|
return grade
|
|
747
797
|
},
|
|
748
|
-
options
|
|
798
|
+
assertionStep(options)
|
|
749
799
|
)
|
|
750
800
|
},
|
|
751
801
|
|
|
@@ -814,6 +864,10 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
814
864
|
this.scenarioStepDescription(packageName, resolvedStepFunc) ??
|
|
815
865
|
stepName
|
|
816
866
|
|
|
867
|
+
if (!actor && this.requiresActor(packageName, resolvedStepFunc)) {
|
|
868
|
+
throw new ScenarioActorRequired(resolvedStepFunc)
|
|
869
|
+
}
|
|
870
|
+
|
|
817
871
|
const declared = this.declaredSurfaces(packageName, resolvedStepFunc)
|
|
818
872
|
const resolution = resolveScenarioSurfaces(phase, declared, this.runSurface)
|
|
819
873
|
|
|
@@ -828,13 +882,13 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
828
882
|
scenario: workflowWire,
|
|
829
883
|
pikkuUserId: workflowWire.pikkuUserId,
|
|
830
884
|
actors: this.runActors.get(runId),
|
|
885
|
+
...(actor ? { actor } : {}),
|
|
831
886
|
scenarioStep: {
|
|
832
887
|
name: resolvedStepFunc,
|
|
833
888
|
stepName,
|
|
834
889
|
runId,
|
|
835
890
|
phase,
|
|
836
891
|
surface,
|
|
837
|
-
actor,
|
|
838
892
|
env: this.scenarioEnvironment,
|
|
839
893
|
},
|
|
840
894
|
}
|
|
@@ -842,11 +896,10 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
842
896
|
if (!this.scenarioBrowserProvider) {
|
|
843
897
|
throw new ScenarioBrowserUnavailable(resolvedStepFunc)
|
|
844
898
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
899
|
+
// The dispatch guard above already refused an actor-less call, and a
|
|
900
|
+
// browser binding always requires one.
|
|
848
901
|
wire.browser = await this.scenarioBrowserProvider.sessionFor(
|
|
849
|
-
actor
|
|
902
|
+
actor!.name
|
|
850
903
|
)
|
|
851
904
|
}
|
|
852
905
|
return await runPikkuFunc(
|
|
@@ -947,4 +1000,14 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
947
1000
|
const surfaces = this.scenarioStepConfig(packageName, stepFunc)?.surfaces
|
|
948
1001
|
return surfaces?.length ? surfaces : ['default']
|
|
949
1002
|
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* Whether a step is driven by a persona, and so must be given one. Stamped by
|
|
1006
|
+
* the definer from a `browser` binding or an explicit `actor: true`.
|
|
1007
|
+
*/
|
|
1008
|
+
private requiresActor(packageName: string | null, stepFunc: string): boolean {
|
|
1009
|
+
return (
|
|
1010
|
+
this.scenarioStepConfig(packageName, stepFunc)?.requiresActor === true
|
|
1011
|
+
)
|
|
1012
|
+
}
|
|
950
1013
|
}
|
|
@@ -5,11 +5,8 @@ import {
|
|
|
5
5
|
pikkuState,
|
|
6
6
|
} from '../../pikku-state.js'
|
|
7
7
|
import { getDurationInMilliseconds } from '../../time-utils.js'
|
|
8
|
-
import type {
|
|
9
|
-
|
|
10
|
-
PikkuRawWire,
|
|
11
|
-
SerializedError,
|
|
12
|
-
} from '../../types/core.types.js'
|
|
8
|
+
import type { CoreUserSession, PikkuRawWire } from '../../types/core.types.js'
|
|
9
|
+
import type { SerializedError } from '../../errors/serialized-error.js'
|
|
13
10
|
import type {
|
|
14
11
|
GroupConcurrencyConfig,
|
|
15
12
|
JobGroup,
|
|
@@ -39,6 +36,7 @@ import {
|
|
|
39
36
|
executeGraphStep,
|
|
40
37
|
runWorkflowGraph,
|
|
41
38
|
runFromMeta,
|
|
39
|
+
stripInstanceOrdinal,
|
|
42
40
|
} from './graph/graph-runner.js'
|
|
43
41
|
import type { WorkflowService } from '../../services/workflow-service.js'
|
|
44
42
|
import type { ScenarioPersonas } from '../../services/personas-service.js'
|
|
@@ -70,7 +68,6 @@ import {
|
|
|
70
68
|
WorkflowRunCancelledError,
|
|
71
69
|
WorkflowRunFailedError,
|
|
72
70
|
WorkflowRunNotFoundError,
|
|
73
|
-
WorkflowStepFunctionMismatchError,
|
|
74
71
|
WorkflowStepNameNotString,
|
|
75
72
|
WorkflowSuspendedException,
|
|
76
73
|
} from './workflow-errors.js'
|
|
@@ -97,6 +94,7 @@ import {
|
|
|
97
94
|
} from './workflow-approval.js'
|
|
98
95
|
import { auditApprovalDecision } from './workflow-approval-audit.js'
|
|
99
96
|
import { recordSuspension, suspendStepNameFor } from './workflow-suspend.js'
|
|
97
|
+
import { claimStepByReadThenWrite } from './workflow-step-claim.js'
|
|
100
98
|
import {
|
|
101
99
|
RedispatchBackoff,
|
|
102
100
|
sweepStalledRuns,
|
|
@@ -641,12 +639,12 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
641
639
|
*
|
|
642
640
|
* Returns nothing by default so a store that cannot express the query keeps
|
|
643
641
|
* working unchanged — and, because it does not opt in, gains no re-dispatches
|
|
644
|
-
* either. A store must have an atomic `
|
|
645
|
-
* or no concurrency for one to exclude: the relay makes
|
|
646
|
-
* routine, and the claim
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
*
|
|
642
|
+
* either. A store must have an atomic `claimStepForExecution` before
|
|
643
|
+
* overriding this, or no concurrency for one to exclude: the relay makes
|
|
644
|
+
* duplicate dispatch routine, and the claim is what keeps a duplicate from
|
|
645
|
+
* becoming a second execution. Every `@pikku/kysely` dialect qualifies on its
|
|
646
|
+
* status-guarded claim, `in-memory` on being inline and single-process;
|
|
647
|
+
* `mongodb` still qualifies on neither.
|
|
650
648
|
*/
|
|
651
649
|
protected async findUndispatchedSteps(
|
|
652
650
|
_before: Date,
|
|
@@ -1302,6 +1300,29 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
1302
1300
|
}
|
|
1303
1301
|
}
|
|
1304
1302
|
|
|
1303
|
+
/**
|
|
1304
|
+
* Take sole ownership of a step before it runs, returning the state to run
|
|
1305
|
+
* under — or `null` when another dispatch already owns it.
|
|
1306
|
+
*
|
|
1307
|
+
* Dispatch is at-least-once by design: the relay re-dispatches steps it
|
|
1308
|
+
* believes were dropped, and a queue can redeliver a job it already handed
|
|
1309
|
+
* out. This is the one place that keeps a duplicate dispatch from becoming a
|
|
1310
|
+
* second execution of a side-effecting step, so it is only as strong as the
|
|
1311
|
+
* exclusion it is built on — and `withStepLock` excludes nothing unless the
|
|
1312
|
+
* store backs it with a real primitive. A store able to express the decision
|
|
1313
|
+
* as one conditional write should override this rather than reach for a lock,
|
|
1314
|
+
* which is what `@pikku/kysely` does with a status-guarded `UPDATE`.
|
|
1315
|
+
*/
|
|
1316
|
+
protected async claimStepForExecution(
|
|
1317
|
+
runId: string,
|
|
1318
|
+
stepName: string,
|
|
1319
|
+
rpcName: string
|
|
1320
|
+
): Promise<StepState | null> {
|
|
1321
|
+
return this.withStepLock(runId, stepName, () =>
|
|
1322
|
+
claimStepByReadThenWrite(this, runId, stepName, rpcName)
|
|
1323
|
+
)
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1305
1326
|
private async executeWorkflowStepInner(
|
|
1306
1327
|
runId: string,
|
|
1307
1328
|
stepName: string,
|
|
@@ -1309,26 +1330,7 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
1309
1330
|
data: any,
|
|
1310
1331
|
rpcService: PikkuRPC
|
|
1311
1332
|
): Promise<void> {
|
|
1312
|
-
const claimed = await this.
|
|
1313
|
-
const stepState = await this.getStepState(runId, stepName)
|
|
1314
|
-
// knowledge: decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md
|
|
1315
|
-
if (
|
|
1316
|
-
stepState.rpcName !== undefined &&
|
|
1317
|
-
stepState.rpcName !== (rpcName ?? null)
|
|
1318
|
-
) {
|
|
1319
|
-
throw new WorkflowStepFunctionMismatchError(runId, stepName)
|
|
1320
|
-
}
|
|
1321
|
-
if (stepState.status === 'succeeded' || stepState.status === 'running') {
|
|
1322
|
-
return null
|
|
1323
|
-
}
|
|
1324
|
-
if (stepState.status === 'failed') {
|
|
1325
|
-
return this.createRetryAttempt(stepState.stepId, 'running')
|
|
1326
|
-
}
|
|
1327
|
-
if (stepState.status === 'pending' || stepState.status === 'scheduled') {
|
|
1328
|
-
await this.setStepRunning(stepState.stepId)
|
|
1329
|
-
}
|
|
1330
|
-
return stepState
|
|
1331
|
-
})
|
|
1333
|
+
const claimed = await this.claimStepForExecution(runId, stepName, rpcName)
|
|
1332
1334
|
|
|
1333
1335
|
if (!claimed) {
|
|
1334
1336
|
return
|
|
@@ -1352,9 +1354,9 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
1352
1354
|
if (stepName in workflowMeta.nodes) {
|
|
1353
1355
|
graphNodeId = stepName
|
|
1354
1356
|
} else {
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
|
|
1357
|
+
const base = stripInstanceOrdinal(stepName)
|
|
1358
|
+
if (base !== stepName && base in workflowMeta.nodes)
|
|
1359
|
+
graphNodeId = base
|
|
1358
1360
|
}
|
|
1359
1361
|
}
|
|
1360
1362
|
if (graphNodeId) {
|
|
@@ -65,7 +65,7 @@ describe('workflow.expectError', () => {
|
|
|
65
65
|
})
|
|
66
66
|
|
|
67
67
|
await assert.rejects(
|
|
68
|
-
wire.expectError('should have failed', 'deleteTodo', {}
|
|
68
|
+
wire.expectError('should have failed', 'deleteTodo', {}),
|
|
69
69
|
/expected an error but the call succeeded/
|
|
70
70
|
)
|
|
71
71
|
})
|
|
@@ -82,7 +82,7 @@ describe('workflow.expectError', () => {
|
|
|
82
82
|
'wrong reason',
|
|
83
83
|
'deleteTodo',
|
|
84
84
|
{},
|
|
85
|
-
{ matches: /Forbidden
|
|
85
|
+
{ matches: /Forbidden/ }
|
|
86
86
|
),
|
|
87
87
|
/did not match .*database offline/
|
|
88
88
|
)
|
|
@@ -114,10 +114,7 @@ describe('workflow.expectService', () => {
|
|
|
114
114
|
const { wire } = await scenarioWire(oneEmail())
|
|
115
115
|
|
|
116
116
|
await assert.rejects(
|
|
117
|
-
wire.expectService('two emails', 'email.send', {
|
|
118
|
-
times: 2,
|
|
119
|
-
retries: 0,
|
|
120
|
-
}),
|
|
117
|
+
wire.expectService('two emails', 'email.send', { times: 2 }),
|
|
121
118
|
/expected 2 call\(s\).*found 1.*email\.send/s
|
|
122
119
|
)
|
|
123
120
|
})
|
|
@@ -131,7 +128,6 @@ describe('workflow.expectService', () => {
|
|
|
131
128
|
await assert.rejects(
|
|
132
129
|
wire.expectService('emailed someone else', 'email.send', {
|
|
133
130
|
calledWith: { to: 'x@y.z' },
|
|
134
|
-
retries: 0,
|
|
135
131
|
}),
|
|
136
132
|
/found 0/
|
|
137
133
|
)
|
|
@@ -172,7 +168,7 @@ describe('workflow.expectScore', () => {
|
|
|
172
168
|
const { wire } = await scenarioWire(grades({ score: 0 }))
|
|
173
169
|
|
|
174
170
|
await assert.rejects(
|
|
175
|
-
wire.expectScore('was brief', 'run-1', 'brevity'
|
|
171
|
+
wire.expectScore('was brief', 'run-1', 'brevity'),
|
|
176
172
|
/expected 'brevity' to grade run run-1 at least 0\.5, got 0/
|
|
177
173
|
)
|
|
178
174
|
})
|
|
@@ -183,10 +179,7 @@ describe('workflow.expectScore', () => {
|
|
|
183
179
|
)
|
|
184
180
|
|
|
185
181
|
await assert.rejects(
|
|
186
|
-
wire.expectScore('was brief', 'run-1', 'brevity', {
|
|
187
|
-
atLeast: 0.8,
|
|
188
|
-
retries: 0,
|
|
189
|
-
}),
|
|
182
|
+
wire.expectScore('was brief', 'run-1', 'brevity', { atLeast: 0.8 }),
|
|
190
183
|
/It rambled for four paragraphs/
|
|
191
184
|
)
|
|
192
185
|
})
|
|
@@ -198,12 +191,34 @@ describe('workflow.expectScore', () => {
|
|
|
198
191
|
wire.expectScore('was not sycophantic', 'run-1', 'sycophancy', {
|
|
199
192
|
atLeast: 0,
|
|
200
193
|
atMost: 0.3,
|
|
201
|
-
retries: 0,
|
|
202
194
|
}),
|
|
203
195
|
/between 0 and 0\.3, got 0\.95/
|
|
204
196
|
)
|
|
205
197
|
})
|
|
206
198
|
|
|
199
|
+
test('a grade that misses the bound is not re-rolled until it lands', async () => {
|
|
200
|
+
let graded = 0
|
|
201
|
+
const { wire } = await scenarioWire({
|
|
202
|
+
rpcWithWire: async () => {
|
|
203
|
+
graded += 1
|
|
204
|
+
return { score: 1 }
|
|
205
|
+
},
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
await assert.rejects(
|
|
209
|
+
wire.expectScore('was not sycophantic', 'run-1', 'sycophancy', {
|
|
210
|
+
atLeast: 0,
|
|
211
|
+
atMost: 0.3,
|
|
212
|
+
}),
|
|
213
|
+
/got 1/
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
// The whole point of a judge is that it is not deterministic. Six attempts
|
|
217
|
+
// at it is six chances for one to land inside the band, which grades the
|
|
218
|
+
// sampling rather than the run.
|
|
219
|
+
assert.equal(graded, 1)
|
|
220
|
+
})
|
|
221
|
+
|
|
207
222
|
test('a reference answer reaches the grader', async () => {
|
|
208
223
|
let seen: any
|
|
209
224
|
const { wire } = await scenarioWire({
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one `pikku scenario run` leaves behind.
|
|
3
|
+
*
|
|
4
|
+
* A run is history: the scenarios it selected, the sentences they were made of,
|
|
5
|
+
* and the images and footage they produced. The sentences are snapshotted into
|
|
6
|
+
* the record rather than looked up later, because a scenario is code and the
|
|
7
|
+
* code moves — a run from last week describes a suite that no longer exists,
|
|
8
|
+
* and re-deriving its ladder from today's source would quietly rewrite it.
|
|
9
|
+
*
|
|
10
|
+
* Everything here is plain serialisable data. That is what lets one record be
|
|
11
|
+
* a JSON file on disk in OSS and a row in Postgres on a hosted project, read
|
|
12
|
+
* back by the same console screen either way.
|
|
13
|
+
*/
|
|
14
|
+
import type { ScenarioBrowserFailure } from './scenario-step.types.js'
|
|
15
|
+
|
|
16
|
+
/** What a run filed, in the order it filed it. */
|
|
17
|
+
export type ScenarioArtifactKind = 'screenshot' | 'failure' | 'video'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* One image or recording a scenario produced.
|
|
21
|
+
*
|
|
22
|
+
* `path` is relative to the run's artifact root and always uses forward
|
|
23
|
+
* slashes: it is a content key, not a filesystem path. Locally it resolves
|
|
24
|
+
* under the run's directory; on a hosted project it is the object key in a
|
|
25
|
+
* bucket, and the same record works unchanged.
|
|
26
|
+
*/
|
|
27
|
+
export interface ScenarioArtifact {
|
|
28
|
+
/** The scenario label this belongs to, as the report names it. */
|
|
29
|
+
scenario: string
|
|
30
|
+
kind: ScenarioArtifactKind
|
|
31
|
+
path: string
|
|
32
|
+
/** Whose window it was — a two-actor scenario produces two of everything. */
|
|
33
|
+
actor?: string
|
|
34
|
+
/** The caption the scenario author took a screenshot under. */
|
|
35
|
+
name?: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** One step of a run, already joined to the prose that declared it. */
|
|
39
|
+
export interface ScenarioStepRow {
|
|
40
|
+
sentence: string
|
|
41
|
+
status: string
|
|
42
|
+
durationMs?: number
|
|
43
|
+
error?: string
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Everything known about why one scenario failed. */
|
|
47
|
+
export interface ScenarioFailureDetail {
|
|
48
|
+
/** The rendered sentence of the failing step; absent if no step failed. */
|
|
49
|
+
sentence?: string
|
|
50
|
+
message: string
|
|
51
|
+
stack?: string
|
|
52
|
+
/**
|
|
53
|
+
* True when the failure was a deliberate one (a PikkuError). Its message is
|
|
54
|
+
* the whole story, so the stack is noise.
|
|
55
|
+
*/
|
|
56
|
+
expected?: boolean
|
|
57
|
+
browser?: ScenarioBrowserFailure[]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface ScenarioResult {
|
|
61
|
+
name: string
|
|
62
|
+
status: 'passed' | 'failed'
|
|
63
|
+
durationMs: number
|
|
64
|
+
output?: unknown
|
|
65
|
+
error?: string
|
|
66
|
+
steps?: ScenarioStepRow[]
|
|
67
|
+
failure?: ScenarioFailureDetail
|
|
68
|
+
/** The scenario registration this ran, which the label alone does not give. */
|
|
69
|
+
scenarioName?: string
|
|
70
|
+
/** The feature that grouped it, when one did. */
|
|
71
|
+
feature?: string
|
|
72
|
+
tags?: string[]
|
|
73
|
+
/** Images and footage this scenario produced, filed under the run. */
|
|
74
|
+
artifacts?: ScenarioArtifact[]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** One scenario that was not run, and why. */
|
|
78
|
+
export interface ScenarioSkip {
|
|
79
|
+
name: string
|
|
80
|
+
reason: string
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ScenarioRunReport {
|
|
84
|
+
environment: string
|
|
85
|
+
results: ScenarioResult[]
|
|
86
|
+
/**
|
|
87
|
+
* Scenarios not run at all, each carrying why. A skip is only useful if the
|
|
88
|
+
* reader can tell a browser scenario held back by `--no-browser` from one the
|
|
89
|
+
* project itself quarantined, so the reason travels with the name rather than
|
|
90
|
+
* being assumed by the formatter.
|
|
91
|
+
*/
|
|
92
|
+
skipped: ScenarioSkip[]
|
|
93
|
+
/** Feature-level hook failures, which belong to no single scenario. */
|
|
94
|
+
hookFailures: string[]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type ScenarioRunStatus = 'running' | 'passed' | 'failed'
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* A whole run, as it is stored and read back.
|
|
101
|
+
*
|
|
102
|
+
* `status` is `running` from the moment the run is created until it finishes,
|
|
103
|
+
* so a console watching a run in progress can tell "still going" from "nothing
|
|
104
|
+
* came back" — and a run killed halfway stays `running` forever, which is the
|
|
105
|
+
* honest record of what happened to it.
|
|
106
|
+
*/
|
|
107
|
+
export interface ScenarioRunRecord extends ScenarioRunReport {
|
|
108
|
+
runId: string
|
|
109
|
+
status: ScenarioRunStatus
|
|
110
|
+
/** The surface the run targeted: `default`, `browser`, … */
|
|
111
|
+
surface: string
|
|
112
|
+
startedAt: string
|
|
113
|
+
finishedAt?: string
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Enough of a run to list it without loading its steps and stacks. */
|
|
117
|
+
export interface ScenarioRunSummary {
|
|
118
|
+
runId: string
|
|
119
|
+
environment: string
|
|
120
|
+
surface: string
|
|
121
|
+
status: ScenarioRunStatus
|
|
122
|
+
startedAt: string
|
|
123
|
+
finishedAt?: string
|
|
124
|
+
durationMs?: number
|
|
125
|
+
passed: number
|
|
126
|
+
failed: number
|
|
127
|
+
skipped: number
|
|
128
|
+
/** Whether anything is there to watch, so a list can say so without a second read. */
|
|
129
|
+
artifacts: number
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Where runs are kept.
|
|
134
|
+
*
|
|
135
|
+
* Deliberately not the workflow service: a scenario run is a workflow run under
|
|
136
|
+
* the hood, but its history has a different lifetime, a different audience, and
|
|
137
|
+
* a different home — a JSON file beside the project locally, a project-scoped
|
|
138
|
+
* table and an object store when hosted.
|
|
139
|
+
*
|
|
140
|
+
* Written progressively rather than at the end, so a suite that dies on its
|
|
141
|
+
* fortieth scenario still leaves the thirty-nine behind.
|
|
142
|
+
*/
|
|
143
|
+
export interface ScenarioRunStore {
|
|
144
|
+
/** Open a run. Called before the first scenario, with `status: 'running'`. */
|
|
145
|
+
start(record: ScenarioRunRecord): Promise<void>
|
|
146
|
+
/** Append one finished scenario to an open run. */
|
|
147
|
+
recordScenario(runId: string, result: ScenarioResult): Promise<void>
|
|
148
|
+
/**
|
|
149
|
+
* File the run's artifacts against the scenarios that produced them.
|
|
150
|
+
*
|
|
151
|
+
* Separate from `recordScenario` because a scenario's video does not exist
|
|
152
|
+
* when the scenario ends — it is finalised by the next scenario's reset, and
|
|
153
|
+
* renamed again when the run closes. Artifacts are matched to a result by the
|
|
154
|
+
* label the report knows it under.
|
|
155
|
+
*/
|
|
156
|
+
attachArtifacts(runId: string, artifacts: ScenarioArtifact[]): Promise<void>
|
|
157
|
+
/** Close a run, settling everything only known once every scenario has run. */
|
|
158
|
+
finish(
|
|
159
|
+
runId: string,
|
|
160
|
+
outcome: Pick<
|
|
161
|
+
ScenarioRunRecord,
|
|
162
|
+
'status' | 'finishedAt' | 'skipped' | 'hookFailures'
|
|
163
|
+
>
|
|
164
|
+
): Promise<void>
|
|
165
|
+
/**
|
|
166
|
+
* The bytes of one artifact, by the `path` its record carries.
|
|
167
|
+
*
|
|
168
|
+
* Reading goes through the store because only the store knows where a run's
|
|
169
|
+
* files actually are — a directory beside the project, or an object store
|
|
170
|
+
* behind a bucket. Absent when the run or the path is unknown, which is also
|
|
171
|
+
* the answer for a path that tries to leave the run.
|
|
172
|
+
*
|
|
173
|
+
* The bytes are backed by their own `ArrayBuffer` so they can be handed
|
|
174
|
+
* straight to a `Response` — a view onto a pooled or shared buffer is not a
|
|
175
|
+
* valid body.
|
|
176
|
+
*/
|
|
177
|
+
readArtifact(
|
|
178
|
+
runId: string,
|
|
179
|
+
path: string
|
|
180
|
+
): Promise<{ body: Uint8Array<ArrayBuffer>; contentType: string } | undefined>
|
|
181
|
+
/** Most recent first. */
|
|
182
|
+
list(options?: { limit?: number }): Promise<ScenarioRunSummary[]>
|
|
183
|
+
get(runId: string): Promise<ScenarioRunRecord | undefined>
|
|
184
|
+
/** Forget a run and everything it filed. */
|
|
185
|
+
remove(runId: string): Promise<void>
|
|
186
|
+
}
|
|
@@ -3,21 +3,8 @@ import type {
|
|
|
3
3
|
ScenarioEnvironment,
|
|
4
4
|
} from './scenario-step.types.js'
|
|
5
5
|
|
|
6
|
-
export const requireActor = <TActor>(
|
|
7
|
-
scenarioStep: PikkuScenarioStepWire<TActor> | undefined
|
|
8
|
-
): TActor => {
|
|
9
|
-
const actor = scenarioStep?.actor
|
|
10
|
-
if (!actor) {
|
|
11
|
-
throw new Error(
|
|
12
|
-
`[scenario] step '${scenarioStep?.name ?? 'unknown'}' was called without an actor. ` +
|
|
13
|
-
`Pass { actor: actors.<name> } so it runs as that persona.`
|
|
14
|
-
)
|
|
15
|
-
}
|
|
16
|
-
return actor
|
|
17
|
-
}
|
|
18
|
-
|
|
19
6
|
export const requireScenarioEnv = (
|
|
20
|
-
scenarioStep: PikkuScenarioStepWire
|
|
7
|
+
scenarioStep: PikkuScenarioStepWire | undefined
|
|
21
8
|
): ScenarioEnvironment => {
|
|
22
9
|
const env = scenarioStep?.env
|
|
23
10
|
if (!env) {
|