@pikku/core 0.12.3 → 0.12.4
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 +6 -0
- package/dist/services/in-memory-workflow-service.d.ts +15 -2
- package/dist/services/in-memory-workflow-service.js +49 -0
- package/lcov.info +18891 -0
- package/package.json +1 -1
- package/src/crypto-utils.test.ts +0 -214
- package/src/crypto-utils.ts +0 -213
- package/src/errors/error-handler.ts +0 -62
- package/src/errors/error.test.ts +0 -195
- package/src/errors/errors.ts +0 -374
- package/src/errors/index.ts +0 -2
- package/src/factory-functions.test.ts +0 -109
- package/src/function/function-runner.test.ts +0 -536
- package/src/function/function-runner.ts +0 -365
- package/src/function/functions.types.ts +0 -304
- package/src/function/index.ts +0 -5
- package/src/handle-error.test.ts +0 -424
- package/src/handle-error.ts +0 -69
- package/src/index.ts +0 -118
- package/src/internal.ts +0 -6
- package/src/middleware/auth-apikey.test.ts +0 -363
- package/src/middleware/auth-apikey.ts +0 -47
- package/src/middleware/auth-bearer.test.ts +0 -450
- package/src/middleware/auth-bearer.ts +0 -72
- package/src/middleware/auth-cookie.test.ts +0 -528
- package/src/middleware/auth-cookie.ts +0 -80
- package/src/middleware/cors.test.ts +0 -424
- package/src/middleware/cors.ts +0 -104
- package/src/middleware/index.ts +0 -5
- package/src/middleware/remote-auth.test.ts +0 -488
- package/src/middleware/remote-auth.ts +0 -68
- package/src/middleware/timeout.ts +0 -15
- package/src/middleware-runner.test.ts +0 -418
- package/src/middleware-runner.ts +0 -234
- package/src/permissions.test.ts +0 -434
- package/src/permissions.ts +0 -319
- package/src/pikku-request.ts +0 -23
- package/src/pikku-response.ts +0 -5
- package/src/pikku-state.test.ts +0 -224
- package/src/pikku-state.ts +0 -216
- package/src/run-tests-script.test.ts +0 -49
- package/src/schema.test.ts +0 -249
- package/src/schema.ts +0 -151
- package/src/services/ai-agent-runner-service.ts +0 -41
- package/src/services/ai-run-state-service.ts +0 -20
- package/src/services/ai-storage-service.ts +0 -39
- package/src/services/content-service.ts +0 -76
- package/src/services/deployment-service.ts +0 -22
- package/src/services/gateway-service.ts +0 -20
- package/src/services/gopass-secrets.ts +0 -98
- package/src/services/in-memory-ai-run-state-service.ts +0 -73
- package/src/services/in-memory-trigger-service.ts +0 -64
- package/src/services/in-memory-workflow-service.test.ts +0 -351
- package/src/services/in-memory-workflow-service.ts +0 -438
- package/src/services/index.ts +0 -56
- package/src/services/jwt-service.ts +0 -30
- package/src/services/local-content.ts +0 -120
- package/src/services/local-gateway-service.ts +0 -62
- package/src/services/local-secrets.test.ts +0 -80
- package/src/services/local-secrets.ts +0 -94
- package/src/services/local-variables.test.ts +0 -61
- package/src/services/local-variables.ts +0 -39
- package/src/services/logger-console.test.ts +0 -118
- package/src/services/logger-console.ts +0 -98
- package/src/services/logger.ts +0 -57
- package/src/services/scheduler-service.ts +0 -86
- package/src/services/schema-service.ts +0 -33
- package/src/services/scoped-secret-service.test.ts +0 -74
- package/src/services/scoped-secret-service.ts +0 -41
- package/src/services/secret-service.ts +0 -38
- package/src/services/trigger-service.ts +0 -17
- package/src/services/typed-secret-service.test.ts +0 -93
- package/src/services/typed-secret-service.ts +0 -70
- package/src/services/typed-variables-service.test.ts +0 -73
- package/src/services/typed-variables-service.ts +0 -81
- package/src/services/user-session-service.test.ts +0 -113
- package/src/services/user-session-service.ts +0 -86
- package/src/services/variables-service.ts +0 -11
- package/src/services/workflow-service.ts +0 -95
- package/src/testing/index.ts +0 -2
- package/src/testing/service-tests.ts +0 -873
- package/src/time-utils.test.ts +0 -56
- package/src/time-utils.ts +0 -107
- package/src/types/core.types.ts +0 -478
- package/src/types/state.types.ts +0 -188
- package/src/utils/hash.test.ts +0 -68
- package/src/utils/hash.ts +0 -26
- package/src/utils.test.ts +0 -350
- package/src/utils.ts +0 -129
- package/src/version.test.ts +0 -80
- package/src/version.ts +0 -25
- package/src/wirings/ai-agent/agent-dynamic-workflow.ts +0 -469
- package/src/wirings/ai-agent/ai-agent-helpers.test.ts +0 -152
- package/src/wirings/ai-agent/ai-agent-helpers.ts +0 -76
- package/src/wirings/ai-agent/ai-agent-memory.ts +0 -310
- package/src/wirings/ai-agent/ai-agent-model-config.test.ts +0 -115
- package/src/wirings/ai-agent/ai-agent-model-config.ts +0 -43
- package/src/wirings/ai-agent/ai-agent-prepare.ts +0 -636
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +0 -37
- package/src/wirings/ai-agent/ai-agent-registry.ts +0 -82
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +0 -319
- package/src/wirings/ai-agent/ai-agent-runner.ts +0 -773
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +0 -859
- package/src/wirings/ai-agent/ai-agent-stream.ts +0 -1153
- package/src/wirings/ai-agent/ai-agent.types.ts +0 -382
- package/src/wirings/ai-agent/index.ts +0 -37
- package/src/wirings/channel/channel-common.ts +0 -90
- package/src/wirings/channel/channel-handler.ts +0 -250
- package/src/wirings/channel/channel-middleware-runner.ts +0 -120
- package/src/wirings/channel/channel-runner.ts +0 -166
- package/src/wirings/channel/channel-store.ts +0 -29
- package/src/wirings/channel/channel.types.ts +0 -172
- package/src/wirings/channel/define-channel-routes.ts +0 -25
- package/src/wirings/channel/eventhub-service.ts +0 -34
- package/src/wirings/channel/eventhub-store.ts +0 -13
- package/src/wirings/channel/index.ts +0 -24
- package/src/wirings/channel/local/index.ts +0 -3
- package/src/wirings/channel/local/local-channel-handler.ts +0 -81
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -215
- package/src/wirings/channel/local/local-channel-runner.ts +0 -210
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -95
- package/src/wirings/channel/local/local-eventhub-service.ts +0 -101
- package/src/wirings/channel/log-channels.ts +0 -20
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -54
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -45
- package/src/wirings/channel/serverless/index.ts +0 -5
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -289
- package/src/wirings/cli/channel/cli-channel-runner.ts +0 -136
- package/src/wirings/cli/channel/index.ts +0 -1
- package/src/wirings/cli/cli-runner.test.ts +0 -403
- package/src/wirings/cli/cli-runner.ts +0 -529
- package/src/wirings/cli/cli.types.ts +0 -358
- package/src/wirings/cli/command-parser.test.ts +0 -445
- package/src/wirings/cli/command-parser.ts +0 -504
- package/src/wirings/cli/define-cli-commands.ts +0 -24
- package/src/wirings/cli/index.ts +0 -19
- package/src/wirings/gateway/gateway-runner.test.ts +0 -474
- package/src/wirings/gateway/gateway-runner.ts +0 -411
- package/src/wirings/gateway/gateway.types.ts +0 -149
- package/src/wirings/gateway/index.ts +0 -13
- package/src/wirings/http/http-routes.test.ts +0 -322
- package/src/wirings/http/http-routes.ts +0 -197
- package/src/wirings/http/http-runner.test.ts +0 -144
- package/src/wirings/http/http-runner.ts +0 -588
- package/src/wirings/http/http.types.ts +0 -369
- package/src/wirings/http/index.ts +0 -28
- package/src/wirings/http/log-http-routes.ts +0 -22
- package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -237
- package/src/wirings/http/pikku-fetch-http-request.ts +0 -170
- package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -82
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -147
- package/src/wirings/http/routers/http-router.ts +0 -13
- package/src/wirings/http/routers/path-to-regex.test.ts +0 -319
- package/src/wirings/http/routers/path-to-regex.ts +0 -126
- package/src/wirings/http/web-request.test.ts +0 -236
- package/src/wirings/http/web-request.ts +0 -104
- package/src/wirings/mcp/index.ts +0 -27
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -389
- package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
- package/src/wirings/mcp/mcp-runner.ts +0 -323
- package/src/wirings/mcp/mcp.types.ts +0 -216
- package/src/wirings/node/index.ts +0 -2
- package/src/wirings/node/node.types.ts +0 -23
- package/src/wirings/oauth2/index.ts +0 -3
- package/src/wirings/oauth2/oauth2-client.test.ts +0 -929
- package/src/wirings/oauth2/oauth2-client.ts +0 -335
- package/src/wirings/oauth2/oauth2.types.ts +0 -69
- package/src/wirings/oauth2/wire-oauth2-credential.ts +0 -23
- package/src/wirings/queue/index.ts +0 -31
- package/src/wirings/queue/queue-runner.test.ts +0 -710
- package/src/wirings/queue/queue-runner.ts +0 -192
- package/src/wirings/queue/queue.types.ts +0 -189
- package/src/wirings/queue/register-queue-helper.ts +0 -60
- package/src/wirings/queue/validate-worker-config.test.ts +0 -108
- package/src/wirings/queue/validate-worker-config.ts +0 -116
- package/src/wirings/rpc/index.ts +0 -4
- package/src/wirings/rpc/rpc-runner.ts +0 -460
- package/src/wirings/rpc/rpc-types.ts +0 -56
- package/src/wirings/rpc/wire-addon.ts +0 -21
- package/src/wirings/scheduler/index.ts +0 -11
- package/src/wirings/scheduler/log-schedulers.ts +0 -20
- package/src/wirings/scheduler/scheduler-runner.test.ts +0 -660
- package/src/wirings/scheduler/scheduler-runner.ts +0 -133
- package/src/wirings/scheduler/scheduler.types.ts +0 -53
- package/src/wirings/secret/index.ts +0 -9
- package/src/wirings/secret/secret.types.ts +0 -32
- package/src/wirings/secret/validate-secret-definitions.test.ts +0 -140
- package/src/wirings/secret/validate-secret-definitions.ts +0 -82
- package/src/wirings/trigger/index.ts +0 -10
- package/src/wirings/trigger/pikku-trigger-service.ts +0 -112
- package/src/wirings/trigger/trigger-runner.test.ts +0 -79
- package/src/wirings/trigger/trigger-runner.ts +0 -135
- package/src/wirings/trigger/trigger.types.ts +0 -178
- package/src/wirings/variable/index.ts +0 -8
- package/src/wirings/variable/validate-variable-definitions.test.ts +0 -91
- package/src/wirings/variable/validate-variable-definitions.ts +0 -69
- package/src/wirings/variable/variable.types.ts +0 -22
- package/src/wirings/workflow/dsl/index.ts +0 -31
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -320
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -28
- package/src/wirings/workflow/graph/graph-node.ts +0 -222
- package/src/wirings/workflow/graph/graph-runner.test.ts +0 -487
- package/src/wirings/workflow/graph/graph-runner.ts +0 -816
- package/src/wirings/workflow/graph/graph-validation.test.ts +0 -170
- package/src/wirings/workflow/graph/graph-validation.ts +0 -237
- package/src/wirings/workflow/graph/index.ts +0 -19
- package/src/wirings/workflow/graph/template.test.ts +0 -49
- package/src/wirings/workflow/graph/template.ts +0 -42
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -29
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -104
- package/src/wirings/workflow/index.ts +0 -82
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -200
- package/src/wirings/workflow/pikku-workflow-service.ts +0 -1176
- package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
- package/src/wirings/workflow/workflow-helpers.ts +0 -79
- package/src/wirings/workflow/workflow.types.ts +0 -274
- package/tsconfig.json +0 -14
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -1,438 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'crypto'
|
|
2
|
-
import { PikkuWorkflowService } from '../wirings/workflow/pikku-workflow-service.js'
|
|
3
|
-
import type { SerializedError } from '../types/core.types.js'
|
|
4
|
-
import type {
|
|
5
|
-
WorkflowRun,
|
|
6
|
-
WorkflowRunWire,
|
|
7
|
-
StepState,
|
|
8
|
-
WorkflowStatus,
|
|
9
|
-
WorkflowVersionStatus,
|
|
10
|
-
WorkflowStepOptions,
|
|
11
|
-
} from '../wirings/workflow/workflow.types.js'
|
|
12
|
-
|
|
13
|
-
interface InternalStepData {
|
|
14
|
-
rpcName: string | null
|
|
15
|
-
data: any
|
|
16
|
-
stepName: string
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* In-memory implementation of WorkflowService for inline-only execution
|
|
21
|
-
*
|
|
22
|
-
* This is a lightweight workflow service that stores all state in memory.
|
|
23
|
-
* It only supports inline execution (no queue workers) and is ideal for:
|
|
24
|
-
* - CLI tools that need workflow-like step orchestration
|
|
25
|
-
* - Testing and development
|
|
26
|
-
* - Single-process applications without persistence requirements
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```typescript
|
|
30
|
-
* const workflowService = new InMemoryWorkflowService()
|
|
31
|
-
* await workflowService.startWorkflow('myWorkflow', input, { type: 'cli' }, rpc, { inline: true })
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
export class InMemoryWorkflowService extends PikkuWorkflowService {
|
|
35
|
-
private runs = new Map<string, WorkflowRun>()
|
|
36
|
-
private steps = new Map<string, StepState>() // keyed by `${runId}:${stepName}`
|
|
37
|
-
private stepData = new Map<string, InternalStepData>() // keyed by stepId
|
|
38
|
-
private stepHistory = new Map<
|
|
39
|
-
string,
|
|
40
|
-
Array<StepState & { stepName: string }>
|
|
41
|
-
>() // keyed by runId
|
|
42
|
-
private runState = new Map<string, Record<string, unknown>>() // keyed by runId
|
|
43
|
-
private branchKeys = new Map<string, string>() // keyed by stepId
|
|
44
|
-
private workflowVersions = new Map<
|
|
45
|
-
string,
|
|
46
|
-
{ graph: any; source: string; status: WorkflowVersionStatus }
|
|
47
|
-
>() // keyed by `${name}:${graphHash}`
|
|
48
|
-
|
|
49
|
-
async createRun(
|
|
50
|
-
workflowName: string,
|
|
51
|
-
input: any,
|
|
52
|
-
inline: boolean,
|
|
53
|
-
graphHash: string,
|
|
54
|
-
wire: WorkflowRunWire
|
|
55
|
-
): Promise<string> {
|
|
56
|
-
const runId = randomUUID()
|
|
57
|
-
const now = new Date()
|
|
58
|
-
|
|
59
|
-
const run: WorkflowRun = {
|
|
60
|
-
id: runId,
|
|
61
|
-
workflow: workflowName,
|
|
62
|
-
status: 'running',
|
|
63
|
-
input,
|
|
64
|
-
inline,
|
|
65
|
-
graphHash,
|
|
66
|
-
wire,
|
|
67
|
-
createdAt: now,
|
|
68
|
-
updatedAt: now,
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
this.runs.set(runId, run)
|
|
72
|
-
this.stepHistory.set(runId, [])
|
|
73
|
-
this.runState.set(runId, {})
|
|
74
|
-
|
|
75
|
-
if (inline) {
|
|
76
|
-
this.registerInlineRun(runId)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return runId
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async getRun(id: string): Promise<WorkflowRun | null> {
|
|
83
|
-
return this.runs.get(id) || null
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async getRunHistory(
|
|
87
|
-
runId: string
|
|
88
|
-
): Promise<Array<StepState & { stepName: string }>> {
|
|
89
|
-
return this.stepHistory.get(runId) || []
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async updateRunStatus(
|
|
93
|
-
id: string,
|
|
94
|
-
status: WorkflowStatus,
|
|
95
|
-
output?: any,
|
|
96
|
-
error?: SerializedError
|
|
97
|
-
): Promise<void> {
|
|
98
|
-
const run = this.runs.get(id)
|
|
99
|
-
if (run) {
|
|
100
|
-
run.status = status
|
|
101
|
-
run.updatedAt = new Date()
|
|
102
|
-
if (output !== undefined) run.output = output
|
|
103
|
-
if (error !== undefined) run.error = error
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async insertStepState(
|
|
108
|
-
runId: string,
|
|
109
|
-
stepName: string,
|
|
110
|
-
rpcName: string | null,
|
|
111
|
-
data: any,
|
|
112
|
-
stepOptions?: WorkflowStepOptions
|
|
113
|
-
): Promise<StepState> {
|
|
114
|
-
const stepId = randomUUID()
|
|
115
|
-
const now = new Date()
|
|
116
|
-
|
|
117
|
-
const step: StepState = {
|
|
118
|
-
stepId,
|
|
119
|
-
status: 'pending',
|
|
120
|
-
attemptCount: 1,
|
|
121
|
-
retries: stepOptions?.retries,
|
|
122
|
-
retryDelay: stepOptions?.retryDelay,
|
|
123
|
-
createdAt: now,
|
|
124
|
-
updatedAt: now,
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const key = `${runId}:${stepName}`
|
|
128
|
-
this.steps.set(key, step)
|
|
129
|
-
this.stepData.set(stepId, { rpcName, data, stepName })
|
|
130
|
-
|
|
131
|
-
// Add to history
|
|
132
|
-
const history = this.stepHistory.get(runId) || []
|
|
133
|
-
history.push({ ...step, stepName })
|
|
134
|
-
this.stepHistory.set(runId, history)
|
|
135
|
-
|
|
136
|
-
return step
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async getStepState(runId: string, stepName: string): Promise<StepState> {
|
|
140
|
-
const key = `${runId}:${stepName}`
|
|
141
|
-
const step = this.steps.get(key)
|
|
142
|
-
if (!step) {
|
|
143
|
-
return {
|
|
144
|
-
stepId: '',
|
|
145
|
-
status: 'pending',
|
|
146
|
-
attemptCount: 0,
|
|
147
|
-
createdAt: new Date(),
|
|
148
|
-
updatedAt: new Date(),
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return step
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
async setStepRunning(stepId: string): Promise<void> {
|
|
155
|
-
for (const step of this.steps.values()) {
|
|
156
|
-
if (step.stepId === stepId) {
|
|
157
|
-
step.status = 'running'
|
|
158
|
-
step.runningAt = new Date()
|
|
159
|
-
step.updatedAt = new Date()
|
|
160
|
-
break
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async setStepScheduled(stepId: string): Promise<void> {
|
|
166
|
-
for (const step of this.steps.values()) {
|
|
167
|
-
if (step.stepId === stepId) {
|
|
168
|
-
step.status = 'scheduled'
|
|
169
|
-
step.scheduledAt = new Date()
|
|
170
|
-
step.updatedAt = new Date()
|
|
171
|
-
break
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async setStepResult(stepId: string, result: any): Promise<void> {
|
|
177
|
-
for (const step of this.steps.values()) {
|
|
178
|
-
if (step.stepId === stepId) {
|
|
179
|
-
step.status = 'succeeded'
|
|
180
|
-
step.result = result
|
|
181
|
-
step.succeededAt = new Date()
|
|
182
|
-
step.updatedAt = new Date()
|
|
183
|
-
break
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
async setStepError(stepId: string, error: Error): Promise<void> {
|
|
189
|
-
for (const step of this.steps.values()) {
|
|
190
|
-
if (step.stepId === stepId) {
|
|
191
|
-
step.status = 'failed'
|
|
192
|
-
step.error = {
|
|
193
|
-
name: error.name,
|
|
194
|
-
message: error.message,
|
|
195
|
-
stack: error.stack,
|
|
196
|
-
}
|
|
197
|
-
step.failedAt = new Date()
|
|
198
|
-
step.updatedAt = new Date()
|
|
199
|
-
break
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
async createRetryAttempt(
|
|
205
|
-
failedStepId: string,
|
|
206
|
-
status: 'pending' | 'running'
|
|
207
|
-
): Promise<StepState> {
|
|
208
|
-
// Find the failed step
|
|
209
|
-
let failedStep: StepState | undefined
|
|
210
|
-
let runId: string | undefined
|
|
211
|
-
let stepName: string | undefined
|
|
212
|
-
|
|
213
|
-
for (const [key, step] of this.steps.entries()) {
|
|
214
|
-
if (step.stepId === failedStepId) {
|
|
215
|
-
failedStep = step
|
|
216
|
-
const parts = key.split(':')
|
|
217
|
-
runId = parts[0]
|
|
218
|
-
stepName = parts.slice(1).join(':')
|
|
219
|
-
break
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (!failedStep || !runId || !stepName) {
|
|
224
|
-
throw new Error(`Step not found: ${failedStepId}`)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const failedStepData = this.stepData.get(failedStepId)
|
|
228
|
-
const newStepId = randomUUID()
|
|
229
|
-
const now = new Date()
|
|
230
|
-
|
|
231
|
-
const newStep: StepState = {
|
|
232
|
-
stepId: newStepId,
|
|
233
|
-
status,
|
|
234
|
-
attemptCount: failedStep.attemptCount + 1,
|
|
235
|
-
retries: failedStep.retries,
|
|
236
|
-
retryDelay: failedStep.retryDelay,
|
|
237
|
-
createdAt: now,
|
|
238
|
-
updatedAt: now,
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (status === 'running') {
|
|
242
|
-
newStep.runningAt = now
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
const key = `${runId}:${stepName}`
|
|
246
|
-
this.steps.set(key, newStep)
|
|
247
|
-
|
|
248
|
-
// Copy step data to new step
|
|
249
|
-
if (failedStepData) {
|
|
250
|
-
this.stepData.set(newStepId, { ...failedStepData })
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Add to history
|
|
254
|
-
const history = this.stepHistory.get(runId) || []
|
|
255
|
-
history.push({ ...newStep, stepName })
|
|
256
|
-
this.stepHistory.set(runId, history)
|
|
257
|
-
|
|
258
|
-
return newStep
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
async withRunLock<T>(_id: string, fn: () => Promise<T>): Promise<T> {
|
|
262
|
-
// In-memory service doesn't need locking for inline execution
|
|
263
|
-
return fn()
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
async withStepLock<T>(
|
|
267
|
-
_runId: string,
|
|
268
|
-
_stepName: string,
|
|
269
|
-
fn: () => Promise<T>
|
|
270
|
-
): Promise<T> {
|
|
271
|
-
// In-memory service doesn't need locking for inline execution
|
|
272
|
-
return fn()
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
async close(): Promise<void> {
|
|
276
|
-
// Clear all in-memory state
|
|
277
|
-
this.runs.clear()
|
|
278
|
-
this.steps.clear()
|
|
279
|
-
this.stepData.clear()
|
|
280
|
-
this.stepHistory.clear()
|
|
281
|
-
this.runState.clear()
|
|
282
|
-
this.branchKeys.clear()
|
|
283
|
-
this.workflowVersions.clear()
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Graph workflow methods
|
|
287
|
-
|
|
288
|
-
async getCompletedGraphState(runId: string): Promise<{
|
|
289
|
-
completedNodeIds: string[]
|
|
290
|
-
failedNodeIds: string[]
|
|
291
|
-
branchKeys: Record<string, string>
|
|
292
|
-
}> {
|
|
293
|
-
const completedNodeIds: string[] = []
|
|
294
|
-
const failedNodeIds: string[] = []
|
|
295
|
-
const prefix = `${runId}:`
|
|
296
|
-
for (const [key, step] of this.steps.entries()) {
|
|
297
|
-
if (!key.startsWith(prefix)) continue
|
|
298
|
-
const nodeId = key.substring(prefix.length)
|
|
299
|
-
if (step.status === 'succeeded') {
|
|
300
|
-
completedNodeIds.push(nodeId)
|
|
301
|
-
} else if (step.status === 'failed') {
|
|
302
|
-
const maxAttempts = (step.retries ?? 0) + 1
|
|
303
|
-
if (step.attemptCount >= maxAttempts) {
|
|
304
|
-
failedNodeIds.push(nodeId)
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
const branchKeys: Record<string, string> = {}
|
|
310
|
-
for (const [stepId, branchKey] of this.branchKeys.entries()) {
|
|
311
|
-
const stepData = this.stepData.get(stepId)
|
|
312
|
-
if (stepData) {
|
|
313
|
-
branchKeys[stepData.stepName] = branchKey
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return { completedNodeIds, failedNodeIds, branchKeys }
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
async getNodesWithoutSteps(
|
|
321
|
-
runId: string,
|
|
322
|
-
nodeIds: string[]
|
|
323
|
-
): Promise<string[]> {
|
|
324
|
-
const existingSteps = new Set<string>()
|
|
325
|
-
const prefix = `${runId}:`
|
|
326
|
-
for (const [key] of this.steps.entries()) {
|
|
327
|
-
if (key.startsWith(prefix)) {
|
|
328
|
-
existingSteps.add(key.substring(prefix.length))
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return nodeIds.filter((id) => !existingSteps.has(id))
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
async getNodeResults(
|
|
335
|
-
runId: string,
|
|
336
|
-
nodeIds: string[]
|
|
337
|
-
): Promise<Record<string, any>> {
|
|
338
|
-
const results: Record<string, any> = {}
|
|
339
|
-
for (const nodeId of nodeIds) {
|
|
340
|
-
const key = `${runId}:${nodeId}`
|
|
341
|
-
const step = this.steps.get(key)
|
|
342
|
-
if (step?.result !== undefined) {
|
|
343
|
-
results[nodeId] = step.result
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
return results
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
async setBranchKey(
|
|
350
|
-
runId: string,
|
|
351
|
-
nodeId: string,
|
|
352
|
-
branchKey: string
|
|
353
|
-
): Promise<void> {
|
|
354
|
-
const key = `${runId}:${nodeId}`
|
|
355
|
-
const step = this.steps.get(key)
|
|
356
|
-
if (step) {
|
|
357
|
-
this.branchKeys.set(step.stepId, branchKey)
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
async setBranchTaken(stepId: string, branchKey: string): Promise<void> {
|
|
362
|
-
this.branchKeys.set(stepId, branchKey)
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
async updateRunState(
|
|
366
|
-
runId: string,
|
|
367
|
-
name: string,
|
|
368
|
-
value: unknown
|
|
369
|
-
): Promise<void> {
|
|
370
|
-
const state = this.runState.get(runId) || {}
|
|
371
|
-
state[name] = value
|
|
372
|
-
this.runState.set(runId, state)
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
async getRunState(runId: string): Promise<Record<string, unknown>> {
|
|
376
|
-
return this.runState.get(runId) || {}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
async upsertWorkflowVersion(
|
|
380
|
-
name: string,
|
|
381
|
-
graphHash: string,
|
|
382
|
-
graph: any,
|
|
383
|
-
source: string,
|
|
384
|
-
status?: WorkflowVersionStatus
|
|
385
|
-
): Promise<void> {
|
|
386
|
-
this.workflowVersions.set(`${name}:${graphHash}`, {
|
|
387
|
-
graph,
|
|
388
|
-
source,
|
|
389
|
-
status: status ?? 'active',
|
|
390
|
-
})
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
async updateWorkflowVersionStatus(
|
|
394
|
-
name: string,
|
|
395
|
-
graphHash: string,
|
|
396
|
-
status: WorkflowVersionStatus
|
|
397
|
-
): Promise<void> {
|
|
398
|
-
const key = `${name}:${graphHash}`
|
|
399
|
-
const version = this.workflowVersions.get(key)
|
|
400
|
-
if (version) {
|
|
401
|
-
version.status = status
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
async getWorkflowVersion(
|
|
406
|
-
name: string,
|
|
407
|
-
graphHash: string
|
|
408
|
-
): Promise<{ graph: any; source: string } | null> {
|
|
409
|
-
const version = this.workflowVersions.get(`${name}:${graphHash}`)
|
|
410
|
-
if (!version) return null
|
|
411
|
-
return { graph: version.graph, source: version.source }
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
async getAIGeneratedWorkflows(
|
|
415
|
-
agentName?: string
|
|
416
|
-
): Promise<Array<{ workflowName: string; graphHash: string; graph: any }>> {
|
|
417
|
-
const results: Array<{
|
|
418
|
-
workflowName: string
|
|
419
|
-
graphHash: string
|
|
420
|
-
graph: any
|
|
421
|
-
}> = []
|
|
422
|
-
const prefix = agentName ? `ai:${agentName}:` : 'ai:'
|
|
423
|
-
for (const [key, value] of this.workflowVersions) {
|
|
424
|
-
if (value.source !== 'ai-agent' || value.status !== 'active') continue
|
|
425
|
-
const separatorIdx = key.lastIndexOf(':')
|
|
426
|
-
const wfName = key.substring(0, separatorIdx)
|
|
427
|
-
const hash = key.substring(separatorIdx + 1)
|
|
428
|
-
if (wfName.startsWith(prefix)) {
|
|
429
|
-
results.push({
|
|
430
|
-
workflowName: wfName,
|
|
431
|
-
graphHash: hash,
|
|
432
|
-
graph: value.graph,
|
|
433
|
-
})
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
return results
|
|
437
|
-
}
|
|
438
|
-
}
|
package/src/services/index.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module @pikku/core
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { LogLevel } from './logger.js'
|
|
6
|
-
export { ScopedSecretService } from './scoped-secret-service.js'
|
|
7
|
-
export {
|
|
8
|
-
PikkuSessionService,
|
|
9
|
-
createMiddlewareSessionWireProps,
|
|
10
|
-
createFunctionSessionWireProps,
|
|
11
|
-
} from './user-session-service.js'
|
|
12
|
-
export { TypedSecretService } from './typed-secret-service.js'
|
|
13
|
-
export { TypedVariablesService } from './typed-variables-service.js'
|
|
14
|
-
export { LocalSecretService } from './local-secrets.js'
|
|
15
|
-
export { LocalVariablesService } from './local-variables.js'
|
|
16
|
-
export { ConsoleLogger } from './logger-console.js'
|
|
17
|
-
export { InMemoryWorkflowService } from './in-memory-workflow-service.js'
|
|
18
|
-
export { InMemoryTriggerService } from './in-memory-trigger-service.js'
|
|
19
|
-
export { InMemoryAIRunStateService } from './in-memory-ai-run-state-service.js'
|
|
20
|
-
export { LocalGatewayService } from './local-gateway-service.js'
|
|
21
|
-
export type { ContentService } from './content-service.js'
|
|
22
|
-
export type { JWTService } from './jwt-service.js'
|
|
23
|
-
export type { Logger } from './logger.js'
|
|
24
|
-
export type { SecretService } from './secret-service.js'
|
|
25
|
-
export type { VariablesService } from './variables-service.js'
|
|
26
|
-
export type { SchemaService } from './schema-service.js'
|
|
27
|
-
export type { SessionService } from './user-session-service.js'
|
|
28
|
-
export type {
|
|
29
|
-
ScheduledTaskSummary,
|
|
30
|
-
ScheduledTaskInfo,
|
|
31
|
-
SchedulerService,
|
|
32
|
-
} from './scheduler-service.js'
|
|
33
|
-
export type { TriggerService } from './trigger-service.js'
|
|
34
|
-
export type { GatewayService } from './gateway-service.js'
|
|
35
|
-
export type {
|
|
36
|
-
DeploymentService,
|
|
37
|
-
DeploymentConfig,
|
|
38
|
-
DeploymentInfo,
|
|
39
|
-
DeploymentServiceConfig,
|
|
40
|
-
} from './deployment-service.js'
|
|
41
|
-
export type { AIStorageService } from './ai-storage-service.js'
|
|
42
|
-
export type {
|
|
43
|
-
AIAgentRunnerParams,
|
|
44
|
-
AIAgentRunnerResult,
|
|
45
|
-
AIAgentStepResult,
|
|
46
|
-
AIAgentRunnerService,
|
|
47
|
-
} from './ai-agent-runner-service.js'
|
|
48
|
-
export type {
|
|
49
|
-
CreateRunInput,
|
|
50
|
-
AIRunStateService,
|
|
51
|
-
} from './ai-run-state-service.js'
|
|
52
|
-
export type {
|
|
53
|
-
CredentialStatus,
|
|
54
|
-
CredentialMeta,
|
|
55
|
-
} from './typed-secret-service.js'
|
|
56
|
-
export type { VariableStatus, VariableMeta } from './typed-variables-service.js'
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { RelativeTimeInput } from '../time-utils.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Interface for handling JSON Web Tokens (JWT).
|
|
5
|
-
*/
|
|
6
|
-
export interface JWTService {
|
|
7
|
-
/**
|
|
8
|
-
* Encodes a payload into a JWT.
|
|
9
|
-
* @param expiresIn - The expiration time of the token.
|
|
10
|
-
* @param payload - The payload to encode.
|
|
11
|
-
* @returns A promise that resolves to the encoded JWT.
|
|
12
|
-
*/
|
|
13
|
-
encode: <T extends any>(
|
|
14
|
-
expiresIn: RelativeTimeInput,
|
|
15
|
-
payload: T
|
|
16
|
-
) => Promise<string>
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Decodes a JWT into its payload.
|
|
20
|
-
* @param hash - The JWT to decode.
|
|
21
|
-
* @param invalidHashError - An optional error to throw if the hash is invalid.
|
|
22
|
-
* @param debug - An optional flag for debugging.
|
|
23
|
-
* @returns A promise that resolves to the decoded payload.
|
|
24
|
-
*/
|
|
25
|
-
decode: <T>(
|
|
26
|
-
hash: string,
|
|
27
|
-
invalidHashError?: Error,
|
|
28
|
-
debug?: boolean
|
|
29
|
-
) => Promise<T>
|
|
30
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { createReadStream, createWriteStream, promises } from 'fs'
|
|
2
|
-
import { mkdir, readFile } from 'fs/promises'
|
|
3
|
-
import type { ContentService, Logger } from '@pikku/core/services'
|
|
4
|
-
import { pipeline } from 'stream/promises'
|
|
5
|
-
import type { Readable } from 'stream'
|
|
6
|
-
|
|
7
|
-
export interface LocalContentConfig {
|
|
8
|
-
localFileUploadPath: string
|
|
9
|
-
uploadUrlPrefix: string
|
|
10
|
-
assetUrlPrefix: string
|
|
11
|
-
server?: string
|
|
12
|
-
sizeLimit?: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export class LocalContent implements ContentService {
|
|
16
|
-
constructor(
|
|
17
|
-
private config: LocalContentConfig,
|
|
18
|
-
private logger: Logger
|
|
19
|
-
) {}
|
|
20
|
-
|
|
21
|
-
public async init() {}
|
|
22
|
-
|
|
23
|
-
public async signURL(url: string): Promise<string> {
|
|
24
|
-
return `${url}?signed=true`
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
public async signContentKey(assetKey: string): Promise<string> {
|
|
28
|
-
return this.config.server
|
|
29
|
-
? `${this.config.server}${this.config.assetUrlPrefix}/${assetKey}?signed=true`
|
|
30
|
-
: `${this.config.assetUrlPrefix}/${assetKey}?signed=true`
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
public async getUploadURL(assetKey: string) {
|
|
34
|
-
this.logger.debug(`Going to upload with key: ${assetKey}`)
|
|
35
|
-
return {
|
|
36
|
-
uploadUrl: `${this.config.uploadUrlPrefix}/${assetKey}`,
|
|
37
|
-
assetKey,
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public async writeFile(
|
|
42
|
-
assetKey: string,
|
|
43
|
-
stream: ReadableStream | NodeJS.ReadableStream
|
|
44
|
-
): Promise<boolean> {
|
|
45
|
-
this.logger.debug(`Writing file: ${assetKey}`)
|
|
46
|
-
|
|
47
|
-
const path = `${this.config.localFileUploadPath}/${assetKey}`
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
await this.createDirectoryForFile(path)
|
|
51
|
-
const fileStream = createWriteStream(path)
|
|
52
|
-
// Use pipeline to properly manage stream piping and errors
|
|
53
|
-
await pipeline(stream as Readable, fileStream)
|
|
54
|
-
return true
|
|
55
|
-
} catch (e) {
|
|
56
|
-
console.error(e)
|
|
57
|
-
this.logger.error(`Error writing content ${assetKey}`, e)
|
|
58
|
-
return false
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
public async copyFile(
|
|
63
|
-
assetKey: string,
|
|
64
|
-
fromAbsolutePath: string
|
|
65
|
-
): Promise<boolean> {
|
|
66
|
-
this.logger.debug(`Writing file: ${assetKey}`)
|
|
67
|
-
try {
|
|
68
|
-
const path = `${this.config.localFileUploadPath}/${assetKey}`
|
|
69
|
-
await this.createDirectoryForFile(path)
|
|
70
|
-
await promises.copyFile(fromAbsolutePath, path)
|
|
71
|
-
} catch (e) {
|
|
72
|
-
console.error(e)
|
|
73
|
-
this.logger.error(`Error inserting content ${assetKey}`, e)
|
|
74
|
-
}
|
|
75
|
-
return false
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
public async readFile(
|
|
79
|
-
assetKey: string
|
|
80
|
-
): Promise<ReadableStream | NodeJS.ReadableStream> {
|
|
81
|
-
this.logger.debug(`Getting key: ${assetKey}`)
|
|
82
|
-
|
|
83
|
-
const filePath = `${this.config.localFileUploadPath}/${assetKey}`
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
const stream = createReadStream(filePath)
|
|
87
|
-
// Handle early stream errors (like file not found, permission denied, etc.)
|
|
88
|
-
stream.on('error', (err) => {
|
|
89
|
-
this.logger.error(`Error getting content ${assetKey}`, err)
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
return stream
|
|
93
|
-
} catch (e) {
|
|
94
|
-
this.logger.error(`Error setting up stream for ${assetKey}`, e)
|
|
95
|
-
throw e
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
public async readFileAsBuffer(assetKey: string): Promise<Buffer> {
|
|
100
|
-
const filePath = `${this.config.localFileUploadPath}/${assetKey}`
|
|
101
|
-
this.logger.debug(`Reading file as buffer: ${assetKey}`)
|
|
102
|
-
return readFile(filePath)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
public async deleteFile(assetKey: string): Promise<boolean> {
|
|
106
|
-
this.logger.debug(`deleting key: ${assetKey}`)
|
|
107
|
-
try {
|
|
108
|
-
await promises.unlink(`${this.config.localFileUploadPath}/${assetKey}`)
|
|
109
|
-
return true
|
|
110
|
-
} catch (e: any) {
|
|
111
|
-
this.logger.error(`Error deleting content ${assetKey}`, e)
|
|
112
|
-
}
|
|
113
|
-
return false
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
private async createDirectoryForFile(path: string): Promise<void> {
|
|
117
|
-
const dir = path.split('/').slice(0, -1).join('/')
|
|
118
|
-
await mkdir(dir, { recursive: true })
|
|
119
|
-
}
|
|
120
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import type { GatewayService } from './gateway-service.js'
|
|
2
|
-
import type { GatewayAdapter } from '../wirings/gateway/gateway.types.js'
|
|
3
|
-
import { pikkuState, getSingletonServices } from '../pikku-state.js'
|
|
4
|
-
import { createListenerMessageHandler } from '../wirings/gateway/gateway-runner.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Local GatewayService implementation.
|
|
8
|
-
*
|
|
9
|
-
* Starts all registered listener gateways unconditionally (single-process).
|
|
10
|
-
* For distributed deployments, implement `GatewayService` with leader
|
|
11
|
-
* election or similar coordination.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* const gatewayService = new LocalGatewayService()
|
|
16
|
-
* await gatewayService.start()
|
|
17
|
-
*
|
|
18
|
-
* // On shutdown
|
|
19
|
-
* await gatewayService.stop()
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export class LocalGatewayService implements GatewayService {
|
|
23
|
-
private activeAdapters = new Map<string, GatewayAdapter>()
|
|
24
|
-
|
|
25
|
-
async start(): Promise<void> {
|
|
26
|
-
const singletonServices = getSingletonServices()
|
|
27
|
-
const gateways = pikkuState(null, 'gateway', 'gateways')
|
|
28
|
-
|
|
29
|
-
for (const [name, config] of gateways) {
|
|
30
|
-
if (config.type !== 'listener') continue
|
|
31
|
-
if (this.activeAdapters.has(name)) continue
|
|
32
|
-
|
|
33
|
-
const handleMessage = createListenerMessageHandler(
|
|
34
|
-
name,
|
|
35
|
-
config,
|
|
36
|
-
singletonServices
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
await config.adapter.init(handleMessage)
|
|
40
|
-
this.activeAdapters.set(name, config.adapter)
|
|
41
|
-
singletonServices.logger.info(`Started listener gateway: ${name}`)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async stop(): Promise<void> {
|
|
46
|
-
for (const [name, adapter] of this.activeAdapters) {
|
|
47
|
-
try {
|
|
48
|
-
await adapter.close()
|
|
49
|
-
} catch (e: any) {
|
|
50
|
-
try {
|
|
51
|
-
getSingletonServices().logger.error(
|
|
52
|
-
`Error closing listener gateway '${name}':`,
|
|
53
|
-
e
|
|
54
|
-
)
|
|
55
|
-
} catch {
|
|
56
|
-
// logger may not be available during shutdown
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
this.activeAdapters.clear()
|
|
61
|
-
}
|
|
62
|
-
}
|