@pikku/core 0.9.11 → 0.9.12-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/function/function-runner.d.ts +13 -8
- package/dist/function/function-runner.js +49 -37
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/middleware-runner.d.ts +61 -40
- package/dist/middleware-runner.js +118 -66
- package/dist/permissions.js +1 -0
- package/dist/pikku-state.d.ts +26 -1
- package/dist/pikku-state.js +10 -1
- package/dist/services/content-service.d.ts +2 -3
- package/dist/services/index.d.ts +0 -1
- package/dist/services/index.js +0 -1
- package/dist/services/local-content.d.ts +2 -4
- package/dist/types/core.types.d.ts +51 -2
- package/dist/types/core.types.js +21 -0
- package/dist/wirings/channel/channel-handler.d.ts +2 -2
- package/dist/wirings/channel/channel-handler.js +12 -9
- package/dist/wirings/channel/channel-runner.d.ts +0 -2
- package/dist/wirings/channel/channel-runner.js +2 -3
- package/dist/wirings/channel/channel.types.d.ts +5 -3
- package/dist/wirings/channel/local/local-channel-runner.js +12 -12
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +7 -8
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +12 -0
- package/dist/wirings/cli/channel/cli-channel-runner.js +80 -0
- package/dist/wirings/cli/channel/index.d.ts +1 -0
- package/dist/wirings/cli/channel/index.js +1 -0
- package/dist/wirings/cli/cli-runner.d.ts +32 -0
- package/dist/wirings/cli/cli-runner.js +328 -0
- package/dist/wirings/cli/cli.types.d.ts +177 -0
- package/dist/wirings/cli/cli.types.js +1 -0
- package/dist/wirings/cli/command-parser.d.ts +19 -0
- package/dist/wirings/cli/command-parser.js +373 -0
- package/dist/wirings/cli/index.d.ts +5 -0
- package/dist/wirings/cli/index.js +5 -0
- package/dist/wirings/http/http-runner.d.ts +29 -10
- package/dist/wirings/http/http-runner.js +103 -131
- package/dist/wirings/http/http.types.d.ts +10 -10
- package/dist/wirings/http/index.d.ts +1 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/http/pikku-fetch-http-response.js +3 -1
- package/dist/wirings/http/routers/http-router.d.ts +0 -2
- package/dist/wirings/http/routers/path-to-regex.d.ts +1 -1
- package/dist/wirings/http/routers/path-to-regex.js +5 -34
- package/dist/wirings/mcp/mcp-runner.d.ts +4 -5
- package/dist/wirings/mcp/mcp-runner.js +30 -34
- package/dist/wirings/mcp/mcp.types.d.ts +11 -8
- package/dist/wirings/queue/queue-runner.d.ts +2 -2
- package/dist/wirings/queue/queue-runner.js +25 -27
- package/dist/wirings/queue/queue.types.d.ts +6 -5
- package/dist/wirings/rpc/index.d.ts +1 -1
- package/dist/wirings/rpc/index.js +1 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +6 -18
- package/dist/wirings/rpc/rpc-runner.js +13 -8
- package/dist/wirings/scheduler/scheduler-runner.d.ts +2 -2
- package/dist/wirings/scheduler/scheduler-runner.js +37 -35
- package/dist/wirings/scheduler/scheduler.types.d.ts +4 -3
- package/package.json +4 -3
- package/src/function/function-runner.test.ts +73 -23
- package/src/function/function-runner.ts +74 -55
- package/src/index.ts +8 -1
- package/src/middleware-runner.test.ts +24 -16
- package/src/middleware-runner.ts +136 -83
- package/src/permissions.ts +1 -0
- package/src/pikku-state.ts +47 -2
- package/src/services/content-service.ts +5 -4
- package/src/services/index.ts +0 -1
- package/src/services/local-content.ts +9 -4
- package/src/types/core.types.ts +74 -3
- package/src/wirings/channel/channel-handler.ts +9 -13
- package/src/wirings/channel/channel-runner.ts +2 -6
- package/src/wirings/channel/channel.types.ts +5 -1
- package/src/wirings/channel/local/local-channel-runner.ts +25 -15
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +15 -17
- package/src/wirings/cli/channel/cli-channel-runner.ts +118 -0
- package/src/wirings/cli/channel/index.ts +1 -0
- package/src/wirings/cli/cli-runner.test.ts +382 -0
- package/src/wirings/cli/cli-runner.ts +503 -0
- package/src/wirings/cli/cli.types.ts +320 -0
- package/src/wirings/cli/command-parser.test.ts +440 -0
- package/src/wirings/cli/command-parser.ts +470 -0
- package/src/wirings/cli/index.ts +12 -0
- package/src/wirings/http/http-runner.test.ts +8 -7
- package/src/wirings/http/http-runner.ts +126 -159
- package/src/wirings/http/http.types.ts +56 -11
- package/src/wirings/http/index.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +3 -1
- package/src/wirings/http/routers/http-router.ts +0 -2
- package/src/wirings/http/routers/path-to-regex.test.ts +4 -5
- package/src/wirings/http/routers/path-to-regex.ts +6 -43
- package/src/wirings/mcp/mcp-runner.ts +56 -55
- package/src/wirings/mcp/mcp.types.ts +23 -8
- package/src/wirings/queue/queue-runner.ts +44 -47
- package/src/wirings/queue/queue.types.ts +10 -6
- package/src/wirings/rpc/index.ts +1 -1
- package/src/wirings/rpc/rpc-runner.ts +27 -9
- package/src/wirings/scheduler/scheduler-runner.ts +57 -56
- package/src/wirings/scheduler/scheduler.types.ts +9 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -2,35 +2,31 @@ import { match, MatchFunction } from 'path-to-regexp'
|
|
|
2
2
|
import { MatchResult, Router } from './http-router.js'
|
|
3
3
|
import { HTTPMethod } from '../http.types.js'
|
|
4
4
|
import { pikkuState } from '../../../pikku-state.js'
|
|
5
|
-
import { CorePikkuMiddleware } from '../../../types/core.types.js'
|
|
6
5
|
|
|
7
6
|
interface CompiledRoute {
|
|
8
7
|
matcher: MatchFunction<Partial<Record<string, string | string[]>>>
|
|
9
8
|
route: string
|
|
10
|
-
middleware: CorePikkuMiddleware[]
|
|
11
9
|
}
|
|
12
10
|
|
|
13
11
|
interface StaticRoute {
|
|
14
12
|
route: string
|
|
15
|
-
middleware: CorePikkuMiddleware[]
|
|
16
13
|
}
|
|
17
14
|
|
|
18
15
|
export class PathToRegexRouter implements Router {
|
|
19
16
|
private compiledRoutes: Map<HTTPMethod, Map<string, CompiledRoute>> =
|
|
20
17
|
new Map()
|
|
21
18
|
private staticRoutes: Map<HTTPMethod, Map<string, StaticRoute>> = new Map()
|
|
22
|
-
private precompiledMiddleware: Map<string, CorePikkuMiddleware[]> = new Map()
|
|
23
19
|
private isInitialized = false
|
|
24
20
|
|
|
21
|
+
public reset() {
|
|
22
|
+
this.compiledRoutes = new Map()
|
|
23
|
+
this.staticRoutes = new Map()
|
|
24
|
+
this.isInitialized = false
|
|
25
|
+
}
|
|
26
|
+
|
|
25
27
|
public initialize() {
|
|
26
28
|
const routes = pikkuState('http', 'routes')
|
|
27
29
|
const channelRoutes = pikkuState('channel', 'channels')
|
|
28
|
-
const middlewareMap = pikkuState('http', 'middleware')
|
|
29
|
-
|
|
30
|
-
// Precompile middleware lookups
|
|
31
|
-
for (const [middlewareRoute, middlewareArray] of middlewareMap.entries()) {
|
|
32
|
-
this.precompiledMiddleware.set(middlewareRoute, middlewareArray)
|
|
33
|
-
}
|
|
34
30
|
|
|
35
31
|
// Helper function to compile routes for a given method
|
|
36
32
|
const compileRoutesForMethod = (
|
|
@@ -51,40 +47,10 @@ export class PathToRegexRouter implements Router {
|
|
|
51
47
|
// Check if route is static (no parameters or wildcards)
|
|
52
48
|
const isStaticRoute = !/\*|:/.test(normalizedRoutePath)
|
|
53
49
|
|
|
54
|
-
// Precompute middleware for this route
|
|
55
|
-
const routeMiddleware: CorePikkuMiddleware[] = []
|
|
56
|
-
|
|
57
|
-
// Add global middleware (*)
|
|
58
|
-
const globalMiddleware = this.precompiledMiddleware.get('*')
|
|
59
|
-
if (globalMiddleware) {
|
|
60
|
-
routeMiddleware.push(...globalMiddleware)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Add route-specific middleware
|
|
64
|
-
for (const [
|
|
65
|
-
middlewareRoute,
|
|
66
|
-
middlewareArray,
|
|
67
|
-
] of this.precompiledMiddleware.entries()) {
|
|
68
|
-
if (middlewareRoute !== '*') {
|
|
69
|
-
// Use regex test for pattern matching
|
|
70
|
-
try {
|
|
71
|
-
if (new RegExp(middlewareRoute).test(normalizedRoutePath)) {
|
|
72
|
-
routeMiddleware.push(...middlewareArray)
|
|
73
|
-
}
|
|
74
|
-
} catch {
|
|
75
|
-
// If regex is invalid, do exact match
|
|
76
|
-
if (middlewareRoute === normalizedRoutePath) {
|
|
77
|
-
routeMiddleware.push(...middlewareArray)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
50
|
if (isStaticRoute) {
|
|
84
51
|
// Store static routes for O(1) lookup
|
|
85
52
|
methodStaticRoutes.set(normalizedRoutePath, {
|
|
86
53
|
route: routePath, // Keep the original route path for lookup in pikkuState
|
|
87
|
-
middleware: routeMiddleware,
|
|
88
54
|
})
|
|
89
55
|
} else {
|
|
90
56
|
// Compile dynamic routes with path-to-regexp
|
|
@@ -95,7 +61,6 @@ export class PathToRegexRouter implements Router {
|
|
|
95
61
|
methodCompiledRoutes.set(normalizedRoutePath, {
|
|
96
62
|
matcher,
|
|
97
63
|
route: routePath, // Keep the original route path for lookup in pikkuState
|
|
98
|
-
middleware: routeMiddleware,
|
|
99
64
|
})
|
|
100
65
|
}
|
|
101
66
|
}
|
|
@@ -134,7 +99,6 @@ export class PathToRegexRouter implements Router {
|
|
|
134
99
|
return {
|
|
135
100
|
route: staticRoute.route,
|
|
136
101
|
params: {},
|
|
137
|
-
middleware: staticRoute.middleware,
|
|
138
102
|
}
|
|
139
103
|
}
|
|
140
104
|
}
|
|
@@ -152,7 +116,6 @@ export class PathToRegexRouter implements Router {
|
|
|
152
116
|
return {
|
|
153
117
|
route: compiledRoute.route,
|
|
154
118
|
params: result.params,
|
|
155
|
-
middleware: compiledRoute.middleware,
|
|
156
119
|
}
|
|
157
120
|
}
|
|
158
121
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
PikkuInteraction,
|
|
2
3
|
PikkuWiringTypes,
|
|
3
4
|
type CoreServices,
|
|
4
5
|
type CoreSingletonServices,
|
|
@@ -14,14 +15,16 @@ import type {
|
|
|
14
15
|
JsonRpcErrorResponse,
|
|
15
16
|
PikkuMCP,
|
|
16
17
|
} from './mcp.types.js'
|
|
17
|
-
import type {
|
|
18
|
+
import type {
|
|
19
|
+
CorePikkuFunctionConfig,
|
|
20
|
+
CorePikkuFunctionSessionless,
|
|
21
|
+
} from '../../function/functions.types.js'
|
|
18
22
|
import { getErrorResponse } from '../../errors/error-handler.js'
|
|
19
23
|
import { closeSessionServices } from '../../utils.js'
|
|
20
24
|
import { pikkuState } from '../../pikku-state.js'
|
|
21
25
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
|
|
22
26
|
import { rpcService } from '../rpc/rpc-runner.js'
|
|
23
27
|
import { BadRequestError, NotFoundError } from '../../errors/errors.js'
|
|
24
|
-
import { combineMiddleware, runMiddleware } from '../../middleware-runner.js'
|
|
25
28
|
|
|
26
29
|
export class MCPError extends Error {
|
|
27
30
|
constructor(public readonly error: JsonRpcErrorResponse) {
|
|
@@ -32,7 +35,6 @@ export class MCPError extends Error {
|
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
export type RunMCPEndpointParams<Tools extends string = any> = {
|
|
35
|
-
session?: CoreUserSession
|
|
36
38
|
singletonServices: CoreSingletonServices
|
|
37
39
|
mcp?: PikkuMCP<Tools>
|
|
38
40
|
createSessionServices?: CreateSessionServices<
|
|
@@ -49,16 +51,18 @@ export type JsonRpcError = {
|
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
export const wireMCPResource = <
|
|
52
|
-
|
|
54
|
+
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
55
|
+
CorePikkuFunctionSessionless<any, any>
|
|
56
|
+
> = CorePikkuFunctionConfig<CorePikkuFunctionSessionless<any, any>>,
|
|
53
57
|
>(
|
|
54
|
-
mcpResource: CoreMCPResource<
|
|
58
|
+
mcpResource: CoreMCPResource<PikkuFunctionConfig>
|
|
55
59
|
) => {
|
|
56
60
|
const resourcesMeta = pikkuState('mcp', 'resourcesMeta')
|
|
57
61
|
const mcpResourceMeta = resourcesMeta[mcpResource.uri]
|
|
58
62
|
if (!mcpResourceMeta) {
|
|
59
63
|
throw new Error(`MCP resource metadata not found for '${mcpResource.uri}'`)
|
|
60
64
|
}
|
|
61
|
-
addFunction(mcpResourceMeta.pikkuFuncName, mcpResource
|
|
65
|
+
addFunction(mcpResourceMeta.pikkuFuncName, mcpResource)
|
|
62
66
|
const resources = pikkuState('mcp', 'resources')
|
|
63
67
|
if (resources.has(mcpResource.uri)) {
|
|
64
68
|
throw new Error(`MCP resource already exists: ${mcpResource.uri}`)
|
|
@@ -67,9 +71,11 @@ export const wireMCPResource = <
|
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
export const wireMCPTool = <
|
|
70
|
-
|
|
74
|
+
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
75
|
+
CorePikkuFunctionSessionless<any, any>
|
|
76
|
+
> = CorePikkuFunctionConfig<CorePikkuFunctionSessionless<any, any>>,
|
|
71
77
|
>(
|
|
72
|
-
mcpTool: CoreMCPTool<
|
|
78
|
+
mcpTool: CoreMCPTool<PikkuFunctionConfig>
|
|
73
79
|
) => {
|
|
74
80
|
const toolsMeta = pikkuState('mcp', 'toolsMeta')
|
|
75
81
|
const mcpToolMeta = toolsMeta[mcpTool.name]
|
|
@@ -85,9 +91,11 @@ export const wireMCPTool = <
|
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
export const wireMCPPrompt = <
|
|
88
|
-
|
|
94
|
+
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
95
|
+
CorePikkuFunctionSessionless<any, any>
|
|
96
|
+
> = CorePikkuFunctionConfig<CorePikkuFunctionSessionless<any, any>>,
|
|
89
97
|
>(
|
|
90
|
-
mcpPrompt: CoreMCPPrompt<
|
|
98
|
+
mcpPrompt: CoreMCPPrompt<PikkuFunctionConfig>
|
|
91
99
|
) => {
|
|
92
100
|
const promptsMeta = pikkuState('mcp', 'promptsMeta')
|
|
93
101
|
const mcpPromptMeta = promptsMeta[mcpPrompt.name]
|
|
@@ -200,10 +208,9 @@ async function runMCPPikkuFunc(
|
|
|
200
208
|
mcp: CoreMCPResource | CoreMCPTool | CoreMCPPrompt | undefined,
|
|
201
209
|
pikkuFuncName: string | undefined,
|
|
202
210
|
{
|
|
203
|
-
session,
|
|
204
211
|
singletonServices,
|
|
205
212
|
createSessionServices,
|
|
206
|
-
mcp:
|
|
213
|
+
mcp: mcpInteraction,
|
|
207
214
|
}: RunMCPEndpointParams
|
|
208
215
|
): Promise<JsonRpcResponse> {
|
|
209
216
|
let sessionServices: any
|
|
@@ -230,54 +237,48 @@ async function runMCPPikkuFunc(
|
|
|
230
237
|
|
|
231
238
|
singletonServices.logger.debug(`Running MCP ${type}: ${name}`)
|
|
232
239
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
{ mcp: interaction },
|
|
242
|
-
session
|
|
243
|
-
)
|
|
244
|
-
sessionServices = services
|
|
245
|
-
return rpcService.injectRPCService({
|
|
246
|
-
...singletonServices,
|
|
247
|
-
...services,
|
|
248
|
-
mcp: interaction,
|
|
249
|
-
})
|
|
250
|
-
}
|
|
251
|
-
return rpcService.injectRPCService({
|
|
252
|
-
...singletonServices,
|
|
253
|
-
mcp: interaction,
|
|
254
|
-
})
|
|
255
|
-
}
|
|
240
|
+
const interaction: PikkuInteraction = { mcp: mcpInteraction }
|
|
241
|
+
|
|
242
|
+
const getAllServices = async () => {
|
|
243
|
+
sessionServices = await createSessionServices?.(
|
|
244
|
+
singletonServices,
|
|
245
|
+
interaction,
|
|
246
|
+
undefined
|
|
247
|
+
)
|
|
256
248
|
|
|
257
|
-
|
|
258
|
-
PikkuWiringTypes.mcp,
|
|
259
|
-
`${type}:${name}`,
|
|
260
|
-
pikkuFuncName,
|
|
249
|
+
return rpcService.injectRPCService(
|
|
261
250
|
{
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
251
|
+
...singletonServices,
|
|
252
|
+
...sessionServices,
|
|
253
|
+
},
|
|
254
|
+
interaction
|
|
267
255
|
)
|
|
268
256
|
}
|
|
269
257
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
258
|
+
// Get metadata for the MCP endpoint to access pre-resolved middleware
|
|
259
|
+
let meta: any
|
|
260
|
+
if (type === 'resource') {
|
|
261
|
+
meta = pikkuState('mcp', 'resourcesMeta')[name]
|
|
262
|
+
} else if (type === 'tool') {
|
|
263
|
+
meta = pikkuState('mcp', 'toolsMeta')[name]
|
|
264
|
+
} else if (type === 'prompt') {
|
|
265
|
+
meta = pikkuState('mcp', 'promptsMeta')[name]
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const result = await runPikkuFunc(
|
|
269
|
+
PikkuWiringTypes.mcp,
|
|
270
|
+
`${type}:${name}`,
|
|
271
|
+
pikkuFuncName,
|
|
272
|
+
{
|
|
273
|
+
singletonServices,
|
|
274
|
+
getAllServices,
|
|
275
|
+
userSession: undefined, // TODO
|
|
276
|
+
data: () => request.params,
|
|
277
|
+
inheritedMiddleware: meta?.middleware,
|
|
278
|
+
wireMiddleware: mcp.middleware,
|
|
279
|
+
tags: mcp.tags,
|
|
280
|
+
interaction,
|
|
281
|
+
}
|
|
281
282
|
)
|
|
282
283
|
|
|
283
284
|
return {
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
CorePikkuFunctionConfig,
|
|
3
|
+
CorePikkuFunctionSessionless,
|
|
4
|
+
} from '../../function/functions.types.js'
|
|
5
|
+
import {
|
|
6
|
+
CorePikkuMiddleware,
|
|
7
|
+
MiddlewareMetadata,
|
|
8
|
+
} from '../../types/core.types.js'
|
|
3
9
|
|
|
4
10
|
export type PikkuMCP<Tools extends string = any> = {
|
|
5
11
|
// elicitInput: <Input>(message: string) => Promise<{ action: string, content: Input }>
|
|
@@ -15,10 +21,11 @@ export type PikkuMCP<Tools extends string = any> = {
|
|
|
15
21
|
*/
|
|
16
22
|
export type MCPResourceMeta = Record<
|
|
17
23
|
string,
|
|
18
|
-
Omit<CoreMCPResource, 'func'> & {
|
|
24
|
+
Omit<CoreMCPResource, 'func' | 'middleware'> & {
|
|
19
25
|
pikkuFuncName: string
|
|
20
26
|
inputSchema: string | null
|
|
21
27
|
outputSchema: string | null
|
|
28
|
+
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
22
29
|
}
|
|
23
30
|
>
|
|
24
31
|
|
|
@@ -27,10 +34,11 @@ export type MCPResourceMeta = Record<
|
|
|
27
34
|
*/
|
|
28
35
|
export type MCPToolMeta = Record<
|
|
29
36
|
string,
|
|
30
|
-
Omit<CoreMCPTool, 'func'> & {
|
|
37
|
+
Omit<CoreMCPTool, 'func' | 'middleware'> & {
|
|
31
38
|
pikkuFuncName: string
|
|
32
39
|
inputSchema: string | null
|
|
33
40
|
outputSchema: string | null
|
|
41
|
+
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
34
42
|
}
|
|
35
43
|
>
|
|
36
44
|
|
|
@@ -39,7 +47,7 @@ export type MCPToolMeta = Record<
|
|
|
39
47
|
*/
|
|
40
48
|
export type MCPPromptMeta = Record<
|
|
41
49
|
string,
|
|
42
|
-
Omit<CoreMCPPrompt, 'func'> & {
|
|
50
|
+
Omit<CoreMCPPrompt, 'func' | 'middleware'> & {
|
|
43
51
|
pikkuFuncName: string
|
|
44
52
|
inputSchema: string | null
|
|
45
53
|
outputSchema: string | null
|
|
@@ -48,6 +56,7 @@ export type MCPPromptMeta = Record<
|
|
|
48
56
|
description: string
|
|
49
57
|
required: boolean
|
|
50
58
|
}>
|
|
59
|
+
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
51
60
|
}
|
|
52
61
|
>
|
|
53
62
|
|
|
@@ -55,7 +64,9 @@ export type MCPPromptMeta = Record<
|
|
|
55
64
|
* Represents an MCP resource with specific properties.
|
|
56
65
|
*/
|
|
57
66
|
export type CoreMCPResource<
|
|
58
|
-
PikkuFunction =
|
|
67
|
+
PikkuFunction = CorePikkuFunctionConfig<
|
|
68
|
+
CorePikkuFunctionSessionless<any, any>
|
|
69
|
+
>,
|
|
59
70
|
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
60
71
|
> = {
|
|
61
72
|
uri: string
|
|
@@ -73,7 +84,9 @@ export type CoreMCPResource<
|
|
|
73
84
|
* Represents an MCP tool with specific properties.
|
|
74
85
|
*/
|
|
75
86
|
export type CoreMCPTool<
|
|
76
|
-
PikkuFunction =
|
|
87
|
+
PikkuFunction = CorePikkuFunctionConfig<
|
|
88
|
+
CorePikkuFunctionSessionless<any, any>
|
|
89
|
+
>,
|
|
77
90
|
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
78
91
|
> = {
|
|
79
92
|
name: string
|
|
@@ -90,7 +103,9 @@ export type CoreMCPTool<
|
|
|
90
103
|
* Represents an MCP prompt with specific properties.
|
|
91
104
|
*/
|
|
92
105
|
export type CoreMCPPrompt<
|
|
93
|
-
PikkuFunction =
|
|
106
|
+
PikkuFunction = CorePikkuFunctionConfig<
|
|
107
|
+
CorePikkuFunctionSessionless<any, MCPPromptResponse>
|
|
108
|
+
>,
|
|
94
109
|
PikkuMiddleware = CorePikkuMiddleware<any>,
|
|
95
110
|
> = {
|
|
96
111
|
name: string
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { CoreServices } from '../../types/core.types.js'
|
|
2
2
|
import type { CoreQueueWorker, QueueJob, PikkuQueue } from './queue.types.js'
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
CorePikkuFunctionConfig,
|
|
5
|
+
CorePikkuFunctionSessionless,
|
|
6
|
+
} from '../../function/functions.types.js'
|
|
4
7
|
import { getErrorResponse, PikkuError } from '../../errors/error-handler.js'
|
|
5
8
|
import { pikkuState } from '../../pikku-state.js'
|
|
6
9
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
|
|
@@ -8,7 +11,6 @@ import {
|
|
|
8
11
|
CreateSessionServices,
|
|
9
12
|
PikkuWiringTypes,
|
|
10
13
|
} from '../../types/core.types.js'
|
|
11
|
-
import { combineMiddleware, runMiddleware } from '../../middleware-runner.js'
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* Error class for queue processor not found
|
|
@@ -44,12 +46,13 @@ export class QueueJobDiscardedError extends PikkuError {
|
|
|
44
46
|
export const wireQueueWorker = <
|
|
45
47
|
InputData = any,
|
|
46
48
|
OutputData = any,
|
|
47
|
-
|
|
48
|
-
InputData,
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
50
|
+
CorePikkuFunctionSessionless<InputData, OutputData>
|
|
51
|
+
> = CorePikkuFunctionConfig<
|
|
52
|
+
CorePikkuFunctionSessionless<InputData, OutputData>
|
|
53
|
+
>,
|
|
51
54
|
>(
|
|
52
|
-
queueWorker: CoreQueueWorker<
|
|
55
|
+
queueWorker: CoreQueueWorker<PikkuFunctionConfig>
|
|
53
56
|
) => {
|
|
54
57
|
// Get processor metadata
|
|
55
58
|
const meta = pikkuState('queue', 'meta')
|
|
@@ -61,7 +64,14 @@ export const wireQueueWorker = <
|
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
// Register the function with pikku
|
|
64
|
-
addFunction(processorMeta.pikkuFuncName,
|
|
67
|
+
addFunction(processorMeta.pikkuFuncName, {
|
|
68
|
+
func: queueWorker.func.func,
|
|
69
|
+
auth: queueWorker.func.auth,
|
|
70
|
+
permissions: queueWorker.func.permissions,
|
|
71
|
+
middleware: queueWorker.func.middleware as any,
|
|
72
|
+
tags: queueWorker.func.tags,
|
|
73
|
+
docs: queueWorker.func.docs as any,
|
|
74
|
+
})
|
|
65
75
|
|
|
66
76
|
// Store processor definition in state - runtime adapters will pick this up
|
|
67
77
|
const registrations = pikkuState('queue', 'registrations')
|
|
@@ -139,51 +149,38 @@ export async function runQueueJob({
|
|
|
139
149
|
try {
|
|
140
150
|
logger.info(`Processing job ${job.id} in queue ${job.queueName}`)
|
|
141
151
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
...singletonServices,
|
|
149
|
-
...(createSessionServices
|
|
150
|
-
? createSessionServices(singletonServices, { queue }, undefined)
|
|
151
|
-
: {}),
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
// Execute the pikku function with the job data
|
|
155
|
-
result = await runPikkuFunc(
|
|
156
|
-
PikkuWiringTypes.queue,
|
|
157
|
-
job.queueName,
|
|
158
|
-
processorMeta.pikkuFuncName,
|
|
159
|
-
{
|
|
160
|
-
getAllServices,
|
|
161
|
-
data: job.data,
|
|
162
|
-
tags: queueWorker.tags,
|
|
163
|
-
}
|
|
152
|
+
// Use provided singleton services
|
|
153
|
+
const getAllServices = async () => {
|
|
154
|
+
const sessionServices = await createSessionServices?.(
|
|
155
|
+
singletonServices,
|
|
156
|
+
{ queue },
|
|
157
|
+
undefined
|
|
164
158
|
)
|
|
165
159
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
160
|
+
return {
|
|
161
|
+
...singletonServices,
|
|
162
|
+
...sessionServices,
|
|
163
|
+
}
|
|
169
164
|
}
|
|
170
165
|
|
|
171
|
-
//
|
|
172
|
-
const
|
|
173
|
-
|
|
166
|
+
// Execute the pikku function with the job data
|
|
167
|
+
const result = await runPikkuFunc(
|
|
168
|
+
PikkuWiringTypes.queue,
|
|
169
|
+
job.queueName,
|
|
170
|
+
processorMeta.pikkuFuncName,
|
|
171
|
+
{
|
|
172
|
+
singletonServices,
|
|
173
|
+
getAllServices,
|
|
174
|
+
data: () => job.data,
|
|
175
|
+
inheritedMiddleware: processorMeta.middleware,
|
|
176
|
+
wireMiddleware: queueWorker.middleware,
|
|
177
|
+
tags: queueWorker.tags,
|
|
178
|
+
interaction: { queue },
|
|
179
|
+
}
|
|
174
180
|
)
|
|
175
181
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
singletonServices,
|
|
179
|
-
{ queue },
|
|
180
|
-
combineMiddleware(PikkuWiringTypes.queue, `${job.queueName}:${job.id}`, {
|
|
181
|
-
wiringMiddleware: queueWorker.middleware,
|
|
182
|
-
wiringTags: queueWorker.tags,
|
|
183
|
-
funcMiddleware: funcConfig?.middleware,
|
|
184
|
-
funcTags: funcConfig?.tags,
|
|
185
|
-
}),
|
|
186
|
-
runMain
|
|
182
|
+
logger.debug(
|
|
183
|
+
`Successfully processed job ${job.id} in queue ${job.queueName}`
|
|
187
184
|
)
|
|
188
185
|
|
|
189
186
|
return result
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PikkuDocs,
|
|
2
|
-
import {
|
|
1
|
+
import { PikkuDocs, MiddlewareMetadata } from '../../types/core.types.js'
|
|
2
|
+
import { CorePikkuFunctionConfig } from '../../function/functions.types.js'
|
|
3
3
|
import { QueueConfigMapping } from './validate-worker-config.js'
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -158,6 +158,7 @@ export type queueWorkersMeta = Record<
|
|
|
158
158
|
docs?: PikkuDocs
|
|
159
159
|
tags?: string[]
|
|
160
160
|
config?: PikkuWorkerConfig
|
|
161
|
+
middleware?: MiddlewareMetadata[] // Pre-resolved middleware chain (tag + explicit)
|
|
161
162
|
}
|
|
162
163
|
>
|
|
163
164
|
|
|
@@ -165,16 +166,19 @@ export type queueWorkersMeta = Record<
|
|
|
165
166
|
* Core queue processor definition
|
|
166
167
|
*/
|
|
167
168
|
export type CoreQueueWorker<
|
|
168
|
-
|
|
169
|
-
|
|
169
|
+
PikkuFunctionConfig extends CorePikkuFunctionConfig<
|
|
170
|
+
any,
|
|
171
|
+
any,
|
|
172
|
+
any
|
|
173
|
+
> = CorePikkuFunctionConfig<any, any, any>,
|
|
170
174
|
> = {
|
|
171
175
|
queueName: string
|
|
172
|
-
func:
|
|
176
|
+
func: PikkuFunctionConfig
|
|
173
177
|
config?: PikkuWorkerConfig
|
|
174
178
|
docs?: PikkuDocs
|
|
175
179
|
session?: undefined
|
|
176
180
|
tags?: string[]
|
|
177
|
-
middleware?:
|
|
181
|
+
middleware?: PikkuFunctionConfig['middleware']
|
|
178
182
|
}
|
|
179
183
|
|
|
180
184
|
/**
|
package/src/wirings/rpc/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { initialize } from './rpc-runner.js'
|
|
1
|
+
export { initialize, PikkuRPCService } from './rpc-runner.js'
|
|
2
2
|
export type { PikkuRPC, RPCMeta } from './rpc-types.js'
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
CoreServices,
|
|
3
|
+
PikkuInteraction,
|
|
4
|
+
PikkuWiringTypes,
|
|
5
|
+
} from '../../types/core.types.js'
|
|
2
6
|
import { runPikkuFunc } from '../../function/function-runner.js'
|
|
3
7
|
import { pikkuState } from '../../pikku-state.js'
|
|
4
8
|
import { ForbiddenError } from '../../errors/errors.js'
|
|
9
|
+
import { PikkuRPC } from './rpc-types.js'
|
|
5
10
|
|
|
6
11
|
// Type for the RPC service configuration
|
|
7
12
|
type RPCServiceConfig = {
|
|
@@ -21,8 +26,10 @@ const getPikkuFunctionName = (rpcName: string): string => {
|
|
|
21
26
|
class ContextAwareRPCService {
|
|
22
27
|
constructor(
|
|
23
28
|
private services: CoreServices,
|
|
29
|
+
private interaction: PikkuInteraction,
|
|
24
30
|
private options: {
|
|
25
31
|
coerceDataFromSchema?: boolean
|
|
32
|
+
requiresAuth?: boolean
|
|
26
33
|
}
|
|
27
34
|
) {}
|
|
28
35
|
|
|
@@ -41,7 +48,6 @@ class ContextAwareRPCService {
|
|
|
41
48
|
funcName: string,
|
|
42
49
|
data: In
|
|
43
50
|
): Promise<Out> {
|
|
44
|
-
const session = await this.services.userSession?.get()
|
|
45
51
|
const rpcDepth = this.services.rpc?.depth || 0
|
|
46
52
|
const pikkuFuncName = getPikkuFunctionName(funcName)
|
|
47
53
|
return runPikkuFunc<In, Out>(
|
|
@@ -49,6 +55,8 @@ class ContextAwareRPCService {
|
|
|
49
55
|
pikkuFuncName,
|
|
50
56
|
pikkuFuncName,
|
|
51
57
|
{
|
|
58
|
+
auth: this.options.requiresAuth,
|
|
59
|
+
singletonServices: this.services,
|
|
52
60
|
getAllServices: () => {
|
|
53
61
|
this.services.rpc = this.services.rpc
|
|
54
62
|
? ({
|
|
@@ -59,16 +67,20 @@ class ContextAwareRPCService {
|
|
|
59
67
|
: undefined
|
|
60
68
|
return this.services
|
|
61
69
|
},
|
|
62
|
-
data,
|
|
63
|
-
|
|
70
|
+
data: () => data,
|
|
71
|
+
userSession: this.services.userSession,
|
|
64
72
|
coerceDataFromSchema: this.options.coerceDataFromSchema,
|
|
73
|
+
interaction: this.interaction,
|
|
65
74
|
}
|
|
66
75
|
)
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
// RPC Service class for the global interface
|
|
71
|
-
export class PikkuRPCService
|
|
80
|
+
export class PikkuRPCService<
|
|
81
|
+
Services extends CoreServices,
|
|
82
|
+
TypedRPC = PikkuRPC,
|
|
83
|
+
> {
|
|
72
84
|
private config?: RPCServiceConfig
|
|
73
85
|
|
|
74
86
|
// Initialize the RPC service with configuration
|
|
@@ -77,12 +89,18 @@ export class PikkuRPCService {
|
|
|
77
89
|
}
|
|
78
90
|
|
|
79
91
|
// Convenience function for initializing
|
|
80
|
-
injectRPCService(
|
|
92
|
+
injectRPCService(
|
|
93
|
+
services: Services,
|
|
94
|
+
interaction: PikkuInteraction,
|
|
95
|
+
requiresAuth?: boolean | undefined,
|
|
96
|
+
depth: number = 0
|
|
97
|
+
): Services & { rpc: TypedRPC } {
|
|
81
98
|
const serviceCopy = {
|
|
82
|
-
...
|
|
99
|
+
...services,
|
|
83
100
|
}
|
|
84
|
-
const serviceRPC = new ContextAwareRPCService(serviceCopy, {
|
|
101
|
+
const serviceRPC = new ContextAwareRPCService(serviceCopy, interaction, {
|
|
85
102
|
coerceDataFromSchema: this.config?.coerceDataFromSchema,
|
|
103
|
+
requiresAuth,
|
|
86
104
|
})
|
|
87
105
|
serviceCopy.rpc = {
|
|
88
106
|
depth,
|
|
@@ -90,7 +108,7 @@ export class PikkuRPCService {
|
|
|
90
108
|
invoke: serviceRPC.rpc.bind(serviceRPC),
|
|
91
109
|
invokeExposed: serviceRPC.rpc.bind(serviceRPC),
|
|
92
110
|
} as any
|
|
93
|
-
return serviceCopy
|
|
111
|
+
return serviceCopy as Services & { rpc: TypedRPC }
|
|
94
112
|
}
|
|
95
113
|
}
|
|
96
114
|
|