@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
|
@@ -8,7 +8,7 @@ import { addFunction } from '../../function/function-runner.js'
|
|
|
8
8
|
import type { ScenarioPersona } from '../../services/personas-service.js'
|
|
9
9
|
import type { PikkuWire } from '../../types/core.types.js'
|
|
10
10
|
import type { ScenarioSurface } from './scenario-step.types.js'
|
|
11
|
-
import {
|
|
11
|
+
import { requireScenarioEnv } from './scenario-step-guards.js'
|
|
12
12
|
|
|
13
13
|
const noopLogger = { error() {}, info() {}, warn() {}, debug() {} }
|
|
14
14
|
|
|
@@ -145,6 +145,7 @@ const registerStep = (
|
|
|
145
145
|
config: {
|
|
146
146
|
description?: string
|
|
147
147
|
surfaces?: ScenarioSurface[]
|
|
148
|
+
requiresActor?: boolean
|
|
148
149
|
func: (services: any, data: any, wire: PikkuWire) => Promise<unknown>
|
|
149
150
|
}
|
|
150
151
|
) => {
|
|
@@ -215,7 +216,7 @@ describe('pikkuScenarioStep (scenario.given/when/then)', () => {
|
|
|
215
216
|
let received: unknown
|
|
216
217
|
registerStep('checksOut', {
|
|
217
218
|
func: async (_services, _data, wire) => {
|
|
218
|
-
received = wire.
|
|
219
|
+
received = wire.actor
|
|
219
220
|
return null
|
|
220
221
|
},
|
|
221
222
|
})
|
|
@@ -712,16 +713,17 @@ describe('the scenario environment reaches the step wire', () => {
|
|
|
712
713
|
})
|
|
713
714
|
})
|
|
714
715
|
|
|
715
|
-
describe('
|
|
716
|
+
describe('a step driven by a persona is given its actor', () => {
|
|
716
717
|
beforeEach(() => resetPikkuState())
|
|
717
718
|
|
|
718
|
-
test('
|
|
719
|
+
test('the actor is on the wire, not something the body unwraps', async () => {
|
|
719
720
|
const { workflowService: ws, scenarioService } = createScenarioRunner()
|
|
720
721
|
const shopper = fakeActor('shopper', async () => null)
|
|
721
722
|
let resolved: unknown
|
|
722
723
|
registerStep('needsAnActor', {
|
|
724
|
+
requiresActor: true,
|
|
723
725
|
func: async (_services, _data, wire) => {
|
|
724
|
-
resolved =
|
|
726
|
+
resolved = wire.actor
|
|
725
727
|
return null
|
|
726
728
|
},
|
|
727
729
|
})
|
|
@@ -735,10 +737,15 @@ describe('requireActor / requireScenarioEnv', () => {
|
|
|
735
737
|
assert.equal(resolved, shopper)
|
|
736
738
|
})
|
|
737
739
|
|
|
738
|
-
test('
|
|
740
|
+
test('one dispatched without an actor is refused before its body runs', async () => {
|
|
739
741
|
const { workflowService: ws, scenarioService } = createScenarioRunner()
|
|
742
|
+
let bodyRan = false
|
|
740
743
|
registerStep('needsAnActor', {
|
|
741
|
-
|
|
744
|
+
requiresActor: true,
|
|
745
|
+
func: async () => {
|
|
746
|
+
bodyRan = true
|
|
747
|
+
return null
|
|
748
|
+
},
|
|
742
749
|
})
|
|
743
750
|
|
|
744
751
|
const runId = await setup(ws)
|
|
@@ -747,6 +754,24 @@ describe('requireActor / requireScenarioEnv', () => {
|
|
|
747
754
|
wire.when('nobody acts', 'needsAnActor'),
|
|
748
755
|
/needsAnActor.*actor/s
|
|
749
756
|
)
|
|
757
|
+
assert.equal(bodyRan, false)
|
|
758
|
+
})
|
|
759
|
+
|
|
760
|
+
test('a step that declares no persona runs without one', async () => {
|
|
761
|
+
const { workflowService: ws, scenarioService } = createScenarioRunner()
|
|
762
|
+
let seen: unknown = 'unset'
|
|
763
|
+
registerStep('assertsSomething', {
|
|
764
|
+
func: async (_services, _data, wire) => {
|
|
765
|
+
seen = wire.actor
|
|
766
|
+
return null
|
|
767
|
+
},
|
|
768
|
+
})
|
|
769
|
+
|
|
770
|
+
const runId = await setup(ws)
|
|
771
|
+
const wire = ws.createWorkflowWire('scenarioTest', runId, {})
|
|
772
|
+
await wire.then('it holds', 'assertsSomething')
|
|
773
|
+
|
|
774
|
+
assert.equal(seen, undefined)
|
|
750
775
|
})
|
|
751
776
|
|
|
752
777
|
test('requireScenarioEnv returns the environment, or says how to declare one', async () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ScenarioArtifact } from './scenario-run.types.js'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Scenario steps: named, typed units of scenario behaviour.
|
|
@@ -99,7 +99,10 @@ export type ScenarioSurfaceResolution =
|
|
|
99
99
|
* default to no retries.
|
|
100
100
|
*/
|
|
101
101
|
export interface ScenarioStepOptions {
|
|
102
|
-
/**
|
|
102
|
+
/**
|
|
103
|
+
* The actor this step runs as. Required for a step that declares `actor: true`
|
|
104
|
+
* or a `browser` binding; the runner refuses to dispatch one without it.
|
|
105
|
+
*/
|
|
103
106
|
actor?: unknown
|
|
104
107
|
/** Overrides the step's own `description` for this call site only. */
|
|
105
108
|
description?: string
|
|
@@ -122,11 +125,12 @@ export interface ScenarioEnvironment {
|
|
|
122
125
|
/**
|
|
123
126
|
* The `scenarioStep` wire, present on every scenario step invocation.
|
|
124
127
|
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
+
* The persona a step runs as is not here: it arrives as `wire.actor`, injected
|
|
129
|
+
* by the runner and typed as present exactly on the bindings that declared they
|
|
130
|
+
* need one. Keeping it off this interface is what makes that possible — a wire
|
|
131
|
+
* member can be required per binding, a property of one cannot.
|
|
128
132
|
*/
|
|
129
|
-
export interface PikkuScenarioStepWire
|
|
133
|
+
export interface PikkuScenarioStepWire {
|
|
130
134
|
/** Registered step name (also its pikkuFuncId) */
|
|
131
135
|
name: string
|
|
132
136
|
/** Durable key within the run; may carry an `#ordinal` suffix when repeated */
|
|
@@ -138,12 +142,6 @@ export interface PikkuScenarioStepWire<TActor = ScenarioPersona> {
|
|
|
138
142
|
* per witness, so its body sees this change between invocations.
|
|
139
143
|
*/
|
|
140
144
|
surface: ScenarioSurface
|
|
141
|
-
/**
|
|
142
|
-
* The actor this step runs as, when one was given. Call RPCs through it
|
|
143
|
-
* (`actor.invoke(...)`) so they run against the target environment as that
|
|
144
|
-
* persona.
|
|
145
|
-
*/
|
|
146
|
-
actor?: TActor
|
|
147
145
|
/**
|
|
148
146
|
* The environment this run targets. A step runs in the CLI process, where
|
|
149
147
|
* there is no `variables` service — this is how a raw-HTTP step learns the
|
|
@@ -237,11 +235,28 @@ export interface ScenarioBrowserProvider {
|
|
|
237
235
|
* folder — findable only by timestamp.
|
|
238
236
|
*/
|
|
239
237
|
beginScenario?(scenario: string): void
|
|
238
|
+
/**
|
|
239
|
+
* Report how the scenario that just ran finished.
|
|
240
|
+
*
|
|
241
|
+
* Called after each scenario, and separate from `reset()` because artifacts
|
|
242
|
+
* that only exist once a window closes — a video — are produced by the NEXT
|
|
243
|
+
* scenario's reset, long after the outcome that decides whether to keep them.
|
|
244
|
+
*/
|
|
245
|
+
endScenario?(outcome: 'passed' | 'failed'): void
|
|
240
246
|
/**
|
|
241
247
|
* Snapshot every open window for a failed scenario. `label` identifies the
|
|
242
248
|
* scenario in artifact filenames. Never throws: a failure to capture must
|
|
243
249
|
* not replace the failure being captured.
|
|
244
250
|
*/
|
|
245
251
|
captureFailure?(label: string): Promise<ScenarioBrowserFailure[]>
|
|
252
|
+
/**
|
|
253
|
+
* Everything the run filed, each entry naming the scenario it belongs to.
|
|
254
|
+
*
|
|
255
|
+
* Reported by the driver rather than discovered by scanning the directory:
|
|
256
|
+
* only the driver knows which window produced a file and under what caption,
|
|
257
|
+
* and a video's final name is not settled until the run closes. Read after
|
|
258
|
+
* `close()`, which is the first moment the answer is complete.
|
|
259
|
+
*/
|
|
260
|
+
artifacts?(): ScenarioArtifact[]
|
|
246
261
|
close(): Promise<void>
|
|
247
262
|
}
|
|
@@ -166,9 +166,14 @@ describe('approval policy enforcement', () => {
|
|
|
166
166
|
})
|
|
167
167
|
await runToGate(ws, runId)
|
|
168
168
|
|
|
169
|
-
await ws.approveStep(
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
await ws.approveStep(
|
|
170
|
+
runId,
|
|
171
|
+
'Release funds',
|
|
172
|
+
{ ok: true },
|
|
173
|
+
{
|
|
174
|
+
userId: 'someone-else',
|
|
175
|
+
}
|
|
176
|
+
)
|
|
172
177
|
await ws.runWorkflowJob(runId, {})
|
|
173
178
|
|
|
174
179
|
assert.equal((await ws.getRun(runId))?.status, 'completed')
|
|
@@ -188,15 +193,25 @@ describe('approval policy enforcement', () => {
|
|
|
188
193
|
await runToGate(ws, runId)
|
|
189
194
|
|
|
190
195
|
await assert.rejects(
|
|
191
|
-
ws.approveStep(
|
|
192
|
-
|
|
193
|
-
|
|
196
|
+
ws.approveStep(
|
|
197
|
+
runId,
|
|
198
|
+
'Release funds',
|
|
199
|
+
{ ok: true },
|
|
200
|
+
{
|
|
201
|
+
userId: 'initiator',
|
|
202
|
+
}
|
|
203
|
+
),
|
|
194
204
|
WorkflowApprovalForbiddenError
|
|
195
205
|
)
|
|
196
206
|
|
|
197
|
-
await ws.approveStep(
|
|
198
|
-
|
|
199
|
-
|
|
207
|
+
await ws.approveStep(
|
|
208
|
+
runId,
|
|
209
|
+
'Release funds',
|
|
210
|
+
{ ok: true },
|
|
211
|
+
{
|
|
212
|
+
userId: 'reviewer',
|
|
213
|
+
}
|
|
214
|
+
)
|
|
200
215
|
await ws.runWorkflowJob(runId, {})
|
|
201
216
|
|
|
202
217
|
assert.equal((await ws.getRun(runId))?.status, 'completed')
|
|
@@ -216,15 +231,25 @@ describe('approval policy enforcement', () => {
|
|
|
216
231
|
await runToGate(ws, runId)
|
|
217
232
|
|
|
218
233
|
await assert.rejects(
|
|
219
|
-
ws.approveStep(
|
|
220
|
-
|
|
221
|
-
|
|
234
|
+
ws.approveStep(
|
|
235
|
+
runId,
|
|
236
|
+
'Release funds',
|
|
237
|
+
{ ok: true },
|
|
238
|
+
{
|
|
239
|
+
userId: 'attacker',
|
|
240
|
+
}
|
|
241
|
+
),
|
|
222
242
|
WorkflowApprovalForbiddenError
|
|
223
243
|
)
|
|
224
244
|
|
|
225
|
-
await ws.approveStep(
|
|
226
|
-
|
|
227
|
-
|
|
245
|
+
await ws.approveStep(
|
|
246
|
+
runId,
|
|
247
|
+
'Release funds',
|
|
248
|
+
{ ok: true },
|
|
249
|
+
{
|
|
250
|
+
userId: 'initiator',
|
|
251
|
+
}
|
|
252
|
+
)
|
|
228
253
|
await ws.runWorkflowJob(runId, {})
|
|
229
254
|
|
|
230
255
|
assert.equal((await ws.getRun(runId))?.status, 'completed')
|
|
@@ -244,17 +269,27 @@ describe('approval policy enforcement', () => {
|
|
|
244
269
|
await runToGate(ws, runId)
|
|
245
270
|
|
|
246
271
|
await assert.rejects(
|
|
247
|
-
ws.approveStep(
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
272
|
+
ws.approveStep(
|
|
273
|
+
runId,
|
|
274
|
+
'Release funds',
|
|
275
|
+
{ ok: true },
|
|
276
|
+
{
|
|
277
|
+
userId: 'reviewer',
|
|
278
|
+
scopes: ['payments:read'],
|
|
279
|
+
}
|
|
280
|
+
),
|
|
251
281
|
WorkflowApprovalForbiddenError
|
|
252
282
|
)
|
|
253
283
|
|
|
254
|
-
await ws.approveStep(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
284
|
+
await ws.approveStep(
|
|
285
|
+
runId,
|
|
286
|
+
'Release funds',
|
|
287
|
+
{ ok: true },
|
|
288
|
+
{
|
|
289
|
+
userId: 'reviewer',
|
|
290
|
+
scopes: ['payments:approve'],
|
|
291
|
+
}
|
|
292
|
+
)
|
|
258
293
|
await ws.runWorkflowJob(runId, {})
|
|
259
294
|
|
|
260
295
|
assert.equal((await ws.getRun(runId))?.status, 'completed')
|
|
@@ -280,10 +315,15 @@ describe('approval policy enforcement', () => {
|
|
|
280
315
|
})
|
|
281
316
|
await runToGate(ws, runId)
|
|
282
317
|
|
|
283
|
-
await ws.approveStep(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
318
|
+
await ws.approveStep(
|
|
319
|
+
runId,
|
|
320
|
+
'Release funds',
|
|
321
|
+
{ ok: true },
|
|
322
|
+
{
|
|
323
|
+
userId: 'reviewer',
|
|
324
|
+
scopes: ['payments:approve'],
|
|
325
|
+
}
|
|
326
|
+
)
|
|
287
327
|
await ws.runWorkflowJob(runId, {})
|
|
288
328
|
|
|
289
329
|
const step = await ws.getStepState(
|
|
@@ -343,9 +383,14 @@ describe('approval policy enforcement', () => {
|
|
|
343
383
|
|
|
344
384
|
// The gate has not been reached, so no policy has been published and the
|
|
345
385
|
// submission cannot be judged here — it is accepted and judged on replay.
|
|
346
|
-
await ws.approveStep(
|
|
347
|
-
|
|
348
|
-
|
|
386
|
+
await ws.approveStep(
|
|
387
|
+
runId,
|
|
388
|
+
'Release funds',
|
|
389
|
+
{ ok: true },
|
|
390
|
+
{
|
|
391
|
+
userId: 'initiator',
|
|
392
|
+
}
|
|
393
|
+
)
|
|
349
394
|
|
|
350
395
|
await runToGate(ws, runId)
|
|
351
396
|
|
|
@@ -392,10 +437,15 @@ describe('approval audit trail', () => {
|
|
|
392
437
|
pikkuUserId: 'initiator',
|
|
393
438
|
})
|
|
394
439
|
await runToGate(ws, runId)
|
|
395
|
-
await ws.approveStep(
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
440
|
+
await ws.approveStep(
|
|
441
|
+
runId,
|
|
442
|
+
'Release funds',
|
|
443
|
+
{ ok: true },
|
|
444
|
+
{
|
|
445
|
+
userId: 'reviewer',
|
|
446
|
+
scopes: ['payments:approve'],
|
|
447
|
+
}
|
|
448
|
+
)
|
|
399
449
|
await ws.runWorkflowJob(runId, {})
|
|
400
450
|
|
|
401
451
|
assert.equal(events.length, 1)
|
|
@@ -428,9 +478,14 @@ describe('approval audit trail', () => {
|
|
|
428
478
|
await runToGate(ws, runId)
|
|
429
479
|
|
|
430
480
|
await assert.rejects(
|
|
431
|
-
ws.approveStep(
|
|
432
|
-
|
|
433
|
-
|
|
481
|
+
ws.approveStep(
|
|
482
|
+
runId,
|
|
483
|
+
'Release funds',
|
|
484
|
+
{ ok: true },
|
|
485
|
+
{
|
|
486
|
+
userId: 'initiator',
|
|
487
|
+
}
|
|
488
|
+
),
|
|
434
489
|
WorkflowApprovalForbiddenError
|
|
435
490
|
)
|
|
436
491
|
|
|
@@ -462,9 +517,14 @@ describe('approval audit trail', () => {
|
|
|
462
517
|
|
|
463
518
|
// Submitted before the gate published its policy, so it is accepted here
|
|
464
519
|
// and only refused on replay.
|
|
465
|
-
await ws.approveStep(
|
|
466
|
-
|
|
467
|
-
|
|
520
|
+
await ws.approveStep(
|
|
521
|
+
runId,
|
|
522
|
+
'Release funds',
|
|
523
|
+
{ ok: true },
|
|
524
|
+
{
|
|
525
|
+
userId: 'initiator',
|
|
526
|
+
}
|
|
527
|
+
)
|
|
468
528
|
assert.equal(events[0].outcome, 'success')
|
|
469
529
|
|
|
470
530
|
await runToGate(ws, runId)
|
|
@@ -495,9 +555,14 @@ describe('approval audit trail', () => {
|
|
|
495
555
|
pikkuUserId: 'initiator',
|
|
496
556
|
})
|
|
497
557
|
await runToGate(ws, runId)
|
|
498
|
-
await ws.approveStep(
|
|
499
|
-
|
|
500
|
-
|
|
558
|
+
await ws.approveStep(
|
|
559
|
+
runId,
|
|
560
|
+
'Release funds',
|
|
561
|
+
{ ok: true },
|
|
562
|
+
{
|
|
563
|
+
userId: 'reviewer',
|
|
564
|
+
}
|
|
565
|
+
)
|
|
501
566
|
await ws.runWorkflowJob(runId, {})
|
|
502
567
|
|
|
503
568
|
assert.equal((await ws.getRun(runId))?.status, 'completed')
|
|
@@ -513,12 +578,17 @@ describe('approval audit trail', () => {
|
|
|
513
578
|
pikkuUserId: 'initiator',
|
|
514
579
|
})
|
|
515
580
|
await runToGate(ws, runId)
|
|
516
|
-
await ws.approveStep(
|
|
517
|
-
|
|
518
|
-
|
|
581
|
+
await ws.approveStep(
|
|
582
|
+
runId,
|
|
583
|
+
'Release funds',
|
|
584
|
+
{ ok: true },
|
|
585
|
+
{
|
|
586
|
+
userId: 'reviewer',
|
|
587
|
+
}
|
|
588
|
+
)
|
|
519
589
|
await ws.runWorkflowJob(runId, {})
|
|
520
590
|
|
|
521
591
|
assert.equal((await ws.getRun(runId))?.status, 'completed')
|
|
522
592
|
cleanup()
|
|
523
593
|
})
|
|
524
|
-
})
|
|
594
|
+
})
|
|
@@ -202,7 +202,8 @@ export const evaluateApprovalStep = async (
|
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
const stateKey = approvalStateKey(approvalStepName)
|
|
205
|
-
let record = ((await store.getRunState(runId))[stateKey] ??
|
|
205
|
+
let record = ((await store.getRunState(runId))[stateKey] ??
|
|
206
|
+
{}) as ApprovalRecord
|
|
206
207
|
|
|
207
208
|
const policy: WorkflowApprovalPolicy = {
|
|
208
209
|
approvers: options.approvers,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { WorkflowStepFunctionMismatchError } from './workflow-errors.js'
|
|
2
|
+
import type { StepState } from './workflow.types.js'
|
|
3
|
+
|
|
4
|
+
/** What claiming a step needs from the workflow service. */
|
|
5
|
+
export type StepClaimStore = {
|
|
6
|
+
getStepState(runId: string, stepName: string): Promise<StepState>
|
|
7
|
+
setStepRunning(stepId: string): Promise<void>
|
|
8
|
+
createRetryAttempt(
|
|
9
|
+
failedStepId: string,
|
|
10
|
+
status: 'pending' | 'running'
|
|
11
|
+
): Promise<StepState>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Decide whether this dispatch owns the step, by reading its state and then
|
|
16
|
+
* writing it — which only excludes a concurrent dispatch when the caller holds
|
|
17
|
+
* a lock that genuinely excludes one.
|
|
18
|
+
*
|
|
19
|
+
* A store that can express the whole decision as a single conditional write
|
|
20
|
+
* should do that instead of calling this.
|
|
21
|
+
*/
|
|
22
|
+
export const claimStepByReadThenWrite = async (
|
|
23
|
+
store: StepClaimStore,
|
|
24
|
+
runId: string,
|
|
25
|
+
stepName: string,
|
|
26
|
+
rpcName: string
|
|
27
|
+
): Promise<StepState | null> => {
|
|
28
|
+
const stepState = await store.getStepState(runId, stepName)
|
|
29
|
+
// knowledge: decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md
|
|
30
|
+
if (
|
|
31
|
+
stepState.rpcName !== undefined &&
|
|
32
|
+
stepState.rpcName !== (rpcName ?? null)
|
|
33
|
+
) {
|
|
34
|
+
throw new WorkflowStepFunctionMismatchError(runId, stepName)
|
|
35
|
+
}
|
|
36
|
+
if (stepState.status === 'succeeded' || stepState.status === 'running') {
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
39
|
+
if (stepState.status === 'failed') {
|
|
40
|
+
return store.createRetryAttempt(stepState.stepId, 'running')
|
|
41
|
+
}
|
|
42
|
+
if (stepState.status === 'pending' || stepState.status === 'scheduled') {
|
|
43
|
+
await store.setStepRunning(stepState.stepId)
|
|
44
|
+
}
|
|
45
|
+
return stepState
|
|
46
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CommonWireMeta } from '../../types/core.types.js'
|
|
2
|
+
import type { SerializedError } from '../../errors/serialized-error.js'
|
|
2
3
|
import type { CorePikkuFunctionConfig } from '../../function/functions.types.js'
|
|
3
4
|
import type { GroupConcurrencyConfig } from '../queue/queue.types.js'
|
|
4
5
|
|
|
@@ -62,21 +63,12 @@ export interface WorkflowPlannedStep {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
export type WorkflowStatus =
|
|
65
|
-
| '
|
|
66
|
-
| 'suspended'
|
|
67
|
-
| 'completed'
|
|
68
|
-
| 'failed'
|
|
69
|
-
| 'cancelled'
|
|
66
|
+
'running' | 'suspended' | 'completed' | 'failed' | 'cancelled'
|
|
70
67
|
|
|
71
68
|
export type WorkflowVersionStatus = 'draft' | 'active' | 'declined'
|
|
72
69
|
|
|
73
70
|
export type StepStatus =
|
|
74
|
-
| '
|
|
75
|
-
| 'running'
|
|
76
|
-
| 'scheduled'
|
|
77
|
-
| 'succeeded'
|
|
78
|
-
| 'failed'
|
|
79
|
-
| 'suspended'
|
|
71
|
+
'pending' | 'running' | 'scheduled' | 'succeeded' | 'failed' | 'suspended'
|
|
80
72
|
|
|
81
73
|
export interface WorkflowRun {
|
|
82
74
|
id: string
|
|
@@ -25,13 +25,16 @@ const ALLOWED: Record<string, string[]> = {
|
|
|
25
25
|
http: ['channel'],
|
|
26
26
|
cli: ['channel'],
|
|
27
27
|
// An agent streams over a channel and is invoked over rpc, and grades itself
|
|
28
|
-
// as the last thing a finished run does.
|
|
29
|
-
|
|
28
|
+
// as the last thing a finished run does. Its own functions may come from an
|
|
29
|
+
// installed addon, so it builds that addon's services the same way rpc does.
|
|
30
|
+
agent: ['channel', 'rpc', 'agent-scorer', 'addon'],
|
|
30
31
|
// A judge is a degenerate agent — it builds agent messages and runs them —
|
|
31
32
|
// and a grade is dispatched to a queue.
|
|
32
33
|
'agent-scorer': ['agent', 'queue'],
|
|
33
34
|
// `wire.rpc.agent` — the facade lives with the agent runtime it delegates to.
|
|
34
|
-
rpc
|
|
35
|
+
// An rpc call is how an installed addon's function is reached, so the runner
|
|
36
|
+
// resolves the addon instance that owns the namespace.
|
|
37
|
+
rpc: ['agent', 'addon'],
|
|
35
38
|
gateway: ['http'],
|
|
36
39
|
mcp: ['rpc'],
|
|
37
40
|
trigger: ['rpc'],
|