@pikku/core 0.12.83 → 0.12.86
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 +492 -0
- package/README.md +1 -1
- 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/ecosystem/agent-scorer.d.ts +12 -0
- package/dist/ecosystem/agent-scorer.js +5 -0
- package/dist/ecosystem/agent.d.ts +21 -0
- package/dist/ecosystem/agent.js +6 -0
- package/dist/ecosystem/channel/local.d.ts +3 -0
- package/dist/ecosystem/channel/local.js +3 -0
- package/dist/ecosystem/channel/serverless.d.ts +9 -0
- package/dist/ecosystem/channel/serverless.js +1 -0
- package/dist/ecosystem/channel.d.ts +15 -0
- package/dist/ecosystem/channel.js +5 -0
- package/dist/ecosystem/cli/channel.d.ts +16 -0
- package/dist/ecosystem/cli/channel.js +2 -0
- package/dist/ecosystem/cli.d.ts +9 -0
- package/dist/ecosystem/cli.js +2 -0
- package/dist/ecosystem/credential.d.ts +10 -0
- package/dist/ecosystem/credential.js +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 +9 -0
- package/dist/ecosystem/dev.js +2 -0
- package/dist/ecosystem/errors.d.ts +8 -0
- package/dist/ecosystem/errors.js +2 -0
- package/dist/ecosystem/function.d.ts +13 -0
- package/dist/ecosystem/function.js +2 -0
- package/dist/ecosystem/gateway.d.ts +1 -0
- package/dist/ecosystem/hmac.d.ts +1 -0
- package/dist/ecosystem/hmac.js +1 -0
- package/dist/ecosystem/http.d.ts +13 -0
- package/dist/ecosystem/http.js +5 -0
- package/dist/ecosystem/mcp.d.ts +3 -0
- package/dist/ecosystem/mcp.js +2 -0
- package/dist/ecosystem/middleware.d.ts +18 -0
- package/dist/ecosystem/middleware.js +7 -0
- package/dist/ecosystem/node-host-resolver.d.ts +1 -0
- package/dist/ecosystem/node-host-resolver.js +1 -0
- package/dist/ecosystem/node.d.ts +1 -0
- package/dist/ecosystem/oauth2.d.ts +1 -0
- package/dist/ecosystem/oauth2.js +1 -0
- package/dist/ecosystem/persona.d.ts +17 -0
- package/dist/ecosystem/persona.js +5 -0
- package/dist/ecosystem/queue.d.ts +13 -0
- package/dist/ecosystem/queue.js +4 -0
- package/dist/ecosystem/remote.d.ts +8 -0
- package/dist/ecosystem/remote.js +1 -0
- package/dist/ecosystem/role.d.ts +4 -0
- package/dist/ecosystem/role.js +2 -0
- package/dist/ecosystem/rpc.d.ts +6 -0
- package/dist/ecosystem/rpc.js +3 -0
- package/dist/ecosystem/safe-fetch.d.ts +7 -0
- package/dist/ecosystem/safe-fetch.js +1 -0
- package/dist/ecosystem/scenario.d.ts +21 -0
- package/dist/ecosystem/scenario.js +8 -0
- package/dist/ecosystem/scheduler.d.ts +3 -0
- package/dist/ecosystem/scheduler.js +2 -0
- package/dist/ecosystem/schema.d.ts +2 -0
- package/dist/ecosystem/schema.js +1 -0
- package/dist/ecosystem/scope.d.ts +5 -0
- package/dist/ecosystem/scope.js +3 -0
- package/dist/ecosystem/secret.d.ts +11 -0
- package/dist/ecosystem/secret.js +2 -0
- package/dist/ecosystem/services/istanbul-coverage.d.ts +1 -0
- package/dist/ecosystem/services/istanbul-coverage.js +1 -0
- package/dist/ecosystem/services/local-content-request-handler.d.ts +9 -0
- package/dist/ecosystem/services/local-content-request-handler.js +1 -0
- package/dist/ecosystem/services/local-content.d.ts +2 -0
- package/dist/ecosystem/services/local-content.js +1 -0
- package/dist/ecosystem/services/local-meta.d.ts +1 -0
- package/dist/ecosystem/services/local-meta.js +1 -0
- package/dist/ecosystem/services/v8-coverage.d.ts +1 -0
- package/dist/ecosystem/services/v8-coverage.js +1 -0
- package/dist/ecosystem/services.d.ts +36 -0
- package/dist/ecosystem/services.js +12 -0
- package/dist/ecosystem/testing.d.ts +7 -0
- package/dist/ecosystem/testing.js +1 -0
- package/dist/ecosystem/trigger.d.ts +2 -0
- package/dist/ecosystem/trigger.js +1 -0
- package/dist/ecosystem/types.d.ts +12 -0
- package/dist/ecosystem/types.js +6 -0
- package/dist/ecosystem/variable.d.ts +9 -0
- package/dist/ecosystem/variable.js +1 -0
- package/dist/ecosystem/virtual-user.d.ts +24 -0
- package/dist/ecosystem/virtual-user.js +8 -0
- package/dist/ecosystem/workflow.d.ts +20 -0
- package/dist/ecosystem/workflow.js +6 -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/errors/serialized-error.js +1 -0
- package/dist/function/function-meta.types.d.ts +139 -0
- package/dist/function/function-meta.types.js +1 -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/index.d.ts +8 -8
- package/dist/index.js +3 -3
- 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 +1 -1
- 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/{ai-run-state-service.d.ts → agent-run-state-service.d.ts} +5 -5
- package/dist/services/agent-run-state-service.js +1 -0
- package/dist/services/{ai-agent-runner-service.d.ts → agent-runner-service.d.ts} +12 -12
- package/dist/services/agent-runner-service.js +1 -0
- package/dist/services/{ai-storage-service.d.ts → agent-storage-service.d.ts} +7 -7
- package/dist/services/agent-storage-service.js +1 -0
- 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/http-personas.d.ts +1 -1
- package/dist/services/http-personas.js +3 -3
- package/dist/services/{in-memory-ai-run-state-service.d.ts → in-memory-agent-run-state-service.d.ts} +5 -5
- package/dist/services/{in-memory-ai-run-state-service.js → in-memory-agent-run-state-service.js} +1 -1
- package/dist/services/in-memory-workflow-service.d.ts +1 -1
- package/dist/services/index.d.ts +9 -5
- package/dist/services/index.js +4 -1
- 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 +5 -4
- 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/testing/service-tests/agent-run-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/agent-run-service-tests.js +3 -3
- package/dist/testing/service-tests/agent-storage-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/{ai-storage-service-tests.js → agent-storage-service-tests.js} +4 -4
- package/dist/testing/service-tests.d.ts +4 -4
- package/dist/testing/service-tests.js +4 -4
- package/dist/types/core.types.d.ts +37 -187
- 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 +8 -6
- package/dist/utils.d.ts +13 -0
- package/dist/utils.js +2 -0
- package/dist/wirings/actor-flow/run-conversation.d.ts +2 -2
- 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/{ai-agent/ai-agent-agui.d.ts → agent/agent-agui.d.ts} +2 -2
- package/dist/wirings/{ai-agent/ai-agent-agui.js → agent/agent-agui.js} +1 -1
- package/dist/wirings/{ai-agent/ai-agent-finalize.d.ts → agent/agent-finalize.d.ts} +10 -10
- package/dist/wirings/{ai-agent/ai-agent-finalize.js → agent/agent-finalize.js} +7 -7
- package/dist/wirings/{ai-agent/ai-agent-helpers.d.ts → agent/agent-helpers.d.ts} +1 -1
- package/dist/wirings/{ai-agent/ai-agent-interrupt.d.ts → agent/agent-interrupt.d.ts} +4 -4
- package/dist/wirings/{ai-agent/ai-agent-interrupt.js → agent/agent-interrupt.js} +2 -2
- package/dist/wirings/{ai-agent/ai-agent-memory.d.ts → agent/agent-memory.d.ts} +14 -14
- package/dist/wirings/{ai-agent/ai-agent-memory.js → agent/agent-memory.js} +1 -1
- package/dist/wirings/{ai-agent/ai-agent-model-config.js → agent/agent-model-config.js} +1 -1
- package/dist/wirings/{ai-agent/ai-agent-prepare.d.ts → agent/agent-prepare.d.ts} +24 -24
- package/dist/wirings/{ai-agent/ai-agent-prepare.js → agent/agent-prepare.js} +17 -17
- package/dist/wirings/agent/agent-registry.d.ts +16 -0
- package/dist/wirings/{ai-agent/ai-agent-registry.js → agent/agent-registry.js} +9 -9
- package/dist/wirings/{ai-agent → agent}/agent-rpc.js +8 -8
- package/dist/wirings/agent/agent-runner.d.ts +7 -0
- package/dist/wirings/{ai-agent/ai-agent-runner.js → agent/agent-runner.js} +49 -50
- package/dist/wirings/{ai-agent/ai-agent-stream.d.ts → agent/agent-stream.d.ts} +15 -15
- package/dist/wirings/{ai-agent/ai-agent-stream.js → agent/agent-stream.js} +78 -78
- package/dist/wirings/{ai-agent/ai-agent-turn.d.ts → agent/agent-turn.d.ts} +5 -5
- package/dist/wirings/{ai-agent/ai-agent-turn.js → agent/agent-turn.js} +4 -4
- package/dist/wirings/agent/agent-utils.d.ts +14 -0
- package/dist/wirings/agent/agent-utils.js +17 -0
- package/dist/wirings/{ai-agent/ai-agent.types.d.ts → agent/agent.types.d.ts} +47 -46
- package/dist/wirings/agent/agent.types.js +1 -0
- package/dist/wirings/agent/index.d.ts +12 -0
- package/dist/wirings/agent/index.js +10 -0
- package/dist/wirings/{ai-agent → agent}/voice-input.d.ts +1 -1
- package/dist/wirings/{ai-agent → agent}/voice-input.js +5 -5
- package/dist/wirings/{ai-agent → agent}/voice-output.d.ts +2 -3
- package/dist/wirings/{ai-agent → agent}/voice-output.js +8 -8
- package/dist/wirings/{ai-scorer/ai-scorer-grade.d.ts → agent-scorer/agent-scorer-grade.d.ts} +3 -3
- package/dist/wirings/{ai-scorer/ai-scorer-grade.js → agent-scorer/agent-scorer-grade.js} +6 -6
- package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +30 -0
- package/dist/wirings/{ai-scorer/ai-scorer-judge.js → agent-scorer/agent-scorer-judge.js} +57 -5
- package/dist/wirings/{ai-scorer/ai-scorer-live.d.ts → agent-scorer/agent-scorer-live.d.ts} +1 -1
- package/dist/wirings/{ai-scorer/ai-scorer-live.js → agent-scorer/agent-scorer-live.js} +3 -3
- package/dist/wirings/{ai-scorer/ai-scorer-registry.d.ts → agent-scorer/agent-scorer-registry.d.ts} +6 -6
- package/dist/wirings/{ai-scorer/ai-scorer-registry.js → agent-scorer/agent-scorer-registry.js} +4 -4
- package/dist/wirings/{ai-scorer/ai-scorer-snapshots.d.ts → agent-scorer/agent-scorer-snapshots.d.ts} +1 -1
- package/dist/wirings/{ai-scorer/ai-scorer-worker.d.ts → agent-scorer/agent-scorer-worker.d.ts} +3 -3
- package/dist/wirings/{ai-scorer/ai-scorer-worker.js → agent-scorer/agent-scorer-worker.js} +9 -7
- package/dist/wirings/{ai-scorer/ai-scorer.d.ts → agent-scorer/agent-scorer.d.ts} +12 -6
- package/dist/wirings/{ai-scorer/ai-scorer.js → agent-scorer/agent-scorer.js} +4 -3
- package/dist/wirings/{ai-scorer/ai-scorer.types.d.ts → agent-scorer/agent-scorer.types.d.ts} +24 -4
- package/dist/wirings/agent-scorer/agent-scorer.types.js +4 -0
- package/dist/wirings/agent-scorer/index.d.ts +6 -0
- package/dist/wirings/agent-scorer/index.js +5 -0
- 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-rpc.types.d.ts +2 -2
- 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.d.ts +1 -1
- package/dist/wirings/rpc/rpc-runner.js +4 -4
- package/dist/wirings/rpc/rpc-types.d.ts +1 -1
- 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 +9 -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/prepare-virtual-user-run.js +1 -1
- package/dist/wirings/virtual-user/virtual-user-agents.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 +14 -4
- package/dist/wirings/workflow/pikku-scenario-service.js +44 -16
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -1
- package/dist/wirings/workflow/pikku-workflow-service.js +3 -4
- package/dist/wirings/workflow/run-timeline.d.ts +2 -3
- 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.types.d.ts +2 -1
- package/knowledge/decisions/index.md +2 -0
- package/knowledge/decisions/internals/{a-non-streaming-agent-run-registers-with-airunstate-too.md → a-non-streaming-agent-run-registers-with-agentrunstate-too.md} +6 -6
- package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +1 -1
- 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/actor-flow-drives-the-target-through-a-transport-seam.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/{ai-agent-agui-bridge-obeys-the-client-ordering-contract.md → agent-agui-bridge-obeys-the-client-ordering-contract.md} +5 -5
- package/knowledge/decisions/internals/{ai-agent-audio-chunks-carry-the-format-the-provider-returned.md → agent-audio-chunks-carry-the-format-the-provider-returned.md} +2 -2
- package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +1 -1
- package/knowledge/decisions/internals/{ai-agent-credential-suspensions-hide-the-tool-result.md → agent-credential-suspensions-hide-the-tool-result.md} +2 -2
- package/knowledge/decisions/internals/{ai-agent-delegate-and-supervise-hide-different-text.md → agent-delegate-and-supervise-hide-different-text.md} +4 -4
- package/knowledge/decisions/internals/{ai-agent-llm-tool-arguments-have-nulls-stripped.md → agent-llm-tool-arguments-have-nulls-stripped.md} +3 -3
- package/knowledge/decisions/internals/{ai-agent-model-config-stays-a-single-resolution-seam.md → agent-model-config-stays-a-single-resolution-seam.md} +3 -3
- package/knowledge/decisions/internals/{ai-agent-onerror-hooks-cannot-change-the-failure.md → agent-onerror-hooks-cannot-change-the-failure.md} +6 -6
- package/knowledge/decisions/internals/{ai-agent-runner-methods-must-keep-their-receiver.md → agent-runner-methods-must-keep-their-receiver.md} +4 -4
- package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +1 -1
- package/knowledge/decisions/internals/{ai-agent-stream-persistence-is-best-effort.md → agent-stream-persistence-is-best-effort.md} +4 -4
- package/knowledge/decisions/internals/{ai-agent-sub-agents-inherit-the-parent-context-block.md → agent-sub-agents-inherit-the-parent-context-block.md} +3 -3
- package/knowledge/decisions/internals/{ai-agent-tool-execute-failures-are-logged-unconditionally.md → agent-tool-execute-failures-are-logged-unconditionally.md} +3 -3
- package/knowledge/decisions/internals/{ai-agent-voice-input-transcribes-audio-parts-in-place.md → agent-voice-input-transcribes-audio-parts-in-place.md} +2 -2
- package/knowledge/decisions/internals/{ai-agent-working-memory-is-persisted-only-when-valid.md → agent-working-memory-is-persisted-only-when-valid.md} +2 -2
- package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +1 -1
- package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +2 -2
- package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +3 -3
- package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +2 -2
- package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +1 -1
- package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.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/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +1 -1
- package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +1 -1
- package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.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-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +1 -1
- package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +5 -5
- package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +1 -1
- package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +2 -2
- package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +1 -1
- package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +2 -2
- 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/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.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-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/{ai-agent-approval-forwarding-requires-a-symbol-brand.md → agent-approval-forwarding-requires-a-symbol-brand.md} +3 -3
- package/knowledge/decisions/security/{ai-agent-credential-requests-are-symbol-branded.md → agent-credential-requests-are-symbol-branded.md} +4 -4
- package/knowledge/decisions/security/{ai-agent-gate-requires-a-session-only-when-auth-is-true.md → agent-gate-requires-a-session-only-when-auth-is-true.md} +4 -4
- package/knowledge/decisions/security/{ai-agent-ownership-failures-never-echo-the-resource.md → agent-ownership-failures-never-echo-the-resource.md} +2 -2
- package/knowledge/decisions/security/{ai-agent-resume-re-runs-the-authorization-gate.md → agent-resume-re-runs-the-authorization-gate.md} +4 -4
- package/knowledge/decisions/security/{ai-agent-sessionless-deployments-have-no-thread-ownership.md → agent-sessionless-deployments-have-no-thread-ownership.md} +5 -5
- package/knowledge/decisions/security/{ai-agent-thread-ownership-composes-the-session-principal.md → agent-thread-ownership-composes-the-session-principal.md} +2 -2
- package/knowledge/decisions/security/{ai-agent-tool-filtering-reads-the-live-function-config.md → agent-tool-filtering-reads-the-live-function-config.md} +2 -2
- package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +3 -3
- package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +3 -3
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +3 -3
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +21 -13
- 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 +3 -2
- 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 +2 -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 +16 -14
- 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 +37 -47
- package/src/agent-naming.test.ts +68 -0
- 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/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 +6 -4
- package/src/public-surface.json +90 -170
- package/src/public-surface.json.README +20 -2
- package/src/public-surface.test.ts +31 -3
- package/src/remote.test.ts +1 -1
- package/src/removed-legacy-exports.test.ts +5 -1
- package/src/services/{ai-run-state-service.ts → agent-run-state-service.ts} +5 -5
- package/src/services/{ai-agent-runner-service.ts → agent-runner-service.ts} +18 -18
- package/src/services/{ai-storage-service.ts → agent-storage-service.ts} +7 -7
- 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/http-personas-converse.test.ts +3 -3
- package/src/services/http-personas.ts +4 -4
- package/src/services/{in-memory-ai-run-state-service.ts → in-memory-agent-run-state-service.ts} +7 -7
- package/src/services/in-memory-workflow-service.ts +1 -1
- package/src/services/index.ts +22 -10
- 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 +5 -5
- 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/testing/service-tests/agent-run-service-tests.ts +4 -4
- package/src/testing/service-tests/{ai-storage-service-tests.ts → agent-storage-service-tests.ts} +8 -8
- package/src/testing/service-tests.ts +10 -8
- package/src/types/core.types.ts +40 -292
- package/src/types/index.ts +2 -0
- package/src/types/state.types.ts +12 -14
- package/src/types/typed-credentials.test.ts +72 -0
- package/src/utils.ts +34 -0
- package/src/wirings/actor-flow/run-conversation.test.ts +2 -2
- package/src/wirings/actor-flow/run-conversation.ts +7 -9
- 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/{ai-agent/ai-agent-agui.test.ts → agent/agent-agui.test.ts} +126 -105
- package/src/wirings/{ai-agent/ai-agent-agui.ts → agent/agent-agui.ts} +7 -7
- package/src/wirings/{ai-agent/ai-agent-authorization.test.ts → agent/agent-authorization.test.ts} +6 -6
- package/src/wirings/{ai-agent/ai-agent-finalize.test.ts → agent/agent-finalize.test.ts} +17 -16
- package/src/wirings/{ai-agent/ai-agent-finalize.ts → agent/agent-finalize.ts} +22 -22
- package/src/wirings/{ai-agent/ai-agent-helpers.test.ts → agent/agent-helpers.test.ts} +1 -1
- package/src/wirings/{ai-agent/ai-agent-helpers.ts → agent/agent-helpers.ts} +1 -1
- package/src/wirings/{ai-agent/ai-agent-interrupt.test.ts → agent/agent-interrupt.test.ts} +67 -77
- package/src/wirings/{ai-agent/ai-agent-interrupt.ts → agent/agent-interrupt.ts} +5 -5
- package/src/wirings/{ai-agent/ai-agent-memory.test.ts → agent/agent-memory.test.ts} +12 -12
- package/src/wirings/{ai-agent/ai-agent-memory.ts → agent/agent-memory.ts} +36 -36
- package/src/wirings/{ai-agent/ai-agent-model-config.test.ts → agent/agent-model-config.test.ts} +2 -5
- package/src/wirings/{ai-agent/ai-agent-model-config.ts → agent/agent-model-config.ts} +1 -1
- package/src/wirings/{ai-agent/ai-agent-prepare.test.ts → agent/agent-prepare.test.ts} +18 -18
- package/src/wirings/{ai-agent/ai-agent-prepare.ts → agent/agent-prepare.ts} +60 -56
- package/src/wirings/{ai-agent/ai-agent-registry.test.ts → agent/agent-registry.test.ts} +49 -43
- package/src/wirings/{ai-agent/ai-agent-registry.ts → agent/agent-registry.ts} +14 -14
- package/src/wirings/{ai-agent/ai-agent-resume-authorization.test.ts → agent/agent-resume-authorization.test.ts} +18 -18
- package/src/wirings/{ai-agent → agent}/agent-rpc.ts +16 -20
- package/src/wirings/{ai-agent/ai-agent-runner.test.ts → agent/agent-runner.test.ts} +105 -106
- package/src/wirings/{ai-agent/ai-agent-runner.ts → agent/agent-runner.ts} +91 -82
- package/src/wirings/{ai-agent/ai-agent-stream-output-hooks.test.ts → agent/agent-stream-output-hooks.test.ts} +25 -25
- package/src/wirings/{ai-agent/ai-agent-stream.test.ts → agent/agent-stream.test.ts} +147 -143
- package/src/wirings/{ai-agent/ai-agent-stream.ts → agent/agent-stream.ts} +148 -148
- package/src/wirings/{ai-agent/ai-agent-thread-ownership.test.ts → agent/agent-thread-ownership.test.ts} +24 -28
- package/src/wirings/{ai-agent/ai-agent-turn.test.ts → agent/agent-turn.test.ts} +3 -5
- package/src/wirings/{ai-agent/ai-agent-turn.ts → agent/agent-turn.ts} +7 -7
- package/src/wirings/agent/agent-utils.ts +20 -0
- package/src/wirings/{ai-agent/ai-agent.types.ts → agent/agent.types.ts} +54 -51
- package/src/wirings/agent/index.ts +57 -0
- package/src/wirings/{ai-agent → agent}/voice-input.test.ts +15 -15
- package/src/wirings/{ai-agent → agent}/voice-input.ts +11 -11
- package/src/wirings/{ai-agent → agent}/voice-output.test.ts +25 -27
- package/src/wirings/{ai-agent → agent}/voice-output.ts +11 -11
- package/src/wirings/{ai-scorer/ai-scorer-grade.test.ts → agent-scorer/agent-scorer-grade.test.ts} +8 -8
- package/src/wirings/{ai-scorer/ai-scorer-grade.ts → agent-scorer/agent-scorer-grade.ts} +9 -9
- package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +285 -0
- package/src/wirings/agent-scorer/agent-scorer-judge.ts +180 -0
- package/src/wirings/{ai-scorer/ai-scorer-live.test.ts → agent-scorer/agent-scorer-live.test.ts} +11 -11
- package/src/wirings/{ai-scorer/ai-scorer-live.ts → agent-scorer/agent-scorer-live.ts} +3 -3
- package/src/wirings/{ai-scorer/ai-scorer-registry.ts → agent-scorer/agent-scorer-registry.ts} +11 -8
- package/src/wirings/{ai-scorer/ai-scorer-sampling.test.ts → agent-scorer/agent-scorer-sampling.test.ts} +1 -1
- package/src/wirings/{ai-scorer/ai-scorer-snapshots.test.ts → agent-scorer/agent-scorer-snapshots.test.ts} +2 -2
- package/src/wirings/{ai-scorer/ai-scorer-snapshots.ts → agent-scorer/agent-scorer-snapshots.ts} +1 -1
- package/src/wirings/{ai-scorer/ai-scorer-worker.test.ts → agent-scorer/agent-scorer-worker.test.ts} +15 -15
- package/src/wirings/{ai-scorer/ai-scorer-worker.ts → agent-scorer/agent-scorer-worker.ts} +9 -7
- package/src/wirings/{ai-scorer/ai-scorer.ts → agent-scorer/agent-scorer.ts} +15 -7
- package/src/wirings/{ai-scorer/ai-scorer.types.ts → agent-scorer/agent-scorer.types.ts} +27 -6
- package/src/wirings/agent-scorer/index.ts +23 -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 +3 -7
- 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 +5 -5
- package/src/wirings/rpc/rpc-types.ts +1 -1
- 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 +23 -0
- package/src/wirings/variable/validate-variable-definitions.ts +2 -0
- package/src/wirings/variable/variable.types.ts +9 -0
- package/src/wirings/virtual-user/index.ts +1 -4
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +2 -2
- package/src/wirings/virtual-user/run-virtual-user.test.ts +2 -2
- package/src/wirings/virtual-user/run-virtual-user.ts +3 -3
- package/src/wirings/virtual-user/virtual-user-agents.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 +59 -19
- package/src/wirings/workflow/pikku-workflow-service.ts +6 -8
- package/src/wirings/workflow/run-timeline.ts +2 -2
- 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.types.ts +4 -12
- package/src/wirings-stay-decoupled.test.ts +7 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/tsconfig.type-tests.json +3 -2
- package/dist/testing/service-tests/ai-storage-service-tests.d.ts +0 -3
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +0 -16
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +0 -7
- 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/index.d.ts +0 -12
- package/dist/wirings/ai-agent/index.js +0 -10
- package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +0 -17
- 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.ts +0 -40
- package/src/index.ts +0 -255
- package/src/wirings/ai-agent/ai-agent-utils.ts +0 -1
- package/src/wirings/ai-agent/index.ts +0 -65
- package/src/wirings/ai-scorer/ai-scorer-judge.test.ts +0 -143
- package/src/wirings/ai-scorer/ai-scorer-judge.ts +0 -120
- package/src/wirings/ai-scorer/index.ts +0 -24
- /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 → ecosystem/gateway.js} +0 -0
- /package/dist/{wirings/ai-agent/ai-agent.types.js → ecosystem/node.js} +0 -0
- /package/dist/wirings/{ai-agent/ai-agent-helpers.js → agent/agent-helpers.js} +0 -0
- /package/dist/wirings/{ai-agent/ai-agent-model-config.d.ts → agent/agent-model-config.d.ts} +0 -0
- /package/dist/wirings/{ai-agent → agent}/agent-rpc.d.ts +0 -0
- /package/dist/wirings/{ai-scorer/ai-scorer-sampling.d.ts → agent-scorer/agent-scorer-sampling.d.ts} +0 -0
- /package/dist/wirings/{ai-scorer/ai-scorer-sampling.js → agent-scorer/agent-scorer-sampling.js} +0 -0
- /package/dist/wirings/{ai-scorer/ai-scorer-snapshots.js → agent-scorer/agent-scorer-snapshots.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
- /package/src/wirings/{ai-scorer/ai-scorer-sampling.ts → agent-scorer/agent-scorer-sampling.ts} +0 -0
|
@@ -36,10 +36,31 @@ 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
62
|
export type * from './scenario.types.js'
|
|
63
|
+
export type * from './scenario-run.types.js'
|
|
43
64
|
export { SCENARIO_SURFACES } from './scenario-step.types.js'
|
|
44
65
|
|
|
45
66
|
// Which of a step's bindings run: one for an action, every witness for a `then`
|
|
@@ -50,7 +71,7 @@ export { createCookieJar } from './scenario-cookie-jar.js'
|
|
|
50
71
|
export type { ScenarioCookieJar } from './scenario-cookie-jar.js'
|
|
51
72
|
export { composeStepProse, renderStepTemplate } from './scenario-prose.js'
|
|
52
73
|
|
|
53
|
-
export {
|
|
74
|
+
export { requireScenarioEnv } from './scenario-step-guards.js'
|
|
54
75
|
|
|
55
76
|
export type {
|
|
56
77
|
ScenarioHttpResponse,
|
|
@@ -171,20 +192,24 @@ addError(ScenarioBrowserUnavailable, {
|
|
|
171
192
|
})
|
|
172
193
|
|
|
173
194
|
/**
|
|
174
|
-
* A
|
|
175
|
-
*
|
|
195
|
+
* A step that is driven by a persona was dispatched without one.
|
|
196
|
+
*
|
|
197
|
+
* Raised before the body runs rather than partway through it: the step declared
|
|
198
|
+
* that it needs an actor — by having a `browser` binding, which cannot be
|
|
199
|
+
* provisioned without a window to open, or by `actor: true` — so a call site
|
|
200
|
+
* that omits one is a mistake at the call site.
|
|
176
201
|
*/
|
|
177
|
-
export class
|
|
202
|
+
export class ScenarioActorRequired extends PikkuError {
|
|
178
203
|
constructor(public readonly stepFunc: string) {
|
|
179
204
|
super(
|
|
180
|
-
`[scenario] step '${stepFunc}'
|
|
181
|
-
`Pass { actor: actors.<name> } so
|
|
205
|
+
`[scenario] step '${stepFunc}' is driven by a persona but was called without an actor. ` +
|
|
206
|
+
`Pass { actor: actors.<name> } so it runs as that persona.`
|
|
182
207
|
)
|
|
183
208
|
}
|
|
184
209
|
}
|
|
185
|
-
addError(
|
|
210
|
+
addError(ScenarioActorRequired, {
|
|
186
211
|
status: 500,
|
|
187
|
-
message: '
|
|
212
|
+
message: 'This step needs an actor.',
|
|
188
213
|
})
|
|
189
214
|
|
|
190
215
|
/**
|
|
@@ -480,8 +505,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
480
505
|
let wireServices: Record<string, unknown> | undefined
|
|
481
506
|
try {
|
|
482
507
|
wireServices = (await createWireServices?.(singletonServices, wire)) as
|
|
483
|
-
|
|
484
|
-
| undefined
|
|
508
|
+
Record<string, unknown> | undefined
|
|
485
509
|
const services =
|
|
486
510
|
wireServices && Object.keys(wireServices).length > 0
|
|
487
511
|
? { ...singletonServices, ...wireServices }
|
|
@@ -602,7 +626,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
602
626
|
await new Promise((resolve) => setTimeout(resolve, interval))
|
|
603
627
|
}
|
|
604
628
|
},
|
|
605
|
-
options
|
|
629
|
+
assertionStep(options)
|
|
606
630
|
)
|
|
607
631
|
},
|
|
608
632
|
|
|
@@ -645,7 +669,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
645
669
|
`[workflow] expectError '${stepName}' ('${resolvedRpcName}') expected an error but the call succeeded: ${JSON.stringify(result)?.slice(0, 300)}`
|
|
646
670
|
)
|
|
647
671
|
},
|
|
648
|
-
options
|
|
672
|
+
assertionStep(options)
|
|
649
673
|
)
|
|
650
674
|
},
|
|
651
675
|
|
|
@@ -700,7 +724,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
700
724
|
)
|
|
701
725
|
}
|
|
702
726
|
},
|
|
703
|
-
options
|
|
727
|
+
assertionStep(options)
|
|
704
728
|
)
|
|
705
729
|
},
|
|
706
730
|
|
|
@@ -745,7 +769,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
745
769
|
}
|
|
746
770
|
return grade
|
|
747
771
|
},
|
|
748
|
-
options
|
|
772
|
+
assertionStep(options)
|
|
749
773
|
)
|
|
750
774
|
},
|
|
751
775
|
|
|
@@ -814,6 +838,10 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
814
838
|
this.scenarioStepDescription(packageName, resolvedStepFunc) ??
|
|
815
839
|
stepName
|
|
816
840
|
|
|
841
|
+
if (!actor && this.requiresActor(packageName, resolvedStepFunc)) {
|
|
842
|
+
throw new ScenarioActorRequired(resolvedStepFunc)
|
|
843
|
+
}
|
|
844
|
+
|
|
817
845
|
const declared = this.declaredSurfaces(packageName, resolvedStepFunc)
|
|
818
846
|
const resolution = resolveScenarioSurfaces(phase, declared, this.runSurface)
|
|
819
847
|
|
|
@@ -828,13 +856,13 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
828
856
|
scenario: workflowWire,
|
|
829
857
|
pikkuUserId: workflowWire.pikkuUserId,
|
|
830
858
|
actors: this.runActors.get(runId),
|
|
859
|
+
...(actor ? { actor } : {}),
|
|
831
860
|
scenarioStep: {
|
|
832
861
|
name: resolvedStepFunc,
|
|
833
862
|
stepName,
|
|
834
863
|
runId,
|
|
835
864
|
phase,
|
|
836
865
|
surface,
|
|
837
|
-
actor,
|
|
838
866
|
env: this.scenarioEnvironment,
|
|
839
867
|
},
|
|
840
868
|
}
|
|
@@ -842,11 +870,10 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
842
870
|
if (!this.scenarioBrowserProvider) {
|
|
843
871
|
throw new ScenarioBrowserUnavailable(resolvedStepFunc)
|
|
844
872
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
873
|
+
// The dispatch guard above already refused an actor-less call, and a
|
|
874
|
+
// browser binding always requires one.
|
|
848
875
|
wire.browser = await this.scenarioBrowserProvider.sessionFor(
|
|
849
|
-
actor
|
|
876
|
+
actor!.name
|
|
850
877
|
)
|
|
851
878
|
}
|
|
852
879
|
return await runPikkuFunc(
|
|
@@ -947,4 +974,17 @@ export class PikkuScenarioService implements WorkflowRunExtension {
|
|
|
947
974
|
const surfaces = this.scenarioStepConfig(packageName, stepFunc)?.surfaces
|
|
948
975
|
return surfaces?.length ? surfaces : ['default']
|
|
949
976
|
}
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* Whether a step is driven by a persona, and so must be given one. Stamped by
|
|
980
|
+
* the definer from a `browser` binding or an explicit `actor: true`.
|
|
981
|
+
*/
|
|
982
|
+
private requiresActor(
|
|
983
|
+
packageName: string | null,
|
|
984
|
+
stepFunc: string
|
|
985
|
+
): boolean {
|
|
986
|
+
return (
|
|
987
|
+
this.scenarioStepConfig(packageName, stepFunc)?.requiresActor === true
|
|
988
|
+
)
|
|
989
|
+
}
|
|
950
990
|
}
|
|
@@ -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'
|
|
@@ -1352,9 +1350,9 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
1352
1350
|
if (stepName in workflowMeta.nodes) {
|
|
1353
1351
|
graphNodeId = stepName
|
|
1354
1352
|
} else {
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
|
|
1353
|
+
const base = stripInstanceOrdinal(stepName)
|
|
1354
|
+
if (base !== stepName && base in workflowMeta.nodes)
|
|
1355
|
+
graphNodeId = base
|
|
1358
1356
|
}
|
|
1359
1357
|
}
|
|
1360
1358
|
if (graphNodeId) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SerializedError } from '../../
|
|
1
|
+
import type { SerializedError } from '../../errors/serialized-error.js'
|
|
2
2
|
import type { StepState, StepStatus } from './workflow.types.js'
|
|
3
3
|
|
|
4
4
|
export interface RunTimelineEvent {
|
|
@@ -17,7 +17,7 @@ export interface RunTimelineEvent {
|
|
|
17
17
|
|
|
18
18
|
export type RunTimeline = RunTimelineEvent[]
|
|
19
19
|
|
|
20
|
-
type HistoryEntry = StepState & { stepName: string }
|
|
20
|
+
export type HistoryEntry = StepState & { stepName: string }
|
|
21
21
|
|
|
22
22
|
const LIFECYCLE_ORDER: Record<RunTimelineEvent['type'], number> = {
|
|
23
23
|
pending: 0,
|
|
@@ -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) {
|
|
@@ -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 () => {
|