@pikku/core 0.12.78 → 0.12.80
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 +234 -0
- package/dist/dev/hot-reload.js +1 -6
- package/dist/ecosystem.d.ts +27 -0
- package/dist/ecosystem.js +26 -0
- package/dist/errors/error-handler.js +4 -2
- package/dist/function/function-runner.js +20 -42
- package/dist/function/functions.types.d.ts +9 -5
- package/dist/index.d.ts +4 -9
- package/dist/index.js +3 -8
- package/dist/middleware/auth-cookie.d.ts +0 -4
- package/dist/middleware/auth-cookie.js +38 -2
- package/dist/middleware/cors.js +1 -0
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/middleware/remote-auth.js +14 -3
- package/dist/permissions.d.ts +8 -10
- package/dist/permissions.js +0 -11
- package/dist/pikku-state.js +12 -5
- package/dist/schema.js +35 -1
- package/dist/services/ai-run-state-service.d.ts +7 -1
- package/dist/services/in-memory-ai-run-state-service.d.ts +1 -1
- package/dist/services/in-memory-ai-run-state-service.js +2 -1
- package/dist/services/in-memory-workflow-service.d.ts +10 -0
- package/dist/services/in-memory-workflow-service.js +25 -0
- package/dist/services/local-content-request-handler.d.ts +21 -0
- package/dist/services/local-content-request-handler.js +72 -53
- package/dist/services/local-content.d.ts +6 -0
- package/dist/services/local-content.js +14 -1
- package/dist/services/workflow-service.d.ts +4 -2
- package/dist/testing/service-tests/agent-run-service-tests.d.ts +10 -0
- package/dist/testing/service-tests/agent-run-service-tests.js +72 -0
- package/dist/testing/service-tests/ai-storage-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/ai-storage-service-tests.js +226 -0
- package/dist/testing/service-tests/channel-store-tests.d.ts +3 -0
- package/dist/testing/service-tests/channel-store-tests.js +72 -0
- package/dist/testing/service-tests/credential-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/credential-service-tests.js +109 -0
- package/dist/testing/service-tests/deployment-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/deployment-service-tests.js +21 -0
- package/dist/testing/service-tests/event-hub-store-tests.d.ts +3 -0
- package/dist/testing/service-tests/event-hub-store-tests.js +34 -0
- package/dist/testing/service-tests/secret-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/secret-service-tests.js +80 -0
- package/dist/testing/service-tests/session-store-tests.d.ts +3 -0
- package/dist/testing/service-tests/session-store-tests.js +43 -0
- package/dist/testing/service-tests/workflow-run-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/workflow-run-service-tests.js +42 -0
- package/dist/testing/service-tests/workflow-service-tests.d.ts +3 -0
- package/dist/testing/service-tests/workflow-service-tests.js +150 -0
- package/dist/testing/service-tests.d.ts +6 -0
- package/dist/testing/service-tests.js +26 -791
- package/dist/types/core.types.d.ts +11 -1
- package/dist/types/state.types.d.ts +1 -1
- package/dist/utils/node-host-resolver.d.ts +12 -0
- package/dist/utils/node-host-resolver.js +16 -0
- package/dist/utils/safe-fetch.d.ts +18 -0
- package/dist/utils/safe-fetch.js +167 -29
- package/dist/wirings/actor-flow/run-conversation.js +1 -6
- package/dist/wirings/ai-agent/agent-rpc.d.ts +15 -0
- package/dist/wirings/ai-agent/agent-rpc.js +53 -0
- package/dist/wirings/ai-agent/ai-agent-agui.js +1 -5
- package/dist/wirings/ai-agent/ai-agent-memory.js +3 -1
- package/dist/wirings/ai-agent/ai-agent-prepare.js +3 -9
- package/dist/wirings/ai-agent/ai-agent-runner.js +28 -107
- package/dist/wirings/ai-agent/ai-agent-stream.js +20 -61
- package/dist/wirings/ai-agent/ai-agent-turn.d.ts +56 -0
- package/dist/wirings/ai-agent/ai-agent-turn.js +81 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +1 -1
- package/dist/wirings/ai-agent/voice-input.js +1 -6
- package/dist/wirings/ai-agent/voice-output.js +2 -12
- package/dist/wirings/channel/channel-common.js +1 -0
- package/dist/wirings/channel/channel-handler.js +3 -5
- package/dist/wirings/channel/channel-rpc-service.d.ts +0 -6
- package/dist/wirings/channel/channel-rpc-service.js +0 -8
- package/dist/wirings/channel/channel-rpc.types.d.ts +6 -0
- package/dist/wirings/channel/channel-rpc.types.js +8 -0
- package/dist/wirings/channel/channel-runner.d.ts +1 -3
- package/dist/wirings/channel/channel-runner.js +16 -8
- package/dist/wirings/channel/channel.types.d.ts +2 -0
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +1 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +3 -0
- package/dist/wirings/cli/channel/cli-channel-runner.js +2 -0
- package/dist/wirings/cli/cli-runner.js +4 -2
- package/dist/wirings/cli/cli.types.d.ts +0 -8
- package/dist/wirings/cli/command-parser.js +13 -0
- package/dist/wirings/gateway/gateway-runner.js +41 -5
- package/dist/wirings/http/http-routes.js +2 -0
- package/dist/wirings/http/http-runner.d.ts +0 -10
- package/dist/wirings/http/http-runner.js +6 -13
- package/dist/wirings/http/http.types.d.ts +0 -10
- package/dist/wirings/http/index.d.ts +1 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/mcp/mcp-runner.d.ts +0 -7
- package/dist/wirings/mcp/mcp-runner.js +0 -6
- package/dist/wirings/rpc/rpc-runner.d.ts +8 -51
- package/dist/wirings/rpc/rpc-runner.js +53 -86
- package/dist/wirings/rpc/rpc-types.d.ts +3 -0
- package/dist/wirings/secret/validate-secret-definitions.js +2 -0
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +0 -4
- package/dist/wirings/trigger/trigger-runner.js +1 -0
- package/dist/wirings/virtual-user/run-virtual-user.js +11 -11
- package/dist/wirings/virtual-user/virtual-user-derive.js +4 -25
- package/dist/wirings/virtual-user/virtual-user-dispositions.js +1 -4
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +29 -2
- package/dist/wirings/workflow/feature.js +7 -4
- package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -2
- package/dist/wirings/workflow/graph/graph-runner.js +8 -7
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -4
- package/dist/wirings/workflow/index.d.ts +7 -2
- package/dist/wirings/workflow/index.js +5 -1
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +17 -3
- package/dist/wirings/workflow/pikku-scenario-service.js +38 -10
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +44 -111
- package/dist/wirings/workflow/pikku-workflow-service.js +86 -404
- package/dist/wirings/workflow/workflow-approval.d.ts +39 -0
- package/dist/wirings/workflow/workflow-approval.js +114 -0
- package/dist/wirings/workflow/workflow-constants.d.ts +26 -0
- package/dist/wirings/workflow/workflow-constants.js +35 -0
- package/dist/wirings/workflow/workflow-errors.d.ts +58 -0
- package/dist/wirings/workflow/workflow-errors.js +112 -0
- package/dist/wirings/workflow/workflow-meta-resolver.d.ts +11 -0
- package/dist/wirings/workflow/workflow-meta-resolver.js +31 -0
- package/dist/wirings/workflow/workflow-queue-routing.d.ts +8 -0
- package/dist/wirings/workflow/workflow-queue-routing.js +38 -0
- package/dist/wirings/workflow/workflow-queue-wiring.d.ts +20 -0
- package/dist/wirings/workflow/workflow-queue-wiring.js +79 -0
- package/dist/wirings/workflow/workflow-recovery.d.ts +68 -0
- package/dist/wirings/workflow/workflow-recovery.js +101 -0
- package/dist/wirings/workflow/workflow-run-engine.types.d.ts +54 -0
- package/dist/wirings/workflow/workflow-run-engine.types.js +1 -0
- package/dist/wirings/workflow/workflow-run-ownership.d.ts +16 -0
- package/dist/wirings/workflow/workflow-run-ownership.js +29 -0
- package/dist/wirings/workflow/workflow-suspend.d.ts +12 -0
- package/dist/wirings/workflow/workflow-suspend.js +33 -0
- package/dist/wirings/workflow/workflow.types.d.ts +7 -0
- package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-airunstate-too.md +22 -0
- package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +20 -0
- package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +21 -0
- package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +21 -0
- package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +46 -0
- package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +45 -0
- package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +21 -0
- package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +22 -0
- package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +23 -0
- package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +25 -0
- package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +22 -0
- package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +20 -0
- package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +22 -0
- package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +66 -0
- package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +33 -0
- package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +43 -0
- package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +26 -0
- package/knowledge/decisions/internals/index.md +38 -26
- package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +21 -0
- package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +24 -0
- package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +34 -0
- package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +24 -0
- package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +22 -0
- package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +26 -0
- package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +43 -0
- package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +58 -0
- package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +40 -0
- package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +40 -0
- package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +28 -0
- package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +25 -0
- package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +21 -0
- package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +22 -0
- package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +25 -0
- package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +21 -0
- package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +24 -0
- package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +35 -0
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +4 -2
- package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +33 -0
- package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +33 -0
- package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +37 -0
- package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +28 -0
- package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +34 -0
- package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +33 -0
- package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +24 -0
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +13 -3
- package/knowledge/decisions/security/index.md +7 -0
- package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +35 -0
- package/knowledge/questions/index.md +2 -1
- package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +44 -0
- package/package.json +14 -3
- package/scripts/generate-api-report.d.mts +1 -0
- package/scripts/generate-api-report.mjs +89 -0
- package/scripts/generate-api-report.mts +218 -0
- package/src/api-report.test.ts +69 -0
- package/src/column-form.ts +1 -4
- package/src/crypto-utils.test.ts +15 -2
- package/src/dev/hot-reload.ts +2 -7
- package/src/ecosystem.ts +40 -0
- package/src/errors/error-handler.ts +5 -3
- package/src/errors/error.test.ts +4 -1
- package/src/function/function-runner.test.ts +1 -1
- package/src/function/function-runner.ts +28 -39
- package/src/function/functions.types.ts +15 -9
- package/src/handle-error.ts +1 -1
- package/src/index.ts +3 -22
- package/src/middleware/auth-cookie.test.ts +50 -0
- package/src/middleware/auth-cookie.ts +38 -2
- package/src/middleware/cors.ts +2 -1
- package/src/middleware/index.ts +1 -1
- package/src/middleware/remote-auth.test.ts +43 -0
- package/src/middleware/remote-auth.ts +17 -3
- package/src/middleware-runner.ts +4 -2
- package/src/no-any-casts.test.ts +57 -0
- package/src/permissions.test.ts +3 -1
- package/src/permissions.ts +22 -24
- package/src/pikku-state.ts +17 -6
- package/src/public-surface.json +578 -0
- package/src/public-surface.json.README +25 -0
- package/src/public-surface.test.ts +105 -0
- package/src/removed-legacy-exports.test.ts +62 -0
- package/src/schema.test.ts +78 -0
- package/src/schema.ts +36 -1
- package/src/services/ai-run-state-service.ts +7 -1
- package/src/services/audit-service.ts +2 -2
- package/src/services/in-memory-ai-run-state-service.ts +3 -2
- package/src/services/in-memory-workflow-service.ts +25 -0
- package/src/services/index.ts +1 -4
- package/src/services/local-content-request-handler.test.ts +43 -5
- package/src/services/local-content-request-handler.ts +103 -74
- package/src/services/local-content.ts +15 -1
- package/src/services/local-email-service.ts +5 -1
- package/src/services/system-role-guard.test.ts +4 -1
- package/src/services/workflow-service.ts +9 -2
- package/src/side-effects-are-declared.test.ts +84 -0
- package/src/source-files-stay-composable.test.ts +41 -0
- package/src/testing/service-tests/agent-run-service-tests.ts +98 -0
- package/src/testing/service-tests/ai-storage-service-tests.ts +286 -0
- package/src/testing/service-tests/channel-store-tests.ts +98 -0
- package/src/testing/service-tests/credential-service-tests.ts +143 -0
- package/src/testing/service-tests/deployment-service-tests.ts +33 -0
- package/src/testing/service-tests/event-hub-store-tests.ts +48 -0
- package/src/testing/service-tests/secret-service-tests.ts +105 -0
- package/src/testing/service-tests/session-store-tests.ts +62 -0
- package/src/testing/service-tests/workflow-run-service-tests.ts +59 -0
- package/src/testing/service-tests/workflow-service-tests.ts +308 -0
- package/src/testing/service-tests.ts +31 -1111
- package/src/types/core.types.ts +15 -1
- package/src/types/state.types.ts +1 -1
- package/src/utils/node-host-resolver.ts +20 -0
- package/src/utils/safe-fetch.test.ts +143 -1
- package/src/utils/safe-fetch.ts +200 -25
- package/src/wirings/actor-flow/run-conversation.ts +1 -6
- package/src/wirings/ai-agent/agent-rpc.ts +120 -0
- package/src/wirings/ai-agent/ai-agent-agui.ts +1 -5
- package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +2 -1
- package/src/wirings/ai-agent/ai-agent-memory.ts +8 -1
- package/src/wirings/ai-agent/ai-agent-prepare.ts +10 -12
- package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +1 -0
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +82 -2
- package/src/wirings/ai-agent/ai-agent-runner.ts +49 -120
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +2 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +36 -63
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +1 -1
- package/src/wirings/ai-agent/ai-agent-turn.ts +121 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +1 -1
- package/src/wirings/ai-agent/voice-input.ts +1 -6
- package/src/wirings/ai-agent/voice-output.ts +2 -12
- package/src/wirings/channel/channel-common.ts +5 -2
- package/src/wirings/channel/channel-handler-shapes.test.ts +72 -0
- package/src/wirings/channel/channel-handler.ts +7 -7
- package/src/wirings/channel/channel-rpc-service.ts +0 -14
- package/src/wirings/channel/channel-rpc.test.ts +25 -4
- package/src/wirings/channel/channel-rpc.types.ts +14 -0
- package/src/wirings/channel/channel-runner.ts +33 -20
- package/src/wirings/channel/channel.types.ts +2 -0
- package/src/wirings/channel/local/local-channel-runner.ts +1 -1
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +2 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +6 -3
- package/src/wirings/cli/channel/cli-channel-runner.ts +3 -1
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +4 -1
- package/src/wirings/cli/cli-runner.ts +7 -4
- package/src/wirings/cli/cli.types.ts +0 -39
- package/src/wirings/cli/command-parser.test.ts +19 -0
- package/src/wirings/cli/command-parser.ts +17 -1
- package/src/wirings/gateway/gateway-authorization.test.ts +131 -0
- package/src/wirings/gateway/gateway-channel-meta.test.ts +44 -0
- package/src/wirings/gateway/gateway-runner.ts +62 -22
- package/src/wirings/http/http-routes.ts +4 -1
- package/src/wirings/http/http-runner.ts +11 -26
- package/src/wirings/http/http.types.ts +0 -15
- package/src/wirings/http/index.ts +1 -7
- package/src/wirings/http/pikku-fetch-http-request.ts +2 -2
- package/src/wirings/http/web-request.ts +1 -1
- package/src/wirings/mcp/mcp-runner.ts +2 -16
- package/src/wirings/persona/persona-environments.test.ts +14 -3
- package/src/wirings/persona/persona.test.ts +13 -3
- package/src/wirings/persona/validate-personas.ts +5 -1
- package/src/wirings/queue/queue-runner.ts +1 -1
- package/src/wirings/rpc/addon-auth-tags.test.ts +1 -5
- package/src/wirings/rpc/rpc-runner.ts +58 -136
- package/src/wirings/rpc/rpc-types.ts +7 -0
- package/src/wirings/rpc/wire-addon.ts +3 -1
- package/src/wirings/secret/validate-secret-definitions.test.ts +69 -0
- package/src/wirings/secret/validate-secret-definitions.ts +2 -0
- package/src/wirings/trigger/pikku-trigger-service.ts +0 -5
- package/src/wirings/trigger/trigger-runner.ts +7 -5
- package/src/wirings/virtual-user/run-virtual-user.test.ts +18 -9
- package/src/wirings/virtual-user/run-virtual-user.ts +28 -15
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +4 -1
- package/src/wirings/virtual-user/virtual-user-derive.ts +4 -25
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +7 -2
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +1 -4
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +13 -3
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +35 -2
- package/src/wirings/workflow/feature.ts +7 -4
- package/src/wirings/workflow/graph/graph-node.ts +1 -1
- package/src/wirings/workflow/graph/graph-runner.test.ts +4 -2
- package/src/wirings/workflow/graph/graph-runner.ts +13 -16
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -5
- package/src/wirings/workflow/index.ts +12 -4
- package/src/wirings/workflow/pikku-scenario-service.ts +54 -25
- package/src/wirings/workflow/pikku-workflow-service.test.ts +2 -2
- package/src/wirings/workflow/pikku-workflow-service.ts +208 -630
- package/src/wirings/workflow/scenario-hooks.test.ts +51 -0
- package/src/wirings/workflow/workflow-approval.ts +185 -0
- package/src/wirings/workflow/workflow-child-run-session.test.ts +89 -0
- package/src/wirings/workflow/workflow-constants.ts +47 -0
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +1 -1
- package/src/wirings/workflow/workflow-dispatch-relay.test.ts +128 -0
- package/src/wirings/workflow/workflow-errors.ts +128 -0
- package/src/wirings/workflow/workflow-inline-authority.test.ts +12 -6
- package/src/wirings/workflow/workflow-meta-resolver.ts +45 -0
- package/src/wirings/workflow/workflow-missing-meta.test.ts +92 -0
- package/src/wirings/workflow/workflow-queue-routing.ts +85 -0
- package/src/wirings/workflow/workflow-queue-wiring.ts +149 -0
- package/src/wirings/workflow/workflow-recovery.ts +162 -0
- package/src/wirings/workflow/workflow-retry-policy.test.ts +1 -1
- package/src/wirings/workflow/workflow-run-authority.test.ts +215 -0
- package/src/wirings/workflow/workflow-run-engine.types.ts +91 -0
- package/src/wirings/workflow/workflow-run-ownership.ts +36 -0
- package/src/wirings/workflow/workflow-suspend.ts +61 -0
- package/src/wirings/workflow/workflow.types.ts +7 -0
- package/src/wirings-stay-decoupled.test.ts +123 -0
- package/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/src/internal.ts +0 -10
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, test, before } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
/** Conformance suite for `workflowRunService`. Runs only when a backend supplies one. */
|
|
4
|
+
export const defineWorkflowRunServiceTests = (name, workflowRunService) => {
|
|
5
|
+
const factory = workflowRunService;
|
|
6
|
+
describe(`WorkflowRunService [${name}]`, () => {
|
|
7
|
+
let runService;
|
|
8
|
+
before(async () => {
|
|
9
|
+
runService = await factory();
|
|
10
|
+
});
|
|
11
|
+
test('listRuns returns runs', async () => {
|
|
12
|
+
const runs = await runService.listRuns();
|
|
13
|
+
assert.ok(Array.isArray(runs));
|
|
14
|
+
assert.ok(runs.length > 0);
|
|
15
|
+
});
|
|
16
|
+
test('listRuns with filter', async () => {
|
|
17
|
+
const runs = await runService.listRuns({
|
|
18
|
+
workflowName: 'test-workflow',
|
|
19
|
+
});
|
|
20
|
+
assert.ok(runs.every((r) => r.workflow === 'test-workflow'));
|
|
21
|
+
});
|
|
22
|
+
test('getDistinctWorkflowNames', async () => {
|
|
23
|
+
const names = await runService.getDistinctWorkflowNames();
|
|
24
|
+
assert.ok(Array.isArray(names));
|
|
25
|
+
assert.ok(names.includes('test-workflow'));
|
|
26
|
+
});
|
|
27
|
+
test('deleteRun', async () => {
|
|
28
|
+
const runs = await runService.listRuns({
|
|
29
|
+
workflowName: 'status-workflow',
|
|
30
|
+
});
|
|
31
|
+
assert.ok(runs.length > 0);
|
|
32
|
+
const deleted = await runService.deleteRun(runs[0].id);
|
|
33
|
+
assert.equal(deleted, true);
|
|
34
|
+
const afterDelete = await runService.getRun(runs[0].id);
|
|
35
|
+
assert.equal(afterDelete, null);
|
|
36
|
+
});
|
|
37
|
+
test('deleteRun returns false for missing', async () => {
|
|
38
|
+
const deleted = await runService.deleteRun('non-existent-id');
|
|
39
|
+
assert.equal(deleted, false);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ServiceTestConfig } from '../service-tests.js';
|
|
2
|
+
/** Conformance suite for `workflowService`. Runs only when a backend supplies one. */
|
|
3
|
+
export declare const defineWorkflowServiceTests: (name: string, workflowService: NonNullable<ServiceTestConfig["services"]["workflowService"]>) => void;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { describe, test, before } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
/** Conformance suite for `workflowService`. Runs only when a backend supplies one. */
|
|
4
|
+
export const defineWorkflowServiceTests = (name, workflowService) => {
|
|
5
|
+
const factory = workflowService;
|
|
6
|
+
const wire = { type: 'test' };
|
|
7
|
+
describe(`WorkflowService [${name}]`, () => {
|
|
8
|
+
let service;
|
|
9
|
+
before(async () => {
|
|
10
|
+
service = await factory();
|
|
11
|
+
});
|
|
12
|
+
test('createRun and getRun', async () => {
|
|
13
|
+
const runId = await service.createRun('test-workflow', { key: 'value' }, false, 'hash-1', wire);
|
|
14
|
+
assert.ok(runId);
|
|
15
|
+
const run = await service.getRun(runId);
|
|
16
|
+
assert.ok(run);
|
|
17
|
+
assert.equal(run.workflow, 'test-workflow');
|
|
18
|
+
assert.equal(run.status, 'running');
|
|
19
|
+
assert.deepEqual(run.input, { key: 'value' });
|
|
20
|
+
assert.equal(run.graphHash, 'hash-1');
|
|
21
|
+
});
|
|
22
|
+
test('updateRunStatus', async () => {
|
|
23
|
+
const runId = await service.createRun('status-workflow', {}, false, 'hash-2', wire);
|
|
24
|
+
await service.updateRunStatus(runId, 'completed', { result: 'done' });
|
|
25
|
+
const run = await service.getRun(runId);
|
|
26
|
+
assert.ok(run);
|
|
27
|
+
assert.equal(run.status, 'completed');
|
|
28
|
+
assert.deepEqual(run.output, { result: 'done' });
|
|
29
|
+
});
|
|
30
|
+
test('insertStepState and getStepState', async () => {
|
|
31
|
+
const runId = await service.createRun('step-workflow', {}, false, 'hash-3', wire);
|
|
32
|
+
const step = await service.insertStepState(runId, 'step-1', 'myRpc', { data: 'test' }, { retries: 3, retryDelay: '1000' });
|
|
33
|
+
assert.ok(step.stepId);
|
|
34
|
+
assert.equal(step.status, 'pending');
|
|
35
|
+
assert.equal(step.attemptCount, 1);
|
|
36
|
+
assert.equal(step.retries, 3);
|
|
37
|
+
assert.equal(step.retryDelay, '1000');
|
|
38
|
+
const fetched = await service.getStepState(runId, 'step-1');
|
|
39
|
+
assert.equal(fetched.stepId, step.stepId);
|
|
40
|
+
assert.equal(fetched.status, 'pending');
|
|
41
|
+
assert.equal(fetched.attemptCount, 1);
|
|
42
|
+
});
|
|
43
|
+
test('setStepRunning, setStepResult', async () => {
|
|
44
|
+
const runId = await service.createRun('result-workflow', {}, false, 'hash-4', wire);
|
|
45
|
+
const step = await service.insertStepState(runId, 'result-step', 'myRpc', {});
|
|
46
|
+
await service.setStepRunning(step.stepId);
|
|
47
|
+
let fetched = await service.getStepState(runId, 'result-step');
|
|
48
|
+
assert.equal(fetched.status, 'running');
|
|
49
|
+
await service.setStepResult(step.stepId, { answer: 42 });
|
|
50
|
+
fetched = await service.getStepState(runId, 'result-step');
|
|
51
|
+
assert.equal(fetched.status, 'succeeded');
|
|
52
|
+
assert.deepEqual(fetched.result, { answer: 42 });
|
|
53
|
+
});
|
|
54
|
+
test('setStepError', async () => {
|
|
55
|
+
const runId = await service.createRun('error-workflow', {}, false, 'hash-5', wire);
|
|
56
|
+
const step = await service.insertStepState(runId, 'error-step', 'myRpc', {});
|
|
57
|
+
await service.setStepRunning(step.stepId);
|
|
58
|
+
await service.setStepError(step.stepId, new Error('boom'));
|
|
59
|
+
const fetched = await service.getStepState(runId, 'error-step');
|
|
60
|
+
assert.equal(fetched.status, 'failed');
|
|
61
|
+
assert.equal(fetched.error?.message, 'boom');
|
|
62
|
+
});
|
|
63
|
+
test('createRetryAttempt', async () => {
|
|
64
|
+
const runId = await service.createRun('retry-workflow', {}, false, 'hash-6', wire);
|
|
65
|
+
const step = await service.insertStepState(runId, 'retry-step', 'myRpc', {}, { retries: 2 });
|
|
66
|
+
await service.setStepError(step.stepId, new Error('fail'));
|
|
67
|
+
const retried = await service.createRetryAttempt(step.stepId, 'pending');
|
|
68
|
+
assert.equal(retried.status, 'pending');
|
|
69
|
+
assert.equal(retried.attemptCount, 2);
|
|
70
|
+
assert.equal(retried.error, undefined);
|
|
71
|
+
assert.equal(retried.result, undefined);
|
|
72
|
+
});
|
|
73
|
+
test('getRunStatus reports per-step duration and attempts', async () => {
|
|
74
|
+
const runId = await service.createRun('status-timing-workflow', {}, false, 'hash-timing', wire);
|
|
75
|
+
const step = await service.insertStepState(runId, 'timed-step', 'myRpc', {});
|
|
76
|
+
await service.setStepRunning(step.stepId);
|
|
77
|
+
await service.setStepResult(step.stepId, { ok: true });
|
|
78
|
+
const status = await service.getRunStatus(runId);
|
|
79
|
+
assert.ok(status);
|
|
80
|
+
const timed = status.steps.find((s) => s.name === 'timed-step');
|
|
81
|
+
assert.ok(timed, 'step appears in run status');
|
|
82
|
+
// running→succeeded must stamp runningAt/succeededAt so a duration is
|
|
83
|
+
// computable. Regression guard: the kysely store previously updated
|
|
84
|
+
// only the status on transitions, leaving the timestamps null and
|
|
85
|
+
// duration permanently undefined.
|
|
86
|
+
assert.ok(timed.duration !== undefined, 'duration is computed from stamped transition timestamps');
|
|
87
|
+
assert.ok(timed.duration >= 0, 'duration is non-negative');
|
|
88
|
+
assert.equal(timed.attempts, 1, 'single attempt');
|
|
89
|
+
});
|
|
90
|
+
test('getRunStatus surfaces retried attempt count', async () => {
|
|
91
|
+
const runId = await service.createRun('status-retry-workflow', {}, false, 'hash-retry-status', wire);
|
|
92
|
+
const step = await service.insertStepState(runId, 'flaky-step', 'myRpc', {}, { retries: 2 });
|
|
93
|
+
await service.setStepRunning(step.stepId);
|
|
94
|
+
await service.setStepError(step.stepId, new Error('first try'));
|
|
95
|
+
// Guarantee the retry's history row sorts after the failed attempt so
|
|
96
|
+
// getRunStatus picks the latest attempt (it tie-breaks on timestamps).
|
|
97
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
98
|
+
const retry = await service.createRetryAttempt(step.stepId, 'pending');
|
|
99
|
+
await service.setStepRunning(retry.stepId);
|
|
100
|
+
await service.setStepResult(retry.stepId, { ok: true });
|
|
101
|
+
const status = await service.getRunStatus(runId);
|
|
102
|
+
assert.ok(status);
|
|
103
|
+
const flaky = status.steps.find((s) => s.name === 'flaky-step');
|
|
104
|
+
assert.ok(flaky, 'retried step collapses to a single status entry');
|
|
105
|
+
assert.equal(flaky.status, 'succeeded', 'latest attempt wins');
|
|
106
|
+
assert.equal(flaky.attempts, 2, 'attempt count surfaces in status');
|
|
107
|
+
});
|
|
108
|
+
test('getNodeResults', async () => {
|
|
109
|
+
const runId = await service.createRun('results-workflow', {}, false, 'hash-8', wire);
|
|
110
|
+
const step = await service.insertStepState(runId, 'node-a', 'rpc', {});
|
|
111
|
+
await service.setStepResult(step.stepId, { out: 'hello' });
|
|
112
|
+
const results = await service.getNodeResults(runId, ['node-a']);
|
|
113
|
+
assert.deepEqual(results['node-a'], { out: 'hello' });
|
|
114
|
+
});
|
|
115
|
+
test('setBranchTaken and getCompletedGraphState', async () => {
|
|
116
|
+
const runId = await service.createRun('branch-workflow', {}, false, 'hash-9', wire);
|
|
117
|
+
const step = await service.insertStepState(runId, 'branch-node', 'rpc', {});
|
|
118
|
+
await service.setStepResult(step.stepId, {});
|
|
119
|
+
await service.setBranchTaken(step.stepId, 'left');
|
|
120
|
+
const state = await service.getCompletedGraphState(runId);
|
|
121
|
+
assert.ok(state.completedNodeIds.includes('branch-node'));
|
|
122
|
+
assert.equal(state.branchKeys['branch-node'], 'left');
|
|
123
|
+
});
|
|
124
|
+
test('updateRunState and getRunState', async () => {
|
|
125
|
+
const runId = await service.createRun('state-workflow', {}, false, 'hash-10', wire);
|
|
126
|
+
await service.updateRunState(runId, 'counter', 5);
|
|
127
|
+
await service.updateRunState(runId, 'name', 'test');
|
|
128
|
+
const state = await service.getRunState(runId);
|
|
129
|
+
assert.equal(state.counter, 5);
|
|
130
|
+
assert.equal(state.name, 'test');
|
|
131
|
+
});
|
|
132
|
+
test('upsertWorkflowVersion and getWorkflowVersion', async () => {
|
|
133
|
+
await service.upsertWorkflowVersion('my-workflow', 'v1-hash', { nodes: ['a', 'b'] }, 'dsl');
|
|
134
|
+
const version = await service.getWorkflowVersion('my-workflow', 'v1-hash');
|
|
135
|
+
assert.ok(version);
|
|
136
|
+
assert.deepEqual(version.graph, { nodes: ['a', 'b'] });
|
|
137
|
+
assert.equal(version.source, 'dsl');
|
|
138
|
+
});
|
|
139
|
+
test('upsertWorkflowVersion duplicate is no-op', async () => {
|
|
140
|
+
await service.upsertWorkflowVersion('my-workflow', 'v1-hash', { nodes: ['changed'] }, 'dsl');
|
|
141
|
+
const version = await service.getWorkflowVersion('my-workflow', 'v1-hash');
|
|
142
|
+
assert.ok(version);
|
|
143
|
+
assert.deepEqual(version.graph, { nodes: ['a', 'b'] });
|
|
144
|
+
});
|
|
145
|
+
test('getWorkflowVersion returns null for missing', async () => {
|
|
146
|
+
const version = await service.getWorkflowVersion('missing', 'missing');
|
|
147
|
+
assert.equal(version, null);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
};
|
|
@@ -38,4 +38,10 @@ export interface ServiceTestConfig {
|
|
|
38
38
|
sessionStore?: () => Promise<SessionStore>;
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* The shared conformance suite every storage backend runs.
|
|
43
|
+
*
|
|
44
|
+
* One module per service so a backend author can read the contract for the one
|
|
45
|
+
* they implement; this dispatches to whichever the caller supplied.
|
|
46
|
+
*/
|
|
41
47
|
export declare function defineServiceTests(config: ServiceTestConfig): void;
|