@pikku/core 0.12.106 → 0.12.111
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 +358 -0
- package/dist/analytics/analytics.d.ts +6 -0
- package/dist/analytics/analytics.js +58 -0
- package/dist/analytics/analytics.types.d.ts +156 -0
- package/dist/analytics/analytics.types.js +1 -0
- package/dist/analytics/anonymous-analytics-identity.d.ts +23 -0
- package/dist/analytics/anonymous-analytics-identity.js +27 -0
- package/dist/analytics/compose-analytics-identity.d.ts +14 -0
- package/dist/analytics/compose-analytics-identity.js +33 -0
- package/dist/analytics/cookie-analytics-identity.d.ts +24 -0
- package/dist/analytics/cookie-analytics-identity.js +37 -0
- package/dist/analytics/define-analytics-events.d.ts +22 -0
- package/dist/analytics/define-analytics-events.js +9 -0
- package/dist/analytics/fan-out-analytics.d.ts +15 -0
- package/dist/analytics/fan-out-analytics.js +36 -0
- package/dist/analytics/index.d.ts +13 -0
- package/dist/analytics/index.js +8 -0
- package/dist/analytics/logger-analytics-service.d.ts +14 -0
- package/dist/analytics/logger-analytics-service.js +23 -0
- package/dist/analytics/mint-cookie.d.ts +44 -0
- package/dist/analytics/mint-cookie.js +55 -0
- package/dist/errors/errors.d.ts +7 -0
- package/dist/errors/errors.js +17 -0
- package/dist/function/function-meta.types.d.ts +2 -0
- package/dist/function/function-runner.js +29 -0
- package/dist/function/functions.types.d.ts +22 -3
- package/dist/middleware/auth-apikey.d.ts +1 -1
- package/dist/pikku-state.d.ts +1 -1
- package/dist/scopes.d.ts +11 -0
- package/dist/scopes.js +17 -0
- package/dist/services/credential-wire-service.d.ts +1 -1
- package/dist/services/feature-flag-service.d.ts +100 -0
- package/dist/services/feature-flag-service.js +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/meta-service.d.ts +16 -0
- package/dist/services/meta-service.js +19 -0
- package/dist/services/webhook-service.d.ts +7 -2
- package/dist/services/webhook-service.js +11 -6
- package/dist/testing/service-tests/agent-run-service-tests.d.ts +2 -2
- package/dist/testing/service-tests/agent-storage-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/channel-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/credential-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/deployment-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/event-hub-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/secret-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/session-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-run-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-service-tests.d.ts +1 -1
- package/dist/types/core.types.d.ts +23 -0
- package/dist/wirings/agent/agent-rpc.d.ts +1 -1
- package/dist/wirings/agent/agent-turn.d.ts +1 -1
- package/dist/wirings/agent-scorer/agent-scorer-live.d.ts +1 -1
- package/dist/wirings/channel/channel-common.d.ts +1 -1
- package/dist/wirings/channel/channel-rpc-validators.d.ts +2 -2
- package/dist/wirings/channel/channel-runner.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
- package/dist/wirings/cli/channel/cli-approval.d.ts +2 -2
- package/dist/wirings/flag/assert-feature-available.d.ts +15 -0
- package/dist/wirings/flag/assert-feature-available.js +23 -0
- package/dist/wirings/flag/cached-flag-source.d.ts +73 -0
- package/dist/wirings/flag/cached-flag-source.js +96 -0
- package/dist/wirings/flag/define-feature-flags.d.ts +33 -0
- package/dist/wirings/flag/define-feature-flags.js +32 -0
- package/dist/wirings/flag/flag.types.d.ts +97 -0
- package/dist/wirings/flag/flag.types.js +1 -0
- package/dist/wirings/flag/index.d.ts +7 -0
- package/dist/wirings/flag/index.js +5 -0
- package/dist/wirings/flag/resolve-flag.d.ts +52 -0
- package/dist/wirings/flag/resolve-flag.js +90 -0
- package/dist/wirings/flag/validate-flag-definitions.d.ts +26 -0
- package/dist/wirings/flag/validate-flag-definitions.js +103 -0
- package/dist/wirings/rpc/rpc-runner.js +3 -0
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +8 -8
- package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +1 -1
- package/dist/wirings/workflow/workflow-queue-routing.d.ts +1 -1
- package/package.json +11 -5
- package/run-tests.sh +17 -9
- package/src/public-surface.json +26 -0
- package/src/agent-naming.test.ts +0 -68
- package/src/api-report.test.ts +0 -138
- package/src/app-alias-surface.test.ts +0 -179
- package/src/app-leaf-surface.test.ts +0 -222
- package/src/bootstrap-compat/root.ts +0 -20
- package/src/classification/column-form.test.ts +0 -97
- package/src/classification/column-form.ts +0 -55
- package/src/classification/data-classification.ts +0 -73
- package/src/classification/index.ts +0 -40
- package/src/classification/key-ids.ts +0 -2
- package/src/classification/secret-value.test.ts +0 -204
- package/src/classification/secret-value.ts +0 -106
- package/src/crypto-utils.test.ts +0 -668
- package/src/crypto-utils.ts +0 -460
- package/src/dev/hot-reload.test.ts +0 -587
- package/src/dev/hot-reload.ts +0 -225
- package/src/dev/module-runner.test.ts +0 -235
- package/src/dev/module-runner.ts +0 -138
- package/src/dev/reload-meta.test.ts +0 -183
- package/src/dev/reload-meta.ts +0 -144
- package/src/ecosystem-tier-removed.test.ts +0 -72
- package/src/env.ts +0 -1
- package/src/errors/error-handler.ts +0 -77
- package/src/errors/error.test.ts +0 -229
- package/src/errors/errors.ts +0 -393
- package/src/errors/index.ts +0 -11
- package/src/errors/serialized-error.ts +0 -12
- package/src/factory-functions.test.ts +0 -111
- package/src/function/abort-scope.test.ts +0 -97
- package/src/function/abort-scope.ts +0 -80
- package/src/function/function-meta.types.ts +0 -151
- package/src/function/function-runner.test.ts +0 -1619
- package/src/function/function-runner.ts +0 -499
- package/src/function/functions.types.ts +0 -319
- package/src/function/index.ts +0 -40
- package/src/function/list.types.test.ts +0 -100
- package/src/function/list.types.ts +0 -69
- package/src/function/pikku-request.test.ts +0 -35
- package/src/function/pikku-request.ts +0 -17
- package/src/gopass-secrets-removed.test.ts +0 -51
- package/src/handle-error.test.ts +0 -532
- package/src/handle-error.ts +0 -64
- package/src/middleware/auth-apikey.test.ts +0 -362
- package/src/middleware/auth-apikey.ts +0 -39
- package/src/middleware/auth-bearer.test.ts +0 -566
- package/src/middleware/auth-bearer.ts +0 -83
- package/src/middleware/auth-cookie.test.ts +0 -572
- package/src/middleware/auth-cookie.ts +0 -107
- package/src/middleware/cors.test.ts +0 -579
- package/src/middleware/cors.ts +0 -103
- package/src/middleware/index.ts +0 -30
- package/src/middleware/middleware-factories.ts +0 -76
- package/src/middleware/middleware.types.ts +0 -61
- package/src/middleware/remote-auth.test.ts +0 -547
- package/src/middleware/remote-auth.ts +0 -95
- package/src/middleware/remote-jobs-secret.ts +0 -35
- package/src/middleware/require-origin.test.ts +0 -115
- package/src/middleware/require-origin.ts +0 -79
- package/src/middleware/telemetry.ts +0 -83
- package/src/middleware-runner.test.ts +0 -578
- package/src/middleware-runner.ts +0 -232
- package/src/no-any-casts.test.ts +0 -57
- package/src/no-root-barrel.test.ts +0 -122
- package/src/permissions.test.ts +0 -256
- package/src/permissions.ts +0 -217
- package/src/pikku-state.test.ts +0 -198
- package/src/pikku-state.ts +0 -206
- package/src/production-barrels-stay-lean.test.ts +0 -110
- package/src/public-surface.test.ts +0 -133
- package/src/remote.test.ts +0 -173
- package/src/remote.ts +0 -56
- package/src/removed-legacy-exports.test.ts +0 -66
- package/src/run-tests-script.test.ts +0 -67
- package/src/schema.test.ts +0 -430
- package/src/schema.ts +0 -204
- package/src/scopes.test.ts +0 -203
- package/src/scopes.ts +0 -67
- package/src/services/agent-run-state-service.ts +0 -37
- package/src/services/agent-runner-service.ts +0 -238
- package/src/services/agent-storage-service.ts +0 -39
- package/src/services/ai-embedding-service.ts +0 -9
- package/src/services/audit-service.test.ts +0 -44
- package/src/services/audit-service.ts +0 -280
- package/src/services/content-service.ts +0 -65
- package/src/services/credential-service.ts +0 -20
- package/src/services/credential-wire-service.test.ts +0 -235
- package/src/services/credential-wire-service.ts +0 -120
- package/src/services/deployment-service.ts +0 -32
- package/src/services/email-service.test.ts +0 -100
- package/src/services/email-service.ts +0 -60
- package/src/services/email-template.test.ts +0 -311
- package/src/services/email-template.ts +0 -254
- package/src/services/file-scenario-run-store.test.ts +0 -349
- package/src/services/file-scenario-run-store.ts +0 -282
- package/src/services/gateway-service.ts +0 -5
- package/src/services/http-personas-converse.test.ts +0 -274
- package/src/services/http-personas.test.ts +0 -379
- package/src/services/http-personas.ts +0 -508
- package/src/services/in-memory-agent-run-state-service.ts +0 -87
- package/src/services/in-memory-queue-service.test.ts +0 -162
- package/src/services/in-memory-queue-service.ts +0 -78
- package/src/services/in-memory-session-store.test.ts +0 -58
- package/src/services/in-memory-session-store.ts +0 -20
- package/src/services/in-memory-trigger-service.ts +0 -47
- package/src/services/in-memory-workflow-service.test.ts +0 -430
- package/src/services/in-memory-workflow-service.ts +0 -595
- package/src/services/index.ts +0 -192
- package/src/services/istanbul-coverage-service.test.ts +0 -66
- package/src/services/istanbul-coverage-service.ts +0 -59
- package/src/services/jwt-service.ts +0 -15
- package/src/services/local-content-request-handler.test.ts +0 -240
- package/src/services/local-content-request-handler.ts +0 -295
- package/src/services/local-content.test.ts +0 -186
- package/src/services/local-content.ts +0 -242
- package/src/services/local-credential-service.ts +0 -63
- package/src/services/local-email-service.test.ts +0 -182
- package/src/services/local-email-service.ts +0 -43
- package/src/services/local-gateway-service.ts +0 -51
- package/src/services/local-secrets.test.ts +0 -95
- package/src/services/local-secrets.ts +0 -71
- package/src/services/local-variables.test.ts +0 -61
- package/src/services/local-variables.ts +0 -45
- package/src/services/logger-console.test.ts +0 -117
- package/src/services/logger-console.ts +0 -174
- package/src/services/logger.ts +0 -48
- package/src/services/meta-service.test.ts +0 -75
- package/src/services/meta-service.ts +0 -767
- package/src/services/persona-actor-secret.test.ts +0 -68
- package/src/services/persona-actor-secret.ts +0 -70
- package/src/services/persona-sign-in.test.ts +0 -219
- package/src/services/persona-sign-in.ts +0 -238
- package/src/services/personas-service.ts +0 -191
- package/src/services/pikku-user-id.test.ts +0 -62
- package/src/services/pikku-user-id.ts +0 -13
- package/src/services/queue-webhook-service.test.ts +0 -409
- package/src/services/queue-webhook-service.ts +0 -150
- package/src/services/remote-jobs.test.ts +0 -106
- package/src/services/remote-jobs.ts +0 -92
- package/src/services/scheduler-service.ts +0 -37
- package/src/services/schema-service.ts +0 -10
- package/src/services/scope-service.ts +0 -91
- package/src/services/scoped-credential-service.test.ts +0 -86
- package/src/services/scoped-credential-service.ts +0 -63
- package/src/services/scoped-secret-service.test.ts +0 -93
- package/src/services/scoped-secret-service.ts +0 -40
- package/src/services/secret-host-binding.test.ts +0 -138
- package/src/services/secret-host-binding.ts +0 -51
- package/src/services/secret-service.ts +0 -25
- package/src/services/secretless.test.ts +0 -54
- package/src/services/secretless.ts +0 -29
- package/src/services/session-store.ts +0 -9
- package/src/services/stub-tracker.test.ts +0 -104
- package/src/services/stub-tracker.ts +0 -175
- package/src/services/system-role-guard.test.ts +0 -96
- package/src/services/system-role-guard.ts +0 -71
- package/src/services/temporary-file-service.ts +0 -76
- package/src/services/trigger-service.ts +0 -5
- package/src/services/typed-credential-service.ts +0 -83
- package/src/services/typed-secret-service.test.ts +0 -204
- package/src/services/typed-secret-service.ts +0 -132
- package/src/services/typed-variables-service.test.ts +0 -166
- package/src/services/typed-variables-service.ts +0 -166
- package/src/services/user-session-service.test.ts +0 -147
- package/src/services/user-session-service.ts +0 -85
- package/src/services/v8-coverage-service.test.ts +0 -69
- package/src/services/v8-coverage-service.ts +0 -163
- package/src/services/variables-service.ts +0 -13
- package/src/services/webhook-service.ts +0 -147
- package/src/services/workflow-service.ts +0 -120
- package/src/side-effects-are-declared.test.ts +0 -84
- package/src/source-files-stay-composable.test.ts +0 -41
- package/src/template-alias-surface.test.ts +0 -240
- package/src/test-utils.ts +0 -38
- package/src/testing/index.ts +0 -3
- package/src/testing/service-tests/agent-run-service-tests.ts +0 -98
- package/src/testing/service-tests/agent-storage-service-tests.ts +0 -379
- package/src/testing/service-tests/channel-store-tests.ts +0 -98
- package/src/testing/service-tests/credential-service-tests.ts +0 -143
- package/src/testing/service-tests/deployment-service-tests.ts +0 -33
- package/src/testing/service-tests/event-hub-store-tests.ts +0 -48
- package/src/testing/service-tests/secret-service-tests.ts +0 -105
- package/src/testing/service-tests/session-store-tests.ts +0 -62
- package/src/testing/service-tests/workflow-run-service-tests.ts +0 -59
- package/src/testing/service-tests/workflow-service-tests.ts +0 -308
- package/src/testing/service-tests.ts +0 -95
- package/src/time-utils.test.ts +0 -56
- package/src/time-utils.ts +0 -89
- package/src/types/core.types.ts +0 -446
- package/src/types/index.ts +0 -25
- package/src/types/state.types.ts +0 -226
- package/src/types/typed-credentials.test.ts +0 -72
- package/src/utils/hash.test.ts +0 -68
- package/src/utils/hash.ts +0 -26
- package/src/utils/hmac.ts +0 -21
- package/src/utils/node-host-resolver.ts +0 -20
- package/src/utils/safe-fetch.test.ts +0 -515
- package/src/utils/safe-fetch.ts +0 -347
- package/src/utils.test.ts +0 -359
- package/src/utils.ts +0 -165
- package/src/version.test.ts +0 -80
- package/src/version.ts +0 -25
- package/src/wirings/actor-flow/actor-flow.types.ts +0 -40
- package/src/wirings/actor-flow/index.ts +0 -10
- package/src/wirings/actor-flow/run-conversation.test.ts +0 -187
- package/src/wirings/actor-flow/run-conversation.ts +0 -280
- package/src/wirings/addon/addon-auth-tags.test.ts +0 -219
- package/src/wirings/addon/addon-runner.ts +0 -236
- package/src/wirings/addon/addon-scopes.test.ts +0 -225
- package/src/wirings/addon/addon-secrets.test.ts +0 -391
- package/src/wirings/addon/index.ts +0 -12
- package/src/wirings/addon/remote-addon-auth.ts +0 -65
- package/src/wirings/addon/wire-addon.test.ts +0 -102
- package/src/wirings/addon/wire-addon.ts +0 -202
- package/src/wirings/addon/wire-remote-addon.ts +0 -41
- package/src/wirings/agent/agent-agui.test.ts +0 -1213
- package/src/wirings/agent/agent-agui.ts +0 -405
- package/src/wirings/agent/agent-authorization.test.ts +0 -208
- package/src/wirings/agent/agent-finalize.test.ts +0 -187
- package/src/wirings/agent/agent-finalize.ts +0 -197
- package/src/wirings/agent/agent-helpers.test.ts +0 -215
- package/src/wirings/agent/agent-helpers.ts +0 -96
- package/src/wirings/agent/agent-interrupt.test.ts +0 -833
- package/src/wirings/agent/agent-interrupt.ts +0 -400
- package/src/wirings/agent/agent-memory.test.ts +0 -397
- package/src/wirings/agent/agent-memory.ts +0 -496
- package/src/wirings/agent/agent-middleware.types.test.ts +0 -41
- package/src/wirings/agent/agent-model-config.test.ts +0 -103
- package/src/wirings/agent/agent-model-config.ts +0 -59
- package/src/wirings/agent/agent-prepare.test.ts +0 -977
- package/src/wirings/agent/agent-prepare.ts +0 -1083
- package/src/wirings/agent/agent-registry.test.ts +0 -455
- package/src/wirings/agent/agent-registry.ts +0 -99
- package/src/wirings/agent/agent-resume-authorization.test.ts +0 -206
- package/src/wirings/agent/agent-rpc.ts +0 -116
- package/src/wirings/agent/agent-runner.test.ts +0 -1229
- package/src/wirings/agent/agent-runner.ts +0 -858
- package/src/wirings/agent/agent-stream-delegate.test.ts +0 -381
- package/src/wirings/agent/agent-stream-output-hooks.test.ts +0 -353
- package/src/wirings/agent/agent-stream.test.ts +0 -1800
- package/src/wirings/agent/agent-stream.ts +0 -1639
- package/src/wirings/agent/agent-thread-ownership.test.ts +0 -297
- package/src/wirings/agent/agent-turn.test.ts +0 -65
- package/src/wirings/agent/agent-turn.ts +0 -122
- package/src/wirings/agent/agent-utils.ts +0 -20
- package/src/wirings/agent/agent.types.ts +0 -676
- package/src/wirings/agent/index.ts +0 -58
- package/src/wirings/agent/voice-input.test.ts +0 -220
- package/src/wirings/agent/voice-input.ts +0 -180
- package/src/wirings/agent/voice-output.test.ts +0 -510
- package/src/wirings/agent/voice-output.ts +0 -311
- package/src/wirings/agent-scorer/agent-scorer-grade.test.ts +0 -106
- package/src/wirings/agent-scorer/agent-scorer-grade.ts +0 -55
- package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +0 -285
- package/src/wirings/agent-scorer/agent-scorer-judge.ts +0 -180
- package/src/wirings/agent-scorer/agent-scorer-live.test.ts +0 -174
- package/src/wirings/agent-scorer/agent-scorer-live.ts +0 -56
- package/src/wirings/agent-scorer/agent-scorer-registry.ts +0 -66
- package/src/wirings/agent-scorer/agent-scorer-sampling.test.ts +0 -34
- package/src/wirings/agent-scorer/agent-scorer-sampling.ts +0 -36
- package/src/wirings/agent-scorer/agent-scorer-snapshots.test.ts +0 -49
- package/src/wirings/agent-scorer/agent-scorer-snapshots.ts +0 -46
- package/src/wirings/agent-scorer/agent-scorer-worker.test.ts +0 -122
- package/src/wirings/agent-scorer/agent-scorer-worker.ts +0 -71
- package/src/wirings/agent-scorer/agent-scorer.ts +0 -102
- package/src/wirings/agent-scorer/agent-scorer.types.ts +0 -128
- package/src/wirings/agent-scorer/index.ts +0 -23
- package/src/wirings/channel/channel-common.ts +0 -102
- package/src/wirings/channel/channel-handler-shapes.test.ts +0 -72
- package/src/wirings/channel/channel-handler.test.ts +0 -322
- package/src/wirings/channel/channel-handler.ts +0 -259
- package/src/wirings/channel/channel-host-rpc.test.ts +0 -150
- package/src/wirings/channel/channel-host-rpc.ts +0 -69
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -188
- package/src/wirings/channel/channel-middleware-runner.ts +0 -126
- package/src/wirings/channel/channel-rpc-registry.ts +0 -116
- package/src/wirings/channel/channel-rpc-responder.ts +0 -117
- package/src/wirings/channel/channel-rpc-service.ts +0 -132
- package/src/wirings/channel/channel-rpc-validators.ts +0 -65
- package/src/wirings/channel/channel-rpc.test.ts +0 -841
- package/src/wirings/channel/channel-rpc.ts +0 -5
- package/src/wirings/channel/channel-rpc.types.ts +0 -160
- package/src/wirings/channel/channel-runner.ts +0 -164
- package/src/wirings/channel/channel-store.ts +0 -35
- package/src/wirings/channel/channel.types.ts +0 -193
- package/src/wirings/channel/define-channel-routes.ts +0 -5
- package/src/wirings/channel/eventhub-service.ts +0 -16
- package/src/wirings/channel/eventhub-store.ts +0 -13
- package/src/wirings/channel/index.ts +0 -40
- package/src/wirings/channel/local/index.ts +0 -3
- package/src/wirings/channel/local/local-channel-handler.ts +0 -98
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -339
- package/src/wirings/channel/local/local-channel-runner.ts +0 -271
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -77
- package/src/wirings/channel/local/local-eventhub-service.ts +0 -69
- package/src/wirings/channel/log-channels.ts +0 -16
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -135
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -60
- package/src/wirings/channel/serverless/index.ts +0 -6
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -328
- package/src/wirings/cli/channel/cli-approval.test.ts +0 -177
- package/src/wirings/cli/channel/cli-approval.ts +0 -135
- package/src/wirings/cli/channel/cli-channel-runner.ts +0 -118
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +0 -192
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +0 -148
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +0 -480
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +0 -188
- package/src/wirings/cli/channel/index.ts +0 -6
- package/src/wirings/cli/cli-runner.test.ts +0 -969
- package/src/wirings/cli/cli-runner.ts +0 -538
- package/src/wirings/cli/cli.types.ts +0 -388
- package/src/wirings/cli/command-parser.test.ts +0 -1120
- package/src/wirings/cli/command-parser.ts +0 -713
- package/src/wirings/cli/define-cli-commands.ts +0 -13
- package/src/wirings/cli/format-cli-error.test.ts +0 -91
- package/src/wirings/cli/format-cli-error.ts +0 -96
- package/src/wirings/cli/index.ts +0 -19
- package/src/wirings/credential/credential.types.ts +0 -37
- package/src/wirings/credential/define-credential.ts +0 -49
- package/src/wirings/credential/index.ts +0 -7
- package/src/wirings/credential/validate-credential-definitions.ts +0 -63
- package/src/wirings/gateway/gateway-authorization.test.ts +0 -575
- package/src/wirings/gateway/gateway-channel-meta.test.ts +0 -44
- package/src/wirings/gateway/gateway-runner.test.ts +0 -581
- package/src/wirings/gateway/gateway-runner.ts +0 -411
- package/src/wirings/gateway/gateway.types.ts +0 -137
- package/src/wirings/gateway/index.ts +0 -15
- package/src/wirings/http/http-routes.test.ts +0 -318
- package/src/wirings/http/http-routes.ts +0 -111
- package/src/wirings/http/http-runner-addon-ref.test.ts +0 -238
- package/src/wirings/http/http-runner.test.ts +0 -503
- package/src/wirings/http/http-runner.ts +0 -462
- package/src/wirings/http/http.types.ts +0 -307
- package/src/wirings/http/index.ts +0 -27
- package/src/wirings/http/log-http-routes.ts +0 -18
- package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -318
- package/src/wirings/http/pikku-fetch-http-request.ts +0 -260
- package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -123
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -149
- package/src/wirings/http/routers/http-router.ts +0 -13
- package/src/wirings/http/routers/path-to-regex.test.ts +0 -306
- package/src/wirings/http/routers/path-to-regex.ts +0 -115
- package/src/wirings/http/web-request.test.ts +0 -382
- package/src/wirings/http/web-request.ts +0 -162
- package/src/wirings/mcp/index.ts +0 -26
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -388
- package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
- package/src/wirings/mcp/mcp-runner.test.ts +0 -588
- package/src/wirings/mcp/mcp-runner.ts +0 -330
- package/src/wirings/mcp/mcp.types.ts +0 -199
- package/src/wirings/node/index.ts +0 -2
- package/src/wirings/node/node.types.ts +0 -23
- package/src/wirings/oauth2/index.ts +0 -1
- package/src/wirings/oauth2/oauth2.types.ts +0 -12
- package/src/wirings/persona/define-personas.ts +0 -33
- package/src/wirings/persona/index.ts +0 -75
- package/src/wirings/persona/persona-app-scopes.test.ts +0 -47
- package/src/wirings/persona/persona-app-scopes.ts +0 -74
- package/src/wirings/persona/persona-email.ts +0 -87
- package/src/wirings/persona/persona-environments.test.ts +0 -194
- package/src/wirings/persona/persona-environments.ts +0 -138
- package/src/wirings/persona/persona-mailbox.ts +0 -156
- package/src/wirings/persona/persona.test.ts +0 -230
- package/src/wirings/persona/persona.types.ts +0 -156
- package/src/wirings/persona/validate-personas.ts +0 -137
- package/src/wirings/queue/index.ts +0 -29
- package/src/wirings/queue/queue-identity.test.ts +0 -454
- package/src/wirings/queue/queue-identity.ts +0 -176
- package/src/wirings/queue/queue-runner.test.ts +0 -705
- package/src/wirings/queue/queue-runner.ts +0 -181
- package/src/wirings/queue/queue.types.ts +0 -161
- package/src/wirings/queue/register-queue-helper.ts +0 -46
- package/src/wirings/queue/signed-queue-service.ts +0 -60
- package/src/wirings/queue/validate-worker-config.test.ts +0 -108
- package/src/wirings/queue/validate-worker-config.ts +0 -90
- package/src/wirings/role/define-system-role.ts +0 -33
- package/src/wirings/role/index.ts +0 -13
- package/src/wirings/role/role.test.ts +0 -104
- package/src/wirings/role/role.types.ts +0 -47
- package/src/wirings/role/validate-role-definitions.ts +0 -93
- package/src/wirings/rpc/index.ts +0 -8
- package/src/wirings/rpc/rpc-runner.test.ts +0 -1130
- package/src/wirings/rpc/rpc-runner.ts +0 -566
- package/src/wirings/rpc/rpc-types.ts +0 -87
- package/src/wirings/scheduler/index.ts +0 -11
- package/src/wirings/scheduler/log-schedulers.ts +0 -16
- package/src/wirings/scheduler/scheduler-runner.test.ts +0 -835
- package/src/wirings/scheduler/scheduler-runner.ts +0 -138
- package/src/wirings/scheduler/scheduler.types.ts +0 -42
- package/src/wirings/scope/define-scope.ts +0 -33
- package/src/wirings/scope/index.ts +0 -15
- package/src/wirings/scope/scope.test.ts +0 -159
- package/src/wirings/scope/scope.types.ts +0 -42
- package/src/wirings/scope/validate-scope-definitions.ts +0 -107
- package/src/wirings/secret/index.ts +0 -9
- package/src/wirings/secret/secret.types.ts +0 -70
- package/src/wirings/secret/validate-secret-definitions.test.ts +0 -232
- package/src/wirings/secret/validate-secret-definitions.ts +0 -88
- package/src/wirings/trigger/index.ts +0 -9
- package/src/wirings/trigger/pikku-trigger-service.ts +0 -107
- package/src/wirings/trigger/trigger-runner.test.ts +0 -78
- package/src/wirings/trigger/trigger-runner.ts +0 -113
- package/src/wirings/trigger/trigger.types.ts +0 -100
- package/src/wirings/variable/index.ts +0 -8
- package/src/wirings/variable/validate-variable-definitions.test.ts +0 -115
- package/src/wirings/variable/validate-variable-definitions.ts +0 -71
- package/src/wirings/variable/variable.types.ts +0 -40
- package/src/wirings/virtual-user/index.ts +0 -107
- package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +0 -115
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +0 -95
- package/src/wirings/virtual-user/run-virtual-user.test.ts +0 -774
- package/src/wirings/virtual-user/run-virtual-user.ts +0 -684
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-agents.ts +0 -62
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +0 -215
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +0 -184
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +0 -426
- package/src/wirings/virtual-user/virtual-user-derive.ts +0 -161
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +0 -68
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +0 -210
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +0 -218
- package/src/wirings/virtual-user/virtual-user-intents.ts +0 -185
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-rng.ts +0 -50
- package/src/wirings/virtual-user/virtual-user-run-store.ts +0 -131
- package/src/wirings/virtual-user/virtual-user-scaffold.test.ts +0 -854
- package/src/wirings/virtual-user/virtual-user-scaffold.ts +0 -664
- package/src/wirings/virtual-user/virtual-user-schedule-store.ts +0 -93
- package/src/wirings/virtual-user/virtual-user-schedule.test.ts +0 -280
- package/src/wirings/virtual-user/virtual-user-schedule.ts +0 -156
- package/src/wirings/virtual-user/virtual-user-target.ts +0 -47
- package/src/wirings/virtual-user/virtual-user.types.ts +0 -215
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -709
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -25
- package/src/wirings/workflow/feature.test.ts +0 -131
- package/src/wirings/workflow/feature.ts +0 -59
- package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +0 -569
- package/src/wirings/workflow/graph/graph-foreach.test.ts +0 -626
- package/src/wirings/workflow/graph/graph-node.ts +0 -115
- package/src/wirings/workflow/graph/graph-runner.test.ts +0 -1049
- package/src/wirings/workflow/graph/graph-runner.ts +0 -1376
- package/src/wirings/workflow/graph/graph-validation.test.ts +0 -27
- package/src/wirings/workflow/graph/graph-validation.ts +0 -41
- package/src/wirings/workflow/graph/template.test.ts +0 -49
- package/src/wirings/workflow/graph/template.ts +0 -42
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -39
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -75
- package/src/wirings/workflow/index.ts +0 -107
- package/src/wirings/workflow/pikku-scenario-service.ts +0 -1013
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -963
- package/src/wirings/workflow/pikku-workflow-service.ts +0 -1993
- package/src/wirings/workflow/run-timeline.test.ts +0 -199
- package/src/wirings/workflow/run-timeline.ts +0 -185
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -107
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -57
- package/src/wirings/workflow/scenario-expectations.test.ts +0 -238
- package/src/wirings/workflow/scenario-hooks.test.ts +0 -259
- package/src/wirings/workflow/scenario-poll.test.ts +0 -64
- package/src/wirings/workflow/scenario-poll.ts +0 -27
- package/src/wirings/workflow/scenario-prose.test.ts +0 -275
- package/src/wirings/workflow/scenario-prose.ts +0 -86
- package/src/wirings/workflow/scenario-run.types.ts +0 -193
- package/src/wirings/workflow/scenario-service.test.ts +0 -147
- package/src/wirings/workflow/scenario-step-guards.ts +0 -23
- package/src/wirings/workflow/scenario-step.test.ts +0 -800
- package/src/wirings/workflow/scenario-step.types.ts +0 -262
- package/src/wirings/workflow/scenario-surface.test.ts +0 -146
- package/src/wirings/workflow/scenario-surface.ts +0 -71
- package/src/wirings/workflow/scenario.types.ts +0 -63
- package/src/wirings/workflow/workflow-approval-audit.ts +0 -47
- package/src/wirings/workflow/workflow-approval-policy.test.ts +0 -594
- package/src/wirings/workflow/workflow-approval-policy.ts +0 -68
- package/src/wirings/workflow/workflow-approval.ts +0 -290
- package/src/wirings/workflow/workflow-child-run-session.test.ts +0 -168
- package/src/wirings/workflow/workflow-constants.ts +0 -66
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +0 -116
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -55
- package/src/wirings/workflow/workflow-dispatch-relay.test.ts +0 -128
- package/src/wirings/workflow/workflow-errors.ts +0 -132
- package/src/wirings/workflow/workflow-inline-authority.test.ts +0 -175
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -51
- package/src/wirings/workflow/workflow-invocation-id.ts +0 -28
- package/src/wirings/workflow/workflow-meta-resolver.ts +0 -45
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -171
- package/src/wirings/workflow/workflow-missing-meta.test.ts +0 -92
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -145
- package/src/wirings/workflow/workflow-queue-routing.ts +0 -129
- package/src/wirings/workflow/workflow-queue-wiring.ts +0 -149
- package/src/wirings/workflow/workflow-queue-workers.test.ts +0 -131
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -66
- package/src/wirings/workflow/workflow-recovery.ts +0 -192
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +0 -140
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -113
- package/src/wirings/workflow/workflow-run-authority.test.ts +0 -212
- package/src/wirings/workflow/workflow-run-context.test.ts +0 -172
- package/src/wirings/workflow/workflow-run-engine.types.ts +0 -92
- package/src/wirings/workflow/workflow-run-ownership.ts +0 -37
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -127
- package/src/wirings/workflow/workflow-stalled-recovery.test.ts +0 -152
- package/src/wirings/workflow/workflow-status-stream.test.ts +0 -354
- package/src/wirings/workflow/workflow-status-stream.ts +0 -144
- package/src/wirings/workflow/workflow-step-claim.ts +0 -46
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +0 -94
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -87
- package/src/wirings/workflow/workflow-suspend.ts +0 -61
- package/src/wirings/workflow/workflow-terminal-run-guard.test.ts +0 -105
- package/src/wirings/workflow/workflow.types.ts +0 -268
- package/src/wirings-stay-decoupled.test.ts +0 -130
- package/tsconfig.json +0 -14
- package/tsconfig.tsbuildinfo +0 -1
- package/tsconfig.type-tests.json +0 -15
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { beforeEach, describe, test } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { resetPikkuState, pikkuState } from '../../pikku-state.js'
|
|
5
|
-
import {
|
|
6
|
-
pikkuWorkflowWorkerFunc,
|
|
7
|
-
pikkuWorkflowOrchestratorFunc,
|
|
8
|
-
pikkuWorkflowSleeperFunc,
|
|
9
|
-
} from './workflow-queue-workers.js'
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
resetPikkuState()
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
describe('workflow-queue-workers', () => {
|
|
16
|
-
test('worker calls executeWorkflowStep on the workflow service', async () => {
|
|
17
|
-
const calls: unknown[][] = []
|
|
18
|
-
const rpc = { rpcWithWire: async () => ({ ok: true }) }
|
|
19
|
-
|
|
20
|
-
pikkuState(null, 'package', 'singletonServices', {
|
|
21
|
-
workflowService: {
|
|
22
|
-
executeWorkflowStep: async (...args: unknown[]) => {
|
|
23
|
-
calls.push(args)
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
} as never)
|
|
27
|
-
|
|
28
|
-
await pikkuWorkflowWorkerFunc(
|
|
29
|
-
{},
|
|
30
|
-
{
|
|
31
|
-
runId: 'run-1',
|
|
32
|
-
stepName: 'step-a',
|
|
33
|
-
rpcName: 'rpc.doThing',
|
|
34
|
-
data: { ok: true },
|
|
35
|
-
},
|
|
36
|
-
{ rpc: rpc as never }
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
assert.deepEqual(calls, [
|
|
40
|
-
['run-1', 'step-a', 'rpc.doThing', { ok: true }, rpc],
|
|
41
|
-
])
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
test('worker throws when workflow service is missing', async () => {
|
|
45
|
-
pikkuState(null, 'package', 'singletonServices', {} as never)
|
|
46
|
-
|
|
47
|
-
await assert.rejects(
|
|
48
|
-
() =>
|
|
49
|
-
pikkuWorkflowWorkerFunc(
|
|
50
|
-
{},
|
|
51
|
-
{
|
|
52
|
-
runId: 'run-1',
|
|
53
|
-
stepName: 'step-a',
|
|
54
|
-
rpcName: 'rpc.doThing',
|
|
55
|
-
data: {},
|
|
56
|
-
},
|
|
57
|
-
{ rpc: {} as never }
|
|
58
|
-
),
|
|
59
|
-
{
|
|
60
|
-
message:
|
|
61
|
-
'Workflow service not initialized: cannot execute workflow step for runId run-1, stepName step-a',
|
|
62
|
-
}
|
|
63
|
-
)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
test('orchestrator calls orchestrateWorkflow on the workflow service', async () => {
|
|
67
|
-
const calls: unknown[][] = []
|
|
68
|
-
const rpc = { rpcWithWire: async () => ({ ok: true }) }
|
|
69
|
-
|
|
70
|
-
pikkuState(null, 'package', 'singletonServices', {
|
|
71
|
-
workflowService: {
|
|
72
|
-
orchestrateWorkflow: async (...args: unknown[]) => {
|
|
73
|
-
calls.push(args)
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
} as never)
|
|
77
|
-
|
|
78
|
-
await pikkuWorkflowOrchestratorFunc(
|
|
79
|
-
{},
|
|
80
|
-
{ runId: 'run-2' },
|
|
81
|
-
{ rpc: rpc as never }
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
assert.deepEqual(calls, [['run-2', rpc]])
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
test('orchestrator throws when workflow service is missing', async () => {
|
|
88
|
-
pikkuState(null, 'package', 'singletonServices', {} as never)
|
|
89
|
-
|
|
90
|
-
await assert.rejects(
|
|
91
|
-
() =>
|
|
92
|
-
pikkuWorkflowOrchestratorFunc(
|
|
93
|
-
{},
|
|
94
|
-
{ runId: 'run-2' },
|
|
95
|
-
{ rpc: {} as never }
|
|
96
|
-
),
|
|
97
|
-
{
|
|
98
|
-
message:
|
|
99
|
-
'Workflow service not initialized: cannot orchestrate workflow for runId run-2',
|
|
100
|
-
}
|
|
101
|
-
)
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
test('sleeper calls executeWorkflowSleepCompleted on the workflow service', async () => {
|
|
105
|
-
const calls: unknown[][] = []
|
|
106
|
-
|
|
107
|
-
pikkuState(null, 'package', 'singletonServices', {
|
|
108
|
-
workflowService: {
|
|
109
|
-
executeWorkflowSleepCompleted: async (...args: unknown[]) => {
|
|
110
|
-
calls.push(args)
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
} as never)
|
|
114
|
-
|
|
115
|
-
await pikkuWorkflowSleeperFunc({}, { runId: 'run-3', stepId: 'step-3' })
|
|
116
|
-
|
|
117
|
-
assert.deepEqual(calls, [['run-3', 'step-3']])
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
test('sleeper throws when workflow service is missing', async () => {
|
|
121
|
-
pikkuState(null, 'package', 'singletonServices', {} as never)
|
|
122
|
-
|
|
123
|
-
await assert.rejects(
|
|
124
|
-
() => pikkuWorkflowSleeperFunc({}, { runId: 'run-3', stepId: 'step-3' }),
|
|
125
|
-
{
|
|
126
|
-
message:
|
|
127
|
-
'Workflow service not initialized: cannot execute workflow sleep completed for runId run-3, stepId step-3',
|
|
128
|
-
}
|
|
129
|
-
)
|
|
130
|
-
})
|
|
131
|
-
})
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { getSingletonServices } from '../../pikku-state.js'
|
|
2
|
-
import type { PikkuRPC } from '../rpc/rpc-types.js'
|
|
3
|
-
|
|
4
|
-
export interface WorkflowStepInput {
|
|
5
|
-
runId: string
|
|
6
|
-
stepName: string
|
|
7
|
-
rpcName: string
|
|
8
|
-
data: unknown
|
|
9
|
-
fromStepName?: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface PikkuWorkflowOrchestratorInput {
|
|
13
|
-
runId: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface PikkuWorkflowSleeperInput {
|
|
17
|
-
runId: string
|
|
18
|
-
stepId: string
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function pikkuWorkflowWorkerFunc(
|
|
22
|
-
_services: Record<string, unknown>,
|
|
23
|
-
{ runId, stepName, rpcName, data }: WorkflowStepInput,
|
|
24
|
-
{ rpc }: { rpc: PikkuRPC }
|
|
25
|
-
): Promise<void> {
|
|
26
|
-
const services = getSingletonServices()
|
|
27
|
-
if (!services?.workflowService) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
`Workflow service not initialized: cannot execute workflow step for runId ${runId}, stepName ${stepName}`
|
|
30
|
-
)
|
|
31
|
-
}
|
|
32
|
-
await services.workflowService.executeWorkflowStep(
|
|
33
|
-
runId,
|
|
34
|
-
stepName,
|
|
35
|
-
rpcName,
|
|
36
|
-
data,
|
|
37
|
-
rpc
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export async function pikkuWorkflowOrchestratorFunc(
|
|
42
|
-
_services: Record<string, unknown>,
|
|
43
|
-
{ runId }: PikkuWorkflowOrchestratorInput,
|
|
44
|
-
{ rpc }: { rpc: PikkuRPC }
|
|
45
|
-
): Promise<void> {
|
|
46
|
-
const services = getSingletonServices()
|
|
47
|
-
if (!services?.workflowService) {
|
|
48
|
-
throw new Error(
|
|
49
|
-
`Workflow service not initialized: cannot orchestrate workflow for runId ${runId}`
|
|
50
|
-
)
|
|
51
|
-
}
|
|
52
|
-
await services.workflowService.orchestrateWorkflow(runId, rpc)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export async function pikkuWorkflowSleeperFunc(
|
|
56
|
-
_services: Record<string, unknown>,
|
|
57
|
-
{ runId, stepId }: PikkuWorkflowSleeperInput
|
|
58
|
-
): Promise<void> {
|
|
59
|
-
const services = getSingletonServices()
|
|
60
|
-
if (!services?.workflowService) {
|
|
61
|
-
throw new Error(
|
|
62
|
-
`Workflow service not initialized: cannot execute workflow sleep completed for runId ${runId}, stepId ${stepId}`
|
|
63
|
-
)
|
|
64
|
-
}
|
|
65
|
-
await services.workflowService.executeWorkflowSleepCompleted(runId, stepId)
|
|
66
|
-
}
|
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
import type { Logger } from '../../services/logger.js'
|
|
2
|
-
import {
|
|
3
|
-
DEFAULT_STALLED_RUN_LIMIT,
|
|
4
|
-
DEFAULT_STALLED_RUN_MS,
|
|
5
|
-
DEFAULT_UNDISPATCHED_STEP_LIMIT,
|
|
6
|
-
DEFAULT_UNDISPATCHED_STEP_MS,
|
|
7
|
-
REDISPATCH_BACKOFF_MAX_ENTRIES,
|
|
8
|
-
REDISPATCH_BACKOFF_MAX_MS,
|
|
9
|
-
REDISPATCH_BACKOFF_MS,
|
|
10
|
-
} from './workflow-constants.js'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Per-process, advisory record of when a run may next be re-dispatched.
|
|
14
|
-
*
|
|
15
|
-
* Keyed by run rather than by step because the run is the unit of re-drive:
|
|
16
|
-
* `resumeWorkflow` replays the whole run and re-dispatches every step still
|
|
17
|
-
* owed a job, so holding off a single step while resuming its run would
|
|
18
|
-
* suppress nothing.
|
|
19
|
-
*
|
|
20
|
-
* For the same reason one instance is shared by every sweep rather than kept
|
|
21
|
-
* per sweep. The record is of the action, not of the signal that prompted it:
|
|
22
|
-
* a stalled run and an undispatched step are different observations, but both
|
|
23
|
-
* are answered by the one orchestrator message, so a run the relay re-drove a
|
|
24
|
-
* moment ago gains nothing from the stalled sweep re-driving it again. Sharing
|
|
25
|
-
* is what makes the guarantee a message-per-run-per-window instead of one per
|
|
26
|
-
* sweep, and no recovery is lost by it: whichever sweep gets there first
|
|
27
|
-
* performs the identical re-drive, and the cap keeps the delay at 10m.
|
|
28
|
-
*
|
|
29
|
-
* Losing this on restart costs extra dispatches, never correctness.
|
|
30
|
-
*/
|
|
31
|
-
export class RedispatchBackoff {
|
|
32
|
-
private readonly eligibleAt = new Map<string, number>()
|
|
33
|
-
private readonly delays = new Map<string, number>()
|
|
34
|
-
|
|
35
|
-
public isEligible(runId: string, now: number): boolean {
|
|
36
|
-
const at = this.eligibleAt.get(runId)
|
|
37
|
-
return at === undefined || at <= now
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
public note(runId: string, now: number): void {
|
|
41
|
-
const previous = this.delays.get(runId)
|
|
42
|
-
const delay = Math.min(
|
|
43
|
-
previous === undefined ? REDISPATCH_BACKOFF_MS : previous * 2,
|
|
44
|
-
REDISPATCH_BACKOFF_MAX_MS
|
|
45
|
-
)
|
|
46
|
-
// A run that settles is never returned again, so entries are only evicted
|
|
47
|
-
// by this bound — oldest first, which is also least recently re-dispatched.
|
|
48
|
-
if (this.eligibleAt.size >= REDISPATCH_BACKOFF_MAX_ENTRIES) {
|
|
49
|
-
const oldest = this.eligibleAt.keys().next()
|
|
50
|
-
if (!oldest.done) {
|
|
51
|
-
this.eligibleAt.delete(oldest.value)
|
|
52
|
-
this.delays.delete(oldest.value)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
this.delays.set(runId, delay)
|
|
56
|
-
this.eligibleAt.set(runId, now + delay)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
type SweepDeps = {
|
|
61
|
-
resume: (runId: string) => Promise<void>
|
|
62
|
-
logger?: Logger
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const resumeEach = async (
|
|
66
|
-
runIds: Iterable<string>,
|
|
67
|
-
{ resume, logger }: SweepDeps,
|
|
68
|
-
failure: (runId: string, detail: string) => string
|
|
69
|
-
): Promise<string[]> => {
|
|
70
|
-
const succeeded: string[] = []
|
|
71
|
-
for (const runId of runIds) {
|
|
72
|
-
try {
|
|
73
|
-
await resume(runId)
|
|
74
|
-
succeeded.push(runId)
|
|
75
|
-
} catch (err) {
|
|
76
|
-
// One unresumable run must not stop the sweep from recovering the rest.
|
|
77
|
-
logger?.error(
|
|
78
|
-
failure(runId, err instanceof Error ? err.message : String(err))
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return succeeded
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Re-drive runs whose next move was lost, and report which were resumed.
|
|
87
|
-
*
|
|
88
|
-
* Arming a step is two writes to two systems — the step row, then the queue or
|
|
89
|
-
* scheduler job — so a process that dies between them leaves a run that is
|
|
90
|
-
* `running` with nothing in flight. Nothing notices: the run parks on a step
|
|
91
|
-
* that will never complete and never error, so it neither finishes nor fails.
|
|
92
|
-
* (Seen on a `workflow.sleep()`: a deploy restart landed between the sleep
|
|
93
|
-
* step's insert and its timer, parking the run permanently.)
|
|
94
|
-
*
|
|
95
|
-
* Replay is the recovery — `resumeWorkflow` re-orchestrates from persisted step
|
|
96
|
-
* state, and every settled step is memoized, so resuming a run that was not
|
|
97
|
-
* actually stuck costs an orchestration pass and changes nothing. That
|
|
98
|
-
* idempotence is what makes an idle-time heuristic safe here; a run that is
|
|
99
|
-
* legitimately mid-sleep is excluded anyway, since its step is `scheduled`.
|
|
100
|
-
*
|
|
101
|
-
* Idempotent is not free, though: a run stays stalled until something clears
|
|
102
|
-
* the reason it stalled, so an unconditional sweep re-queues the same runs on
|
|
103
|
-
* every tick forever. That is how a handful of wedged runs became a queue of
|
|
104
|
-
* thousands that could not drain — each pass added work the previous pass had
|
|
105
|
-
* not finished. The same per-run backoff the relay uses bounds it: a run is
|
|
106
|
-
* re-driven, then held off for a doubling delay, so a sweep costs at most one
|
|
107
|
-
* message per run per window rather than one per run per tick.
|
|
108
|
-
*/
|
|
109
|
-
export const sweepStalledRuns = async (
|
|
110
|
-
findStalledRunIds: (before: Date, limit: number) => Promise<string[]>,
|
|
111
|
-
backoff: RedispatchBackoff,
|
|
112
|
-
options: { stalledAfterMs?: number; limit?: number } | undefined,
|
|
113
|
-
deps: SweepDeps
|
|
114
|
-
): Promise<{ resumed: string[] }> => {
|
|
115
|
-
const before = new Date(
|
|
116
|
-
Date.now() - (options?.stalledAfterMs ?? DEFAULT_STALLED_RUN_MS)
|
|
117
|
-
)
|
|
118
|
-
const found = await findStalledRunIds(
|
|
119
|
-
before,
|
|
120
|
-
options?.limit ?? DEFAULT_STALLED_RUN_LIMIT
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
const now = Date.now()
|
|
124
|
-
const runIds: string[] = []
|
|
125
|
-
for (const runId of found) {
|
|
126
|
-
if (!backoff.isEligible(runId, now)) continue
|
|
127
|
-
// Noted before the resume, not after: a run whose resume throws is exactly
|
|
128
|
-
// the run most likely to still be here next tick, and re-driving it every
|
|
129
|
-
// tick is the amplification this backoff exists to stop.
|
|
130
|
-
backoff.note(runId, now)
|
|
131
|
-
runIds.push(runId)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
resumed: await resumeEach(
|
|
136
|
-
runIds,
|
|
137
|
-
deps,
|
|
138
|
-
(runId, detail) =>
|
|
139
|
-
`Failed to resume stalled workflow run ${runId}: ${detail}`
|
|
140
|
-
),
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Re-drive steps whose dispatch was lost, and report which runs were nudged.
|
|
146
|
-
*
|
|
147
|
-
* The step row is the outbox record and this is the relay. Age is the only
|
|
148
|
-
* signal available — a step `pending` because its dispatch was lost is
|
|
149
|
-
* indistinguishable from one whose job is merely still queued — so a step past
|
|
150
|
-
* `undispatchedAfterMs` is re-dispatched regardless, and correctness rests on
|
|
151
|
-
* the claim in `executeWorkflowStepInner` rather than on the guess being right.
|
|
152
|
-
* A redundant dispatch costs one queue message: the loser reads `running` and
|
|
153
|
-
* returns without invoking anything.
|
|
154
|
-
*
|
|
155
|
-
* Re-dispatches back off per run (doubling from 30s, capped at 10m) so a
|
|
156
|
-
* genuine queue backlog is not amplified by a tick that keeps firing at the
|
|
157
|
-
* steps the backlog is already delaying.
|
|
158
|
-
*/
|
|
159
|
-
export const sweepUndispatchedSteps = async (
|
|
160
|
-
findUndispatchedSteps: (
|
|
161
|
-
before: Date,
|
|
162
|
-
limit: number
|
|
163
|
-
) => Promise<Array<{ runId: string; stepId: string }>>,
|
|
164
|
-
backoff: RedispatchBackoff,
|
|
165
|
-
options: { undispatchedAfterMs?: number; limit?: number } | undefined,
|
|
166
|
-
deps: SweepDeps
|
|
167
|
-
): Promise<{ redispatched: string[] }> => {
|
|
168
|
-
const before = new Date(
|
|
169
|
-
Date.now() - (options?.undispatchedAfterMs ?? DEFAULT_UNDISPATCHED_STEP_MS)
|
|
170
|
-
)
|
|
171
|
-
const steps = await findUndispatchedSteps(
|
|
172
|
-
before,
|
|
173
|
-
options?.limit ?? DEFAULT_UNDISPATCHED_STEP_LIMIT
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
const now = Date.now()
|
|
177
|
-
const runIds = new Set<string>()
|
|
178
|
-
for (const { runId } of steps) {
|
|
179
|
-
if (!backoff.isEligible(runId, now)) continue
|
|
180
|
-
backoff.note(runId, now)
|
|
181
|
-
runIds.add(runId)
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return {
|
|
185
|
-
redispatched: await resumeEach(
|
|
186
|
-
runIds,
|
|
187
|
-
deps,
|
|
188
|
-
(runId, detail) =>
|
|
189
|
-
`Failed to re-dispatch workflow run ${runId}: ${detail}`
|
|
190
|
-
),
|
|
191
|
-
}
|
|
192
|
-
}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { InMemoryWorkflowService } from '../../services/in-memory-workflow-service.js'
|
|
5
|
-
import { pikkuState } from '../../pikku-state.js'
|
|
6
|
-
|
|
7
|
-
const silentLogger = { error() {}, info() {}, warn() {}, debug() {} }
|
|
8
|
-
|
|
9
|
-
function inlineService() {
|
|
10
|
-
pikkuState(null, 'package', 'singletonServices', {
|
|
11
|
-
queueService: { add: async () => {} },
|
|
12
|
-
logger: silentLogger,
|
|
13
|
-
} as any)
|
|
14
|
-
return new InMemoryWorkflowService()
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function countStepReads(ws: any) {
|
|
18
|
-
const counter = { reads: 0 }
|
|
19
|
-
const original = ws.getStepState.bind(ws)
|
|
20
|
-
ws.getStepState = async (...args: any[]) => {
|
|
21
|
-
counter.reads++
|
|
22
|
-
return original(...args)
|
|
23
|
-
}
|
|
24
|
-
return counter
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async function seedRun(ws: any, steps: number) {
|
|
28
|
-
const runId = await ws.createRun('flow', {}, true, 'hash', { type: 'test' })
|
|
29
|
-
ws.registerInlineRun(runId)
|
|
30
|
-
await ws.beginReplay(runId)
|
|
31
|
-
for (let i = 0; i < steps; i++) {
|
|
32
|
-
await ws.inlineStep(runId, `step-${i}`, async () => i)
|
|
33
|
-
}
|
|
34
|
-
ws.endReplay(runId)
|
|
35
|
-
return runId
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
describe('replay reads the run steps once, not once per step', () => {
|
|
39
|
-
test('a replay over completed steps issues no per-step reads', async () => {
|
|
40
|
-
const ws: any = inlineService()
|
|
41
|
-
const runId = await seedRun(ws, 8)
|
|
42
|
-
|
|
43
|
-
const counter = countStepReads(ws)
|
|
44
|
-
await ws.beginReplay(runId)
|
|
45
|
-
for (let i = 0; i < 8; i++) {
|
|
46
|
-
await ws.inlineStep(runId, `step-${i}`, async () => {
|
|
47
|
-
throw new Error(
|
|
48
|
-
`step-${i} re-ran instead of replaying its cached result`
|
|
49
|
-
)
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
ws.endReplay(runId)
|
|
53
|
-
|
|
54
|
-
assert.equal(
|
|
55
|
-
counter.reads,
|
|
56
|
-
0,
|
|
57
|
-
`the replay still read each step individually (${counter.reads} reads for 8 steps)`
|
|
58
|
-
)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
test('the snapshot still returns each step its own cached result', async () => {
|
|
62
|
-
const ws: any = inlineService()
|
|
63
|
-
const runId = await seedRun(ws, 4)
|
|
64
|
-
|
|
65
|
-
await ws.beginReplay(runId)
|
|
66
|
-
const replayed: unknown[] = []
|
|
67
|
-
for (let i = 0; i < 4; i++) {
|
|
68
|
-
replayed.push(
|
|
69
|
-
await ws.inlineStep(runId, `step-${i}`, async () => 'must not run')
|
|
70
|
-
)
|
|
71
|
-
}
|
|
72
|
-
ws.endReplay(runId)
|
|
73
|
-
|
|
74
|
-
assert.deepEqual(replayed, [0, 1, 2, 3])
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
test('a step reached for the first time mid-replay is created, not mistaken for a miss', async () => {
|
|
78
|
-
const ws: any = inlineService()
|
|
79
|
-
const runId = await seedRun(ws, 2)
|
|
80
|
-
|
|
81
|
-
await ws.beginReplay(runId)
|
|
82
|
-
await ws.inlineStep(runId, 'step-0', async () => 'cached')
|
|
83
|
-
await ws.inlineStep(runId, 'step-1', async () => 'cached')
|
|
84
|
-
const fresh = await ws.inlineStep(runId, 'step-new', async () => 'ran')
|
|
85
|
-
ws.endReplay(runId)
|
|
86
|
-
|
|
87
|
-
assert.equal(fresh, 'ran')
|
|
88
|
-
assert.equal((await ws.getStepState(runId, 'step-new')).result, 'ran')
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
test('a second replay sees what the previous one wrote', async () => {
|
|
92
|
-
const ws: any = inlineService()
|
|
93
|
-
const runId = await seedRun(ws, 1)
|
|
94
|
-
|
|
95
|
-
await ws.beginReplay(runId)
|
|
96
|
-
await ws.inlineStep(runId, 'step-0', async () => 'must not run')
|
|
97
|
-
await ws.inlineStep(runId, 'late', async () => 'first')
|
|
98
|
-
ws.endReplay(runId)
|
|
99
|
-
|
|
100
|
-
await ws.beginReplay(runId)
|
|
101
|
-
await ws.inlineStep(runId, 'step-0', async () => 'must not run')
|
|
102
|
-
const late = await ws.inlineStep(runId, 'late', async () => 'must not run')
|
|
103
|
-
ws.endReplay(runId)
|
|
104
|
-
|
|
105
|
-
assert.equal(
|
|
106
|
-
late,
|
|
107
|
-
'first',
|
|
108
|
-
'the second replay re-ran a step the first one completed'
|
|
109
|
-
)
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
test('outside a replay, steps are still read one at a time', async () => {
|
|
113
|
-
const ws: any = inlineService()
|
|
114
|
-
const runId = await seedRun(ws, 3)
|
|
115
|
-
|
|
116
|
-
const counter = countStepReads(ws)
|
|
117
|
-
await ws.inlineStep(runId, 'step-0', async () => 'must not run')
|
|
118
|
-
|
|
119
|
-
assert.equal(
|
|
120
|
-
counter.reads,
|
|
121
|
-
1,
|
|
122
|
-
'a call outside a replay must read the step directly rather than trust a stale snapshot'
|
|
123
|
-
)
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
test('a backend with no bulk read falls back to per-step reads', async () => {
|
|
127
|
-
const ws: any = inlineService()
|
|
128
|
-
const runId = await seedRun(ws, 3)
|
|
129
|
-
ws.listStepStates = async () => null
|
|
130
|
-
|
|
131
|
-
const counter = countStepReads(ws)
|
|
132
|
-
await ws.beginReplay(runId)
|
|
133
|
-
for (let i = 0; i < 3; i++) {
|
|
134
|
-
await ws.inlineStep(runId, `step-${i}`, async () => 'must not run')
|
|
135
|
-
}
|
|
136
|
-
ws.endReplay(runId)
|
|
137
|
-
|
|
138
|
-
assert.equal(counter.reads, 3)
|
|
139
|
-
})
|
|
140
|
-
})
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { InMemoryWorkflowService } from '../../services/in-memory-workflow-service.js'
|
|
5
|
-
import { pikkuState } from '../../pikku-state.js'
|
|
6
|
-
import { DEFAULT_STEP_RETRIES } from './workflow-constants.js'
|
|
7
|
-
import type { PikkuWorkflowService } from './pikku-workflow-service.js'
|
|
8
|
-
import { deriveInvocationId } from './workflow-invocation-id.js'
|
|
9
|
-
import type { WorkflowStepOptions } from './workflow.types.js'
|
|
10
|
-
|
|
11
|
-
const UUID_RE =
|
|
12
|
-
/^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
|
|
13
|
-
|
|
14
|
-
class TestWorkflowService extends InMemoryWorkflowService {
|
|
15
|
-
public resolve(options?: WorkflowStepOptions) {
|
|
16
|
-
return (this as PikkuWorkflowService as any).resolveStepJobOptions(options)
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
describe('resolveStepJobOptions — workflow owns retry policy', () => {
|
|
21
|
-
const ws = new TestWorkflowService()
|
|
22
|
-
|
|
23
|
-
test('unset retries → default + exponential backoff (rides out outages)', () => {
|
|
24
|
-
assert.deepEqual(ws.resolve(undefined), {
|
|
25
|
-
attempts: DEFAULT_STEP_RETRIES + 1,
|
|
26
|
-
backoff: 'exponential',
|
|
27
|
-
})
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
test('retries: 0 → attempts: 1 and NO backoff (the non-idempotent opt-out)', () => {
|
|
31
|
-
assert.deepEqual(ws.resolve({ retries: 0 }), { attempts: 1 })
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
test('explicit retries always honored', () => {
|
|
35
|
-
assert.deepEqual(ws.resolve({ retries: 3 }), {
|
|
36
|
-
attempts: 4,
|
|
37
|
-
backoff: 'exponential',
|
|
38
|
-
})
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
test('numeric retryDelay → fixed backoff', () => {
|
|
42
|
-
assert.deepEqual(ws.resolve({ retries: 3, retryDelay: 250 }), {
|
|
43
|
-
attempts: 4,
|
|
44
|
-
backoff: { type: 'fixed', delay: 250 },
|
|
45
|
-
})
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
test("duration-string retryDelay ('15s') → fixed backoff in ms", () => {
|
|
49
|
-
assert.deepEqual(ws.resolve({ retries: 3, retryDelay: '15s' }), {
|
|
50
|
-
attempts: 4,
|
|
51
|
-
backoff: { type: 'fixed', delay: 15000 },
|
|
52
|
-
})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
test("retryDelay: 'exponential' → exponential backoff", () => {
|
|
56
|
-
assert.deepEqual(ws.resolve({ retries: 2, retryDelay: 'exponential' }), {
|
|
57
|
-
attempts: 3,
|
|
58
|
-
backoff: 'exponential',
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
describe('executeWorkflowStep surfaces a stable invocationId', () => {
|
|
64
|
-
test('invocationId is stable across a retry; stepId is per-attempt', async () => {
|
|
65
|
-
const ws = new InMemoryWorkflowService()
|
|
66
|
-
pikkuState(null, 'package', 'singletonServices', {
|
|
67
|
-
queueService: { add: async () => {} },
|
|
68
|
-
logger: { error() {}, info() {}, warn() {}, debug() {} },
|
|
69
|
-
} as any)
|
|
70
|
-
|
|
71
|
-
const captured: Array<{
|
|
72
|
-
invocationId: string
|
|
73
|
-
stepId: string
|
|
74
|
-
attemptCount: number
|
|
75
|
-
}> = []
|
|
76
|
-
const rpc = {
|
|
77
|
-
rpcWithWire: async (_n: string, _d: any, opts: any) => {
|
|
78
|
-
captured.push(opts.workflowStep)
|
|
79
|
-
if (captured.length === 1) throw new Error('transient boom')
|
|
80
|
-
return { ok: true }
|
|
81
|
-
},
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const runId = await ws.createRun('invflow', {}, false, 'hash', {
|
|
85
|
-
type: 'test',
|
|
86
|
-
})
|
|
87
|
-
await ws.insertStepState(runId, 'updateUser', 'doUpdateUser', {})
|
|
88
|
-
|
|
89
|
-
await assert.rejects(
|
|
90
|
-
ws.executeWorkflowStep(runId, 'updateUser', 'doUpdateUser', {}, rpc)
|
|
91
|
-
)
|
|
92
|
-
await ws.executeWorkflowStep(runId, 'updateUser', 'doUpdateUser', {}, rpc)
|
|
93
|
-
|
|
94
|
-
assert.equal(captured.length, 2, 'step ran twice')
|
|
95
|
-
assert.equal(
|
|
96
|
-
captured[0]!.invocationId,
|
|
97
|
-
captured[1]!.invocationId,
|
|
98
|
-
'invocationId is identical across retries — the dedupe key'
|
|
99
|
-
)
|
|
100
|
-
assert.equal(
|
|
101
|
-
captured[0]!.invocationId,
|
|
102
|
-
deriveInvocationId(runId, 'updateUser')
|
|
103
|
-
)
|
|
104
|
-
assert.match(captured[0]!.invocationId, UUID_RE)
|
|
105
|
-
assert.equal(captured[0]!.attemptCount, 1)
|
|
106
|
-
assert.equal(captured[1]!.attemptCount, 2)
|
|
107
|
-
assert.notEqual(
|
|
108
|
-
captured[0]!.stepId,
|
|
109
|
-
captured[1]!.stepId,
|
|
110
|
-
'stepId is minted per attempt — must NOT be used as the dedupe key'
|
|
111
|
-
)
|
|
112
|
-
})
|
|
113
|
-
})
|