@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,8 +1,9 @@
|
|
|
1
1
|
import { runPikkuFunc } from '../../function/function-runner.js';
|
|
2
|
-
import { pikkuState } from '../../pikku-state.js';
|
|
2
|
+
import { getSingletonServices, getCreateWireServices, pikkuState, } from '../../pikku-state.js';
|
|
3
3
|
import { getDurationInMilliseconds } from '../../time-utils.js';
|
|
4
|
-
import { executeGraphStep, runWorkflowGraph } from './graph/graph-runner.js';
|
|
5
|
-
import { PikkuError } from '../../errors/error-handler.js';
|
|
4
|
+
import { continueGraph, executeGraphStep, runWorkflowGraph, runFromMeta, } from './graph/graph-runner.js';
|
|
5
|
+
import { PikkuError, addError } from '../../errors/error-handler.js';
|
|
6
|
+
import { RPCNotFoundError } from '../rpc/rpc-runner.js';
|
|
6
7
|
/**
|
|
7
8
|
* Exception thrown when workflow needs to pause for async step
|
|
8
9
|
*/
|
|
@@ -29,6 +30,19 @@ export class WorkflowCancelledException extends Error {
|
|
|
29
30
|
this.name = 'WorkflowCancelledException';
|
|
30
31
|
}
|
|
31
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Exception thrown when workflow is suspended
|
|
35
|
+
*/
|
|
36
|
+
export class WorkflowSuspendedException extends Error {
|
|
37
|
+
runId;
|
|
38
|
+
reason;
|
|
39
|
+
constructor(runId, reason) {
|
|
40
|
+
super(reason || 'Workflow suspended');
|
|
41
|
+
this.runId = runId;
|
|
42
|
+
this.reason = reason;
|
|
43
|
+
this.name = 'WorkflowSuspendedException';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
32
46
|
/**
|
|
33
47
|
* Error class for workflow not found
|
|
34
48
|
*/
|
|
@@ -37,14 +51,19 @@ export class WorkflowNotFoundError extends PikkuError {
|
|
|
37
51
|
super(`Workflow not found: ${name}`);
|
|
38
52
|
}
|
|
39
53
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
54
|
+
addError(WorkflowNotFoundError, {
|
|
55
|
+
status: 404,
|
|
56
|
+
message: 'Workflow not found.',
|
|
57
|
+
});
|
|
58
|
+
export class WorkflowRunNotFoundError extends PikkuError {
|
|
44
59
|
constructor(runId) {
|
|
45
60
|
super(`Workflow run not found: ${runId}`);
|
|
46
61
|
}
|
|
47
62
|
}
|
|
63
|
+
addError(WorkflowRunNotFoundError, {
|
|
64
|
+
status: 404,
|
|
65
|
+
message: 'Workflow run not found.',
|
|
66
|
+
});
|
|
48
67
|
export class WorkflowServiceNotInitialized extends Error {
|
|
49
68
|
}
|
|
50
69
|
export class WorkflowStepNameNotString extends Error {
|
|
@@ -52,15 +71,18 @@ export class WorkflowStepNameNotString extends Error {
|
|
|
52
71
|
super(`Workflow step name must be a string. Received: ${typeof stepName}`);
|
|
53
72
|
}
|
|
54
73
|
}
|
|
74
|
+
const WORKFLOW_END_STATES = new Set([
|
|
75
|
+
'completed',
|
|
76
|
+
'failed',
|
|
77
|
+
'cancelled',
|
|
78
|
+
'suspended',
|
|
79
|
+
]);
|
|
55
80
|
/**
|
|
56
81
|
* Abstract workflow state service
|
|
57
82
|
* Implementations provide pluggable storage backends (SQLite, PostgreSQL, etc.)
|
|
58
83
|
* Combines orchestration and step execution
|
|
59
84
|
*/
|
|
60
85
|
export class PikkuWorkflowService {
|
|
61
|
-
config;
|
|
62
|
-
singletonServices;
|
|
63
|
-
createWireServices;
|
|
64
86
|
inlineRuns = new Set();
|
|
65
87
|
constructor() { }
|
|
66
88
|
/**
|
|
@@ -81,16 +103,13 @@ export class PikkuWorkflowService {
|
|
|
81
103
|
unregisterInlineRun(runId) {
|
|
82
104
|
this.inlineRuns.delete(runId);
|
|
83
105
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
stepWorkerQueueName: workflow?.stepWorkerQueueName ?? 'pikku-workflow-step-worker',
|
|
92
|
-
sleeperRPCName: workflow?.sleeperRPCName ?? 'pikkuWorkflowSleeper',
|
|
93
|
-
};
|
|
106
|
+
async registerWorkflowVersions() {
|
|
107
|
+
const allMeta = pikkuState(null, 'workflows', 'meta');
|
|
108
|
+
for (const [name, meta] of Object.entries(allMeta)) {
|
|
109
|
+
if (!meta.graphHash)
|
|
110
|
+
continue;
|
|
111
|
+
await this.upsertWorkflowVersion(name, meta.graphHash, meta, meta.source);
|
|
112
|
+
}
|
|
94
113
|
}
|
|
95
114
|
// ============================================================================
|
|
96
115
|
// Workflow Lifecycle Methods
|
|
@@ -103,6 +122,15 @@ export class PikkuWorkflowService {
|
|
|
103
122
|
const queueService = this.verifyQueueService();
|
|
104
123
|
await queueService.add(this.getConfig().orchestratorQueueName, { runId });
|
|
105
124
|
}
|
|
125
|
+
async queueStepWorker(runId, stepName, rpcName, data) {
|
|
126
|
+
const queueService = this.verifyQueueService();
|
|
127
|
+
await queueService.add(this.getConfig().stepWorkerQueueName, {
|
|
128
|
+
runId,
|
|
129
|
+
stepName,
|
|
130
|
+
rpcName,
|
|
131
|
+
data,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
106
134
|
/**
|
|
107
135
|
* Execute a workflow sleep step completion
|
|
108
136
|
* Sets the step result to null and resumes the workflow
|
|
@@ -127,7 +155,7 @@ export class PikkuWorkflowService {
|
|
|
127
155
|
* @param options.inline - If true, execute workflow directly without queue service
|
|
128
156
|
* @param options.startNode - Starting node ID for graph workflows (from wire config)
|
|
129
157
|
*/
|
|
130
|
-
async startWorkflow(name, input, rpcService, options) {
|
|
158
|
+
async startWorkflow(name, input, wire, rpcService, options) {
|
|
131
159
|
// Check meta to determine workflow type
|
|
132
160
|
const meta = pikkuState(null, 'workflows', 'meta');
|
|
133
161
|
const workflowMeta = meta[name];
|
|
@@ -136,8 +164,8 @@ export class PikkuWorkflowService {
|
|
|
136
164
|
}
|
|
137
165
|
// Check if this is a graph workflow (source === 'graph')
|
|
138
166
|
if (workflowMeta.source === 'graph') {
|
|
139
|
-
|
|
140
|
-
return runWorkflowGraph(this, name, input, rpcService,
|
|
167
|
+
const shouldInline = options?.inline || !getSingletonServices()?.queueService;
|
|
168
|
+
return runWorkflowGraph(this, name, input, rpcService, shouldInline, options?.startNode, wire);
|
|
141
169
|
}
|
|
142
170
|
// DSL workflow - check registration exists
|
|
143
171
|
const registrations = pikkuState(null, 'workflows', 'registrations');
|
|
@@ -145,34 +173,63 @@ export class PikkuWorkflowService {
|
|
|
145
173
|
if (!workflow) {
|
|
146
174
|
throw new WorkflowNotFoundError(name);
|
|
147
175
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
176
|
+
if (!workflowMeta.graphHash) {
|
|
177
|
+
throw new Error(`Missing workflow graphHash for '${name}'`);
|
|
178
|
+
}
|
|
179
|
+
const runId = await this.createRun(name, input, options?.inline ?? false, workflowMeta.graphHash, wire);
|
|
151
180
|
if (options?.inline) {
|
|
152
181
|
this.inlineRuns.add(runId);
|
|
153
182
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
183
|
+
if (options?.inline || !getSingletonServices()?.queueService) {
|
|
184
|
+
this.runWorkflowJob(runId, rpcService)
|
|
185
|
+
.catch(() => { })
|
|
186
|
+
.finally(() => {
|
|
187
|
+
if (options?.inline) {
|
|
188
|
+
this.inlineRuns.delete(runId);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
await this.resumeWorkflow(runId);
|
|
164
194
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
195
|
+
return { runId };
|
|
196
|
+
}
|
|
197
|
+
async runToCompletion(name, input, rpcService, options) {
|
|
198
|
+
const pollInterval = options?.pollIntervalMs ?? 1000;
|
|
199
|
+
const { runId } = await this.startWorkflow(name, input, options?.wire ?? { type: 'internal' }, rpcService, { inline: true });
|
|
200
|
+
while (true) {
|
|
201
|
+
const run = await this.getRun(runId);
|
|
202
|
+
if (!run) {
|
|
203
|
+
throw new WorkflowRunNotFoundError(runId);
|
|
169
204
|
}
|
|
205
|
+
if (WORKFLOW_END_STATES.has(run.status)) {
|
|
206
|
+
if (run.status === 'failed') {
|
|
207
|
+
throw new Error(run.error?.message || 'Workflow failed');
|
|
208
|
+
}
|
|
209
|
+
if (run.status === 'cancelled') {
|
|
210
|
+
throw new Error('Workflow was cancelled');
|
|
211
|
+
}
|
|
212
|
+
return run.output;
|
|
213
|
+
}
|
|
214
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
170
215
|
}
|
|
171
216
|
}
|
|
172
217
|
async runWorkflowJob(runId, rpcService) {
|
|
173
218
|
const run = await this.getRun(runId);
|
|
174
219
|
if (!run) {
|
|
175
|
-
throw new
|
|
220
|
+
throw new WorkflowRunNotFoundError(runId);
|
|
221
|
+
}
|
|
222
|
+
const meta = pikkuState(null, 'workflows', 'meta');
|
|
223
|
+
const workflowMeta = meta[run.workflow];
|
|
224
|
+
if (run.graphHash &&
|
|
225
|
+
workflowMeta?.graphHash &&
|
|
226
|
+
run.graphHash !== workflowMeta.graphHash) {
|
|
227
|
+
await this.runVersionMismatchFallback(run, workflowMeta, rpcService);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (workflowMeta?.source === 'graph') {
|
|
231
|
+
await continueGraph(this, runId, run.workflow);
|
|
232
|
+
return;
|
|
176
233
|
}
|
|
177
234
|
const registrations = pikkuState(null, 'workflows', 'registrations');
|
|
178
235
|
const workflow = registrations.get(run.workflow);
|
|
@@ -180,27 +237,22 @@ export class PikkuWorkflowService {
|
|
|
180
237
|
throw new WorkflowNotFoundError(run.workflow);
|
|
181
238
|
}
|
|
182
239
|
await this.withRunLock(runId, async () => {
|
|
183
|
-
const meta = pikkuState(null, 'workflows', 'meta');
|
|
184
|
-
const workflowMeta = meta[run.workflow];
|
|
185
240
|
const workflowWire = this.createWorkflowWire(run.workflow, runId, rpcService);
|
|
186
241
|
const wire = { workflow: workflowWire };
|
|
187
242
|
try {
|
|
188
|
-
const result = await runPikkuFunc('workflow', workflowMeta.name, workflowMeta.
|
|
189
|
-
singletonServices:
|
|
243
|
+
const result = await runPikkuFunc('workflow', workflowMeta.name, workflowMeta.pikkuFuncId, {
|
|
244
|
+
singletonServices: getSingletonServices(),
|
|
190
245
|
wire,
|
|
191
|
-
createWireServices:
|
|
246
|
+
createWireServices: getCreateWireServices(),
|
|
192
247
|
data: () => run.input,
|
|
193
248
|
});
|
|
194
249
|
await this.updateRunStatus(runId, 'completed', result);
|
|
195
250
|
}
|
|
196
251
|
catch (error) {
|
|
197
252
|
if (error instanceof WorkflowAsyncException) {
|
|
198
|
-
// Normal - workflow paused for step execution
|
|
199
253
|
throw error;
|
|
200
254
|
}
|
|
201
|
-
// Check if it's a WorkflowCancelledException
|
|
202
255
|
if (error instanceof WorkflowCancelledException) {
|
|
203
|
-
// Workflow was cancelled - update status and rethrow
|
|
204
256
|
await this.updateRunStatus(runId, 'cancelled', undefined, {
|
|
205
257
|
message: error.message || 'Workflow cancelled',
|
|
206
258
|
stack: '',
|
|
@@ -208,6 +260,14 @@ export class PikkuWorkflowService {
|
|
|
208
260
|
});
|
|
209
261
|
throw error;
|
|
210
262
|
}
|
|
263
|
+
if (error instanceof WorkflowSuspendedException) {
|
|
264
|
+
await this.updateRunStatus(runId, 'suspended', undefined, {
|
|
265
|
+
message: error.message || 'Workflow suspended',
|
|
266
|
+
stack: '',
|
|
267
|
+
code: 'WORKFLOW_SUSPENDED',
|
|
268
|
+
});
|
|
269
|
+
throw error;
|
|
270
|
+
}
|
|
211
271
|
await this.updateRunStatus(runId, 'failed', undefined, {
|
|
212
272
|
message: error.message,
|
|
213
273
|
stack: error.stack,
|
|
@@ -217,6 +277,27 @@ export class PikkuWorkflowService {
|
|
|
217
277
|
}
|
|
218
278
|
});
|
|
219
279
|
}
|
|
280
|
+
async runVersionMismatchFallback(run, currentMeta, rpcService) {
|
|
281
|
+
const source = currentMeta.source;
|
|
282
|
+
if (source === 'complex') {
|
|
283
|
+
await this.updateRunStatus(run.id, 'failed', undefined, {
|
|
284
|
+
message: `Workflow '${run.workflow}' definition changed. Complex workflows with inline steps cannot be migrated.`,
|
|
285
|
+
stack: '',
|
|
286
|
+
code: 'VERSION_CONFLICT',
|
|
287
|
+
});
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const version = await this.getWorkflowVersion(run.workflow, run.graphHash);
|
|
291
|
+
if (!version) {
|
|
292
|
+
await this.updateRunStatus(run.id, 'failed', undefined, {
|
|
293
|
+
message: `Workflow '${run.workflow}' version '${run.graphHash}' not found. Cannot resume with changed definition.`,
|
|
294
|
+
stack: '',
|
|
295
|
+
code: 'VERSION_NOT_FOUND',
|
|
296
|
+
});
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
await runFromMeta(this, run.id, version.graph, rpcService);
|
|
300
|
+
}
|
|
220
301
|
/**
|
|
221
302
|
* Execute a single workflow step (called by worker)
|
|
222
303
|
* Handles idempotency, RPC execution, result storage, retry logic, and orchestrator triggering
|
|
@@ -239,25 +320,22 @@ export class PikkuWorkflowService {
|
|
|
239
320
|
if (stepState.status === 'failed') {
|
|
240
321
|
stepState = await this.createRetryAttempt(stepState.stepId, 'running');
|
|
241
322
|
}
|
|
242
|
-
if (stepState.status
|
|
243
|
-
// Mark step as running
|
|
323
|
+
if (stepState.status === 'pending') {
|
|
324
|
+
// Mark pending step as running before execution
|
|
244
325
|
await this.setStepRunning(stepState.stepId);
|
|
245
326
|
}
|
|
246
327
|
try {
|
|
247
328
|
let result;
|
|
248
|
-
|
|
249
|
-
if (
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
// Execute as graph step with graph wire context
|
|
257
|
-
result = await executeGraphStep(this, rpcService, runId, stepState.stepId, stepName, rpcName, data, graphName);
|
|
329
|
+
const run = await this.getRun(runId);
|
|
330
|
+
if (!run) {
|
|
331
|
+
throw new Error(`Workflow run not found: ${runId}`);
|
|
332
|
+
}
|
|
333
|
+
const meta = pikkuState(null, 'workflows', 'meta');
|
|
334
|
+
const workflowMeta = meta[run.workflow];
|
|
335
|
+
if (workflowMeta?.nodes && stepName in workflowMeta.nodes) {
|
|
336
|
+
result = await executeGraphStep(this, rpcService, runId, stepState.stepId, stepName, rpcName, data, run.workflow);
|
|
258
337
|
}
|
|
259
338
|
else {
|
|
260
|
-
// Execute RPC with workflow step context (regular workflow)
|
|
261
339
|
result = await rpcService.rpcWithWire(rpcName, data, {
|
|
262
340
|
workflowStep: {
|
|
263
341
|
runId,
|
|
@@ -272,6 +350,14 @@ export class PikkuWorkflowService {
|
|
|
272
350
|
await this.resumeWorkflow(runId);
|
|
273
351
|
}
|
|
274
352
|
catch (error) {
|
|
353
|
+
if (error instanceof RPCNotFoundError) {
|
|
354
|
+
await this.setStepError(stepState.stepId, error);
|
|
355
|
+
await this.updateRunStatus(runId, 'suspended', undefined, {
|
|
356
|
+
message: `RPC '${rpcName}' not found. Deploy the missing function and resume.`,
|
|
357
|
+
code: 'RPC_NOT_FOUND',
|
|
358
|
+
});
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
275
361
|
// Store error and mark failed
|
|
276
362
|
await this.setStepError(stepState.stepId, error);
|
|
277
363
|
const maxAttempts = (stepState.retries ?? 0) + 1;
|
|
@@ -296,7 +382,8 @@ export class PikkuWorkflowService {
|
|
|
296
382
|
}
|
|
297
383
|
catch (error) {
|
|
298
384
|
if (error.name === 'WorkflowAsyncException' ||
|
|
299
|
-
error.name === 'WorkflowCancelledException'
|
|
385
|
+
error.name === 'WorkflowCancelledException' ||
|
|
386
|
+
error.name === 'WorkflowSuspendedException') {
|
|
300
387
|
return;
|
|
301
388
|
}
|
|
302
389
|
await this.updateRunStatus(runId, 'failed', undefined, {
|
|
@@ -308,10 +395,10 @@ export class PikkuWorkflowService {
|
|
|
308
395
|
}
|
|
309
396
|
}
|
|
310
397
|
verifyQueueService() {
|
|
311
|
-
if (!
|
|
398
|
+
if (!getSingletonServices()?.queueService) {
|
|
312
399
|
throw new Error('QueueService not configured. Remote workflows require a queue service.');
|
|
313
400
|
}
|
|
314
|
-
return
|
|
401
|
+
return getSingletonServices().queueService;
|
|
315
402
|
}
|
|
316
403
|
async rpcStep(runId, stepName, rpcName, data, rpcService, stepOptions) {
|
|
317
404
|
// Check if step already exists
|
|
@@ -344,11 +431,11 @@ export class PikkuWorkflowService {
|
|
|
344
431
|
// Step is pending - schedule it
|
|
345
432
|
await this.setStepScheduled(stepState.stepId);
|
|
346
433
|
// Enqueue step worker (unless inline mode)
|
|
347
|
-
if (!this.isInline(runId) &&
|
|
434
|
+
if (!this.isInline(runId) && getSingletonServices().queueService) {
|
|
348
435
|
// Map step retry options to queue job options
|
|
349
436
|
const retries = stepOptions?.retries ?? 0;
|
|
350
437
|
const retryDelay = stepOptions?.retryDelay;
|
|
351
|
-
await
|
|
438
|
+
await getSingletonServices().queueService.add(this.getConfig().stepWorkerQueueName, {
|
|
352
439
|
runId,
|
|
353
440
|
stepName,
|
|
354
441
|
rpcName,
|
|
@@ -385,6 +472,13 @@ export class PikkuWorkflowService {
|
|
|
385
472
|
return result;
|
|
386
473
|
}
|
|
387
474
|
catch (error) {
|
|
475
|
+
if (error instanceof RPCNotFoundError) {
|
|
476
|
+
await this.updateRunStatus(runId, 'suspended', undefined, {
|
|
477
|
+
message: `RPC '${rpcName}' not found. Deploy the missing function and resume.`,
|
|
478
|
+
code: 'RPC_NOT_FOUND',
|
|
479
|
+
});
|
|
480
|
+
throw error;
|
|
481
|
+
}
|
|
388
482
|
// Record the error (marks step as failed)
|
|
389
483
|
await this.setStepError(currentStepState.stepId, error);
|
|
390
484
|
// Check if we should retry
|
|
@@ -413,9 +507,7 @@ export class PikkuWorkflowService {
|
|
|
413
507
|
}
|
|
414
508
|
catch {
|
|
415
509
|
// Step doesn't exist - create it (inline, no RPC)
|
|
416
|
-
stepState = await this.insertStepState(runId, stepName, null,
|
|
417
|
-
null, // No data for inline steps
|
|
418
|
-
stepOptions);
|
|
510
|
+
stepState = await this.insertStepState(runId, stepName, null, null, stepOptions);
|
|
419
511
|
}
|
|
420
512
|
if (stepState.status === 'succeeded') {
|
|
421
513
|
// Return cached result
|
|
@@ -488,10 +580,9 @@ export class PikkuWorkflowService {
|
|
|
488
580
|
}
|
|
489
581
|
catch {
|
|
490
582
|
// Step doesn't exist - create it (sleep step, no RPC)
|
|
491
|
-
stepState = await this.insertStepState(runId, stepName, null,
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
);
|
|
583
|
+
stepState = await this.insertStepState(runId, stepName, null, {
|
|
584
|
+
duration,
|
|
585
|
+
});
|
|
495
586
|
}
|
|
496
587
|
if (stepState.status === 'succeeded') {
|
|
497
588
|
// Sleep already completed, return immediately
|
|
@@ -504,9 +595,9 @@ export class PikkuWorkflowService {
|
|
|
504
595
|
// Step is pending - schedule it
|
|
505
596
|
await this.setStepScheduled(stepState.stepId);
|
|
506
597
|
// Check if inline mode or no scheduler service
|
|
507
|
-
if (!this.isInline(runId) &&
|
|
598
|
+
if (!this.isInline(runId) && getSingletonServices().schedulerService) {
|
|
508
599
|
// Remote mode - schedule sleep via scheduler service
|
|
509
|
-
await
|
|
600
|
+
await getSingletonServices().schedulerService.scheduleRPC(duration, this.getConfig().sleeperRPCName, {
|
|
510
601
|
runId,
|
|
511
602
|
stepId: stepState.stepId,
|
|
512
603
|
});
|
|
@@ -520,9 +611,45 @@ export class PikkuWorkflowService {
|
|
|
520
611
|
return;
|
|
521
612
|
}
|
|
522
613
|
}
|
|
523
|
-
|
|
614
|
+
getSuspendStepName(reason) {
|
|
615
|
+
if (!reason) {
|
|
616
|
+
return '__workflow_suspend';
|
|
617
|
+
}
|
|
618
|
+
return '__workflow_suspend';
|
|
619
|
+
}
|
|
620
|
+
async suspendStep(runId, reason) {
|
|
621
|
+
const stepName = this.getSuspendStepName(reason);
|
|
622
|
+
await this.withStepLock(runId, stepName, async () => {
|
|
623
|
+
let stepState;
|
|
624
|
+
try {
|
|
625
|
+
stepState = await this.getStepState(runId, stepName);
|
|
626
|
+
}
|
|
627
|
+
catch {
|
|
628
|
+
stepState = await this.insertStepState(runId, stepName, 'pikkuWorkflowSuspend', {
|
|
629
|
+
reason,
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
if (!stepState.stepId) {
|
|
633
|
+
stepState = await this.insertStepState(runId, stepName, 'pikkuWorkflowSuspend', {
|
|
634
|
+
reason,
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
if (stepState.status === 'succeeded') {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
if (stepState.status === 'pending') {
|
|
641
|
+
await this.setStepRunning(stepState.stepId);
|
|
642
|
+
}
|
|
643
|
+
await this.setStepResult(stepState.stepId, {
|
|
644
|
+
reason,
|
|
645
|
+
suspendedAt: new Date().toISOString(),
|
|
646
|
+
});
|
|
647
|
+
throw new WorkflowSuspendedException(runId, reason);
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
createWorkflowWire(name, runId, rpcService) {
|
|
524
651
|
const workflowWire = {
|
|
525
|
-
|
|
652
|
+
name,
|
|
526
653
|
runId,
|
|
527
654
|
getRun: async () => (await this.getRun(runId)),
|
|
528
655
|
// Implement workflow.do() - RPC form
|
|
@@ -540,6 +667,9 @@ export class PikkuWorkflowService {
|
|
|
540
667
|
this.verifyStepName(stepName);
|
|
541
668
|
await this.sleepStep(runId, stepName, getDurationInMilliseconds(duration));
|
|
542
669
|
},
|
|
670
|
+
suspend: async (reason) => {
|
|
671
|
+
await this.suspendStep(runId, reason || 'Workflow suspended');
|
|
672
|
+
},
|
|
543
673
|
};
|
|
544
674
|
return workflowWire;
|
|
545
675
|
}
|
|
@@ -549,9 +679,14 @@ export class PikkuWorkflowService {
|
|
|
549
679
|
}
|
|
550
680
|
}
|
|
551
681
|
getConfig() {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
682
|
+
const singletonServices = getSingletonServices();
|
|
683
|
+
const workflow = singletonServices.config?.workflow;
|
|
684
|
+
return {
|
|
685
|
+
retries: workflow?.retries ?? 0,
|
|
686
|
+
retryDelay: workflow?.retryDelay ?? 0,
|
|
687
|
+
orchestratorQueueName: workflow?.orchestratorQueueName ?? 'pikku-workflow-orchestrator',
|
|
688
|
+
stepWorkerQueueName: workflow?.stepWorkerQueueName ?? 'pikku-workflow-step-worker',
|
|
689
|
+
sleeperRPCName: workflow?.sleeperRPCName ?? 'pikkuWorkflowSleeper',
|
|
690
|
+
};
|
|
556
691
|
}
|
|
557
692
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare function workflow<TWorkflowMap extends Record<string, {
|
|
2
|
+
input: any;
|
|
3
|
+
output: any;
|
|
4
|
+
}>>(workflowName: string & keyof TWorkflowMap, options?: {
|
|
5
|
+
pollIntervalMs?: number;
|
|
6
|
+
}): {
|
|
7
|
+
func: (services: any, data: any, wire: any) => Promise<any>;
|
|
8
|
+
};
|
|
9
|
+
export declare function workflowStart<TWorkflowMap extends Record<string, {
|
|
10
|
+
input: any;
|
|
11
|
+
output: any;
|
|
12
|
+
}>>(workflowName: string & keyof TWorkflowMap): {
|
|
13
|
+
func: (services: any, data: any, wire: any) => Promise<{
|
|
14
|
+
runId: string;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
export declare function workflowStatus<TWorkflowMap extends Record<string, {
|
|
18
|
+
input: any;
|
|
19
|
+
output: any;
|
|
20
|
+
}>>(_workflowName: string & keyof TWorkflowMap): {
|
|
21
|
+
func: (services: any, data: {
|
|
22
|
+
runId: string;
|
|
23
|
+
}) => Promise<{
|
|
24
|
+
id: string;
|
|
25
|
+
status: 'running' | 'suspended' | 'completed' | 'failed' | 'cancelled';
|
|
26
|
+
output?: any;
|
|
27
|
+
error?: {
|
|
28
|
+
message?: string;
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
export declare function graphStart<TGraphsMap extends Record<string, Record<string, any>>>(graphName: string & keyof TGraphsMap, startNode: string): {
|
|
33
|
+
func: (services: any, data: any, wire: any) => Promise<{
|
|
34
|
+
runId: string;
|
|
35
|
+
}>;
|
|
36
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { WorkflowRunNotFoundError } from './pikku-workflow-service.js';
|
|
2
|
+
export function workflow(workflowName, options) {
|
|
3
|
+
return {
|
|
4
|
+
func: async (services, data, { rpc }) => {
|
|
5
|
+
return services.workflowService.runToCompletion(workflowName, data, rpc, options);
|
|
6
|
+
},
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function workflowStart(workflowName) {
|
|
10
|
+
return {
|
|
11
|
+
func: async (_services, data, { rpc }) => {
|
|
12
|
+
return rpc.startWorkflow(workflowName, data);
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function workflowStatus(_workflowName) {
|
|
17
|
+
return {
|
|
18
|
+
func: async (services, data) => {
|
|
19
|
+
const run = await services.workflowService.getRun(data.runId);
|
|
20
|
+
if (!run) {
|
|
21
|
+
throw new WorkflowRunNotFoundError(data.runId);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
id: run.id,
|
|
25
|
+
status: run.status,
|
|
26
|
+
output: run.output,
|
|
27
|
+
error: run.error ? { message: run.error.message } : undefined,
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function graphStart(graphName, startNode) {
|
|
33
|
+
return {
|
|
34
|
+
func: async (_services, data, { rpc }) => {
|
|
35
|
+
return rpc.startWorkflow(graphName, data, { startNode });
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|