@pikku/core 0.11.2 → 0.12.1
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 +57 -2
- package/dist/crypto-utils.d.ts +2 -0
- package/dist/crypto-utils.js +78 -0
- package/dist/errors/errors.d.ts +14 -0
- package/dist/errors/errors.js +26 -0
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/function/function-runner.d.ts +10 -4
- package/dist/function/function-runner.js +126 -45
- package/dist/function/functions.types.d.ts +32 -87
- package/dist/function/functions.types.js +16 -46
- package/dist/function/index.d.ts +2 -2
- package/dist/function/index.js +1 -2
- package/dist/handle-error.d.ts +2 -2
- package/dist/handle-error.js +3 -12
- package/dist/index.d.ts +30 -26
- package/dist/index.js +19 -29
- package/dist/internal.d.ts +3 -0
- package/dist/internal.js +2 -0
- package/dist/middleware/auth-apikey.d.ts +2 -2
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.d.ts +3 -3
- package/dist/middleware/auth-bearer.js +4 -7
- package/dist/middleware/auth-cookie.d.ts +4 -4
- package/dist/middleware/auth-cookie.js +7 -9
- package/dist/middleware/cors.d.ts +46 -0
- package/dist/middleware/cors.js +81 -0
- package/dist/middleware/index.d.ts +5 -3
- package/dist/middleware/index.js +5 -3
- package/dist/middleware/remote-auth.d.ts +5 -0
- package/dist/middleware/remote-auth.js +55 -0
- package/dist/middleware/timeout.d.ts +2 -2
- package/dist/middleware-runner.d.ts +1 -1
- package/dist/middleware-runner.js +8 -10
- package/dist/permissions.d.ts +2 -2
- package/dist/permissions.js +11 -15
- package/dist/pikku-state.d.ts +10 -8
- package/dist/pikku-state.js +48 -25
- package/dist/schema.d.ts +4 -4
- package/dist/schema.js +20 -15
- package/dist/services/ai-agent-runner-service.d.ts +43 -0
- package/dist/services/ai-agent-runner-service.js +1 -0
- package/dist/services/ai-run-state-service.d.ts +13 -0
- package/dist/services/ai-run-state-service.js +1 -0
- package/dist/services/ai-storage-service.d.ts +18 -0
- package/dist/services/ai-storage-service.js +1 -0
- package/dist/services/content-service.d.ts +6 -0
- package/dist/services/deployment-service.d.ts +19 -0
- package/dist/services/deployment-service.js +1 -0
- package/dist/services/gopass-secrets.d.ts +47 -0
- package/dist/services/gopass-secrets.js +97 -0
- package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
- package/dist/services/in-memory-ai-run-state-service.js +44 -0
- package/dist/services/in-memory-trigger-service.d.ts +22 -0
- package/dist/services/in-memory-trigger-service.js +48 -0
- package/dist/services/in-memory-workflow-service.d.ts +59 -0
- package/dist/services/in-memory-workflow-service.js +287 -0
- package/dist/services/index.d.ts +26 -11
- package/dist/services/index.js +11 -13
- package/dist/services/local-content.d.ts +2 -1
- package/dist/services/local-content.js +6 -1
- package/dist/services/local-secrets.d.ts +25 -2
- package/dist/services/local-secrets.js +45 -0
- package/dist/services/local-variables.d.ts +6 -1
- package/dist/services/local-variables.js +18 -0
- package/dist/services/logger-console.d.ts +2 -1
- package/dist/services/scheduler-service.d.ts +9 -1
- package/dist/services/scheduler-service.js +8 -0
- package/dist/services/schema-service.d.ts +6 -0
- package/dist/services/scoped-secret-service.d.ts +16 -0
- package/dist/services/scoped-secret-service.js +35 -0
- package/dist/services/secret-service.d.ts +25 -4
- package/dist/services/trigger-service.d.ts +16 -0
- package/dist/services/trigger-service.js +1 -0
- package/dist/services/typed-secret-service.d.ts +30 -0
- package/dist/services/typed-secret-service.js +40 -0
- package/dist/services/typed-variables-service.d.ts +27 -0
- package/dist/services/typed-variables-service.js +46 -0
- package/dist/services/user-session-service.d.ts +15 -2
- package/dist/services/user-session-service.js +17 -0
- package/dist/services/variables-service.d.ts +5 -0
- package/dist/services/workflow-service.d.ts +9 -5
- package/dist/types/core.types.d.ts +67 -25
- package/dist/types/core.types.js +8 -1
- package/dist/types/state.types.d.ts +53 -59
- package/dist/utils.d.ts +7 -6
- package/dist/utils.js +27 -12
- package/dist/version.d.ts +6 -0
- package/dist/version.js +19 -0
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
- package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +146 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +29 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +199 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +9 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.js +36 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +59 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +348 -0
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +15 -0
- package/dist/wirings/ai-agent/ai-agent-registry.js +47 -0
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +3 -0
- package/dist/wirings/ai-agent/ai-agent-runner.js +195 -0
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +12 -0
- package/dist/wirings/ai-agent/ai-agent-stream.js +662 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +313 -0
- package/dist/wirings/ai-agent/ai-agent.types.js +1 -0
- package/dist/wirings/ai-agent/index.d.ts +7 -0
- package/dist/wirings/ai-agent/index.js +6 -0
- package/dist/wirings/channel/channel-common.d.ts +8 -5
- package/dist/wirings/channel/channel-common.js +15 -8
- package/dist/wirings/channel/channel-handler.d.ts +3 -3
- package/dist/wirings/channel/channel-handler.js +15 -6
- package/dist/wirings/channel/channel-middleware-runner.d.ts +9 -0
- package/dist/wirings/channel/channel-middleware-runner.js +73 -0
- package/dist/wirings/channel/channel-runner.d.ts +5 -5
- package/dist/wirings/channel/channel-runner.js +10 -9
- package/dist/wirings/channel/channel-store.d.ts +1 -1
- package/dist/wirings/channel/channel.types.d.ts +9 -7
- package/dist/wirings/channel/define-channel-routes.d.ts +21 -0
- package/dist/wirings/channel/define-channel-routes.js +23 -0
- package/dist/wirings/channel/index.d.ts +10 -8
- package/dist/wirings/channel/index.js +7 -8
- package/dist/wirings/channel/local/index.d.ts +3 -3
- package/dist/wirings/channel/local/index.js +3 -3
- package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
- package/dist/wirings/channel/local/local-channel-runner.js +22 -9
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
- package/dist/wirings/channel/log-channels.d.ts +1 -1
- package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +1 -1
- package/dist/wirings/channel/serverless/index.d.ts +1 -1
- package/dist/wirings/channel/serverless/index.js +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +4 -4
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +40 -23
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
- package/dist/wirings/cli/channel/index.d.ts +1 -1
- package/dist/wirings/cli/channel/index.js +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +3 -3
- package/dist/wirings/cli/cli-runner.js +12 -8
- package/dist/wirings/cli/cli.types.d.ts +9 -9
- package/dist/wirings/cli/command-parser.d.ts +1 -1
- package/dist/wirings/cli/define-cli-commands.d.ts +19 -0
- package/dist/wirings/cli/define-cli-commands.js +20 -0
- package/dist/wirings/cli/index.d.ts +2 -3
- package/dist/wirings/cli/index.js +1 -3
- package/dist/wirings/http/http-routes.d.ts +69 -0
- package/dist/wirings/http/http-routes.js +139 -0
- package/dist/wirings/http/http-runner.d.ts +9 -9
- package/dist/wirings/http/http-runner.js +79 -34
- package/dist/wirings/http/http.types.d.ts +77 -41
- package/dist/wirings/http/index.d.ts +5 -4
- package/dist/wirings/http/index.js +4 -3
- package/dist/wirings/http/log-http-routes.d.ts +1 -1
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
- package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
- package/dist/wirings/http/routers/http-router.d.ts +1 -1
- package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
- package/dist/wirings/mcp/index.d.ts +4 -3
- package/dist/wirings/mcp/index.js +3 -3
- package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
- package/dist/wirings/mcp/mcp-runner.d.ts +1 -6
- package/dist/wirings/mcp/mcp-runner.js +28 -40
- package/dist/wirings/mcp/mcp.types.d.ts +5 -5
- package/dist/wirings/node/index.d.ts +2 -0
- package/dist/wirings/node/index.js +1 -0
- package/dist/wirings/node/node.types.d.ts +20 -0
- package/dist/wirings/node/node.types.js +1 -0
- package/dist/wirings/oauth2/index.d.ts +3 -0
- package/dist/wirings/oauth2/index.js +2 -0
- package/dist/wirings/oauth2/oauth2-client.d.ts +47 -0
- package/dist/wirings/oauth2/oauth2-client.js +267 -0
- package/dist/wirings/oauth2/oauth2.types.d.ts +65 -0
- package/dist/wirings/oauth2/oauth2.types.js +4 -0
- package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +20 -0
- package/dist/wirings/oauth2/wire-oauth2-credential.js +21 -0
- package/dist/wirings/queue/index.d.ts +1 -1
- package/dist/wirings/queue/queue-runner.d.ts +1 -5
- package/dist/wirings/queue/queue-runner.js +11 -8
- package/dist/wirings/queue/queue.types.d.ts +5 -5
- package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
- package/dist/wirings/queue/register-queue-helper.js +1 -1
- package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
- package/dist/wirings/rpc/index.d.ts +3 -1
- package/dist/wirings/rpc/index.js +2 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +58 -8
- package/dist/wirings/rpc/rpc-runner.js +177 -31
- package/dist/wirings/rpc/rpc-types.d.ts +20 -4
- package/dist/wirings/rpc/wire-addon.d.ts +10 -0
- package/dist/wirings/rpc/wire-addon.js +9 -0
- package/dist/wirings/scheduler/index.d.ts +2 -2
- package/dist/wirings/scheduler/index.js +1 -2
- package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -5
- package/dist/wirings/scheduler/scheduler-runner.js +11 -14
- package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
- package/dist/wirings/secret/index.d.ts +3 -0
- package/dist/wirings/secret/index.js +2 -0
- package/dist/wirings/secret/secret.types.d.ts +27 -0
- package/dist/wirings/secret/secret.types.js +1 -0
- package/dist/wirings/secret/validate-secret-definitions.d.ts +6 -0
- package/dist/wirings/secret/validate-secret-definitions.js +55 -0
- package/dist/wirings/trigger/index.d.ts +3 -2
- package/dist/wirings/trigger/index.js +2 -2
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +22 -0
- package/dist/wirings/trigger/pikku-trigger-service.js +70 -0
- package/dist/wirings/trigger/trigger-runner.d.ts +18 -9
- package/dist/wirings/trigger/trigger-runner.js +48 -19
- package/dist/wirings/trigger/trigger.types.d.ts +99 -11
- package/dist/wirings/trigger/trigger.types.js +40 -1
- package/dist/wirings/variable/index.d.ts +3 -0
- package/dist/wirings/variable/index.js +2 -0
- package/dist/wirings/variable/validate-variable-definitions.d.ts +6 -0
- package/dist/wirings/variable/validate-variable-definitions.js +45 -0
- package/dist/wirings/variable/variable.types.d.ts +18 -0
- package/dist/wirings/variable/variable.types.js +1 -0
- package/dist/wirings/workflow/dsl/index.d.ts +1 -1
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +7 -1
- package/dist/wirings/workflow/dsl/workflow-runner.js +3 -2
- package/dist/wirings/workflow/graph/graph-node.d.ts +1 -6
- package/dist/wirings/workflow/graph/graph-runner.d.ts +5 -31
- package/dist/wirings/workflow/graph/graph-runner.js +384 -296
- package/dist/wirings/workflow/graph/index.d.ts +4 -3
- package/dist/wirings/workflow/graph/index.js +3 -3
- package/dist/wirings/workflow/graph/template.d.ts +15 -0
- package/dist/wirings/workflow/graph/template.js +27 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +15 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.js +8 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -13
- package/dist/wirings/workflow/index.d.ts +6 -6
- package/dist/wirings/workflow/index.js +6 -4
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +29 -19
- package/dist/wirings/workflow/pikku-workflow-service.js +217 -82
- package/dist/wirings/workflow/workflow-helpers.d.ts +36 -0
- package/dist/wirings/workflow/workflow-helpers.js +38 -0
- package/dist/wirings/workflow/workflow.types.d.ts +42 -95
- package/package.json +14 -15
- package/run-tests.sh +4 -1
- package/src/crypto-utils.test.ts +116 -0
- package/src/crypto-utils.ts +99 -0
- package/src/errors/error.test.ts +143 -2
- package/src/errors/errors.ts +27 -0
- package/src/errors/index.ts +1 -1
- package/src/factory-functions.test.ts +42 -2
- package/src/function/function-runner.test.ts +6 -13
- package/src/function/function-runner.ts +161 -53
- package/src/function/functions.types.ts +63 -132
- package/src/function/index.ts +5 -2
- package/src/handle-error.test.ts +361 -0
- package/src/handle-error.ts +6 -14
- package/src/index.ts +97 -30
- package/src/internal.ts +6 -0
- package/src/middleware/auth-apikey.test.ts +16 -13
- package/src/middleware/auth-apikey.ts +3 -3
- package/src/middleware/auth-bearer.test.ts +18 -15
- package/src/middleware/auth-bearer.ts +27 -32
- package/src/middleware/auth-cookie.test.ts +17 -14
- package/src/middleware/auth-cookie.ts +9 -13
- package/src/middleware/cors.test.ts +424 -0
- package/src/middleware/cors.ts +104 -0
- package/src/middleware/index.ts +5 -3
- package/src/middleware/remote-auth.test.ts +488 -0
- package/src/middleware/remote-auth.ts +68 -0
- package/src/middleware-runner.test.ts +123 -1
- package/src/middleware-runner.ts +13 -13
- package/src/permissions.test.ts +83 -9
- package/src/permissions.ts +17 -19
- package/src/pikku-state.test.ts +224 -0
- package/src/pikku-state.ts +59 -35
- package/src/run-tests-script.test.ts +49 -0
- package/src/schema.test.ts +198 -6
- package/src/schema.ts +28 -21
- package/src/services/ai-agent-runner-service.ts +41 -0
- package/src/services/ai-run-state-service.ts +20 -0
- package/src/services/ai-storage-service.ts +39 -0
- package/src/services/content-service.ts +7 -0
- package/src/services/deployment-service.ts +22 -0
- package/src/services/gopass-secrets.ts +98 -0
- package/src/services/in-memory-ai-run-state-service.ts +73 -0
- package/src/services/in-memory-trigger-service.ts +64 -0
- package/src/services/in-memory-workflow-service.test.ts +351 -0
- package/src/services/in-memory-workflow-service.ts +395 -0
- package/src/services/index.ts +50 -14
- package/src/services/local-content.ts +9 -3
- package/src/services/local-secrets.test.ts +80 -0
- package/src/services/local-secrets.ts +53 -2
- package/src/services/local-variables.test.ts +61 -0
- package/src/services/local-variables.ts +23 -1
- package/src/services/logger-console.test.ts +118 -0
- package/src/services/logger-console.ts +2 -1
- package/src/services/scheduler-service.ts +11 -1
- package/src/services/schema-service.ts +7 -0
- package/src/services/scoped-secret-service.test.ts +74 -0
- package/src/services/scoped-secret-service.ts +41 -0
- package/src/services/secret-service.ts +25 -4
- package/src/services/trigger-service.ts +17 -0
- package/src/services/typed-secret-service.test.ts +93 -0
- package/src/services/typed-secret-service.ts +70 -0
- package/src/services/typed-variables-service.test.ts +73 -0
- package/src/services/typed-variables-service.ts +81 -0
- package/src/services/user-session-service.test.ts +113 -0
- package/src/services/user-session-service.ts +25 -2
- package/src/services/variables-service.ts +5 -0
- package/src/services/workflow-service.ts +23 -13
- package/src/time-utils.test.ts +1 -1
- package/src/types/core.types.ts +95 -24
- package/src/types/state.types.ts +56 -73
- package/src/utils.test.ts +350 -0
- package/src/utils.ts +33 -18
- package/src/version.test.ts +80 -0
- package/src/version.ts +25 -0
- package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
- package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +214 -0
- package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
- package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +300 -0
- package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
- package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +504 -0
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +37 -0
- package/src/wirings/ai-agent/ai-agent-registry.ts +82 -0
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +317 -0
- package/src/wirings/ai-agent/ai-agent-runner.ts +251 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +652 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +1049 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +328 -0
- package/src/wirings/ai-agent/index.ts +39 -0
- package/src/wirings/channel/channel-common.ts +33 -20
- package/src/wirings/channel/channel-handler.ts +26 -9
- package/src/wirings/channel/channel-middleware-runner.ts +119 -0
- package/src/wirings/channel/channel-runner.ts +15 -16
- package/src/wirings/channel/channel-store.ts +1 -1
- package/src/wirings/channel/channel.types.ts +21 -9
- package/src/wirings/channel/define-channel-routes.ts +25 -0
- package/src/wirings/channel/index.ts +23 -8
- package/src/wirings/channel/local/index.ts +3 -3
- package/src/wirings/channel/local/local-channel-runner.test.ts +57 -7
- package/src/wirings/channel/local/local-channel-runner.ts +40 -19
- package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
- package/src/wirings/channel/log-channels.ts +1 -1
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +1 -1
- package/src/wirings/channel/serverless/index.ts +5 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +57 -36
- package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
- package/src/wirings/cli/channel/index.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +10 -10
- package/src/wirings/cli/cli-runner.ts +28 -14
- package/src/wirings/cli/cli.types.ts +14 -14
- package/src/wirings/cli/command-parser.test.ts +9 -9
- package/src/wirings/cli/command-parser.ts +1 -1
- package/src/wirings/cli/define-cli-commands.ts +24 -0
- package/src/wirings/cli/index.ts +10 -4
- package/src/wirings/http/http-routes.test.ts +322 -0
- package/src/wirings/http/http-routes.ts +198 -0
- package/src/wirings/http/http-runner.test.ts +12 -20
- package/src/wirings/http/http-runner.ts +101 -51
- package/src/wirings/http/http.types.ts +119 -48
- package/src/wirings/http/index.ts +16 -4
- package/src/wirings/http/log-http-routes.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
- package/src/wirings/http/routers/http-router.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.ts +4 -3
- package/src/wirings/mcp/index.ts +27 -3
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +3 -3
- package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
- package/src/wirings/mcp/mcp-runner.ts +48 -65
- package/src/wirings/mcp/mcp.types.ts +5 -5
- package/src/wirings/node/index.ts +2 -0
- package/src/wirings/node/node.types.ts +23 -0
- package/src/wirings/oauth2/index.ts +3 -0
- package/src/wirings/oauth2/oauth2-client.test.ts +929 -0
- package/src/wirings/oauth2/oauth2-client.ts +335 -0
- package/src/wirings/oauth2/oauth2.types.ts +69 -0
- package/src/wirings/oauth2/wire-oauth2-credential.ts +23 -0
- package/src/wirings/queue/index.ts +13 -2
- package/src/wirings/queue/queue-runner.test.ts +142 -73
- package/src/wirings/queue/queue-runner.ts +18 -14
- package/src/wirings/queue/queue.types.ts +5 -5
- package/src/wirings/queue/register-queue-helper.ts +3 -5
- package/src/wirings/queue/validate-worker-config.test.ts +108 -0
- package/src/wirings/queue/validate-worker-config.ts +4 -1
- package/src/wirings/rpc/index.ts +3 -1
- package/src/wirings/rpc/rpc-runner.ts +254 -41
- package/src/wirings/rpc/rpc-types.ts +28 -4
- package/src/wirings/rpc/wire-addon.ts +20 -0
- package/src/wirings/scheduler/index.ts +6 -4
- package/src/wirings/scheduler/log-schedulers.ts +1 -1
- package/src/wirings/scheduler/scheduler-runner.test.ts +78 -45
- package/src/wirings/scheduler/scheduler-runner.ts +20 -27
- package/src/wirings/scheduler/scheduler.types.ts +2 -2
- package/src/wirings/secret/index.ts +9 -0
- package/src/wirings/secret/secret.types.ts +32 -0
- package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
- package/src/wirings/secret/validate-secret-definitions.ts +82 -0
- package/src/wirings/trigger/index.ts +10 -2
- package/src/wirings/trigger/pikku-trigger-service.ts +112 -0
- package/src/wirings/trigger/trigger-runner.test.ts +79 -0
- package/src/wirings/trigger/trigger-runner.ts +80 -41
- package/src/wirings/trigger/trigger.types.ts +144 -22
- package/src/wirings/variable/index.ts +8 -0
- package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
- package/src/wirings/variable/validate-variable-definitions.ts +69 -0
- package/src/wirings/variable/variable.types.ts +22 -0
- package/src/wirings/workflow/dsl/index.ts +1 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +9 -1
- package/src/wirings/workflow/dsl/workflow-runner.ts +4 -3
- package/src/wirings/workflow/graph/graph-node.ts +1 -6
- package/src/wirings/workflow/graph/graph-runner.test.ts +487 -0
- package/src/wirings/workflow/graph/graph-runner.ts +496 -374
- package/src/wirings/workflow/graph/index.ts +14 -3
- package/src/wirings/workflow/graph/template.test.ts +49 -0
- package/src/wirings/workflow/graph/template.ts +42 -0
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +29 -0
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -22
- package/src/wirings/workflow/index.ts +21 -10
- package/src/wirings/workflow/pikku-workflow-service.test.ts +200 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +308 -105
- package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
- package/src/wirings/workflow/workflow-helpers.ts +79 -0
- package/src/wirings/workflow/workflow.types.ts +47 -92
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/forge-node/forge-node.types.d.ts +0 -120
- package/dist/wirings/forge-node/forge-node.types.js +0 -38
- package/dist/wirings/forge-node/index.d.ts +0 -1
- package/dist/wirings/forge-node/index.js +0 -1
- package/dist/wirings/workflow/wire-workflow.d.ts +0 -42
- package/dist/wirings/workflow/wire-workflow.js +0 -53
- package/dist/wirings/workflow/workflow-utils.d.ts +0 -23
- package/dist/wirings/workflow/workflow-utils.js +0 -66
- package/src/wirings/forge-node/forge-node.types.ts +0 -135
- package/src/wirings/forge-node/index.ts +0 -1
- package/src/wirings/workflow/wire-workflow.ts +0 -94
- package/src/wirings/workflow/workflow-utils.ts +0 -120
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
import { runPikkuFunc } from '../../function/function-runner.js'
|
|
2
|
-
import { pikkuState } from '../../pikku-state.js'
|
|
3
|
-
import { getDurationInMilliseconds } from '../../time-utils.js'
|
|
4
2
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from '../../types/core.types.js'
|
|
11
|
-
import { QueueService } from '../queue/queue.types.js'
|
|
3
|
+
getSingletonServices,
|
|
4
|
+
getCreateWireServices,
|
|
5
|
+
pikkuState,
|
|
6
|
+
} from '../../pikku-state.js'
|
|
7
|
+
import { getDurationInMilliseconds } from '../../time-utils.js'
|
|
8
|
+
import type { PikkuWire, SerializedError } from '../../types/core.types.js'
|
|
9
|
+
import type { QueueService } from '../queue/queue.types.js'
|
|
12
10
|
import type {
|
|
13
11
|
PikkuWorkflowWire,
|
|
14
12
|
StepState,
|
|
15
13
|
WorkflowRun,
|
|
14
|
+
WorkflowRunWire,
|
|
16
15
|
WorkflowStatus,
|
|
17
16
|
WorkflowServiceConfig,
|
|
18
17
|
WorkflowStepOptions,
|
|
19
18
|
} from './workflow.types.js'
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
import {
|
|
20
|
+
continueGraph,
|
|
21
|
+
executeGraphStep,
|
|
22
|
+
runWorkflowGraph,
|
|
23
|
+
runFromMeta,
|
|
24
|
+
} from './graph/graph-runner.js'
|
|
25
|
+
import type { WorkflowService } from '../../services/workflow-service.js'
|
|
26
|
+
import { PikkuError, addError } from '../../errors/error-handler.js'
|
|
27
|
+
import { RPCNotFoundError } from '../rpc/rpc-runner.js'
|
|
23
28
|
|
|
24
29
|
/**
|
|
25
30
|
* Exception thrown when workflow needs to pause for async step
|
|
@@ -47,6 +52,19 @@ export class WorkflowCancelledException extends Error {
|
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Exception thrown when workflow is suspended
|
|
57
|
+
*/
|
|
58
|
+
export class WorkflowSuspendedException extends Error {
|
|
59
|
+
constructor(
|
|
60
|
+
public readonly runId: string,
|
|
61
|
+
public readonly reason: string
|
|
62
|
+
) {
|
|
63
|
+
super(reason || 'Workflow suspended')
|
|
64
|
+
this.name = 'WorkflowSuspendedException'
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
50
68
|
/**
|
|
51
69
|
* Error class for workflow not found
|
|
52
70
|
*/
|
|
@@ -55,15 +73,20 @@ export class WorkflowNotFoundError extends PikkuError {
|
|
|
55
73
|
super(`Workflow not found: ${name}`)
|
|
56
74
|
}
|
|
57
75
|
}
|
|
76
|
+
addError(WorkflowNotFoundError, {
|
|
77
|
+
status: 404,
|
|
78
|
+
message: 'Workflow not found.',
|
|
79
|
+
})
|
|
58
80
|
|
|
59
|
-
|
|
60
|
-
* Error class for workflow not found
|
|
61
|
-
*/
|
|
62
|
-
export class WorkflowRunNotFound extends PikkuError {
|
|
81
|
+
export class WorkflowRunNotFoundError extends PikkuError {
|
|
63
82
|
constructor(runId: string) {
|
|
64
83
|
super(`Workflow run not found: ${runId}`)
|
|
65
84
|
}
|
|
66
85
|
}
|
|
86
|
+
addError(WorkflowRunNotFoundError, {
|
|
87
|
+
status: 404,
|
|
88
|
+
message: 'Workflow run not found.',
|
|
89
|
+
})
|
|
67
90
|
|
|
68
91
|
export class WorkflowServiceNotInitialized extends Error {}
|
|
69
92
|
export class WorkflowStepNameNotString extends Error {
|
|
@@ -72,15 +95,19 @@ export class WorkflowStepNameNotString extends Error {
|
|
|
72
95
|
}
|
|
73
96
|
}
|
|
74
97
|
|
|
98
|
+
const WORKFLOW_END_STATES: ReadonlySet<string> = new Set([
|
|
99
|
+
'completed',
|
|
100
|
+
'failed',
|
|
101
|
+
'cancelled',
|
|
102
|
+
'suspended',
|
|
103
|
+
])
|
|
104
|
+
|
|
75
105
|
/**
|
|
76
106
|
* Abstract workflow state service
|
|
77
107
|
* Implementations provide pluggable storage backends (SQLite, PostgreSQL, etc.)
|
|
78
108
|
* Combines orchestration and step execution
|
|
79
109
|
*/
|
|
80
110
|
export abstract class PikkuWorkflowService implements WorkflowService {
|
|
81
|
-
private config: WorkflowServiceConfig | undefined
|
|
82
|
-
private singletonServices: CoreSingletonServices | undefined
|
|
83
|
-
private createWireServices: CreateWireServices | undefined
|
|
84
111
|
private inlineRuns = new Set<string>()
|
|
85
112
|
|
|
86
113
|
constructor() {}
|
|
@@ -106,34 +133,20 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
106
133
|
this.inlineRuns.delete(runId)
|
|
107
134
|
}
|
|
108
135
|
|
|
109
|
-
public
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
this.singletonServices = singletonServices
|
|
115
|
-
this.createWireServices = createWireServices
|
|
116
|
-
this.config = {
|
|
117
|
-
retries: workflow?.retries ?? 0,
|
|
118
|
-
retryDelay: workflow?.retryDelay ?? 0,
|
|
119
|
-
orchestratorQueueName:
|
|
120
|
-
workflow?.orchestratorQueueName ?? 'pikku-workflow-orchestrator',
|
|
121
|
-
stepWorkerQueueName:
|
|
122
|
-
workflow?.stepWorkerQueueName ?? 'pikku-workflow-step-worker',
|
|
123
|
-
sleeperRPCName: workflow?.sleeperRPCName ?? 'pikkuWorkflowSleeper',
|
|
136
|
+
public async registerWorkflowVersions(): Promise<void> {
|
|
137
|
+
const allMeta = pikkuState(null, 'workflows', 'meta')
|
|
138
|
+
for (const [name, meta] of Object.entries(allMeta)) {
|
|
139
|
+
if (!meta.graphHash) continue
|
|
140
|
+
await this.upsertWorkflowVersion(name, meta.graphHash, meta, meta.source)
|
|
124
141
|
}
|
|
125
142
|
}
|
|
126
143
|
|
|
127
|
-
/**
|
|
128
|
-
* Create a new workflow run
|
|
129
|
-
* @param name - Workflow name
|
|
130
|
-
* @param input - Input data for the workflow
|
|
131
|
-
* @returns Run ID
|
|
132
|
-
*/
|
|
133
144
|
abstract createRun(
|
|
134
145
|
workflowName: string,
|
|
135
146
|
input: any,
|
|
136
|
-
inline
|
|
147
|
+
inline: boolean,
|
|
148
|
+
graphHash: string,
|
|
149
|
+
wire: WorkflowRunWire
|
|
137
150
|
): Promise<string>
|
|
138
151
|
|
|
139
152
|
/**
|
|
@@ -270,6 +283,7 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
270
283
|
*/
|
|
271
284
|
abstract getCompletedGraphState(runId: string): Promise<{
|
|
272
285
|
completedNodeIds: string[]
|
|
286
|
+
failedNodeIds: string[]
|
|
273
287
|
branchKeys: Record<string, string>
|
|
274
288
|
}>
|
|
275
289
|
|
|
@@ -321,6 +335,18 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
321
335
|
*/
|
|
322
336
|
abstract getRunState(runId: string): Promise<Record<string, unknown>>
|
|
323
337
|
|
|
338
|
+
abstract upsertWorkflowVersion(
|
|
339
|
+
name: string,
|
|
340
|
+
graphHash: string,
|
|
341
|
+
graph: any,
|
|
342
|
+
source: string
|
|
343
|
+
): Promise<void>
|
|
344
|
+
|
|
345
|
+
abstract getWorkflowVersion(
|
|
346
|
+
name: string,
|
|
347
|
+
graphHash: string
|
|
348
|
+
): Promise<{ graph: any; source: string } | null>
|
|
349
|
+
|
|
324
350
|
// ============================================================================
|
|
325
351
|
// Workflow Lifecycle Methods
|
|
326
352
|
// ============================================================================
|
|
@@ -334,6 +360,21 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
334
360
|
await queueService.add(this.getConfig().orchestratorQueueName, { runId })
|
|
335
361
|
}
|
|
336
362
|
|
|
363
|
+
public async queueStepWorker(
|
|
364
|
+
runId: string,
|
|
365
|
+
stepName: string,
|
|
366
|
+
rpcName: string,
|
|
367
|
+
data: any
|
|
368
|
+
): Promise<void> {
|
|
369
|
+
const queueService = this.verifyQueueService()
|
|
370
|
+
await queueService.add(this.getConfig().stepWorkerQueueName, {
|
|
371
|
+
runId,
|
|
372
|
+
stepName,
|
|
373
|
+
rpcName,
|
|
374
|
+
data,
|
|
375
|
+
})
|
|
376
|
+
}
|
|
377
|
+
|
|
337
378
|
/**
|
|
338
379
|
* Execute a workflow sleep step completion
|
|
339
380
|
* Sets the step result to null and resumes the workflow
|
|
@@ -373,6 +414,7 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
373
414
|
public async startWorkflow<I>(
|
|
374
415
|
name: string,
|
|
375
416
|
input: I,
|
|
417
|
+
wire: WorkflowRunWire,
|
|
376
418
|
rpcService: any,
|
|
377
419
|
options?: { inline?: boolean; startNode?: string }
|
|
378
420
|
): Promise<{ runId: string }> {
|
|
@@ -386,14 +428,16 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
386
428
|
|
|
387
429
|
// Check if this is a graph workflow (source === 'graph')
|
|
388
430
|
if (workflowMeta.source === 'graph') {
|
|
389
|
-
|
|
431
|
+
const shouldInline =
|
|
432
|
+
options?.inline || !getSingletonServices()?.queueService
|
|
390
433
|
return runWorkflowGraph(
|
|
391
434
|
this,
|
|
392
435
|
name,
|
|
393
436
|
input,
|
|
394
437
|
rpcService,
|
|
395
|
-
|
|
396
|
-
options?.startNode
|
|
438
|
+
shouldInline,
|
|
439
|
+
options?.startNode,
|
|
440
|
+
wire
|
|
397
441
|
)
|
|
398
442
|
}
|
|
399
443
|
|
|
@@ -405,36 +449,90 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
405
449
|
throw new WorkflowNotFoundError(name)
|
|
406
450
|
}
|
|
407
451
|
|
|
408
|
-
|
|
409
|
-
|
|
452
|
+
if (!workflowMeta.graphHash) {
|
|
453
|
+
throw new Error(`Missing workflow graphHash for '${name}'`)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const runId = await this.createRun(
|
|
457
|
+
name,
|
|
458
|
+
input,
|
|
459
|
+
options?.inline ?? false,
|
|
460
|
+
workflowMeta.graphHash,
|
|
461
|
+
wire
|
|
462
|
+
)
|
|
410
463
|
|
|
411
|
-
// Register inline run for fast lookup
|
|
412
464
|
if (options?.inline) {
|
|
413
465
|
this.inlineRuns.add(runId)
|
|
414
466
|
}
|
|
415
467
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
468
|
+
if (options?.inline || !getSingletonServices()?.queueService) {
|
|
469
|
+
this.runWorkflowJob(runId, rpcService)
|
|
470
|
+
.catch(() => {})
|
|
471
|
+
.finally(() => {
|
|
472
|
+
if (options?.inline) {
|
|
473
|
+
this.inlineRuns.delete(runId)
|
|
474
|
+
}
|
|
475
|
+
})
|
|
476
|
+
} else {
|
|
477
|
+
await this.resumeWorkflow(runId)
|
|
478
|
+
}
|
|
424
479
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
480
|
+
return { runId }
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
public async runToCompletion<I>(
|
|
484
|
+
name: string,
|
|
485
|
+
input: I,
|
|
486
|
+
rpcService: any,
|
|
487
|
+
options?: { pollIntervalMs?: number; wire?: WorkflowRunWire }
|
|
488
|
+
): Promise<any> {
|
|
489
|
+
const pollInterval = options?.pollIntervalMs ?? 1000
|
|
490
|
+
const { runId } = await this.startWorkflow(
|
|
491
|
+
name,
|
|
492
|
+
input,
|
|
493
|
+
options?.wire ?? { type: 'internal' },
|
|
494
|
+
rpcService,
|
|
495
|
+
{ inline: true }
|
|
496
|
+
)
|
|
497
|
+
while (true) {
|
|
498
|
+
const run = await this.getRun(runId)
|
|
499
|
+
if (!run) {
|
|
500
|
+
throw new WorkflowRunNotFoundError(runId)
|
|
430
501
|
}
|
|
502
|
+
if (WORKFLOW_END_STATES.has(run.status)) {
|
|
503
|
+
if (run.status === 'failed') {
|
|
504
|
+
throw new Error(run.error?.message || 'Workflow failed')
|
|
505
|
+
}
|
|
506
|
+
if (run.status === 'cancelled') {
|
|
507
|
+
throw new Error('Workflow was cancelled')
|
|
508
|
+
}
|
|
509
|
+
return run.output
|
|
510
|
+
}
|
|
511
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval))
|
|
431
512
|
}
|
|
432
513
|
}
|
|
433
514
|
|
|
434
515
|
public async runWorkflowJob(runId: string, rpcService: any): Promise<void> {
|
|
435
516
|
const run = await this.getRun(runId)
|
|
436
517
|
if (!run) {
|
|
437
|
-
throw new
|
|
518
|
+
throw new WorkflowRunNotFoundError(runId)
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const meta = pikkuState(null, 'workflows', 'meta')
|
|
522
|
+
const workflowMeta = meta[run.workflow]
|
|
523
|
+
|
|
524
|
+
if (
|
|
525
|
+
run.graphHash &&
|
|
526
|
+
workflowMeta?.graphHash &&
|
|
527
|
+
run.graphHash !== workflowMeta.graphHash
|
|
528
|
+
) {
|
|
529
|
+
await this.runVersionMismatchFallback(run, workflowMeta, rpcService)
|
|
530
|
+
return
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (workflowMeta?.source === 'graph') {
|
|
534
|
+
await continueGraph(this, runId, run.workflow)
|
|
535
|
+
return
|
|
438
536
|
}
|
|
439
537
|
|
|
440
538
|
const registrations = pikkuState(null, 'workflows', 'registrations')
|
|
@@ -444,9 +542,6 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
444
542
|
}
|
|
445
543
|
|
|
446
544
|
await this.withRunLock(runId, async () => {
|
|
447
|
-
const meta = pikkuState(null, 'workflows', 'meta')
|
|
448
|
-
const workflowMeta = meta[run.workflow]
|
|
449
|
-
|
|
450
545
|
const workflowWire = this.createWorkflowWire(
|
|
451
546
|
run.workflow,
|
|
452
547
|
runId,
|
|
@@ -457,11 +552,11 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
457
552
|
const result = await runPikkuFunc(
|
|
458
553
|
'workflow',
|
|
459
554
|
workflowMeta.name,
|
|
460
|
-
workflowMeta.
|
|
555
|
+
workflowMeta.pikkuFuncId,
|
|
461
556
|
{
|
|
462
|
-
singletonServices:
|
|
557
|
+
singletonServices: getSingletonServices()!,
|
|
463
558
|
wire,
|
|
464
|
-
createWireServices:
|
|
559
|
+
createWireServices: getCreateWireServices(),
|
|
465
560
|
data: () => run.input,
|
|
466
561
|
}
|
|
467
562
|
)
|
|
@@ -469,13 +564,10 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
469
564
|
await this.updateRunStatus(runId, 'completed', result)
|
|
470
565
|
} catch (error: any) {
|
|
471
566
|
if (error instanceof WorkflowAsyncException) {
|
|
472
|
-
// Normal - workflow paused for step execution
|
|
473
567
|
throw error
|
|
474
568
|
}
|
|
475
569
|
|
|
476
|
-
// Check if it's a WorkflowCancelledException
|
|
477
570
|
if (error instanceof WorkflowCancelledException) {
|
|
478
|
-
// Workflow was cancelled - update status and rethrow
|
|
479
571
|
await this.updateRunStatus(runId, 'cancelled', undefined, {
|
|
480
572
|
message: error.message || 'Workflow cancelled',
|
|
481
573
|
stack: '',
|
|
@@ -484,6 +576,15 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
484
576
|
throw error
|
|
485
577
|
}
|
|
486
578
|
|
|
579
|
+
if (error instanceof WorkflowSuspendedException) {
|
|
580
|
+
await this.updateRunStatus(runId, 'suspended', undefined, {
|
|
581
|
+
message: error.message || 'Workflow suspended',
|
|
582
|
+
stack: '',
|
|
583
|
+
code: 'WORKFLOW_SUSPENDED',
|
|
584
|
+
})
|
|
585
|
+
throw error
|
|
586
|
+
}
|
|
587
|
+
|
|
487
588
|
await this.updateRunStatus(runId, 'failed', undefined, {
|
|
488
589
|
message: error.message,
|
|
489
590
|
stack: error.stack,
|
|
@@ -495,6 +596,35 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
495
596
|
})
|
|
496
597
|
}
|
|
497
598
|
|
|
599
|
+
private async runVersionMismatchFallback(
|
|
600
|
+
run: WorkflowRun,
|
|
601
|
+
currentMeta: { source: string },
|
|
602
|
+
rpcService: any
|
|
603
|
+
): Promise<void> {
|
|
604
|
+
const source = currentMeta.source
|
|
605
|
+
|
|
606
|
+
if (source === 'complex') {
|
|
607
|
+
await this.updateRunStatus(run.id, 'failed', undefined, {
|
|
608
|
+
message: `Workflow '${run.workflow}' definition changed. Complex workflows with inline steps cannot be migrated.`,
|
|
609
|
+
stack: '',
|
|
610
|
+
code: 'VERSION_CONFLICT',
|
|
611
|
+
})
|
|
612
|
+
return
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const version = await this.getWorkflowVersion(run.workflow, run.graphHash!)
|
|
616
|
+
if (!version) {
|
|
617
|
+
await this.updateRunStatus(run.id, 'failed', undefined, {
|
|
618
|
+
message: `Workflow '${run.workflow}' version '${run.graphHash}' not found. Cannot resume with changed definition.`,
|
|
619
|
+
stack: '',
|
|
620
|
+
code: 'VERSION_NOT_FOUND',
|
|
621
|
+
})
|
|
622
|
+
return
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
await runFromMeta(this, run.id, version.graph, rpcService)
|
|
626
|
+
}
|
|
627
|
+
|
|
498
628
|
/**
|
|
499
629
|
* Execute a single workflow step (called by worker)
|
|
500
630
|
* Handles idempotency, RPC execution, result storage, retry logic, and orchestrator triggering
|
|
@@ -527,24 +657,23 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
527
657
|
stepState = await this.createRetryAttempt(stepState.stepId, 'running')
|
|
528
658
|
}
|
|
529
659
|
|
|
530
|
-
if (stepState.status
|
|
531
|
-
// Mark step as running
|
|
660
|
+
if (stepState.status === 'pending') {
|
|
661
|
+
// Mark pending step as running before execution
|
|
532
662
|
await this.setStepRunning(stepState.stepId)
|
|
533
663
|
}
|
|
534
664
|
|
|
535
665
|
try {
|
|
536
666
|
let result: any
|
|
537
667
|
|
|
538
|
-
|
|
539
|
-
if (
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
const graphName = run.workflow
|
|
668
|
+
const run = await this.getRun(runId)
|
|
669
|
+
if (!run) {
|
|
670
|
+
throw new Error(`Workflow run not found: ${runId}`)
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
const meta = pikkuState(null, 'workflows', 'meta')
|
|
674
|
+
const workflowMeta = meta[run.workflow]
|
|
546
675
|
|
|
547
|
-
|
|
676
|
+
if (workflowMeta?.nodes && stepName in workflowMeta.nodes) {
|
|
548
677
|
result = await executeGraphStep(
|
|
549
678
|
this,
|
|
550
679
|
rpcService,
|
|
@@ -553,10 +682,9 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
553
682
|
stepName,
|
|
554
683
|
rpcName,
|
|
555
684
|
data,
|
|
556
|
-
|
|
685
|
+
run.workflow
|
|
557
686
|
)
|
|
558
687
|
} else {
|
|
559
|
-
// Execute RPC with workflow step context (regular workflow)
|
|
560
688
|
result = await rpcService.rpcWithWire(rpcName, data, {
|
|
561
689
|
workflowStep: {
|
|
562
690
|
runId,
|
|
@@ -572,6 +700,15 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
572
700
|
// Resume orchestrator to continue workflow
|
|
573
701
|
await this.resumeWorkflow(runId)
|
|
574
702
|
} catch (error: any) {
|
|
703
|
+
if (error instanceof RPCNotFoundError) {
|
|
704
|
+
await this.setStepError(stepState.stepId, error)
|
|
705
|
+
await this.updateRunStatus(runId, 'suspended', undefined, {
|
|
706
|
+
message: `RPC '${rpcName}' not found. Deploy the missing function and resume.`,
|
|
707
|
+
code: 'RPC_NOT_FOUND',
|
|
708
|
+
})
|
|
709
|
+
return
|
|
710
|
+
}
|
|
711
|
+
|
|
575
712
|
// Store error and mark failed
|
|
576
713
|
await this.setStepError(stepState.stepId, error)
|
|
577
714
|
|
|
@@ -603,7 +740,8 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
603
740
|
} catch (error: any) {
|
|
604
741
|
if (
|
|
605
742
|
error.name === 'WorkflowAsyncException' ||
|
|
606
|
-
error.name === 'WorkflowCancelledException'
|
|
743
|
+
error.name === 'WorkflowCancelledException' ||
|
|
744
|
+
error.name === 'WorkflowSuspendedException'
|
|
607
745
|
) {
|
|
608
746
|
return
|
|
609
747
|
}
|
|
@@ -619,13 +757,13 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
619
757
|
}
|
|
620
758
|
|
|
621
759
|
private verifyQueueService(): QueueService {
|
|
622
|
-
if (!
|
|
760
|
+
if (!getSingletonServices()?.queueService) {
|
|
623
761
|
throw new Error(
|
|
624
762
|
'QueueService not configured. Remote workflows require a queue service.'
|
|
625
763
|
)
|
|
626
764
|
}
|
|
627
765
|
|
|
628
|
-
return
|
|
766
|
+
return getSingletonServices()!.queueService!
|
|
629
767
|
}
|
|
630
768
|
|
|
631
769
|
private async rpcStep(
|
|
@@ -678,12 +816,12 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
678
816
|
await this.setStepScheduled(stepState.stepId)
|
|
679
817
|
|
|
680
818
|
// Enqueue step worker (unless inline mode)
|
|
681
|
-
if (!this.isInline(runId) &&
|
|
819
|
+
if (!this.isInline(runId) && getSingletonServices()!.queueService) {
|
|
682
820
|
// Map step retry options to queue job options
|
|
683
821
|
const retries = stepOptions?.retries ?? 0
|
|
684
822
|
const retryDelay = stepOptions?.retryDelay
|
|
685
823
|
|
|
686
|
-
await
|
|
824
|
+
await getSingletonServices()!.queueService!.add(
|
|
687
825
|
this.getConfig().stepWorkerQueueName,
|
|
688
826
|
{
|
|
689
827
|
runId,
|
|
@@ -724,6 +862,14 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
724
862
|
await this.setStepResult(currentStepState.stepId, result)
|
|
725
863
|
return result
|
|
726
864
|
} catch (error: any) {
|
|
865
|
+
if (error instanceof RPCNotFoundError) {
|
|
866
|
+
await this.updateRunStatus(runId, 'suspended', undefined, {
|
|
867
|
+
message: `RPC '${rpcName}' not found. Deploy the missing function and resume.`,
|
|
868
|
+
code: 'RPC_NOT_FOUND',
|
|
869
|
+
})
|
|
870
|
+
throw error
|
|
871
|
+
}
|
|
872
|
+
|
|
727
873
|
// Record the error (marks step as failed)
|
|
728
874
|
await this.setStepError(currentStepState.stepId, error)
|
|
729
875
|
|
|
@@ -766,8 +912,8 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
766
912
|
stepState = await this.insertStepState(
|
|
767
913
|
runId,
|
|
768
914
|
stepName,
|
|
769
|
-
null,
|
|
770
|
-
null,
|
|
915
|
+
null,
|
|
916
|
+
null,
|
|
771
917
|
stepOptions
|
|
772
918
|
)
|
|
773
919
|
}
|
|
@@ -852,13 +998,9 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
852
998
|
stepState = await this.getStepState(runId, stepName)
|
|
853
999
|
} catch {
|
|
854
1000
|
// Step doesn't exist - create it (sleep step, no RPC)
|
|
855
|
-
stepState = await this.insertStepState(
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
null, // No RPC for sleep steps
|
|
859
|
-
{ duration }, // Store duration as data
|
|
860
|
-
undefined // No retry options for sleep
|
|
861
|
-
)
|
|
1001
|
+
stepState = await this.insertStepState(runId, stepName, null, {
|
|
1002
|
+
duration,
|
|
1003
|
+
})
|
|
862
1004
|
}
|
|
863
1005
|
|
|
864
1006
|
if (stepState.status === 'succeeded') {
|
|
@@ -875,9 +1017,9 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
875
1017
|
await this.setStepScheduled(stepState.stepId)
|
|
876
1018
|
|
|
877
1019
|
// Check if inline mode or no scheduler service
|
|
878
|
-
if (!this.isInline(runId) &&
|
|
1020
|
+
if (!this.isInline(runId) && getSingletonServices()!.schedulerService) {
|
|
879
1021
|
// Remote mode - schedule sleep via scheduler service
|
|
880
|
-
await
|
|
1022
|
+
await getSingletonServices()!.schedulerService!.scheduleRPC(
|
|
881
1023
|
duration,
|
|
882
1024
|
this.getConfig().sleeperRPCName,
|
|
883
1025
|
{
|
|
@@ -897,13 +1039,63 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
897
1039
|
}
|
|
898
1040
|
}
|
|
899
1041
|
|
|
1042
|
+
private getSuspendStepName(reason: string): string {
|
|
1043
|
+
if (!reason) {
|
|
1044
|
+
return '__workflow_suspend'
|
|
1045
|
+
}
|
|
1046
|
+
return '__workflow_suspend'
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
private async suspendStep(runId: string, reason: string): Promise<void> {
|
|
1050
|
+
const stepName = this.getSuspendStepName(reason)
|
|
1051
|
+
await this.withStepLock(runId, stepName, async () => {
|
|
1052
|
+
let stepState: StepState
|
|
1053
|
+
try {
|
|
1054
|
+
stepState = await this.getStepState(runId, stepName)
|
|
1055
|
+
} catch {
|
|
1056
|
+
stepState = await this.insertStepState(
|
|
1057
|
+
runId,
|
|
1058
|
+
stepName,
|
|
1059
|
+
'pikkuWorkflowSuspend',
|
|
1060
|
+
{
|
|
1061
|
+
reason,
|
|
1062
|
+
}
|
|
1063
|
+
)
|
|
1064
|
+
}
|
|
1065
|
+
if (!stepState.stepId) {
|
|
1066
|
+
stepState = await this.insertStepState(
|
|
1067
|
+
runId,
|
|
1068
|
+
stepName,
|
|
1069
|
+
'pikkuWorkflowSuspend',
|
|
1070
|
+
{
|
|
1071
|
+
reason,
|
|
1072
|
+
}
|
|
1073
|
+
)
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
if (stepState.status === 'succeeded') {
|
|
1077
|
+
return
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
if (stepState.status === 'pending') {
|
|
1081
|
+
await this.setStepRunning(stepState.stepId)
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
await this.setStepResult(stepState.stepId, {
|
|
1085
|
+
reason,
|
|
1086
|
+
suspendedAt: new Date().toISOString(),
|
|
1087
|
+
})
|
|
1088
|
+
throw new WorkflowSuspendedException(runId, reason)
|
|
1089
|
+
})
|
|
1090
|
+
}
|
|
1091
|
+
|
|
900
1092
|
private createWorkflowWire(
|
|
901
|
-
|
|
1093
|
+
name: string,
|
|
902
1094
|
runId: string,
|
|
903
1095
|
rpcService: any
|
|
904
1096
|
): PikkuWorkflowWire {
|
|
905
1097
|
const workflowWire: PikkuWorkflowWire = {
|
|
906
|
-
|
|
1098
|
+
name,
|
|
907
1099
|
runId,
|
|
908
1100
|
getRun: async () => (await this.getRun(runId)) as WorkflowRun,
|
|
909
1101
|
|
|
@@ -943,6 +1135,10 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
943
1135
|
getDurationInMilliseconds(duration)
|
|
944
1136
|
)
|
|
945
1137
|
},
|
|
1138
|
+
|
|
1139
|
+
suspend: async (reason: string) => {
|
|
1140
|
+
await this.suspendStep(runId, reason || 'Workflow suspended')
|
|
1141
|
+
},
|
|
946
1142
|
}
|
|
947
1143
|
return workflowWire
|
|
948
1144
|
}
|
|
@@ -953,10 +1149,17 @@ export abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
953
1149
|
}
|
|
954
1150
|
}
|
|
955
1151
|
|
|
956
|
-
private getConfig() {
|
|
957
|
-
|
|
958
|
-
|
|
1152
|
+
private getConfig(): WorkflowServiceConfig {
|
|
1153
|
+
const singletonServices = getSingletonServices()
|
|
1154
|
+
const workflow = singletonServices.config?.workflow
|
|
1155
|
+
return {
|
|
1156
|
+
retries: workflow?.retries ?? 0,
|
|
1157
|
+
retryDelay: workflow?.retryDelay ?? 0,
|
|
1158
|
+
orchestratorQueueName:
|
|
1159
|
+
workflow?.orchestratorQueueName ?? 'pikku-workflow-orchestrator',
|
|
1160
|
+
stepWorkerQueueName:
|
|
1161
|
+
workflow?.stepWorkerQueueName ?? 'pikku-workflow-step-worker',
|
|
1162
|
+
sleeperRPCName: workflow?.sleeperRPCName ?? 'pikkuWorkflowSleeper',
|
|
959
1163
|
}
|
|
960
|
-
return this.config
|
|
961
1164
|
}
|
|
962
1165
|
}
|