@pikku/core 0.12.13 → 0.12.15
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 +46 -0
- package/dist/errors/errors.d.ts +18 -0
- package/dist/errors/errors.js +33 -0
- package/dist/function/function-runner.d.ts +1 -1
- package/dist/function/function-runner.js +10 -5
- package/dist/function/functions.types.js +1 -0
- package/dist/function/index.d.ts +2 -1
- package/dist/function/index.js +1 -0
- package/dist/handle-error.d.ts +2 -2
- package/dist/handle-error.js +8 -8
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/middleware/index.d.ts +2 -0
- package/dist/middleware/index.js +2 -0
- package/dist/middleware/remote-auth.js +5 -2
- package/dist/permissions.d.ts +13 -1
- package/dist/permissions.js +51 -0
- package/dist/pikku-state.d.ts +0 -1
- package/dist/pikku-state.js +2 -4
- package/dist/remote.d.ts +10 -0
- package/dist/remote.js +32 -0
- package/dist/schema.js +2 -0
- package/dist/services/credential-service.d.ts +11 -0
- package/dist/services/credential-wire-service.d.ts +14 -3
- package/dist/services/credential-wire-service.js +49 -6
- package/dist/services/deployment-service.d.ts +12 -1
- package/dist/services/in-memory-queue-service.d.ts +7 -0
- package/dist/services/in-memory-queue-service.js +28 -0
- package/dist/services/index.d.ts +4 -1
- package/dist/services/index.js +2 -1
- package/dist/services/local-credential-service.d.ts +2 -0
- package/dist/services/local-credential-service.js +20 -0
- package/dist/services/logger-console.d.ts +26 -40
- package/dist/services/logger-console.js +102 -46
- package/dist/services/logger.d.ts +5 -0
- package/dist/services/meta-service.d.ts +175 -0
- package/dist/services/meta-service.js +310 -0
- package/dist/services/pikku-user-id.d.ts +3 -0
- package/dist/services/pikku-user-id.js +16 -0
- package/dist/services/typed-credential-service.d.ts +2 -0
- package/dist/services/typed-credential-service.js +6 -0
- package/dist/services/workflow-service.d.ts +6 -1
- package/dist/testing/service-tests.js +0 -8
- package/dist/types/core.types.d.ts +14 -2
- package/dist/types/state.types.d.ts +9 -2
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +21 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +90 -21
- package/dist/wirings/ai-agent/ai-agent-registry.js +2 -2
- package/dist/wirings/ai-agent/ai-agent-runner.js +24 -2
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-stream.js +61 -3
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +25 -4
- package/dist/wirings/ai-agent/index.d.ts +1 -1
- package/dist/wirings/ai-agent/index.js +1 -1
- package/dist/wirings/channel/channel-runner.js +3 -3
- package/dist/wirings/cli/cli-runner.js +4 -3
- package/dist/wirings/cli/command-parser.js +7 -3
- package/dist/wirings/http/http-runner.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +23 -15
- package/dist/wirings/http/http.types.d.ts +2 -0
- package/dist/wirings/mcp/mcp-runner.js +5 -3
- package/dist/wirings/queue/queue-runner.d.ts +3 -1
- package/dist/wirings/queue/queue-runner.js +8 -3
- package/dist/wirings/queue/queue.types.d.ts +6 -0
- package/dist/wirings/rpc/rpc-runner.js +57 -90
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -1
- package/dist/wirings/scheduler/scheduler-runner.js +9 -5
- package/dist/wirings/trigger/trigger-runner.js +4 -2
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +2 -0
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +1 -1
- package/dist/wirings/workflow/dsl/workflow-runner.js +6 -9
- package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -1
- package/dist/wirings/workflow/graph/graph-runner.js +18 -4
- package/dist/wirings/workflow/index.d.ts +4 -2
- package/dist/wirings/workflow/index.js +4 -2
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +16 -4
- package/dist/wirings/workflow/pikku-workflow-service.js +218 -24
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +40 -0
- package/dist/wirings/workflow/workflow-queue-workers.js +41 -0
- package/dist/wirings/workflow/workflow.types.d.ts +19 -1
- package/package.json +4 -1
- package/src/errors/errors.ts +44 -0
- package/src/function/function-runner.ts +24 -13
- package/src/function/functions.types.ts +1 -0
- package/src/function/index.ts +10 -0
- package/src/handle-error.test.ts +2 -2
- package/src/handle-error.ts +8 -8
- package/src/index.ts +1 -2
- package/src/middleware/index.ts +2 -0
- package/src/middleware/remote-auth.test.ts +4 -4
- package/src/middleware/remote-auth.ts +7 -2
- package/src/permissions.ts +70 -0
- package/src/pikku-state.test.ts +0 -26
- package/src/pikku-state.ts +2 -5
- package/src/remote.ts +46 -0
- package/src/schema.ts +1 -0
- package/src/services/credential-service.ts +13 -0
- package/src/services/credential-wire-service.test.ts +174 -0
- package/src/services/credential-wire-service.ts +52 -8
- package/src/services/deployment-service.ts +17 -1
- package/src/services/in-memory-queue-service.ts +46 -0
- package/src/services/index.ts +21 -1
- package/src/services/local-credential-service.ts +22 -0
- package/src/services/logger-console.ts +127 -47
- package/src/services/logger.ts +6 -0
- package/src/services/meta-service.ts +523 -0
- package/src/services/pikku-user-id.test.ts +62 -0
- package/src/services/pikku-user-id.ts +17 -0
- package/src/services/typed-credential-service.ts +8 -0
- package/src/services/workflow-service.ts +8 -0
- package/src/testing/service-tests.ts +0 -10
- package/src/types/core.types.ts +16 -2
- package/src/types/state.types.ts +7 -2
- package/src/wirings/ai-agent/ai-agent-prepare.ts +122 -41
- package/src/wirings/ai-agent/ai-agent-registry.ts +3 -3
- package/src/wirings/ai-agent/ai-agent-runner.ts +22 -3
- package/src/wirings/ai-agent/ai-agent-stream.ts +115 -3
- package/src/wirings/ai-agent/ai-agent.types.ts +27 -4
- package/src/wirings/ai-agent/index.ts +1 -0
- package/src/wirings/channel/channel-handler.ts +0 -1
- package/src/wirings/channel/channel-runner.ts +4 -5
- package/src/wirings/cli/cli-runner.test.ts +8 -7
- package/src/wirings/cli/cli-runner.ts +5 -4
- package/src/wirings/cli/command-parser.ts +8 -3
- package/src/wirings/http/http-runner.ts +27 -18
- package/src/wirings/http/http.types.ts +2 -0
- package/src/wirings/mcp/mcp-runner.ts +7 -10
- package/src/wirings/queue/queue-runner.test.ts +5 -11
- package/src/wirings/queue/queue-runner.ts +12 -4
- package/src/wirings/queue/queue.types.ts +6 -0
- package/src/wirings/rpc/rpc-runner.ts +91 -118
- package/src/wirings/scheduler/scheduler-runner.test.ts +5 -11
- package/src/wirings/scheduler/scheduler-runner.ts +13 -5
- package/src/wirings/trigger/trigger-runner.test.ts +10 -11
- package/src/wirings/trigger/trigger-runner.ts +6 -4
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +2 -0
- package/src/wirings/workflow/dsl/workflow-runner.ts +11 -10
- package/src/wirings/workflow/graph/graph-runner.ts +19 -4
- package/src/wirings/workflow/index.ts +17 -6
- package/src/wirings/workflow/pikku-workflow-service.ts +286 -24
- package/src/wirings/workflow/workflow-queue-workers.ts +85 -0
- package/src/wirings/workflow/workflow.types.ts +18 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/ai-agent/agent-dynamic-workflow.d.ts +0 -6
- package/dist/wirings/ai-agent/agent-dynamic-workflow.js +0 -468
- package/dist/wirings/workflow/workflow-helpers.d.ts +0 -36
- package/dist/wirings/workflow/workflow-helpers.js +0 -38
- package/src/wirings/ai-agent/agent-dynamic-workflow.ts +0 -610
- package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
- package/src/wirings/workflow/workflow-helpers.ts +0 -79
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { NotFoundError
|
|
1
|
+
import { NotFoundError } from '../../errors/errors.js';
|
|
2
2
|
import { closeWireServices, createWeakUID, isSerializable, } from '../../utils.js';
|
|
3
3
|
import { getSingletonServices, getCreateWireServices, } from '../../pikku-state.js';
|
|
4
4
|
import { PikkuSessionService } from '../../services/user-session-service.js';
|
|
5
5
|
import { getErrorResponse } from '../../errors/error-handler.js';
|
|
6
|
-
import { PikkuCredentialWireService, createMiddlewareCredentialWireProps, } from '../../services/credential-wire-service.js';
|
|
7
6
|
import { handleHTTPError } from '../../handle-error.js';
|
|
8
7
|
import { pikkuState } from '../../pikku-state.js';
|
|
9
8
|
import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js';
|
|
@@ -113,7 +112,12 @@ export const wireHTTP = (httpWiring) => {
|
|
|
113
112
|
const httpMeta = pikkuState(null, 'http', 'meta');
|
|
114
113
|
const routeMeta = httpMeta[httpWiring.method][httpWiring.route];
|
|
115
114
|
if (!routeMeta) {
|
|
116
|
-
|
|
115
|
+
// In deploy units with filtered metadata, wiring files may include
|
|
116
|
+
// routes for functions not in this unit. This happens when multiple
|
|
117
|
+
// wirings share a file — split them into separate files for better
|
|
118
|
+
// tree-shaking.
|
|
119
|
+
console.warn(`[pikku] Skipping HTTP route '${httpWiring.method.toUpperCase()} ${httpWiring.route}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
120
|
+
return;
|
|
117
121
|
}
|
|
118
122
|
if (httpWiring.func) {
|
|
119
123
|
addFunction(routeMeta.pikkuFuncId, httpWiring.func);
|
|
@@ -198,7 +202,6 @@ export const createHTTPWire = (request, response) => {
|
|
|
198
202
|
*/
|
|
199
203
|
const executeRoute = async (services, matchedRoute, http, options) => {
|
|
200
204
|
const userSession = new PikkuSessionService();
|
|
201
|
-
const credentialWire = new PikkuCredentialWireService();
|
|
202
205
|
const { params, route, meta } = matchedRoute;
|
|
203
206
|
const { singletonServices, createWireServices, skipUserSession, requestId } = services;
|
|
204
207
|
// Attach URL parameters to the request object
|
|
@@ -253,13 +256,13 @@ const executeRoute = async (services, matchedRoute, http, options) => {
|
|
|
253
256
|
};
|
|
254
257
|
}
|
|
255
258
|
const wire = {
|
|
259
|
+
traceId: requestId,
|
|
256
260
|
http,
|
|
257
261
|
channel,
|
|
258
262
|
session: userSession.get(),
|
|
259
263
|
setSession: (s) => userSession.setInitial(s),
|
|
260
264
|
getSession: () => userSession.get(),
|
|
261
265
|
hasSessionChanged: () => userSession.sessionChanged,
|
|
262
|
-
...createMiddlewareCredentialWireProps(credentialWire),
|
|
263
266
|
};
|
|
264
267
|
result = await runPikkuFunc('http', `${meta.method}:${meta.route}`, meta.pikkuFuncId, {
|
|
265
268
|
singletonServices,
|
|
@@ -274,7 +277,6 @@ const executeRoute = async (services, matchedRoute, http, options) => {
|
|
|
274
277
|
tags: route.tags,
|
|
275
278
|
wire,
|
|
276
279
|
sessionService: userSession,
|
|
277
|
-
credentialWireService: credentialWire,
|
|
278
280
|
packageName: meta.packageName,
|
|
279
281
|
});
|
|
280
282
|
if (!matchedRoute.route.sse) {
|
|
@@ -349,19 +351,25 @@ export const pikkuFetch = async (request, params = {}) => {
|
|
|
349
351
|
* @param {RunHTTPWiringOptions} options - Options such as singleton services, session handling, and error configuration.
|
|
350
352
|
* @returns {Promise<Out | void>} The output from the route handler or void if an error occurred.
|
|
351
353
|
*/
|
|
352
|
-
export const fetchData = async (request, response, { skipUserSession = false, respondWith404 = true, logWarningsForStatusCodes = [], coerceDataFromSchema = true, bubbleErrors = false, exposeErrors = false, generateRequestId, } = {}) => {
|
|
354
|
+
export const fetchData = async (request, response, { skipUserSession = false, respondWith404 = true, logWarningsForStatusCodes = [], coerceDataFromSchema = true, bubbleErrors = false, exposeErrors = false, generateRequestId, traceId: externalTraceId, } = {}) => {
|
|
353
355
|
const singletonServices = getSingletonServices();
|
|
354
356
|
const createWireServices = getCreateWireServices();
|
|
355
357
|
let wireServices;
|
|
356
358
|
let result;
|
|
357
359
|
// Combine the request and response into one wire object
|
|
358
360
|
const pikkuRequest = request instanceof Request ? new PikkuFetchHTTPRequest(request) : request;
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
361
|
+
// Resolve traceId: external (e.g. CF-Ray) > x-request-id header > generated
|
|
362
|
+
let requestId = externalTraceId ?? null;
|
|
363
|
+
if (!requestId) {
|
|
364
|
+
try {
|
|
365
|
+
requestId = pikkuRequest.header('x-request-id');
|
|
366
|
+
}
|
|
367
|
+
catch { }
|
|
362
368
|
}
|
|
363
|
-
catch { }
|
|
364
369
|
requestId = requestId || generateRequestId?.() || createWeakUID();
|
|
370
|
+
// Scoped logger for HTTP runner internal logging (error handling, route matching)
|
|
371
|
+
// Functions/middleware receive singletonServices.logger directly for compatibility
|
|
372
|
+
const scopedLogger = singletonServices.logger.scope?.(requestId) ?? singletonServices.logger;
|
|
365
373
|
const http = createHTTPWire(pikkuRequest, response);
|
|
366
374
|
const apiType = http.request.method();
|
|
367
375
|
const apiRoute = http.request.path();
|
|
@@ -379,7 +387,7 @@ export const fetchData = async (request, response, { skipUserSession = false, re
|
|
|
379
387
|
response.status(204).json(undefined);
|
|
380
388
|
return;
|
|
381
389
|
}
|
|
382
|
-
|
|
390
|
+
scopedLogger.info({
|
|
383
391
|
message: 'Route not found',
|
|
384
392
|
apiRoute,
|
|
385
393
|
apiType,
|
|
@@ -399,7 +407,7 @@ export const fetchData = async (request, response, { skipUserSession = false, re
|
|
|
399
407
|
catch (e) {
|
|
400
408
|
if (matchedRoute?.route.sse) {
|
|
401
409
|
// For SSE routes, send error through the stream since the response is already in stream mode
|
|
402
|
-
|
|
410
|
+
scopedLogger.error(e instanceof Error ? e.message : e);
|
|
403
411
|
try {
|
|
404
412
|
const errorResponse = getErrorResponse(e);
|
|
405
413
|
response.arrayBuffer(JSON.stringify({
|
|
@@ -409,12 +417,12 @@ export const fetchData = async (request, response, { skipUserSession = false, re
|
|
|
409
417
|
response.arrayBuffer(JSON.stringify({ type: 'done' }));
|
|
410
418
|
}
|
|
411
419
|
catch (streamErr) {
|
|
412
|
-
|
|
420
|
+
scopedLogger.error(`SSE error while sending error payload: ${streamErr instanceof Error ? streamErr.message : String(streamErr)}`);
|
|
413
421
|
}
|
|
414
422
|
response.close?.();
|
|
415
423
|
}
|
|
416
424
|
else {
|
|
417
|
-
handleHTTPError(e, http, requestId,
|
|
425
|
+
handleHTTPError(e, http, requestId, scopedLogger, logWarningsForStatusCodes, respondWith404, bubbleErrors, exposeErrors);
|
|
418
426
|
}
|
|
419
427
|
}
|
|
420
428
|
finally {
|
|
@@ -17,6 +17,8 @@ export type RunHTTPWiringOptions = Partial<{
|
|
|
17
17
|
bubbleErrors: boolean;
|
|
18
18
|
exposeErrors: boolean;
|
|
19
19
|
generateRequestId: () => string;
|
|
20
|
+
/** Pre-resolved trace ID (e.g. CF-Ray). Falls back to x-request-id header or generated ID. */
|
|
21
|
+
traceId: string;
|
|
20
22
|
}>;
|
|
21
23
|
/**
|
|
22
24
|
* Represents the HTTP methods supported for API HTTP wirings.
|
|
@@ -3,7 +3,7 @@ import { closeWireServices } from '../../utils.js';
|
|
|
3
3
|
import { pikkuState, getSingletonServices, getCreateWireServices, } from '../../pikku-state.js';
|
|
4
4
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
|
|
5
5
|
import { resolveNamespace } from '../rpc/rpc-runner.js';
|
|
6
|
-
import { BadRequestError, NotFoundError
|
|
6
|
+
import { BadRequestError, NotFoundError } from '../../errors/errors.js';
|
|
7
7
|
import { PikkuSessionService, createMiddlewareSessionWireProps, } from '../../services/user-session-service.js';
|
|
8
8
|
export class MCPError extends Error {
|
|
9
9
|
error;
|
|
@@ -18,7 +18,8 @@ export const wireMCPResource = (mcpResource) => {
|
|
|
18
18
|
const resourcesMeta = pikkuState(null, 'mcp', 'resourcesMeta');
|
|
19
19
|
const mcpResourceMeta = resourcesMeta[mcpResource.uri];
|
|
20
20
|
if (!mcpResourceMeta) {
|
|
21
|
-
|
|
21
|
+
console.warn(`[pikku] Skipping MCP resource '${mcpResource.uri}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
22
|
+
return;
|
|
22
23
|
}
|
|
23
24
|
addFunction(mcpResourceMeta.pikkuFuncId, mcpResource.func);
|
|
24
25
|
const resources = pikkuState(null, 'mcp', 'resources');
|
|
@@ -31,7 +32,8 @@ export const wireMCPPrompt = (mcpPrompt) => {
|
|
|
31
32
|
const promptsMeta = pikkuState(null, 'mcp', 'promptsMeta');
|
|
32
33
|
const mcpPromptMeta = promptsMeta[mcpPrompt.name];
|
|
33
34
|
if (!mcpPromptMeta) {
|
|
34
|
-
|
|
35
|
+
console.warn(`[pikku] Skipping MCP prompt '${mcpPrompt.name}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
36
|
+
return;
|
|
35
37
|
}
|
|
36
38
|
addFunction(mcpPromptMeta.pikkuFuncId, mcpPrompt.func);
|
|
37
39
|
const prompts = pikkuState(null, 'mcp', 'prompts');
|
|
@@ -28,7 +28,9 @@ export declare function removeQueueWorker(name: string): Promise<void>;
|
|
|
28
28
|
/**
|
|
29
29
|
* Process a single queue job - this function is called by queue consumers
|
|
30
30
|
*/
|
|
31
|
-
export declare function runQueueJob({ job, updateProgress, }: {
|
|
31
|
+
export declare function runQueueJob({ job, updateProgress, traceId, }: {
|
|
32
32
|
job: QueueJob;
|
|
33
33
|
updateProgress?: (progress: number | string | object) => Promise<void>;
|
|
34
|
+
/** Pre-resolved trace ID (e.g. from queue message metadata) */
|
|
35
|
+
traceId?: string;
|
|
34
36
|
}): Promise<void>;
|
|
@@ -36,7 +36,8 @@ export const wireQueueWorker = (queueWorker) => {
|
|
|
36
36
|
const meta = pikkuState(null, 'queue', 'meta');
|
|
37
37
|
const processorMeta = meta[queueWorker.name];
|
|
38
38
|
if (!processorMeta) {
|
|
39
|
-
|
|
39
|
+
console.warn(`[pikku] Skipping queue worker '${queueWorker.name}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
40
|
+
return;
|
|
40
41
|
}
|
|
41
42
|
// Register the function with pikku
|
|
42
43
|
addFunction(processorMeta.pikkuFuncId, {
|
|
@@ -70,10 +71,12 @@ export async function removeQueueWorker(name) {
|
|
|
70
71
|
/**
|
|
71
72
|
* Process a single queue job - this function is called by queue consumers
|
|
72
73
|
*/
|
|
73
|
-
export async function runQueueJob({ job, updateProgress, }) {
|
|
74
|
+
export async function runQueueJob({ job, updateProgress, traceId, }) {
|
|
74
75
|
const singletonServices = getSingletonServices();
|
|
75
76
|
const createWireServices = getCreateWireServices();
|
|
76
|
-
const
|
|
77
|
+
const resolvedTraceId = traceId ?? `q-${job.id}`;
|
|
78
|
+
const logger = singletonServices.logger.scope?.(resolvedTraceId) ??
|
|
79
|
+
singletonServices.logger;
|
|
77
80
|
const meta = pikkuState(null, 'queue', 'meta');
|
|
78
81
|
const processorMeta = meta[job.queueName];
|
|
79
82
|
if (!processorMeta) {
|
|
@@ -89,6 +92,7 @@ export async function runQueueJob({ job, updateProgress, }) {
|
|
|
89
92
|
const queue = {
|
|
90
93
|
queueName: job.queueName,
|
|
91
94
|
jobId: job.id,
|
|
95
|
+
pikkuUserId: job.pikkuUserId,
|
|
92
96
|
updateProgress: updateProgress ||
|
|
93
97
|
(async (progress) => {
|
|
94
98
|
logger.info(`Job ${job.id} progress: ${progress}`);
|
|
@@ -104,6 +108,7 @@ export async function runQueueJob({ job, updateProgress, }) {
|
|
|
104
108
|
try {
|
|
105
109
|
logger.info(`Processing job ${job.id} in queue ${job.queueName}`);
|
|
106
110
|
const wire = {
|
|
111
|
+
traceId: resolvedTraceId,
|
|
107
112
|
queue,
|
|
108
113
|
};
|
|
109
114
|
// Execute the pikku function with the job data
|
|
@@ -87,6 +87,8 @@ export interface QueueJob<T = any, R = any> {
|
|
|
87
87
|
result?: R;
|
|
88
88
|
waitForCompletion?: (ttl?: number) => Promise<R>;
|
|
89
89
|
metadata?: () => Promise<QueueJobMetadata> | QueueJobMetadata;
|
|
90
|
+
/** Pikku user ID propagated from the job producer */
|
|
91
|
+
pikkuUserId?: string;
|
|
90
92
|
}
|
|
91
93
|
/**
|
|
92
94
|
* Job options for queue operations
|
|
@@ -102,6 +104,8 @@ export interface JobOptions {
|
|
|
102
104
|
removeOnComplete?: number;
|
|
103
105
|
removeOnFail?: number;
|
|
104
106
|
jobId?: string;
|
|
107
|
+
/** Pikku user ID to propagate to the queue worker for credential resolution */
|
|
108
|
+
pikkuUserId?: string;
|
|
105
109
|
}
|
|
106
110
|
/**
|
|
107
111
|
* Queue provider interface for job publishing operations
|
|
@@ -154,6 +158,8 @@ export interface PikkuQueue {
|
|
|
154
158
|
queueName: string;
|
|
155
159
|
/** The current job ID */
|
|
156
160
|
jobId: string;
|
|
161
|
+
/** Pikku user ID propagated from the job producer for credential resolution */
|
|
162
|
+
pikkuUserId?: string;
|
|
157
163
|
/** Update job progress (0-100 or custom value) */
|
|
158
164
|
updateProgress: (progress: number | string | object) => Promise<void>;
|
|
159
165
|
/** Fail the current job with optional reason */
|
|
@@ -3,7 +3,6 @@ import { pikkuState } from '../../pikku-state.js';
|
|
|
3
3
|
import { ForbiddenError } from '../../errors/errors.js';
|
|
4
4
|
import { PikkuError, addError } from '../../errors/error-handler.js';
|
|
5
5
|
import { parseVersionedId } from '../../version.js';
|
|
6
|
-
import { encryptJSON } from '../../crypto-utils.js';
|
|
7
6
|
export class RPCNotFoundError extends PikkuError {
|
|
8
7
|
rpcName;
|
|
9
8
|
constructor(rpcName) {
|
|
@@ -95,17 +94,38 @@ export class ContextAwareRPCService {
|
|
|
95
94
|
}
|
|
96
95
|
: undefined,
|
|
97
96
|
};
|
|
98
|
-
// Check
|
|
97
|
+
// Check addon namespace first (e.g. 'stripe:createCharge')
|
|
99
98
|
if (funcName.includes(':')) {
|
|
100
|
-
|
|
99
|
+
try {
|
|
100
|
+
return await this.invokeAddonFunction(funcName, data, updatedWire);
|
|
101
|
+
}
|
|
102
|
+
catch (addonErr) {
|
|
103
|
+
if (!(addonErr instanceof RPCNotFoundError))
|
|
104
|
+
throw addonErr;
|
|
105
|
+
// Not an addon — fall through to local lookup
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Try local function, then fall back to deployment service (remote)
|
|
109
|
+
try {
|
|
110
|
+
return await runPikkuFunc('rpc', funcName, getPikkuFunctionName(funcName), {
|
|
111
|
+
auth: this.options.requiresAuth,
|
|
112
|
+
singletonServices: this.services,
|
|
113
|
+
data: () => data,
|
|
114
|
+
wire: updatedWire,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
if (e instanceof RPCNotFoundError) {
|
|
119
|
+
// Fall back to deployment service (e.g. CF service binding, Lambda Invoke)
|
|
120
|
+
if (this.services.deploymentService) {
|
|
121
|
+
const session = this.wire.getSession && typeof this.wire.getSession === 'function'
|
|
122
|
+
? await this.wire.getSession()
|
|
123
|
+
: this.wire.session;
|
|
124
|
+
return this.services.deploymentService.invoke(funcName, data, session, this.wire.traceId);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
throw e;
|
|
101
128
|
}
|
|
102
|
-
// Main package function
|
|
103
|
-
return runPikkuFunc('rpc', funcName, getPikkuFunctionName(funcName), {
|
|
104
|
-
auth: this.options.requiresAuth,
|
|
105
|
-
singletonServices: this.services,
|
|
106
|
-
data: () => data,
|
|
107
|
-
wire: updatedWire,
|
|
108
|
-
});
|
|
109
129
|
}
|
|
110
130
|
/**
|
|
111
131
|
* Invoke a function from an addon package
|
|
@@ -117,16 +137,14 @@ export class ContextAwareRPCService {
|
|
|
117
137
|
// Resolve namespace to package name
|
|
118
138
|
const resolved = resolveNamespace(namespacedFunction);
|
|
119
139
|
if (!resolved) {
|
|
120
|
-
throw new
|
|
121
|
-
`Make sure the package is registered in addons config.`);
|
|
140
|
+
throw new RPCNotFoundError(namespacedFunction);
|
|
122
141
|
}
|
|
123
142
|
// Get the function meta from the addon package
|
|
124
143
|
// Addon packages use function meta, not RPC meta
|
|
125
144
|
const addonFunctionMeta = pikkuState(resolved.package, 'function', 'meta');
|
|
126
145
|
const funcMeta = addonFunctionMeta[resolved.function];
|
|
127
146
|
if (!funcMeta) {
|
|
128
|
-
throw new
|
|
129
|
-
`Available functions: ${Object.keys(addonFunctionMeta).join(', ') || '(none)'}`);
|
|
147
|
+
throw new RPCNotFoundError(namespacedFunction);
|
|
130
148
|
}
|
|
131
149
|
const funcName = funcMeta.pikkuFuncId || resolved.function;
|
|
132
150
|
const auth = resolved.addonConfig?.auth ?? this.options.requiresAuth;
|
|
@@ -162,12 +180,23 @@ export class ContextAwareRPCService {
|
|
|
162
180
|
if (rpcName.includes(':')) {
|
|
163
181
|
return this.invokeAddonFunction(rpcName, data, mergedWire);
|
|
164
182
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
183
|
+
try {
|
|
184
|
+
return await runPikkuFunc('rpc', rpcName, getPikkuFunctionName(rpcName), {
|
|
185
|
+
auth: this.options.requiresAuth,
|
|
186
|
+
singletonServices: this.services,
|
|
187
|
+
data: () => data,
|
|
188
|
+
wire: mergedWire,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
if (e instanceof RPCNotFoundError && this.services.deploymentService) {
|
|
193
|
+
const session = this.wire.getSession && typeof this.wire.getSession === 'function'
|
|
194
|
+
? await this.wire.getSession()
|
|
195
|
+
: this.wire.session;
|
|
196
|
+
return this.services.deploymentService.invoke(rpcName, data, session, this.wire.traceId);
|
|
197
|
+
}
|
|
198
|
+
throw e;
|
|
199
|
+
}
|
|
171
200
|
}
|
|
172
201
|
async startWorkflow(workflowName, input, options) {
|
|
173
202
|
if (!this.services.workflowService) {
|
|
@@ -178,6 +207,7 @@ export class ContextAwareRPCService {
|
|
|
178
207
|
type: this.wire.wireType ?? 'unknown',
|
|
179
208
|
id: this.wire.wireId,
|
|
180
209
|
...(parentRunId ? { parentRunId } : {}),
|
|
210
|
+
...(this.wire.pikkuUserId ? { pikkuUserId: this.wire.pikkuUserId } : {}),
|
|
181
211
|
};
|
|
182
212
|
return this.services.workflowService.startWorkflow(workflowName, input, wire, this, options);
|
|
183
213
|
}
|
|
@@ -226,77 +256,14 @@ export class ContextAwareRPCService {
|
|
|
226
256
|
};
|
|
227
257
|
}
|
|
228
258
|
async remote(funcName, data) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
};
|
|
233
|
-
const colonIndex = funcName.indexOf(':');
|
|
234
|
-
if (colonIndex !== -1) {
|
|
235
|
-
const namespace = funcName.substring(0, colonIndex);
|
|
236
|
-
const addons = pikkuState(null, 'addons', 'packages');
|
|
237
|
-
const pkgConfig = addons.get(namespace);
|
|
238
|
-
endpoint = pkgConfig?.rpcEndpoint;
|
|
239
|
-
}
|
|
240
|
-
if (!endpoint && this.services.deploymentService) {
|
|
241
|
-
const deployments = await this.services.deploymentService.findFunction(funcName);
|
|
242
|
-
if (deployments.length > 0) {
|
|
243
|
-
endpoint = deployments[0].endpoint;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
if (!endpoint) {
|
|
247
|
-
throw new Error(`No endpoint configured for remote RPC: ${funcName}. ` +
|
|
248
|
-
`Configure rpcEndpoint in addons config or set up a DeploymentService.`);
|
|
249
|
-
}
|
|
250
|
-
let secret;
|
|
251
|
-
if (this.services.secrets) {
|
|
252
|
-
try {
|
|
253
|
-
secret = await this.services.secrets.getSecret('PIKKU_REMOTE_SECRET');
|
|
254
|
-
}
|
|
255
|
-
catch { }
|
|
256
|
-
}
|
|
257
|
-
if (secret) {
|
|
258
|
-
if (!this.services.jwt) {
|
|
259
|
-
throw new Error('PIKKU_REMOTE_SECRET is set but JWT service is not available');
|
|
260
|
-
}
|
|
261
|
-
const session = this.wire.getSession && typeof this.wire.getSession === 'function'
|
|
262
|
-
? await this.wire.getSession()
|
|
263
|
-
: this.wire.session;
|
|
264
|
-
const sessionEnc = session
|
|
265
|
-
? await encryptJSON(secret, { session })
|
|
266
|
-
: undefined;
|
|
267
|
-
const token = await this.services.jwt.encode({ value: 5, unit: 'minute' }, {
|
|
268
|
-
aud: 'pikku-remote',
|
|
269
|
-
fn: funcName,
|
|
270
|
-
iat: Date.now(),
|
|
271
|
-
session: sessionEnc,
|
|
272
|
-
});
|
|
273
|
-
headers.Authorization = `Bearer ${token}`;
|
|
274
|
-
}
|
|
275
|
-
const url = `${endpoint}/rpc/${encodeURIComponent(funcName)}`;
|
|
276
|
-
const timeoutMs = 30_000;
|
|
277
|
-
const response = await fetch(url, {
|
|
278
|
-
method: 'POST',
|
|
279
|
-
headers,
|
|
280
|
-
body: JSON.stringify({ data }),
|
|
281
|
-
signal: AbortSignal.timeout(timeoutMs),
|
|
282
|
-
});
|
|
283
|
-
if (!response.ok) {
|
|
284
|
-
let errorBody;
|
|
285
|
-
try {
|
|
286
|
-
errorBody = JSON.stringify(await response.json());
|
|
287
|
-
}
|
|
288
|
-
catch {
|
|
289
|
-
errorBody = await response.text();
|
|
290
|
-
}
|
|
291
|
-
throw new Error(`Remote RPC call failed: ${response.status} ${response.statusText}. ${errorBody}`);
|
|
292
|
-
}
|
|
293
|
-
try {
|
|
294
|
-
return (await response.json());
|
|
295
|
-
}
|
|
296
|
-
catch {
|
|
297
|
-
const text = await response.text();
|
|
298
|
-
throw new Error(`Remote RPC call returned non-JSON response: ${response.status} ${response.statusText}. ${text}`);
|
|
259
|
+
if (!this.services.deploymentService) {
|
|
260
|
+
throw new Error(`No DeploymentService configured for remote RPC: ${funcName}. ` +
|
|
261
|
+
`Set up a DeploymentService to enable remote function calls.`);
|
|
299
262
|
}
|
|
263
|
+
const session = this.wire.getSession && typeof this.wire.getSession === 'function'
|
|
264
|
+
? await this.wire.getSession()
|
|
265
|
+
: this.wire.session;
|
|
266
|
+
return this.services.deploymentService.invoke(funcName, data, session, this.wire.traceId);
|
|
300
267
|
}
|
|
301
268
|
}
|
|
302
269
|
// RPC Service class for the global interface
|
|
@@ -4,7 +4,9 @@ import type { CorePikkuFunctionConfig, CorePikkuFunctionSessionless } from '../.
|
|
|
4
4
|
export type RunScheduledTasksParams = {
|
|
5
5
|
name: string;
|
|
6
6
|
session?: CoreUserSession;
|
|
7
|
+
/** Pre-resolved trace ID */
|
|
8
|
+
traceId?: string;
|
|
7
9
|
};
|
|
8
10
|
export declare const wireScheduler: <PikkuFunctionConfig extends CorePikkuFunctionConfig<CorePikkuFunctionSessionless<void, void>>>(scheduledTask: CoreScheduledTask<PikkuFunctionConfig>) => void;
|
|
9
|
-
export declare function runScheduledTask({ name, session, }: RunScheduledTasksParams): Promise<void>;
|
|
11
|
+
export declare function runScheduledTask({ name, session, traceId, }: RunScheduledTasksParams): Promise<void>;
|
|
10
12
|
export declare const getScheduledTasks: () => Map<string, CoreScheduledTask>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getErrorResponse, PikkuError } from '../../errors/error-handler.js';
|
|
2
|
-
import { PikkuMissingMetaError } from '../../errors/errors.js';
|
|
3
2
|
import { getSingletonServices, getCreateWireServices, pikkuState, } from '../../pikku-state.js';
|
|
4
3
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
|
|
5
4
|
import { PikkuSessionService, createMiddlewareSessionWireProps, } from '../../services/user-session-service.js';
|
|
@@ -7,7 +6,8 @@ export const wireScheduler = (scheduledTask) => {
|
|
|
7
6
|
const meta = pikkuState(null, 'scheduler', 'meta');
|
|
8
7
|
const taskMeta = meta[scheduledTask.name];
|
|
9
8
|
if (!taskMeta) {
|
|
10
|
-
|
|
9
|
+
console.warn(`[pikku] Skipping scheduled task '${scheduledTask.name}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
10
|
+
return;
|
|
11
11
|
}
|
|
12
12
|
addFunction(taskMeta.pikkuFuncId, {
|
|
13
13
|
func: scheduledTask.func.func,
|
|
@@ -33,9 +33,12 @@ class ScheduledTaskSkippedError extends PikkuError {
|
|
|
33
33
|
this.name = 'ScheduledTaskSkippedError';
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
export async function runScheduledTask({ name, session, }) {
|
|
36
|
+
export async function runScheduledTask({ name, session, traceId, }) {
|
|
37
37
|
const singletonServices = getSingletonServices();
|
|
38
38
|
const createWireServices = getCreateWireServices();
|
|
39
|
+
const resolvedTraceId = traceId ?? `cron-${name}-${Date.now()}`;
|
|
40
|
+
const scopedLogger = singletonServices.logger.scope?.(resolvedTraceId) ??
|
|
41
|
+
singletonServices.logger;
|
|
39
42
|
const task = pikkuState(null, 'scheduler', 'tasks').get(name);
|
|
40
43
|
const meta = pikkuState(null, 'scheduler', 'meta')[name];
|
|
41
44
|
const userSession = new PikkuSessionService();
|
|
@@ -50,6 +53,7 @@ export async function runScheduledTask({ name, session, }) {
|
|
|
50
53
|
}
|
|
51
54
|
// Create the scheduled task wire object
|
|
52
55
|
const wire = {
|
|
56
|
+
traceId: resolvedTraceId,
|
|
53
57
|
scheduledTask: {
|
|
54
58
|
name,
|
|
55
59
|
schedule: task.schedule,
|
|
@@ -61,7 +65,7 @@ export async function runScheduledTask({ name, session, }) {
|
|
|
61
65
|
...createMiddlewareSessionWireProps(userSession),
|
|
62
66
|
};
|
|
63
67
|
try {
|
|
64
|
-
|
|
68
|
+
scopedLogger.info(`Running schedule task: ${name} | schedule: ${task.schedule}`);
|
|
65
69
|
await runPikkuFunc('scheduler', meta.name, meta.pikkuFuncId, {
|
|
66
70
|
singletonServices,
|
|
67
71
|
createWireServices,
|
|
@@ -78,7 +82,7 @@ export async function runScheduledTask({ name, session, }) {
|
|
|
78
82
|
catch (e) {
|
|
79
83
|
const errorResponse = getErrorResponse(e);
|
|
80
84
|
if (errorResponse != null) {
|
|
81
|
-
|
|
85
|
+
scopedLogger.error(e);
|
|
82
86
|
}
|
|
83
87
|
throw e;
|
|
84
88
|
}
|
|
@@ -10,7 +10,8 @@ export const wireTrigger = (trigger) => {
|
|
|
10
10
|
const meta = pikkuState(null, 'trigger', 'meta');
|
|
11
11
|
const triggerMeta = meta[trigger.name];
|
|
12
12
|
if (!triggerMeta) {
|
|
13
|
-
|
|
13
|
+
console.warn(`[pikku] Skipping trigger '${trigger.name}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
14
|
+
return;
|
|
14
15
|
}
|
|
15
16
|
addFunction(triggerMeta.pikkuFuncId, trigger.func);
|
|
16
17
|
const triggers = pikkuState(null, 'trigger', 'triggers');
|
|
@@ -25,7 +26,8 @@ export const wireTriggerSource = (source) => {
|
|
|
25
26
|
const sourceMeta = pikkuState(null, 'trigger', 'sourceMeta');
|
|
26
27
|
const triggerSourceMeta = sourceMeta[source.name];
|
|
27
28
|
if (!triggerSourceMeta) {
|
|
28
|
-
|
|
29
|
+
console.warn(`[pikku] Skipping trigger source '${source.name}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
30
|
+
return;
|
|
29
31
|
}
|
|
30
32
|
const triggerSources = pikkuState(null, 'trigger', 'triggerSources');
|
|
31
33
|
if (triggerSources.has(source.name)) {
|
|
@@ -281,6 +281,8 @@ export interface PikkuWorkflowWire {
|
|
|
281
281
|
name: string;
|
|
282
282
|
/** The current run ID */
|
|
283
283
|
runId: string;
|
|
284
|
+
/** Pikku user ID propagated from the originating request for credential resolution */
|
|
285
|
+
pikkuUserId?: string;
|
|
284
286
|
/** Get the current workflow run */
|
|
285
287
|
getRun: () => Promise<WorkflowRun>;
|
|
286
288
|
/** Execute a workflow step (overloaded - RPC or inline form) */
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Add a workflow to the system
|
|
3
3
|
* This is called by the generated workflow wirings
|
|
4
4
|
*/
|
|
5
|
-
export declare const addWorkflow: (workflowName: string, workflowFunc: any) => void;
|
|
5
|
+
export declare const addWorkflow: (workflowName: string, workflowFunc: any, packageName?: string | null) => void;
|
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import { pikkuState } from '../../../pikku-state.js';
|
|
2
2
|
import { addFunction } from '../../../function/function-runner.js';
|
|
3
|
-
import { PikkuMissingMetaError } from '../../../errors/errors.js';
|
|
4
3
|
/**
|
|
5
4
|
* Add a workflow to the system
|
|
6
5
|
* This is called by the generated workflow wirings
|
|
7
6
|
*/
|
|
8
|
-
export const addWorkflow = (workflowName, workflowFunc) => {
|
|
9
|
-
|
|
10
|
-
const meta = pikkuState(null, 'workflows', 'meta');
|
|
7
|
+
export const addWorkflow = (workflowName, workflowFunc, packageName = null) => {
|
|
8
|
+
const meta = pikkuState(packageName, 'workflows', 'meta');
|
|
11
9
|
const workflowMeta = meta[workflowName];
|
|
12
10
|
if (!workflowMeta) {
|
|
13
|
-
|
|
11
|
+
console.warn(`[pikku] Skipping workflow '${workflowName}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
12
|
+
return;
|
|
14
13
|
}
|
|
15
|
-
|
|
16
|
-
const registrations = pikkuState(null, 'workflows', 'registrations');
|
|
14
|
+
const registrations = pikkuState(packageName, 'workflows', 'registrations');
|
|
17
15
|
registrations.set(workflowName, {
|
|
18
16
|
name: workflowName,
|
|
19
17
|
func: workflowFunc,
|
|
20
18
|
});
|
|
21
|
-
|
|
22
|
-
addFunction(workflowMeta.pikkuFuncId, workflowFunc);
|
|
19
|
+
addFunction(workflowMeta.pikkuFuncId, workflowFunc, packageName);
|
|
23
20
|
};
|
|
@@ -11,6 +11,6 @@ export declare function continueGraph(workflowService: PikkuWorkflowService, run
|
|
|
11
11
|
export declare function executeGraphStep(workflowService: PikkuWorkflowService, rpcService: any, runId: string, stepId: string, nodeId: string, rpcName: string, data: any, graphName: string): Promise<any>;
|
|
12
12
|
export declare function onGraphNodeComplete(workflowService: PikkuWorkflowService, runId: string, graphName: string): Promise<void>;
|
|
13
13
|
export declare function runFromMeta(workflowService: PikkuWorkflowService, runId: string, meta: WorkflowRuntimeMeta, _rpcService: any): Promise<void>;
|
|
14
|
-
export declare function runWorkflowGraph(workflowService: PikkuWorkflowService, graphName: string, triggerInput: any, rpcService?: any, inline?: boolean, startNode?: string, wire?: WorkflowRunWire): Promise<{
|
|
14
|
+
export declare function runWorkflowGraph(workflowService: PikkuWorkflowService, graphName: string, triggerInput: any, rpcService?: any, inline?: boolean, startNode?: string, wire?: WorkflowRunWire, overrideMeta?: WorkflowRuntimeMeta): Promise<{
|
|
15
15
|
runId: string;
|
|
16
16
|
}>;
|
|
@@ -90,8 +90,22 @@ function isTemplate(value) {
|
|
|
90
90
|
typeof value.$template === 'object');
|
|
91
91
|
}
|
|
92
92
|
function getWorkflowMeta(name) {
|
|
93
|
-
const
|
|
94
|
-
|
|
93
|
+
const rootMeta = pikkuState(null, 'workflows', 'meta');
|
|
94
|
+
if (rootMeta[name])
|
|
95
|
+
return rootMeta[name];
|
|
96
|
+
const colonIndex = name.indexOf(':');
|
|
97
|
+
if (colonIndex !== -1) {
|
|
98
|
+
const namespace = name.substring(0, colonIndex);
|
|
99
|
+
const localName = name.substring(colonIndex + 1);
|
|
100
|
+
const addons = pikkuState(null, 'addons', 'packages');
|
|
101
|
+
const pkgConfig = addons?.get(namespace);
|
|
102
|
+
if (pkgConfig) {
|
|
103
|
+
const addonMeta = pikkuState(pkgConfig.package, 'workflows', 'meta');
|
|
104
|
+
if (addonMeta?.[localName])
|
|
105
|
+
return addonMeta[localName];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return undefined;
|
|
95
109
|
}
|
|
96
110
|
function resolveNextFromConfig(next, branchKey) {
|
|
97
111
|
if (!next)
|
|
@@ -543,8 +557,8 @@ async function continueGraphInline(workflowService, rpcService, runId, graphName
|
|
|
543
557
|
}));
|
|
544
558
|
}
|
|
545
559
|
}
|
|
546
|
-
export async function runWorkflowGraph(workflowService, graphName, triggerInput, rpcService, inline, startNode, wire) {
|
|
547
|
-
const meta = getWorkflowMeta(graphName);
|
|
560
|
+
export async function runWorkflowGraph(workflowService, graphName, triggerInput, rpcService, inline, startNode, wire, overrideMeta) {
|
|
561
|
+
const meta = overrideMeta ?? getWorkflowMeta(graphName);
|
|
548
562
|
if (!meta?.nodes) {
|
|
549
563
|
throw new Error(`Workflow graph '${graphName}' not found`);
|
|
550
564
|
}
|
|
@@ -5,6 +5,8 @@ export { PikkuWorkflowService, WorkflowCancelledException, WorkflowSuspendedExce
|
|
|
5
5
|
export { addWorkflow } from './dsl/workflow-runner.js';
|
|
6
6
|
export { template, type TemplateString } from './graph/template.js';
|
|
7
7
|
export { pikkuWorkflowGraph, type PikkuWorkflowGraphConfig, type PikkuWorkflowGraphResult, } from './graph/wire-workflow-graph.js';
|
|
8
|
-
export {
|
|
9
|
-
export
|
|
8
|
+
export { validateWorkflowWiring, computeEntryNodeIds, } from './graph/graph-validation.js';
|
|
9
|
+
export { pikkuWorkflowWorkerFunc, pikkuWorkflowOrchestratorFunc, pikkuWorkflowSleeperFunc, } from './workflow-queue-workers.js';
|
|
10
|
+
export type { WorkflowStepInput as WorkflowStepQueueInput, PikkuWorkflowOrchestratorInput, PikkuWorkflowSleeperInput, } from './workflow-queue-workers.js';
|
|
11
|
+
export type { WorkflowService, WorkflowServiceConfig, WorkflowRunWire, WorkflowStatus, WorkflowVersionStatus, StepStatus, WorkflowRun, WorkflowRunStatus, StepState, WorkflowRunService, CoreWorkflow, PikkuWorkflow, ContextVariable, WorkflowContext, WorkflowsMeta, WorkflowRuntimeMeta, WorkflowsRuntimeMeta, WorkflowStepInput, WorkflowOrchestratorInput, WorkflowSleeperInput, } from './workflow.types.js';
|
|
10
12
|
export type { WorkflowStepOptions, WorkflowWireDoRPC, WorkflowWireDoInline, WorkflowWireSleep, WorkflowWireSuspend, InputSource, OutputBinding, RpcStepMeta, SimpleCondition, Condition, BranchCase, BranchStepMeta, ParallelGroupStepMeta, FanoutStepMeta, ReturnStepMeta, InlineStepMeta, SleepStepMeta, CancelStepMeta, SetStepMeta, SwitchCaseMeta, SwitchStepMeta, FilterStepMeta, ArrayPredicateStepMeta, WorkflowStepMeta, WorkflowStepWire, PikkuWorkflowWire, } from './workflow.types.js';
|
|
@@ -7,5 +7,7 @@ export { addWorkflow } from './dsl/workflow-runner.js';
|
|
|
7
7
|
// Graph helpers (template, pikkuWorkflowGraph)
|
|
8
8
|
export { template } from './graph/template.js';
|
|
9
9
|
export { pikkuWorkflowGraph, } from './graph/wire-workflow-graph.js';
|
|
10
|
-
//
|
|
11
|
-
export {
|
|
10
|
+
// Graph validation and dynamic workflow utilities
|
|
11
|
+
export { validateWorkflowWiring, computeEntryNodeIds, } from './graph/graph-validation.js';
|
|
12
|
+
// Queue worker functions (registered by codegen, executed at runtime)
|
|
13
|
+
export { pikkuWorkflowWorkerFunc, pikkuWorkflowOrchestratorFunc, pikkuWorkflowSleeperFunc, } from './workflow-queue-workers.js';
|