@pikku/core 0.11.2 → 0.12.0
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 +33 -2
- package/dist/crypto-utils.d.ts +2 -0
- package/dist/crypto-utils.js +78 -0
- package/dist/errors/errors.d.ts +8 -0
- package/dist/errors/errors.js +16 -0
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/function/function-runner.d.ts +7 -1
- package/dist/function/function-runner.js +82 -23
- package/dist/function/functions.types.d.ts +31 -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.js +1 -10
- package/dist/index.d.ts +28 -26
- package/dist/index.js +18 -29
- package/dist/middleware/auth-apikey.d.ts +2 -2
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.d.ts +2 -2
- package/dist/middleware/auth-bearer.js +3 -6
- package/dist/middleware/auth-cookie.d.ts +2 -2
- package/dist/middleware/auth-cookie.js +6 -8
- package/dist/middleware/cors.d.ts +46 -0
- package/dist/middleware/cors.js +73 -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.js +8 -10
- package/dist/permissions.js +11 -15
- package/dist/pikku-state.d.ts +1 -0
- package/dist/pikku-state.js +18 -8
- package/dist/schema.js +12 -11
- package/dist/services/ai-agent-runner-service.d.ts +24 -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/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 +94 -0
- package/dist/services/in-memory-trigger-service.d.ts +23 -0
- package/dist/services/in-memory-trigger-service.js +50 -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 +25 -11
- package/dist/services/index.js +10 -13
- package/dist/services/local-secrets.d.ts +23 -0
- package/dist/services/local-secrets.js +45 -0
- package/dist/services/local-variables.d.ts +5 -0
- package/dist/services/local-variables.js +18 -0
- package/dist/services/scheduler-service.d.ts +21 -1
- package/dist/services/scheduler-service.js +14 -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 +23 -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 +13 -0
- 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 -4
- package/dist/types/core.types.d.ts +48 -12
- package/dist/types/core.types.js +8 -1
- package/dist/types/state.types.d.ts +43 -51
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +15 -3
- package/dist/version.d.ts +6 -0
- package/dist/version.js +19 -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 +60 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +312 -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 +96 -0
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +11 -0
- package/dist/wirings/ai-agent/ai-agent-stream.js +503 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +254 -0
- package/dist/wirings/ai-agent/ai-agent.types.js +1 -0
- package/dist/wirings/ai-agent/index.d.ts +5 -0
- package/dist/wirings/ai-agent/index.js +4 -0
- package/dist/wirings/channel/channel-common.d.ts +7 -4
- package/dist/wirings/channel/channel-common.js +15 -8
- package/dist/wirings/channel/channel-handler.js +12 -3
- 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.js +7 -7
- package/dist/wirings/channel/channel.types.d.ts +5 -1
- 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.js +18 -6
- 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.js +15 -4
- 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 +1 -1
- package/dist/wirings/cli/cli-runner.js +12 -8
- package/dist/wirings/cli/cli.types.d.ts +6 -6
- 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.js +49 -23
- package/dist/wirings/http/http.types.d.ts +78 -38
- package/dist/wirings/http/index.d.ts +5 -4
- package/dist/wirings/http/index.js +4 -3
- package/dist/wirings/mcp/index.d.ts +4 -3
- package/dist/wirings/mcp/index.js +3 -3
- package/dist/wirings/mcp/mcp-runner.d.ts +1 -3
- package/dist/wirings/mcp/mcp-runner.js +25 -39
- package/dist/wirings/mcp/mcp.types.d.ts +3 -3
- 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 +2 -2
- package/dist/wirings/queue/index.js +1 -1
- package/dist/wirings/queue/queue-runner.d.ts +7 -0
- package/dist/wirings/queue/queue-runner.js +17 -6
- package/dist/wirings/queue/queue.types.d.ts +8 -2
- package/dist/wirings/rpc/index.d.ts +1 -1
- package/dist/wirings/rpc/index.js +1 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +33 -5
- package/dist/wirings/rpc/rpc-runner.js +134 -16
- package/dist/wirings/rpc/rpc-types.d.ts +8 -4
- package/dist/wirings/scheduler/index.d.ts +3 -3
- package/dist/wirings/scheduler/index.js +2 -3
- package/dist/wirings/scheduler/scheduler-runner.d.ts +5 -0
- package/dist/wirings/scheduler/scheduler-runner.js +23 -5
- 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 +26 -0
- package/dist/wirings/trigger/pikku-trigger-service.js +75 -0
- package/dist/wirings/trigger/trigger-runner.d.ts +21 -8
- package/dist/wirings/trigger/trigger-runner.js +46 -18
- 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 +28 -14
- package/dist/wirings/workflow/pikku-workflow-service.js +200 -56
- package/dist/wirings/workflow/workflow-helpers.d.ts +36 -0
- package/dist/wirings/workflow/workflow-helpers.js +38 -0
- package/dist/wirings/workflow/workflow-utils.d.ts +1 -23
- package/dist/wirings/workflow/workflow-utils.js +1 -66
- package/dist/wirings/workflow/workflow.types.d.ts +40 -93
- package/package.json +13 -15
- package/run-tests.sh +4 -1
- package/src/crypto-utils.ts +99 -0
- package/src/errors/errors.ts +17 -0
- package/src/errors/index.ts +0 -1
- package/src/factory-functions.test.ts +42 -2
- package/src/function/function-runner.test.ts +4 -11
- package/src/function/function-runner.ts +114 -29
- package/src/function/functions.types.ts +62 -132
- package/src/function/index.ts +5 -2
- package/src/handle-error.ts +2 -10
- package/src/index.ts +99 -25
- package/src/middleware/auth-apikey.test.ts +15 -12
- package/src/middleware/auth-apikey.ts +3 -3
- package/src/middleware/auth-bearer.test.ts +17 -14
- package/src/middleware/auth-bearer.ts +25 -27
- package/src/middleware/auth-cookie.test.ts +16 -13
- package/src/middleware/auth-cookie.ts +6 -8
- package/src/middleware/cors.ts +96 -0
- package/src/middleware/index.ts +5 -3
- package/src/middleware/remote-auth.ts +68 -0
- package/src/middleware-runner.test.ts +122 -0
- package/src/middleware-runner.ts +12 -12
- package/src/permissions.test.ts +81 -7
- package/src/permissions.ts +15 -17
- package/src/pikku-state.ts +20 -8
- package/src/run-tests-script.test.ts +49 -0
- package/src/schema.ts +18 -15
- package/src/services/ai-agent-runner-service.ts +29 -0
- package/src/services/ai-run-state-service.ts +20 -0
- package/src/services/ai-storage-service.ts +39 -0
- package/src/services/deployment-service.ts +22 -0
- package/src/services/gopass-secrets.ts +95 -0
- package/src/services/in-memory-trigger-service.ts +68 -0
- package/src/services/in-memory-workflow-service.ts +395 -0
- package/src/services/index.ts +49 -14
- package/src/services/local-secrets.ts +51 -0
- package/src/services/local-variables.ts +22 -0
- package/src/services/scheduler-service.ts +29 -1
- package/src/services/schema-service.ts +7 -0
- package/src/services/scoped-secret-service.ts +41 -0
- package/src/services/secret-service.ts +25 -4
- package/src/services/trigger-service.ts +38 -0
- package/src/services/typed-secret-service.ts +70 -0
- package/src/services/typed-variables-service.ts +81 -0
- package/src/services/user-session-service.ts +23 -0
- package/src/services/variables-service.ts +5 -0
- package/src/services/workflow-service.ts +22 -2
- package/src/types/core.types.ts +76 -11
- package/src/types/state.types.ts +37 -63
- package/src/utils.ts +20 -6
- package/src/version.test.ts +80 -0
- package/src/version.ts +25 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +300 -0
- package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +470 -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 +75 -0
- package/src/wirings/ai-agent/ai-agent-runner.ts +137 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +246 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +774 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +273 -0
- package/src/wirings/ai-agent/index.ts +28 -0
- package/src/wirings/channel/channel-common.ts +32 -19
- package/src/wirings/channel/channel-handler.ts +17 -4
- package/src/wirings/channel/channel-middleware-runner.ts +119 -0
- package/src/wirings/channel/channel-runner.ts +9 -10
- package/src/wirings/channel/channel.types.ts +17 -1
- 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 +44 -1
- package/src/wirings/channel/local/local-channel-runner.ts +22 -6
- package/src/wirings/channel/serverless/index.ts +5 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +20 -4
- package/src/wirings/cli/channel/index.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +9 -9
- package/src/wirings/cli/cli-runner.ts +17 -10
- package/src/wirings/cli/cli.types.ts +11 -11
- package/src/wirings/cli/command-parser.test.ts +8 -8
- 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 +3 -3
- package/src/wirings/http/http-runner.ts +63 -29
- package/src/wirings/http/http.types.ts +121 -37
- package/src/wirings/http/index.ts +16 -4
- package/src/wirings/mcp/index.ts +27 -3
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +3 -3
- package/src/wirings/mcp/mcp-runner.ts +39 -50
- package/src/wirings/mcp/mcp.types.ts +3 -3
- 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 +14 -2
- package/src/wirings/queue/queue-runner.test.ts +97 -55
- package/src/wirings/queue/queue-runner.ts +33 -7
- package/src/wirings/queue/queue.types.ts +12 -2
- package/src/wirings/rpc/index.ts +1 -1
- package/src/wirings/rpc/rpc-runner.ts +187 -17
- package/src/wirings/rpc/rpc-types.ts +13 -4
- package/src/wirings/scheduler/index.ts +7 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +70 -26
- package/src/wirings/scheduler/scheduler-runner.ts +45 -5
- package/src/wirings/secret/index.ts +9 -0
- package/src/wirings/secret/secret.types.ts +32 -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 +134 -0
- package/src/wirings/trigger/trigger-runner.ts +80 -38
- package/src/wirings/trigger/trigger.types.ts +144 -22
- package/src/wirings/variable/index.ts +8 -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 +495 -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.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 +212 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +285 -66
- package/src/wirings/workflow/workflow-helpers.ts +79 -0
- package/src/wirings/workflow/workflow-utils.ts +0 -120
- package/src/wirings/workflow/workflow.types.ts +45 -90
- 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/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
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { runPikkuFunc } from '../../function/function-runner.js';
|
|
2
2
|
import { 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,6 +71,12 @@ 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.)
|
|
@@ -92,6 +117,14 @@ export class PikkuWorkflowService {
|
|
|
92
117
|
sleeperRPCName: workflow?.sleeperRPCName ?? 'pikkuWorkflowSleeper',
|
|
93
118
|
};
|
|
94
119
|
}
|
|
120
|
+
async registerWorkflowVersions() {
|
|
121
|
+
const allMeta = pikkuState(null, 'workflows', 'meta');
|
|
122
|
+
for (const [name, meta] of Object.entries(allMeta)) {
|
|
123
|
+
if (!meta.graphHash)
|
|
124
|
+
continue;
|
|
125
|
+
await this.upsertWorkflowVersion(name, meta.graphHash, meta, meta.source);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
95
128
|
// ============================================================================
|
|
96
129
|
// Workflow Lifecycle Methods
|
|
97
130
|
// ============================================================================
|
|
@@ -103,6 +136,15 @@ export class PikkuWorkflowService {
|
|
|
103
136
|
const queueService = this.verifyQueueService();
|
|
104
137
|
await queueService.add(this.getConfig().orchestratorQueueName, { runId });
|
|
105
138
|
}
|
|
139
|
+
async queueStepWorker(runId, stepName, rpcName, data) {
|
|
140
|
+
const queueService = this.verifyQueueService();
|
|
141
|
+
await queueService.add(this.getConfig().stepWorkerQueueName, {
|
|
142
|
+
runId,
|
|
143
|
+
stepName,
|
|
144
|
+
rpcName,
|
|
145
|
+
data,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
106
148
|
/**
|
|
107
149
|
* Execute a workflow sleep step completion
|
|
108
150
|
* Sets the step result to null and resumes the workflow
|
|
@@ -127,7 +169,7 @@ export class PikkuWorkflowService {
|
|
|
127
169
|
* @param options.inline - If true, execute workflow directly without queue service
|
|
128
170
|
* @param options.startNode - Starting node ID for graph workflows (from wire config)
|
|
129
171
|
*/
|
|
130
|
-
async startWorkflow(name, input, rpcService, options) {
|
|
172
|
+
async startWorkflow(name, input, wire, rpcService, options) {
|
|
131
173
|
// Check meta to determine workflow type
|
|
132
174
|
const meta = pikkuState(null, 'workflows', 'meta');
|
|
133
175
|
const workflowMeta = meta[name];
|
|
@@ -136,8 +178,8 @@ export class PikkuWorkflowService {
|
|
|
136
178
|
}
|
|
137
179
|
// Check if this is a graph workflow (source === 'graph')
|
|
138
180
|
if (workflowMeta.source === 'graph') {
|
|
139
|
-
|
|
140
|
-
return runWorkflowGraph(this, name, input, rpcService,
|
|
181
|
+
const shouldInline = options?.inline || !this.singletonServices?.queueService;
|
|
182
|
+
return runWorkflowGraph(this, name, input, rpcService, shouldInline, options?.startNode, wire);
|
|
141
183
|
}
|
|
142
184
|
// DSL workflow - check registration exists
|
|
143
185
|
const registrations = pikkuState(null, 'workflows', 'registrations');
|
|
@@ -145,34 +187,63 @@ export class PikkuWorkflowService {
|
|
|
145
187
|
if (!workflow) {
|
|
146
188
|
throw new WorkflowNotFoundError(name);
|
|
147
189
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
190
|
+
if (!workflowMeta.graphHash) {
|
|
191
|
+
throw new Error(`Missing workflow graphHash for '${name}'`);
|
|
192
|
+
}
|
|
193
|
+
const runId = await this.createRun(name, input, options?.inline ?? false, workflowMeta.graphHash, wire);
|
|
151
194
|
if (options?.inline) {
|
|
152
195
|
this.inlineRuns.add(runId);
|
|
153
196
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
197
|
+
if (options?.inline || !this.singletonServices?.queueService) {
|
|
198
|
+
this.runWorkflowJob(runId, rpcService)
|
|
199
|
+
.catch(() => { })
|
|
200
|
+
.finally(() => {
|
|
201
|
+
if (options?.inline) {
|
|
202
|
+
this.inlineRuns.delete(runId);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
await this.resumeWorkflow(runId);
|
|
164
208
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
209
|
+
return { runId };
|
|
210
|
+
}
|
|
211
|
+
async runToCompletion(name, input, rpcService, options) {
|
|
212
|
+
const pollInterval = options?.pollIntervalMs ?? 1000;
|
|
213
|
+
const { runId } = await this.startWorkflow(name, input, options?.wire ?? { type: 'internal' }, rpcService, { inline: true });
|
|
214
|
+
while (true) {
|
|
215
|
+
const run = await this.getRun(runId);
|
|
216
|
+
if (!run) {
|
|
217
|
+
throw new WorkflowRunNotFoundError(runId);
|
|
169
218
|
}
|
|
219
|
+
if (WORKFLOW_END_STATES.has(run.status)) {
|
|
220
|
+
if (run.status === 'failed') {
|
|
221
|
+
throw new Error(run.error?.message || 'Workflow failed');
|
|
222
|
+
}
|
|
223
|
+
if (run.status === 'cancelled') {
|
|
224
|
+
throw new Error('Workflow was cancelled');
|
|
225
|
+
}
|
|
226
|
+
return run.output;
|
|
227
|
+
}
|
|
228
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
170
229
|
}
|
|
171
230
|
}
|
|
172
231
|
async runWorkflowJob(runId, rpcService) {
|
|
173
232
|
const run = await this.getRun(runId);
|
|
174
233
|
if (!run) {
|
|
175
|
-
throw new
|
|
234
|
+
throw new WorkflowRunNotFoundError(runId);
|
|
235
|
+
}
|
|
236
|
+
const meta = pikkuState(null, 'workflows', 'meta');
|
|
237
|
+
const workflowMeta = meta[run.workflow];
|
|
238
|
+
if (run.graphHash &&
|
|
239
|
+
workflowMeta?.graphHash &&
|
|
240
|
+
run.graphHash !== workflowMeta.graphHash) {
|
|
241
|
+
await this.runVersionMismatchFallback(run, workflowMeta, rpcService);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (workflowMeta?.source === 'graph') {
|
|
245
|
+
await continueGraph(this, runId, run.workflow);
|
|
246
|
+
return;
|
|
176
247
|
}
|
|
177
248
|
const registrations = pikkuState(null, 'workflows', 'registrations');
|
|
178
249
|
const workflow = registrations.get(run.workflow);
|
|
@@ -180,12 +251,10 @@ export class PikkuWorkflowService {
|
|
|
180
251
|
throw new WorkflowNotFoundError(run.workflow);
|
|
181
252
|
}
|
|
182
253
|
await this.withRunLock(runId, async () => {
|
|
183
|
-
const meta = pikkuState(null, 'workflows', 'meta');
|
|
184
|
-
const workflowMeta = meta[run.workflow];
|
|
185
254
|
const workflowWire = this.createWorkflowWire(run.workflow, runId, rpcService);
|
|
186
255
|
const wire = { workflow: workflowWire };
|
|
187
256
|
try {
|
|
188
|
-
const result = await runPikkuFunc('workflow', workflowMeta.name, workflowMeta.
|
|
257
|
+
const result = await runPikkuFunc('workflow', workflowMeta.name, workflowMeta.pikkuFuncId, {
|
|
189
258
|
singletonServices: this.singletonServices,
|
|
190
259
|
wire,
|
|
191
260
|
createWireServices: this.createWireServices,
|
|
@@ -195,12 +264,9 @@ export class PikkuWorkflowService {
|
|
|
195
264
|
}
|
|
196
265
|
catch (error) {
|
|
197
266
|
if (error instanceof WorkflowAsyncException) {
|
|
198
|
-
// Normal - workflow paused for step execution
|
|
199
267
|
throw error;
|
|
200
268
|
}
|
|
201
|
-
// Check if it's a WorkflowCancelledException
|
|
202
269
|
if (error instanceof WorkflowCancelledException) {
|
|
203
|
-
// Workflow was cancelled - update status and rethrow
|
|
204
270
|
await this.updateRunStatus(runId, 'cancelled', undefined, {
|
|
205
271
|
message: error.message || 'Workflow cancelled',
|
|
206
272
|
stack: '',
|
|
@@ -208,6 +274,14 @@ export class PikkuWorkflowService {
|
|
|
208
274
|
});
|
|
209
275
|
throw error;
|
|
210
276
|
}
|
|
277
|
+
if (error instanceof WorkflowSuspendedException) {
|
|
278
|
+
await this.updateRunStatus(runId, 'suspended', undefined, {
|
|
279
|
+
message: error.message || 'Workflow suspended',
|
|
280
|
+
stack: '',
|
|
281
|
+
code: 'WORKFLOW_SUSPENDED',
|
|
282
|
+
});
|
|
283
|
+
throw error;
|
|
284
|
+
}
|
|
211
285
|
await this.updateRunStatus(runId, 'failed', undefined, {
|
|
212
286
|
message: error.message,
|
|
213
287
|
stack: error.stack,
|
|
@@ -217,6 +291,27 @@ export class PikkuWorkflowService {
|
|
|
217
291
|
}
|
|
218
292
|
});
|
|
219
293
|
}
|
|
294
|
+
async runVersionMismatchFallback(run, currentMeta, rpcService) {
|
|
295
|
+
const source = currentMeta.source;
|
|
296
|
+
if (source === 'complex') {
|
|
297
|
+
await this.updateRunStatus(run.id, 'failed', undefined, {
|
|
298
|
+
message: `Workflow '${run.workflow}' definition changed. Complex workflows with inline steps cannot be migrated.`,
|
|
299
|
+
stack: '',
|
|
300
|
+
code: 'VERSION_CONFLICT',
|
|
301
|
+
});
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const version = await this.getWorkflowVersion(run.workflow, run.graphHash);
|
|
305
|
+
if (!version) {
|
|
306
|
+
await this.updateRunStatus(run.id, 'failed', undefined, {
|
|
307
|
+
message: `Workflow '${run.workflow}' version '${run.graphHash}' not found. Cannot resume with changed definition.`,
|
|
308
|
+
stack: '',
|
|
309
|
+
code: 'VERSION_NOT_FOUND',
|
|
310
|
+
});
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
await runFromMeta(this, run.id, version.graph, rpcService);
|
|
314
|
+
}
|
|
220
315
|
/**
|
|
221
316
|
* Execute a single workflow step (called by worker)
|
|
222
317
|
* Handles idempotency, RPC execution, result storage, retry logic, and orchestrator triggering
|
|
@@ -239,25 +334,22 @@ export class PikkuWorkflowService {
|
|
|
239
334
|
if (stepState.status === 'failed') {
|
|
240
335
|
stepState = await this.createRetryAttempt(stepState.stepId, 'running');
|
|
241
336
|
}
|
|
242
|
-
if (stepState.status
|
|
243
|
-
// Mark step as running
|
|
337
|
+
if (stepState.status === 'pending') {
|
|
338
|
+
// Mark pending step as running before execution
|
|
244
339
|
await this.setStepRunning(stepState.stepId);
|
|
245
340
|
}
|
|
246
341
|
try {
|
|
247
342
|
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);
|
|
343
|
+
const run = await this.getRun(runId);
|
|
344
|
+
if (!run) {
|
|
345
|
+
throw new Error(`Workflow run not found: ${runId}`);
|
|
346
|
+
}
|
|
347
|
+
const meta = pikkuState(null, 'workflows', 'meta');
|
|
348
|
+
const workflowMeta = meta[run.workflow];
|
|
349
|
+
if (workflowMeta?.nodes && stepName in workflowMeta.nodes) {
|
|
350
|
+
result = await executeGraphStep(this, rpcService, runId, stepState.stepId, stepName, rpcName, data, run.workflow);
|
|
258
351
|
}
|
|
259
352
|
else {
|
|
260
|
-
// Execute RPC with workflow step context (regular workflow)
|
|
261
353
|
result = await rpcService.rpcWithWire(rpcName, data, {
|
|
262
354
|
workflowStep: {
|
|
263
355
|
runId,
|
|
@@ -272,6 +364,14 @@ export class PikkuWorkflowService {
|
|
|
272
364
|
await this.resumeWorkflow(runId);
|
|
273
365
|
}
|
|
274
366
|
catch (error) {
|
|
367
|
+
if (error instanceof RPCNotFoundError) {
|
|
368
|
+
await this.setStepError(stepState.stepId, error);
|
|
369
|
+
await this.updateRunStatus(runId, 'suspended', undefined, {
|
|
370
|
+
message: `RPC '${rpcName}' not found. Deploy the missing function and resume.`,
|
|
371
|
+
code: 'RPC_NOT_FOUND',
|
|
372
|
+
});
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
275
375
|
// Store error and mark failed
|
|
276
376
|
await this.setStepError(stepState.stepId, error);
|
|
277
377
|
const maxAttempts = (stepState.retries ?? 0) + 1;
|
|
@@ -296,7 +396,8 @@ export class PikkuWorkflowService {
|
|
|
296
396
|
}
|
|
297
397
|
catch (error) {
|
|
298
398
|
if (error.name === 'WorkflowAsyncException' ||
|
|
299
|
-
error.name === 'WorkflowCancelledException'
|
|
399
|
+
error.name === 'WorkflowCancelledException' ||
|
|
400
|
+
error.name === 'WorkflowSuspendedException') {
|
|
300
401
|
return;
|
|
301
402
|
}
|
|
302
403
|
await this.updateRunStatus(runId, 'failed', undefined, {
|
|
@@ -385,6 +486,13 @@ export class PikkuWorkflowService {
|
|
|
385
486
|
return result;
|
|
386
487
|
}
|
|
387
488
|
catch (error) {
|
|
489
|
+
if (error instanceof RPCNotFoundError) {
|
|
490
|
+
await this.updateRunStatus(runId, 'suspended', undefined, {
|
|
491
|
+
message: `RPC '${rpcName}' not found. Deploy the missing function and resume.`,
|
|
492
|
+
code: 'RPC_NOT_FOUND',
|
|
493
|
+
});
|
|
494
|
+
throw error;
|
|
495
|
+
}
|
|
388
496
|
// Record the error (marks step as failed)
|
|
389
497
|
await this.setStepError(currentStepState.stepId, error);
|
|
390
498
|
// Check if we should retry
|
|
@@ -413,9 +521,7 @@ export class PikkuWorkflowService {
|
|
|
413
521
|
}
|
|
414
522
|
catch {
|
|
415
523
|
// 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);
|
|
524
|
+
stepState = await this.insertStepState(runId, stepName, null, null, stepOptions);
|
|
419
525
|
}
|
|
420
526
|
if (stepState.status === 'succeeded') {
|
|
421
527
|
// Return cached result
|
|
@@ -488,10 +594,9 @@ export class PikkuWorkflowService {
|
|
|
488
594
|
}
|
|
489
595
|
catch {
|
|
490
596
|
// Step doesn't exist - create it (sleep step, no RPC)
|
|
491
|
-
stepState = await this.insertStepState(runId, stepName, null,
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
);
|
|
597
|
+
stepState = await this.insertStepState(runId, stepName, null, {
|
|
598
|
+
duration,
|
|
599
|
+
});
|
|
495
600
|
}
|
|
496
601
|
if (stepState.status === 'succeeded') {
|
|
497
602
|
// Sleep already completed, return immediately
|
|
@@ -520,9 +625,45 @@ export class PikkuWorkflowService {
|
|
|
520
625
|
return;
|
|
521
626
|
}
|
|
522
627
|
}
|
|
523
|
-
|
|
628
|
+
getSuspendStepName(reason) {
|
|
629
|
+
if (!reason) {
|
|
630
|
+
return '__workflow_suspend';
|
|
631
|
+
}
|
|
632
|
+
return '__workflow_suspend';
|
|
633
|
+
}
|
|
634
|
+
async suspendStep(runId, reason) {
|
|
635
|
+
const stepName = this.getSuspendStepName(reason);
|
|
636
|
+
await this.withStepLock(runId, stepName, async () => {
|
|
637
|
+
let stepState;
|
|
638
|
+
try {
|
|
639
|
+
stepState = await this.getStepState(runId, stepName);
|
|
640
|
+
}
|
|
641
|
+
catch {
|
|
642
|
+
stepState = await this.insertStepState(runId, stepName, 'pikkuWorkflowSuspend', {
|
|
643
|
+
reason,
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
if (!stepState.stepId) {
|
|
647
|
+
stepState = await this.insertStepState(runId, stepName, 'pikkuWorkflowSuspend', {
|
|
648
|
+
reason,
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
if (stepState.status === 'succeeded') {
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
if (stepState.status === 'pending') {
|
|
655
|
+
await this.setStepRunning(stepState.stepId);
|
|
656
|
+
}
|
|
657
|
+
await this.setStepResult(stepState.stepId, {
|
|
658
|
+
reason,
|
|
659
|
+
suspendedAt: new Date().toISOString(),
|
|
660
|
+
});
|
|
661
|
+
throw new WorkflowSuspendedException(runId, reason);
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
createWorkflowWire(name, runId, rpcService) {
|
|
524
665
|
const workflowWire = {
|
|
525
|
-
|
|
666
|
+
name,
|
|
526
667
|
runId,
|
|
527
668
|
getRun: async () => (await this.getRun(runId)),
|
|
528
669
|
// Implement workflow.do() - RPC form
|
|
@@ -540,6 +681,9 @@ export class PikkuWorkflowService {
|
|
|
540
681
|
this.verifyStepName(stepName);
|
|
541
682
|
await this.sleepStep(runId, stepName, getDurationInMilliseconds(duration));
|
|
542
683
|
},
|
|
684
|
+
suspend: async (reason) => {
|
|
685
|
+
await this.suspendStep(runId, reason || 'Workflow suspended');
|
|
686
|
+
},
|
|
543
687
|
};
|
|
544
688
|
return workflowWire;
|
|
545
689
|
}
|
|
@@ -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
|
+
}
|
|
@@ -1,23 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { HTTPWiringMeta } from '../http/http.types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Result of finding a workflow by HTTP wire
|
|
5
|
-
*/
|
|
6
|
-
export interface WorkflowHttpMatch {
|
|
7
|
-
workflowName: string;
|
|
8
|
-
startNode?: string;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Find workflow name by matching route and method against workflow wires
|
|
12
|
-
*/
|
|
13
|
-
export declare const findWorkflowByHttpWire: (route: string, method: string) => WorkflowHttpMatch | undefined;
|
|
14
|
-
/**
|
|
15
|
-
* Start a workflow triggered by an HTTP wire
|
|
16
|
-
* The workflow is responsible for handling the HTTP response
|
|
17
|
-
*/
|
|
18
|
-
export declare const startWorkflowByHttpWire: (singletonServices: CoreSingletonServices, createWireServices: CreateWireServices<CoreSingletonServices, CoreServices<CoreSingletonServices>, CoreUserSession> | undefined, matchedRoute: {
|
|
19
|
-
matchedPath: any;
|
|
20
|
-
params: any;
|
|
21
|
-
route: any;
|
|
22
|
-
meta: HTTPWiringMeta;
|
|
23
|
-
}, wire: PikkuWire) => Promise<void>;
|
|
1
|
+
export {};
|
|
@@ -1,66 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { NotFoundError } from '../../errors/errors.js';
|
|
3
|
-
import { ContextAwareRPCService } from '../rpc/rpc-runner.js';
|
|
4
|
-
/**
|
|
5
|
-
* Find workflow name by matching route and method against workflow wires
|
|
6
|
-
*/
|
|
7
|
-
export const findWorkflowByHttpWire = (route, method) => {
|
|
8
|
-
const wirings = pikkuState(null, 'workflows', 'wirings');
|
|
9
|
-
const graphWirings = pikkuState(null, 'workflows', 'graphWirings');
|
|
10
|
-
// Check DSL workflow wirings
|
|
11
|
-
for (const [, wiring] of wirings) {
|
|
12
|
-
const httpWires = wiring.wires?.http;
|
|
13
|
-
if (httpWires) {
|
|
14
|
-
const matchedWire = httpWires.find((w) => w.route === route && w.method === method);
|
|
15
|
-
if (matchedWire) {
|
|
16
|
-
const meta = pikkuState(null, 'workflows', 'meta');
|
|
17
|
-
for (const [name, workflowMeta] of Object.entries(meta)) {
|
|
18
|
-
if (workflowMeta.source !== 'graph') {
|
|
19
|
-
const registrations = pikkuState(null, 'workflows', 'registrations');
|
|
20
|
-
if (registrations.has(name)) {
|
|
21
|
-
return { workflowName: name, startNode: matchedWire.startNode };
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
// Check graph workflow wirings
|
|
29
|
-
for (const [, wiring] of graphWirings) {
|
|
30
|
-
const httpWires = wiring.wires?.http;
|
|
31
|
-
if (httpWires) {
|
|
32
|
-
const matchedWire = httpWires.find((w) => w.route === route && w.method === method);
|
|
33
|
-
if (matchedWire) {
|
|
34
|
-
const meta = pikkuState(null, 'workflows', 'meta');
|
|
35
|
-
for (const [name, workflowMeta] of Object.entries(meta)) {
|
|
36
|
-
if (workflowMeta.source === 'graph') {
|
|
37
|
-
return { workflowName: name, startNode: matchedWire.startNode };
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return undefined;
|
|
44
|
-
};
|
|
45
|
-
/**
|
|
46
|
-
* Start a workflow triggered by an HTTP wire
|
|
47
|
-
* The workflow is responsible for handling the HTTP response
|
|
48
|
-
*/
|
|
49
|
-
export const startWorkflowByHttpWire = async (singletonServices, createWireServices, matchedRoute, wire) => {
|
|
50
|
-
const { meta } = matchedRoute;
|
|
51
|
-
const match = findWorkflowByHttpWire(meta.route, meta.method);
|
|
52
|
-
if (!match) {
|
|
53
|
-
throw new NotFoundError(`No workflow found for route ${meta.method.toUpperCase()} ${meta.route}`);
|
|
54
|
-
}
|
|
55
|
-
const workflowService = singletonServices.workflowService;
|
|
56
|
-
if (!workflowService) {
|
|
57
|
-
throw new Error('WorkflowService not available');
|
|
58
|
-
}
|
|
59
|
-
const data = await wire.http.request.data();
|
|
60
|
-
const wireServices = createWireServices?.(singletonServices, wire);
|
|
61
|
-
const rpcService = new ContextAwareRPCService({ ...singletonServices, ...wireServices }, wire, {});
|
|
62
|
-
await workflowService.startWorkflow(match.workflowName, data, rpcService, {
|
|
63
|
-
inline: true,
|
|
64
|
-
startNode: match.startNode,
|
|
65
|
-
});
|
|
66
|
-
};
|
|
1
|
+
export {};
|