@pikku/core 0.12.40 → 0.12.41
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/function/function-runner.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/services/credential-wire-service.d.ts +2 -2
- package/dist/services/in-memory-workflow-service.d.ts +1 -0
- package/dist/services/in-memory-workflow-service.js +3 -0
- package/dist/services/pikku-user-id.d.ts +2 -2
- package/dist/services/workflow-service.d.ts +1 -0
- package/dist/types/core.types.d.ts +18 -5
- package/dist/utils.d.ts +3 -1
- package/dist/utils.js +2 -0
- package/dist/wirings/channel/channel-middleware-runner.d.ts +2 -2
- package/dist/wirings/channel/local/local-eventhub-service.js +7 -4
- package/dist/wirings/rpc/rpc-runner.d.ts +4 -4
- package/dist/wirings/rpc/rpc-runner.js +0 -16
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +5 -2
- package/dist/wirings/workflow/pikku-workflow-service.js +11 -4
- package/package.json +1 -1
- package/src/function/function-runner.ts +3 -2
- package/src/index.ts +7 -1
- package/src/services/credential-wire-service.ts +2 -2
- package/src/services/in-memory-workflow-service.test.ts +2 -2
- package/src/services/in-memory-workflow-service.ts +7 -1
- package/src/services/pikku-user-id.ts +2 -2
- package/src/services/workflow-service.ts +1 -0
- package/src/types/core.types.ts +22 -6
- package/src/utils.ts +12 -1
- package/src/wirings/ai-agent/ai-agent-prepare.ts +2 -2
- package/src/wirings/channel/channel-common.ts +8 -2
- package/src/wirings/channel/channel-middleware-runner.ts +3 -3
- package/src/wirings/channel/local/local-channel-runner.ts +7 -3
- package/src/wirings/channel/local/local-eventhub-service.ts +6 -3
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +4 -4
- package/src/wirings/cli/cli-runner.ts +2 -2
- package/src/wirings/gateway/gateway-runner.ts +8 -2
- package/src/wirings/http/http-runner.ts +3 -2
- package/src/wirings/mcp/mcp-runner.ts +2 -2
- package/src/wirings/queue/queue-runner.ts +2 -2
- package/src/wirings/rpc/rpc-runner.ts +12 -24
- package/src/wirings/scheduler/scheduler-runner.ts +2 -2
- package/src/wirings/trigger/trigger-runner.ts +2 -2
- package/src/wirings/workflow/pikku-workflow-service.test.ts +3 -2
- package/src/wirings/workflow/pikku-workflow-service.ts +29 -10
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## 0.12.41
|
|
2
|
+
|
|
3
|
+
### Patch Changes
|
|
4
|
+
|
|
5
|
+
- 04db6a2: Make `rpc` a required property on `PikkuWire`. It is always lazily initialised by the function runner on every invocation regardless of wire type, so marking it optional was misleading.
|
|
6
|
+
|
|
1
7
|
## 0.12.40
|
|
2
8
|
|
|
3
9
|
### Patch Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CoreUserSession, CorePikkuMiddleware, PikkuWiringTypes,
|
|
1
|
+
import type { CoreUserSession, CorePikkuMiddleware, PikkuWiringTypes, PikkuRawWire, MiddlewareMetadata, PermissionMetadata, CoreSingletonServices, CreateWireServices } from '../types/core.types.js';
|
|
2
2
|
import type { CorePikkuChannelMiddleware } from '../wirings/channel/channel.types.js';
|
|
3
3
|
import type { CorePermissionGroup, CorePikkuFunctionConfig, CorePikkuPermission } from './functions.types.js';
|
|
4
4
|
import type { SessionService } from '../services/user-session-service.js';
|
|
@@ -19,7 +19,7 @@ export declare const runPikkuFunc: <In = any, Out = any>(wireType: PikkuWiringTy
|
|
|
19
19
|
wirePermissions?: CorePermissionGroup | CorePikkuPermission[];
|
|
20
20
|
coerceDataFromSchema?: boolean;
|
|
21
21
|
tags?: string[];
|
|
22
|
-
wire:
|
|
22
|
+
wire: PikkuRawWire;
|
|
23
23
|
sessionService?: SessionService<CoreUserSession>;
|
|
24
24
|
credentialWireService?: PikkuCredentialWireService;
|
|
25
25
|
packageName?: string | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module @pikku/core
|
|
3
3
|
*/
|
|
4
|
-
export type { CommonWireMeta, CoreConfig, CorePikkuMiddleware, CorePikkuMiddlewareConfig, CorePikkuMiddlewareFactory, CorePikkuMiddlewareGroup, CoreServices, CoreSingletonServices, CoreUserSession, CreateConfig, FunctionMeta, FunctionRuntimeMeta, FunctionServicesMeta, FunctionWiresMeta, FunctionsMeta, FunctionsRuntimeMeta, JSONPrimitive, JSONValue, MakeRequired, MiddlewareMetadata, MiddlewarePriority, PermissionMetadata, PickOptional, PickRequired, PikkuAIMiddlewareHooks, PikkuWire, PikkuWiringTypes, RequireAtLeastOne, SerializedError, WireServices, } from './types/core.types.js';
|
|
4
|
+
export type { CommonWireMeta, CoreConfig, CorePikkuMiddleware, CorePikkuMiddlewareConfig, CorePikkuMiddlewareFactory, CorePikkuMiddlewareGroup, CoreServices, CoreSingletonServices, CoreUserSession, CreateConfig, ServerLifecycle, FunctionMeta, FunctionRuntimeMeta, FunctionServicesMeta, FunctionWiresMeta, FunctionsMeta, FunctionsRuntimeMeta, JSONPrimitive, JSONValue, MakeRequired, MiddlewareMetadata, MiddlewarePriority, PermissionMetadata, PickOptional, PickRequired, PikkuAIMiddlewareHooks, PikkuWire, PikkuRawWire, PikkuWiringTypes, RequireAtLeastOne, SerializedError, WireServices, } from './types/core.types.js';
|
|
5
5
|
export { pikkuAIMiddleware, pikkuChannelMiddleware, pikkuChannelMiddlewareFactory, pikkuMiddleware, pikkuMiddlewareFactory, } from './types/core.types.js';
|
|
6
6
|
export type { CorePikkuAuth, CorePikkuAuthConfig, CorePikkuFunction, CorePikkuFunctionConfig, CorePikkuPermission, CorePikkuPermissionConfig, CorePikkuPermissionFactory, CorePikkuApprovalDescription, CorePermissionGroup, ZodLike, } from './function/functions.types.js';
|
|
7
7
|
export { pikkuAuth, pikkuPermission, pikkuPermissionFactory, pikkuApprovalDescription, } from './function/functions.types.js';
|
|
@@ -47,7 +47,7 @@ export type { WireAddonConfig } from './wirings/rpc/wire-addon.js';
|
|
|
47
47
|
export type { PikkuPackageState } from './types/state.types.js';
|
|
48
48
|
export { runMiddleware, addTagMiddleware, addTagMiddleware as addMiddleware, addGlobalMiddleware, } from './middleware-runner.js';
|
|
49
49
|
export { addTagPermission, addTagPermission as addPermission, addGlobalPermission, checkAuthPermissions, } from './permissions.js';
|
|
50
|
-
export { isSerializable, stopSingletonServices } from './utils.js';
|
|
50
|
+
export { isSerializable, stopSingletonServices, pikkuServerLifecycle, } from './utils.js';
|
|
51
51
|
export { getSingletonServices, getCreateWireServices, setSingletonServices, } from './pikku-state.js';
|
|
52
52
|
export { clearPikkuRuntimeState } from './test-utils.js';
|
|
53
53
|
export { type ScheduledTaskInfo, type ScheduledTaskSummary, } from './services/scheduler-service.js';
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ export { createGraph } from './wirings/workflow/graph/graph-node.js';
|
|
|
17
17
|
export { wireAddon } from './wirings/rpc/wire-addon.js';
|
|
18
18
|
export { runMiddleware, addTagMiddleware, addTagMiddleware as addMiddleware, addGlobalMiddleware, } from './middleware-runner.js';
|
|
19
19
|
export { addTagPermission, addTagPermission as addPermission, addGlobalPermission, checkAuthPermissions, } from './permissions.js';
|
|
20
|
-
export { isSerializable, stopSingletonServices } from './utils.js';
|
|
20
|
+
export { isSerializable, stopSingletonServices, pikkuServerLifecycle, } from './utils.js';
|
|
21
21
|
export { getSingletonServices, getCreateWireServices, setSingletonServices, } from './pikku-state.js';
|
|
22
22
|
export { clearPikkuRuntimeState } from './test-utils.js';
|
|
23
23
|
export { SchedulerService } from './services/scheduler-service.js';
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { CredentialService } from './credential-service.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { PikkuRawWire } from '../types/core.types.js';
|
|
3
3
|
export declare class PikkuCredentialWireService {
|
|
4
4
|
private credentialService?;
|
|
5
5
|
private wire?;
|
|
6
6
|
private credentials;
|
|
7
7
|
private loaded;
|
|
8
8
|
private loadPromise;
|
|
9
|
-
constructor(credentialService?: CredentialService | undefined, wire?:
|
|
9
|
+
constructor(credentialService?: CredentialService | undefined, wire?: PikkuRawWire | undefined);
|
|
10
10
|
set(name: string, value: unknown): void;
|
|
11
11
|
get<T = unknown>(name: string): T | null | Promise<T | null>;
|
|
12
12
|
getAll(): Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
@@ -17,6 +17,7 @@ import type { WorkflowPlannedStep, WorkflowRun, WorkflowRunService, WorkflowRunW
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
export declare class InMemoryWorkflowService extends PikkuWorkflowService implements WorkflowRunService {
|
|
20
|
+
constructor();
|
|
20
21
|
private sleepTimers;
|
|
21
22
|
private runs;
|
|
22
23
|
private steps;
|
|
@@ -17,6 +17,9 @@ import { isExpectedError } from '../errors/error-handler.js';
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
export class InMemoryWorkflowService extends PikkuWorkflowService {
|
|
20
|
+
constructor() {
|
|
21
|
+
super({ wireQueues: false });
|
|
22
|
+
}
|
|
20
23
|
sleepTimers = new Set();
|
|
21
24
|
runs = new Map();
|
|
22
25
|
steps = new Map(); // keyed by `${runId}:${stepName}`
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export type PikkuUserIdResolver = (wire:
|
|
1
|
+
import type { PikkuRawWire } from '../types/core.types.js';
|
|
2
|
+
export type PikkuUserIdResolver = (wire: PikkuRawWire) => string | undefined;
|
|
3
3
|
export declare const defaultPikkuUserIdResolver: PikkuUserIdResolver;
|
|
@@ -6,6 +6,7 @@ import type { RunTimeline, ReconstructedRunState } from '../wirings/workflow/run
|
|
|
6
6
|
* Handles workflow execution, replay, orchestration logic, and run-level state
|
|
7
7
|
*/
|
|
8
8
|
export interface WorkflowService {
|
|
9
|
+
wireQueueWorkers?(): void;
|
|
9
10
|
createRun(workflowName: string, input: any, inline: boolean, graphHash: string, wire: WorkflowRunWire, options?: {
|
|
10
11
|
deterministic?: boolean;
|
|
11
12
|
plannedSteps?: WorkflowPlannedStep[];
|
|
@@ -126,7 +126,7 @@ export type JSONValue = JSONPrimitive | JSONValue[] | {
|
|
|
126
126
|
/**
|
|
127
127
|
* Utility type for making certain keys required and leaving the rest as optional.
|
|
128
128
|
*/
|
|
129
|
-
export type PickRequired<T, K extends keyof T> = Required<Pick<T, K
|
|
129
|
+
export type PickRequired<T, K extends keyof T> = T & Required<Pick<T, K>>;
|
|
130
130
|
/**
|
|
131
131
|
* Utility type for making certain keys optional while keeping the rest required.
|
|
132
132
|
*/
|
|
@@ -214,7 +214,10 @@ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
|
|
|
214
214
|
/**
|
|
215
215
|
* Represents different forms of wire within Pikku and the outside world.
|
|
216
216
|
*/
|
|
217
|
-
export type PikkuWire<In = unknown, Out = unknown, HasInitialSession extends boolean = false, UserSession extends CoreUserSession = CoreUserSession, TypedRPC extends PikkuRPC = PikkuRPC, IsChannel extends true | null = null, MCPTools extends string | never = never, TypedWorkflow extends PikkuWorkflowWire | never = PikkuWorkflowWire, TriggerOutput = unknown> =
|
|
217
|
+
export type PikkuWire<In = unknown, Out = unknown, HasInitialSession extends boolean = false, UserSession extends CoreUserSession = CoreUserSession, TypedRPC extends PikkuRPC = PikkuRPC, IsChannel extends true | null = null, MCPTools extends string | never = never, TypedWorkflow extends PikkuWorkflowWire | never = PikkuWorkflowWire, TriggerOutput = unknown> = {
|
|
218
|
+
/** Always present — lazily initialised on first access for every function invocation */
|
|
219
|
+
rpc: TypedRPC;
|
|
220
|
+
} & Partial<{
|
|
218
221
|
wireType: PikkuWiringTypes;
|
|
219
222
|
wireId: string;
|
|
220
223
|
/** Trace ID for distributed tracing — propagated across remote RPC calls via x-trace-id header */
|
|
@@ -223,7 +226,6 @@ export type PikkuWire<In = unknown, Out = unknown, HasInitialSession extends boo
|
|
|
223
226
|
functionId: string;
|
|
224
227
|
http: PikkuHTTP<In>;
|
|
225
228
|
mcp: PikkuMCP<MCPTools>;
|
|
226
|
-
rpc: TypedRPC;
|
|
227
229
|
channel: [IsChannel] extends [null] ? PikkuChannel<unknown, Out> : PikkuChannel<unknown, Out> | undefined;
|
|
228
230
|
scheduledTask: PikkuScheduledTask;
|
|
229
231
|
queue: PikkuQueue;
|
|
@@ -255,10 +257,14 @@ export type PikkuWire<In = unknown, Out = unknown, HasInitialSession extends boo
|
|
|
255
257
|
durability: AuditDurability;
|
|
256
258
|
};
|
|
257
259
|
}>;
|
|
260
|
+
/**
|
|
261
|
+
* Wire object as constructed by runners, before rpc is lazily added by the function runner.
|
|
262
|
+
*/
|
|
263
|
+
export type PikkuRawWire = Omit<PikkuWire, 'rpc'>;
|
|
258
264
|
/**
|
|
259
265
|
* A function that can wrap an wire and be called before or after
|
|
260
266
|
*/
|
|
261
|
-
export type CorePikkuMiddleware<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, wires: PikkuWire
|
|
267
|
+
export type CorePikkuMiddleware<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, wires: PikkuWire, next: () => Promise<void>) => Promise<void>;
|
|
262
268
|
/**
|
|
263
269
|
* Priority levels for middleware execution order.
|
|
264
270
|
* Lower priority runs first (outermost in the onion model).
|
|
@@ -356,11 +362,18 @@ export type CreateSingletonServices<Config extends CoreConfig, SingletonServices
|
|
|
356
362
|
/**
|
|
357
363
|
* Defines a function type for creating session-specific services.
|
|
358
364
|
*/
|
|
359
|
-
export type CreateWireServices<SingletonServices extends CoreSingletonServices = CoreSingletonServices, Services extends CoreServices<SingletonServices> = CoreServices<SingletonServices>, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, wire:
|
|
365
|
+
export type CreateWireServices<SingletonServices extends CoreSingletonServices = CoreSingletonServices, Services extends CoreServices<SingletonServices> = CoreServices<SingletonServices>, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, wire: PikkuRawWire) => Promise<WireServices<Services, SingletonServices>>;
|
|
360
366
|
/**
|
|
361
367
|
* Defines a function type for creating config.
|
|
362
368
|
*/
|
|
363
369
|
export type CreateConfig<Config extends CoreConfig, RemainingArgs extends any[] = unknown[]> = (variables?: VariablesService, ...args: RemainingArgs) => Promise<Config>;
|
|
370
|
+
/** Server lifecycle hooks for startup and shutdown phases. */
|
|
371
|
+
export type ServerLifecycle<SingletonServices extends CoreSingletonServices = CoreSingletonServices> = {
|
|
372
|
+
beforeStart?: (services: SingletonServices) => void | Promise<void>;
|
|
373
|
+
afterStart?: (services: SingletonServices) => void | Promise<void>;
|
|
374
|
+
beforeStop?: (services: SingletonServices) => void | Promise<void>;
|
|
375
|
+
afterStop?: (services: SingletonServices) => void | Promise<void>;
|
|
376
|
+
};
|
|
364
377
|
/**
|
|
365
378
|
* Represents the documentation for a route, including summary, description, tags, and errors.
|
|
366
379
|
*/
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Logger } from './services/logger.js';
|
|
2
|
-
import type { WireServices } from './types/core.types.js';
|
|
2
|
+
import type { CoreSingletonServices, ServerLifecycle, WireServices } from './types/core.types.js';
|
|
3
3
|
export declare const closeWireServices: (logger: Logger, wireServices: WireServices) => Promise<void>;
|
|
4
4
|
export declare const createWeakUID: () => string;
|
|
5
5
|
export declare const isSerializable: (data: any) => boolean;
|
|
@@ -12,3 +12,5 @@ export declare const freezeDedupe: <T>(arr?: readonly T[] | T[] | undefined) =>
|
|
|
12
12
|
* @param singletonServices - The parent singleton services to stop
|
|
13
13
|
*/
|
|
14
14
|
export declare const stopSingletonServices: () => Promise<void>;
|
|
15
|
+
/** Wrap server lifecycle hooks so the inspector can discover them. */
|
|
16
|
+
export declare const pikkuServerLifecycle: <SS extends CoreSingletonServices = CoreSingletonServices>(lifecycle: ServerLifecycle<SS>) => ServerLifecycle<SS>;
|
package/dist/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CoreSingletonServices, MiddlewareMetadata,
|
|
1
|
+
import type { CoreSingletonServices, MiddlewareMetadata, PikkuRawWire } from '../../types/core.types.js';
|
|
2
2
|
import type { CorePikkuChannelMiddleware } from './channel.types.js';
|
|
3
3
|
export declare const addChannelMiddleware: (tag: string, middleware: CorePikkuChannelMiddleware[], packageName?: string | null) => CorePikkuChannelMiddleware[];
|
|
4
4
|
export declare const clearChannelMiddlewareCache: () => void;
|
|
@@ -7,4 +7,4 @@ export declare const combineChannelMiddleware: (wireType: string, uid: string, {
|
|
|
7
7
|
wireChannelMiddleware?: CorePikkuChannelMiddleware[];
|
|
8
8
|
packageName?: string | null;
|
|
9
9
|
}) => readonly CorePikkuChannelMiddleware[];
|
|
10
|
-
export declare function wrapChannelWithMiddleware<Out>(wire:
|
|
10
|
+
export declare function wrapChannelWithMiddleware<Out>(wire: PikkuRawWire, services: CoreSingletonServices, middlewares: readonly CorePikkuChannelMiddleware[]): PikkuRawWire;
|
|
@@ -50,10 +50,13 @@ export class LocalEventHubService {
|
|
|
50
50
|
continue; // Skip sending to the sender
|
|
51
51
|
const channel = this.channels.get(toChannelId);
|
|
52
52
|
if (channel) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
try {
|
|
54
|
+
channel.send(data, isBinary);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Channel closed (e.g. SSE ReadableStream controller already closed on browser disconnect) — clean up
|
|
58
|
+
this.onChannelClosed(toChannelId);
|
|
59
|
+
}
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
62
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CoreServices,
|
|
1
|
+
import type { CoreServices, PikkuRawWire } from '../../types/core.types.js';
|
|
2
2
|
import type { SessionService } from '../../services/user-session-service.js';
|
|
3
3
|
import type { CoreUserSession } from '../../types/core.types.js';
|
|
4
4
|
import { PikkuError } from '../../errors/error-handler.js';
|
|
@@ -19,7 +19,7 @@ export declare class ContextAwareRPCService {
|
|
|
19
19
|
private wire;
|
|
20
20
|
private options;
|
|
21
21
|
private packageName;
|
|
22
|
-
constructor(services: CoreServices, wire:
|
|
22
|
+
constructor(services: CoreServices, wire: PikkuRawWire, options: {
|
|
23
23
|
requiresAuth?: boolean;
|
|
24
24
|
sessionService?: SessionService<CoreUserSession>;
|
|
25
25
|
}, packageName?: string | null);
|
|
@@ -32,7 +32,7 @@ export declare class ContextAwareRPCService {
|
|
|
32
32
|
* @private
|
|
33
33
|
*/
|
|
34
34
|
private invokeAddonFunction;
|
|
35
|
-
rpcWithWire<In = any, Out = any>(rpcName: string, data: In, wire:
|
|
35
|
+
rpcWithWire<In = any, Out = any>(rpcName: string, data: In, wire: PikkuRawWire): Promise<Out>;
|
|
36
36
|
startWorkflow<In = any>(workflowName: string, input: In, options?: {
|
|
37
37
|
startNode?: string;
|
|
38
38
|
wire?: {
|
|
@@ -94,7 +94,7 @@ export declare class ContextAwareRPCService {
|
|
|
94
94
|
remote<In = any, Out = any>(funcName: string, data: In): Promise<Out>;
|
|
95
95
|
}
|
|
96
96
|
export declare class PikkuRPCService<Services extends CoreServices, TypedRPC = PikkuRPC> {
|
|
97
|
-
getContextRPCService(services: Services, wire:
|
|
97
|
+
getContextRPCService(services: Services, wire: PikkuRawWire, requiresAuthOrOptions?: boolean | {
|
|
98
98
|
requiresAuth?: boolean;
|
|
99
99
|
sessionService?: SessionService<CoreUserSession>;
|
|
100
100
|
} | undefined, depth?: number, packageName?: string | null): TypedRPC;
|
|
@@ -110,16 +110,8 @@ export class ContextAwareRPCService {
|
|
|
110
110
|
return await this.rpc(funcName, data);
|
|
111
111
|
}
|
|
112
112
|
async rpc(funcName, data) {
|
|
113
|
-
const rpcDepth = this.wire.rpc?.depth || 0;
|
|
114
113
|
const updatedWire = {
|
|
115
114
|
...this.wire,
|
|
116
|
-
rpc: this.wire.rpc
|
|
117
|
-
? {
|
|
118
|
-
...this.wire.rpc,
|
|
119
|
-
depth: rpcDepth + 1,
|
|
120
|
-
global: false,
|
|
121
|
-
}
|
|
122
|
-
: undefined,
|
|
123
115
|
};
|
|
124
116
|
// Check addon namespace first (e.g. 'stripe:createCharge')
|
|
125
117
|
if (funcName.includes(':')) {
|
|
@@ -197,17 +189,9 @@ export class ContextAwareRPCService {
|
|
|
197
189
|
});
|
|
198
190
|
}
|
|
199
191
|
async rpcWithWire(rpcName, data, wire) {
|
|
200
|
-
const rpcDepth = this.wire.rpc?.depth || 0;
|
|
201
192
|
const mergedWire = {
|
|
202
193
|
...this.wire,
|
|
203
194
|
...wire,
|
|
204
|
-
rpc: this.wire.rpc
|
|
205
|
-
? {
|
|
206
|
-
...this.wire.rpc,
|
|
207
|
-
depth: rpcDepth + 1,
|
|
208
|
-
global: false,
|
|
209
|
-
}
|
|
210
|
-
: undefined,
|
|
211
195
|
};
|
|
212
196
|
if (rpcName.includes(':')) {
|
|
213
197
|
return this.invokeAddonFunction(rpcName, data, mergedWire);
|
|
@@ -66,6 +66,9 @@ export declare class WorkflowRunFailedError extends PikkuError {
|
|
|
66
66
|
};
|
|
67
67
|
constructor(message?: string);
|
|
68
68
|
}
|
|
69
|
+
export declare class WorkflowRunCancelledError extends PikkuError {
|
|
70
|
+
constructor();
|
|
71
|
+
}
|
|
69
72
|
export declare class WorkflowServiceNotInitialized extends Error {
|
|
70
73
|
}
|
|
71
74
|
export declare class WorkflowStepNameNotString extends Error {
|
|
@@ -85,13 +88,13 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
|
|
|
85
88
|
mirror?: WorkflowRunMirror;
|
|
86
89
|
});
|
|
87
90
|
private safeMirror;
|
|
88
|
-
rewireQueueWorkers(): void;
|
|
89
91
|
/**
|
|
90
92
|
* Wire the queue-based orchestrator/step/sleeper workers.
|
|
91
93
|
* Subclasses that orchestrate without queues (e.g. Durable Objects) should
|
|
92
94
|
* pass `wireQueues: false` to the base constructor and skip this entirely.
|
|
95
|
+
* Call this explicitly after adding addons dynamically.
|
|
93
96
|
*/
|
|
94
|
-
|
|
97
|
+
wireQueueWorkers(): void;
|
|
95
98
|
/**
|
|
96
99
|
* Check if a run is executing inline (without queues)
|
|
97
100
|
*/
|
|
@@ -131,6 +131,15 @@ addError(WorkflowRunFailedError, {
|
|
|
131
131
|
status: 422,
|
|
132
132
|
message: 'Workflow run failed.',
|
|
133
133
|
});
|
|
134
|
+
export class WorkflowRunCancelledError extends PikkuError {
|
|
135
|
+
constructor() {
|
|
136
|
+
super('Workflow was cancelled');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
addError(WorkflowRunCancelledError, {
|
|
140
|
+
status: 409,
|
|
141
|
+
message: 'Workflow was cancelled.',
|
|
142
|
+
});
|
|
134
143
|
export class WorkflowServiceNotInitialized extends Error {
|
|
135
144
|
}
|
|
136
145
|
export class WorkflowStepNameNotString extends Error {
|
|
@@ -177,13 +186,11 @@ export class PikkuWorkflowService {
|
|
|
177
186
|
}
|
|
178
187
|
}
|
|
179
188
|
}
|
|
180
|
-
rewireQueueWorkers() {
|
|
181
|
-
this.wireQueueWorkers();
|
|
182
|
-
}
|
|
183
189
|
/**
|
|
184
190
|
* Wire the queue-based orchestrator/step/sleeper workers.
|
|
185
191
|
* Subclasses that orchestrate without queues (e.g. Durable Objects) should
|
|
186
192
|
* pass `wireQueues: false` to the base constructor and skip this entirely.
|
|
193
|
+
* Call this explicitly after adding addons dynamically.
|
|
187
194
|
*/
|
|
188
195
|
wireQueueWorkers() {
|
|
189
196
|
const functions = pikkuState(null, 'function', 'functions');
|
|
@@ -683,7 +690,7 @@ export class PikkuWorkflowService {
|
|
|
683
690
|
throw new WorkflowRunFailedError(run.error?.message);
|
|
684
691
|
}
|
|
685
692
|
if (run.status === 'cancelled') {
|
|
686
|
-
throw new
|
|
693
|
+
throw new WorkflowRunCancelledError();
|
|
687
694
|
}
|
|
688
695
|
return run.output;
|
|
689
696
|
}
|
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
CorePikkuMiddleware,
|
|
12
12
|
PikkuWiringTypes,
|
|
13
13
|
PikkuWire,
|
|
14
|
+
PikkuRawWire,
|
|
14
15
|
MiddlewareMetadata,
|
|
15
16
|
PermissionMetadata,
|
|
16
17
|
CoreSingletonServices,
|
|
@@ -37,7 +38,7 @@ import { rpcService } from '../wirings/rpc/rpc-runner.js'
|
|
|
37
38
|
import { closeWireServices } from '../utils.js'
|
|
38
39
|
|
|
39
40
|
async function resolveSession(
|
|
40
|
-
wire:
|
|
41
|
+
wire: PikkuRawWire,
|
|
41
42
|
singletonServices: CoreSingletonServices,
|
|
42
43
|
sessionService?: SessionService<CoreUserSession>
|
|
43
44
|
): Promise<void> {
|
|
@@ -234,7 +235,7 @@ export const runPikkuFunc = async <In = any, Out = any>(
|
|
|
234
235
|
wirePermissions?: CorePermissionGroup | CorePikkuPermission[]
|
|
235
236
|
coerceDataFromSchema?: boolean
|
|
236
237
|
tags?: string[]
|
|
237
|
-
wire:
|
|
238
|
+
wire: PikkuRawWire
|
|
238
239
|
sessionService?: SessionService<CoreUserSession>
|
|
239
240
|
credentialWireService?: PikkuCredentialWireService
|
|
240
241
|
packageName?: string | null
|
package/src/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type {
|
|
|
12
12
|
CoreSingletonServices,
|
|
13
13
|
CoreUserSession,
|
|
14
14
|
CreateConfig,
|
|
15
|
+
ServerLifecycle,
|
|
15
16
|
FunctionMeta,
|
|
16
17
|
FunctionRuntimeMeta,
|
|
17
18
|
FunctionServicesMeta,
|
|
@@ -28,6 +29,7 @@ export type {
|
|
|
28
29
|
PickRequired,
|
|
29
30
|
PikkuAIMiddlewareHooks,
|
|
30
31
|
PikkuWire,
|
|
32
|
+
PikkuRawWire,
|
|
31
33
|
PikkuWiringTypes,
|
|
32
34
|
RequireAtLeastOne,
|
|
33
35
|
SerializedError,
|
|
@@ -187,7 +189,11 @@ export {
|
|
|
187
189
|
addGlobalPermission,
|
|
188
190
|
checkAuthPermissions,
|
|
189
191
|
} from './permissions.js'
|
|
190
|
-
export {
|
|
192
|
+
export {
|
|
193
|
+
isSerializable,
|
|
194
|
+
stopSingletonServices,
|
|
195
|
+
pikkuServerLifecycle,
|
|
196
|
+
} from './utils.js'
|
|
191
197
|
export {
|
|
192
198
|
getSingletonServices,
|
|
193
199
|
getCreateWireServices,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CredentialService } from './credential-service.js'
|
|
2
2
|
import { defaultPikkuUserIdResolver } from './pikku-user-id.js'
|
|
3
|
-
import type {
|
|
3
|
+
import type { PikkuRawWire } from '../types/core.types.js'
|
|
4
4
|
|
|
5
5
|
export class PikkuCredentialWireService {
|
|
6
6
|
private credentials: Record<string, unknown> = {}
|
|
@@ -9,7 +9,7 @@ export class PikkuCredentialWireService {
|
|
|
9
9
|
|
|
10
10
|
constructor(
|
|
11
11
|
private credentialService?: CredentialService,
|
|
12
|
-
private wire?:
|
|
12
|
+
private wire?: PikkuRawWire
|
|
13
13
|
) {}
|
|
14
14
|
|
|
15
15
|
set(name: string, value: unknown): void {
|
|
@@ -366,7 +366,7 @@ describe('InMemoryWorkflowService', () => {
|
|
|
366
366
|
})
|
|
367
367
|
|
|
368
368
|
describe('queue worker registration', () => {
|
|
369
|
-
test('
|
|
369
|
+
test('wireQueueWorkers registers workflow queues added after construction', () => {
|
|
370
370
|
const stepQueue = 'wf-step-regression-enrich'
|
|
371
371
|
const orchQueue = 'wf-orchestrator-regression-onboarding'
|
|
372
372
|
|
|
@@ -385,7 +385,7 @@ describe('InMemoryWorkflowService', () => {
|
|
|
385
385
|
assert.strictEqual(getQueueWorkers().has(stepQueue), false)
|
|
386
386
|
assert.strictEqual(getQueueWorkers().has(orchQueue), false)
|
|
387
387
|
|
|
388
|
-
ws.
|
|
388
|
+
ws.wireQueueWorkers()
|
|
389
389
|
|
|
390
390
|
assert.strictEqual(getQueueWorkers().has(stepQueue), true)
|
|
391
391
|
assert.strictEqual(getQueueWorkers().has(orchQueue), true)
|
|
@@ -39,6 +39,10 @@ export class InMemoryWorkflowService
|
|
|
39
39
|
extends PikkuWorkflowService
|
|
40
40
|
implements WorkflowRunService
|
|
41
41
|
{
|
|
42
|
+
constructor() {
|
|
43
|
+
super({ wireQueues: false })
|
|
44
|
+
}
|
|
45
|
+
|
|
42
46
|
private sleepTimers = new Set<ReturnType<typeof setTimeout>>()
|
|
43
47
|
private runs = new Map<string, WorkflowRun>()
|
|
44
48
|
private steps = new Map<string, StepState>() // keyed by `${runId}:${stepName}`
|
|
@@ -451,7 +455,9 @@ export class InMemoryWorkflowService
|
|
|
451
455
|
return nodeIds.filter((id) => !existingSteps.has(id))
|
|
452
456
|
}
|
|
453
457
|
|
|
454
|
-
async getStepInstances(
|
|
458
|
+
async getStepInstances(
|
|
459
|
+
runId: string
|
|
460
|
+
): Promise<
|
|
455
461
|
Array<{ stepName: string; status: StepStatus; fromStepName?: string }>
|
|
456
462
|
> {
|
|
457
463
|
const prefix = `${runId}:`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PikkuRawWire } from '../types/core.types.js'
|
|
2
2
|
|
|
3
|
-
export type PikkuUserIdResolver = (wire:
|
|
3
|
+
export type PikkuUserIdResolver = (wire: PikkuRawWire) => string | undefined
|
|
4
4
|
|
|
5
5
|
export const defaultPikkuUserIdResolver: PikkuUserIdResolver = (wire) => {
|
|
6
6
|
// Explicit pikkuUserId on wire (set by earlier middleware or runner)
|
package/src/types/core.types.ts
CHANGED
|
@@ -178,8 +178,7 @@ export type JSONValue =
|
|
|
178
178
|
/**
|
|
179
179
|
* Utility type for making certain keys required and leaving the rest as optional.
|
|
180
180
|
*/
|
|
181
|
-
export type PickRequired<T, K extends keyof T> = Required<Pick<T, K>>
|
|
182
|
-
Partial<T>
|
|
181
|
+
export type PickRequired<T, K extends keyof T> = T & Required<Pick<T, K>>
|
|
183
182
|
|
|
184
183
|
/**
|
|
185
184
|
* Utility type for making certain keys optional while keeping the rest required.
|
|
@@ -285,7 +284,10 @@ export type PikkuWire<
|
|
|
285
284
|
MCPTools extends string | never = never,
|
|
286
285
|
TypedWorkflow extends PikkuWorkflowWire | never = PikkuWorkflowWire,
|
|
287
286
|
TriggerOutput = unknown,
|
|
288
|
-
> =
|
|
287
|
+
> = {
|
|
288
|
+
/** Always present — lazily initialised on first access for every function invocation */
|
|
289
|
+
rpc: TypedRPC
|
|
290
|
+
} & Partial<{
|
|
289
291
|
wireType: PikkuWiringTypes
|
|
290
292
|
wireId: string
|
|
291
293
|
/** Trace ID for distributed tracing — propagated across remote RPC calls via x-trace-id header */
|
|
@@ -294,7 +296,6 @@ export type PikkuWire<
|
|
|
294
296
|
functionId: string
|
|
295
297
|
http: PikkuHTTP<In>
|
|
296
298
|
mcp: PikkuMCP<MCPTools>
|
|
297
|
-
rpc: TypedRPC
|
|
298
299
|
channel: [IsChannel] extends [null]
|
|
299
300
|
? PikkuChannel<unknown, Out>
|
|
300
301
|
: PikkuChannel<unknown, Out> | undefined
|
|
@@ -333,6 +334,11 @@ export type PikkuWire<
|
|
|
333
334
|
}
|
|
334
335
|
}>
|
|
335
336
|
|
|
337
|
+
/**
|
|
338
|
+
* Wire object as constructed by runners, before rpc is lazily added by the function runner.
|
|
339
|
+
*/
|
|
340
|
+
export type PikkuRawWire = Omit<PikkuWire, 'rpc'>
|
|
341
|
+
|
|
336
342
|
/**
|
|
337
343
|
* A function that can wrap an wire and be called before or after
|
|
338
344
|
*/
|
|
@@ -341,7 +347,7 @@ export type CorePikkuMiddleware<
|
|
|
341
347
|
UserSession extends CoreUserSession = CoreUserSession,
|
|
342
348
|
> = (
|
|
343
349
|
services: SingletonServices,
|
|
344
|
-
wires: PikkuWire
|
|
350
|
+
wires: PikkuWire,
|
|
345
351
|
next: () => Promise<void>
|
|
346
352
|
) => Promise<void>
|
|
347
353
|
|
|
@@ -527,7 +533,7 @@ export type CreateWireServices<
|
|
|
527
533
|
UserSession extends CoreUserSession = CoreUserSession,
|
|
528
534
|
> = (
|
|
529
535
|
services: SingletonServices,
|
|
530
|
-
wire:
|
|
536
|
+
wire: PikkuRawWire
|
|
531
537
|
) => Promise<WireServices<Services, SingletonServices>>
|
|
532
538
|
|
|
533
539
|
/**
|
|
@@ -538,6 +544,16 @@ export type CreateConfig<
|
|
|
538
544
|
RemainingArgs extends any[] = unknown[],
|
|
539
545
|
> = (variables?: VariablesService, ...args: RemainingArgs) => Promise<Config>
|
|
540
546
|
|
|
547
|
+
/** Server lifecycle hooks for startup and shutdown phases. */
|
|
548
|
+
export type ServerLifecycle<
|
|
549
|
+
SingletonServices extends CoreSingletonServices = CoreSingletonServices,
|
|
550
|
+
> = {
|
|
551
|
+
beforeStart?: (services: SingletonServices) => void | Promise<void>
|
|
552
|
+
afterStart?: (services: SingletonServices) => void | Promise<void>
|
|
553
|
+
beforeStop?: (services: SingletonServices) => void | Promise<void>
|
|
554
|
+
afterStop?: (services: SingletonServices) => void | Promise<void>
|
|
555
|
+
}
|
|
556
|
+
|
|
541
557
|
/**
|
|
542
558
|
* Represents the documentation for a route, including summary, description, tags, and errors.
|
|
543
559
|
*/
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { Logger } from './services/logger.js'
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
CoreSingletonServices,
|
|
4
|
+
ServerLifecycle,
|
|
5
|
+
WireServices,
|
|
6
|
+
} from './types/core.types.js'
|
|
3
7
|
import { getSingletonServices, getAllPackageStates } from './pikku-state.js'
|
|
4
8
|
|
|
5
9
|
export const closeWireServices = async (
|
|
@@ -127,3 +131,10 @@ export const stopSingletonServices = async (): Promise<void> => {
|
|
|
127
131
|
await stopService(logger, name, service)
|
|
128
132
|
}
|
|
129
133
|
}
|
|
134
|
+
|
|
135
|
+
/** Wrap server lifecycle hooks so the inspector can discover them. */
|
|
136
|
+
export const pikkuServerLifecycle = <
|
|
137
|
+
SS extends CoreSingletonServices = CoreSingletonServices,
|
|
138
|
+
>(
|
|
139
|
+
lifecycle: ServerLifecycle<SS>
|
|
140
|
+
): ServerLifecycle<SS> => lifecycle
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PikkuRawWire, CoreUserSession } from '../../types/core.types.js'
|
|
2
2
|
import type {
|
|
3
3
|
CoreAIAgent,
|
|
4
4
|
AIAgentInput,
|
|
@@ -397,7 +397,7 @@ export async function buildToolDefs(
|
|
|
397
397
|
needsApproval: needsApproval || undefined,
|
|
398
398
|
approvalDescriptionFn,
|
|
399
399
|
execute: async (toolInput: unknown) => {
|
|
400
|
-
const wire:
|
|
400
|
+
const wire: PikkuRawWire = params.sessionService
|
|
401
401
|
? { ...createMiddlewareSessionWireProps(params.sessionService) }
|
|
402
402
|
: {}
|
|
403
403
|
const rpcService = new ContextAwareRPCService(
|