@pikku/inspector 0.7.6 → 0.8.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 +18 -0
- package/dist/add-channel.js +16 -25
- package/dist/add-http-route.js +2 -1
- package/dist/add-mcp-prompt.d.ts +3 -0
- package/dist/add-mcp-prompt.js +60 -0
- package/dist/add-mcp-resource.d.ts +3 -0
- package/dist/add-mcp-resource.js +67 -0
- package/dist/add-mcp-tool.d.ts +3 -0
- package/dist/add-mcp-tool.js +63 -0
- package/dist/add-queue-worker.d.ts +3 -0
- package/dist/add-queue-worker.js +47 -0
- package/dist/add-schedule.js +6 -8
- package/dist/inspector.js +10 -1
- package/dist/types.d.ts +13 -2
- package/dist/utils.d.ts +2 -1
- package/dist/visit.js +8 -0
- package/package.json +2 -2
- package/src/add-channel.ts +20 -32
- package/src/add-http-route.ts +8 -2
- package/src/add-mcp-prompt.ts +100 -0
- package/src/add-mcp-resource.ts +112 -0
- package/src/add-mcp-tool.ts +103 -0
- package/src/add-queue-worker.ts +88 -0
- package/src/add-schedule.ts +20 -13
- package/src/inspector.ts +10 -1
- package/src/types.ts +13 -2
- package/src/utils.ts +5 -1
- package/src/visit.ts +8 -0
- package/tsconfig.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/src/add-channel.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
2
|
import { getPropertyValue } from './get-property-value.js'
|
|
3
3
|
import { pathToRegexp } from 'path-to-regexp'
|
|
4
|
-
import { APIDocs } from '@pikku/core'
|
|
5
|
-
import { getInputTypes } from './add-http-route.js'
|
|
4
|
+
import { APIDocs, PikkuEventTypes } from '@pikku/core'
|
|
6
5
|
import {
|
|
7
6
|
extractFunctionName,
|
|
8
7
|
getPropertyAssignmentInitializer,
|
|
@@ -189,8 +188,6 @@ export function addMessagesRoutes(
|
|
|
189
188
|
if (fnMeta) {
|
|
190
189
|
result[channelKey]![routeKey] = {
|
|
191
190
|
pikkuFuncName: handlerName,
|
|
192
|
-
inputs: fnMeta.inputs ?? null,
|
|
193
|
-
outputs: fnMeta.outputs ?? null,
|
|
194
191
|
}
|
|
195
192
|
continue
|
|
196
193
|
}
|
|
@@ -208,8 +205,6 @@ export function addMessagesRoutes(
|
|
|
208
205
|
if (fnMeta) {
|
|
209
206
|
result[channelKey]![routeKey] = {
|
|
210
207
|
pikkuFuncName: handlerName,
|
|
211
|
-
inputs: fnMeta.inputs ?? null,
|
|
212
|
-
outputs: fnMeta.outputs ?? null,
|
|
213
208
|
}
|
|
214
209
|
continue
|
|
215
210
|
}
|
|
@@ -244,8 +239,6 @@ export function addMessagesRoutes(
|
|
|
244
239
|
if (fnMeta) {
|
|
245
240
|
result[channelKey]![routeKey] = {
|
|
246
241
|
pikkuFuncName: handlerName,
|
|
247
|
-
inputs: fnMeta.inputs ?? null,
|
|
248
|
-
outputs: fnMeta.outputs ?? null,
|
|
249
242
|
}
|
|
250
243
|
continue
|
|
251
244
|
}
|
|
@@ -260,8 +253,6 @@ export function addMessagesRoutes(
|
|
|
260
253
|
if (fnMeta) {
|
|
261
254
|
result[channelKey]![routeKey] = {
|
|
262
255
|
pikkuFuncName: handlerName,
|
|
263
|
-
inputs: fnMeta.inputs ?? null,
|
|
264
|
-
outputs: fnMeta.outputs ?? null,
|
|
265
256
|
}
|
|
266
257
|
continue
|
|
267
258
|
}
|
|
@@ -294,8 +285,6 @@ export function addMessagesRoutes(
|
|
|
294
285
|
}
|
|
295
286
|
result[channelKey]![routeKey] = {
|
|
296
287
|
pikkuFuncName: possibleMatch,
|
|
297
|
-
inputs: fnMeta.inputs ?? null,
|
|
298
|
-
outputs: fnMeta.outputs ?? null,
|
|
299
288
|
}
|
|
300
289
|
continue
|
|
301
290
|
}
|
|
@@ -334,8 +323,6 @@ export function addMessagesRoutes(
|
|
|
334
323
|
if (fnMeta) {
|
|
335
324
|
result[channelKey]![routeKey] = {
|
|
336
325
|
pikkuFuncName: handlerName,
|
|
337
|
-
inputs: fnMeta.inputs ?? null,
|
|
338
|
-
outputs: fnMeta.outputs ?? null,
|
|
339
326
|
}
|
|
340
327
|
continue // Skip the normal processing below
|
|
341
328
|
}
|
|
@@ -361,8 +348,6 @@ export function addMessagesRoutes(
|
|
|
361
348
|
|
|
362
349
|
result[channelKey]![routeKey] = {
|
|
363
350
|
pikkuFuncName: handlerName,
|
|
364
|
-
inputs: fnMeta.inputs ?? null,
|
|
365
|
-
outputs: fnMeta.outputs ?? null,
|
|
366
351
|
}
|
|
367
352
|
}
|
|
368
353
|
}
|
|
@@ -406,7 +391,10 @@ export function addChannel(
|
|
|
406
391
|
const tags = getPropertyValue(obj, 'tags') as string[] | undefined
|
|
407
392
|
const query = getPropertyValue(obj, 'query') as string[] | []
|
|
408
393
|
|
|
409
|
-
if (
|
|
394
|
+
if (
|
|
395
|
+
!matchesFilters(filters, { tags }, { type: PikkuEventTypes.channel, name })
|
|
396
|
+
)
|
|
397
|
+
return
|
|
410
398
|
|
|
411
399
|
const connect = getPropertyAssignmentInitializer(
|
|
412
400
|
obj,
|
|
@@ -429,6 +417,7 @@ export function addChannel(
|
|
|
429
417
|
false,
|
|
430
418
|
checker
|
|
431
419
|
)
|
|
420
|
+
|
|
432
421
|
if (onMsgProp) {
|
|
433
422
|
const handlerName =
|
|
434
423
|
onMsgProp && getHandlerNameFromExpression(onMsgProp, checker)
|
|
@@ -442,8 +431,6 @@ export function addChannel(
|
|
|
442
431
|
message = {
|
|
443
432
|
pikkuFuncName: extractFunctionName(onMsgProp as any, checker)
|
|
444
433
|
.pikkuFuncName,
|
|
445
|
-
inputs: fnMeta.inputs ?? null,
|
|
446
|
-
outputs: fnMeta.outputs ?? null,
|
|
447
434
|
}
|
|
448
435
|
}
|
|
449
436
|
}
|
|
@@ -459,21 +446,22 @@ export function addChannel(
|
|
|
459
446
|
input: null,
|
|
460
447
|
params: params.length ? params : undefined,
|
|
461
448
|
query: query?.length ? query : undefined,
|
|
462
|
-
inputTypes: getInputTypes(
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
),
|
|
469
|
-
|
|
470
|
-
? extractFunctionName(connect, checker).pikkuFuncName
|
|
449
|
+
// inputTypes: getInputTypes(
|
|
450
|
+
// state.channels.metaInputTypes,
|
|
451
|
+
// 'get',
|
|
452
|
+
// null, // TODO
|
|
453
|
+
// query,
|
|
454
|
+
// params
|
|
455
|
+
// ),
|
|
456
|
+
connect: connect
|
|
457
|
+
? { pikkuFuncName: extractFunctionName(connect, checker).pikkuFuncName }
|
|
471
458
|
: null,
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
459
|
+
disconnect: disconnect
|
|
460
|
+
? {
|
|
461
|
+
pikkuFuncName: extractFunctionName(disconnect as any, checker)
|
|
462
|
+
.pikkuFuncName,
|
|
463
|
+
}
|
|
475
464
|
: null,
|
|
476
|
-
disconnect: !!disconnect,
|
|
477
465
|
message,
|
|
478
466
|
messageRoutes,
|
|
479
467
|
docs: docs ?? undefined,
|
package/src/add-http-route.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as ts from 'typescript'
|
|
|
2
2
|
import { getPropertyValue } from './get-property-value.js'
|
|
3
3
|
import { pathToRegexp } from 'path-to-regexp'
|
|
4
4
|
import { HTTPMethod } from '@pikku/core/http'
|
|
5
|
-
import { APIDocs } from '@pikku/core'
|
|
5
|
+
import { APIDocs, PikkuEventTypes } from '@pikku/core'
|
|
6
6
|
import {
|
|
7
7
|
extractFunctionName,
|
|
8
8
|
getPropertyAssignmentInitializer,
|
|
@@ -69,7 +69,13 @@ export const addHTTPRoute = (
|
|
|
69
69
|
const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
|
|
70
70
|
const query = (getPropertyValue(obj, 'query') as string[]) || []
|
|
71
71
|
|
|
72
|
-
if (
|
|
72
|
+
if (
|
|
73
|
+
!matchesFilters(
|
|
74
|
+
filters,
|
|
75
|
+
{ tags },
|
|
76
|
+
{ type: PikkuEventTypes.http, name: route }
|
|
77
|
+
)
|
|
78
|
+
) {
|
|
73
79
|
return
|
|
74
80
|
}
|
|
75
81
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as ts from 'typescript'
|
|
2
|
+
import { getPropertyValue } from './get-property-value.js'
|
|
3
|
+
import { PikkuEventTypes } from '@pikku/core'
|
|
4
|
+
import { InspectorFilters, InspectorState } from './types.js'
|
|
5
|
+
import {
|
|
6
|
+
extractFunctionName,
|
|
7
|
+
getPropertyAssignmentInitializer,
|
|
8
|
+
matchesFilters,
|
|
9
|
+
} from './utils.js'
|
|
10
|
+
|
|
11
|
+
export const addMCPPrompt = (
|
|
12
|
+
node: ts.Node,
|
|
13
|
+
checker: ts.TypeChecker,
|
|
14
|
+
state: InspectorState,
|
|
15
|
+
filters: InspectorFilters
|
|
16
|
+
) => {
|
|
17
|
+
if (!ts.isCallExpression(node)) {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const args = node.arguments
|
|
22
|
+
const firstArg = args[0]
|
|
23
|
+
const expression = node.expression
|
|
24
|
+
|
|
25
|
+
// Check if the call is to addMCPPrompt
|
|
26
|
+
if (!ts.isIdentifier(expression) || expression.text !== 'addMCPPrompt') {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!firstArg) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
35
|
+
const obj = firstArg
|
|
36
|
+
|
|
37
|
+
const nameValue = getPropertyValue(obj, 'name') as string | null
|
|
38
|
+
const descriptionValue = getPropertyValue(obj, 'description') as
|
|
39
|
+
| string
|
|
40
|
+
| null
|
|
41
|
+
const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
|
|
42
|
+
|
|
43
|
+
const funcInitializer = getPropertyAssignmentInitializer(
|
|
44
|
+
obj,
|
|
45
|
+
'func',
|
|
46
|
+
true,
|
|
47
|
+
checker
|
|
48
|
+
)
|
|
49
|
+
if (!funcInitializer) {
|
|
50
|
+
console.error(`• No valid 'func' property for MCP prompt '${nameValue}'.`)
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const pikkuFuncName = extractFunctionName(
|
|
55
|
+
funcInitializer,
|
|
56
|
+
checker
|
|
57
|
+
).pikkuFuncName
|
|
58
|
+
|
|
59
|
+
if (!nameValue) {
|
|
60
|
+
console.error(`• MCP prompt is missing the required 'name' property.`)
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!descriptionValue) {
|
|
65
|
+
console.error(`• MCP prompt '${nameValue}' is missing a description.`)
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (
|
|
70
|
+
!matchesFilters(
|
|
71
|
+
filters,
|
|
72
|
+
{ tags },
|
|
73
|
+
{ type: PikkuEventTypes.mcp, name: nameValue }
|
|
74
|
+
)
|
|
75
|
+
) {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// lookup existing function metadata
|
|
80
|
+
const fnMeta = state.functions.meta[pikkuFuncName]
|
|
81
|
+
if (!fnMeta) {
|
|
82
|
+
console.error(`• No function metadata found for '${pikkuFuncName}'.`)
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
const inputSchema = fnMeta.inputs?.[0] || null
|
|
86
|
+
const outputSchema = fnMeta.outputs?.[0] || null
|
|
87
|
+
|
|
88
|
+
state.mcpEndpoints.files.add(node.getSourceFile().fileName)
|
|
89
|
+
|
|
90
|
+
state.mcpEndpoints.promptsMeta[nameValue] = {
|
|
91
|
+
pikkuFuncName,
|
|
92
|
+
name: nameValue,
|
|
93
|
+
description: descriptionValue,
|
|
94
|
+
tags,
|
|
95
|
+
inputSchema,
|
|
96
|
+
outputSchema,
|
|
97
|
+
arguments: [], // Will be populated by CLI during serialization
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import * as ts from 'typescript'
|
|
2
|
+
import { getPropertyValue } from './get-property-value.js'
|
|
3
|
+
import { PikkuEventTypes } from '@pikku/core'
|
|
4
|
+
import { InspectorFilters, InspectorState } from './types.js'
|
|
5
|
+
import {
|
|
6
|
+
extractFunctionName,
|
|
7
|
+
getPropertyAssignmentInitializer,
|
|
8
|
+
matchesFilters,
|
|
9
|
+
} from './utils.js'
|
|
10
|
+
|
|
11
|
+
export const addMCPResource = (
|
|
12
|
+
node: ts.Node,
|
|
13
|
+
checker: ts.TypeChecker,
|
|
14
|
+
state: InspectorState,
|
|
15
|
+
filters: InspectorFilters
|
|
16
|
+
) => {
|
|
17
|
+
if (!ts.isCallExpression(node)) {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const args = node.arguments
|
|
22
|
+
const firstArg = args[0]
|
|
23
|
+
const expression = node.expression
|
|
24
|
+
|
|
25
|
+
// Check if the call is to addMCPResource
|
|
26
|
+
if (!ts.isIdentifier(expression) || expression.text !== 'addMCPResource') {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!firstArg) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
35
|
+
const obj = firstArg
|
|
36
|
+
|
|
37
|
+
const uriValue = getPropertyValue(obj, 'uri') as string | null
|
|
38
|
+
const titleValue = getPropertyValue(obj, 'title') as string | null
|
|
39
|
+
const descriptionValue = getPropertyValue(obj, 'description') as
|
|
40
|
+
| string
|
|
41
|
+
| null
|
|
42
|
+
const streamingValue = getPropertyValue(obj, 'streaming') as boolean | null
|
|
43
|
+
const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
|
|
44
|
+
|
|
45
|
+
const funcInitializer = getPropertyAssignmentInitializer(
|
|
46
|
+
obj,
|
|
47
|
+
'func',
|
|
48
|
+
true,
|
|
49
|
+
checker
|
|
50
|
+
)
|
|
51
|
+
if (!funcInitializer) {
|
|
52
|
+
console.error(
|
|
53
|
+
`• No valid 'func' property for MCP resource '${uriValue}'.`
|
|
54
|
+
)
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const pikkuFuncName = extractFunctionName(
|
|
59
|
+
funcInitializer,
|
|
60
|
+
checker
|
|
61
|
+
).pikkuFuncName
|
|
62
|
+
|
|
63
|
+
if (!uriValue) {
|
|
64
|
+
console.error(`• MCP resource is missing the required 'uri' property.`)
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!titleValue) {
|
|
69
|
+
console.error(
|
|
70
|
+
`• MCP resource '${uriValue}' is missing the required 'title' property.`
|
|
71
|
+
)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!descriptionValue) {
|
|
76
|
+
console.error(`• MCP resource '${uriValue}' is missing a description.`)
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (
|
|
81
|
+
!matchesFilters(
|
|
82
|
+
filters,
|
|
83
|
+
{ tags },
|
|
84
|
+
{ type: PikkuEventTypes.mcp, name: uriValue }
|
|
85
|
+
)
|
|
86
|
+
) {
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// lookup existing function metadata
|
|
91
|
+
const fnMeta = state.functions.meta[pikkuFuncName]
|
|
92
|
+
if (!fnMeta) {
|
|
93
|
+
console.error(`• No function metadata found for '${pikkuFuncName}'.`)
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
const inputSchema = fnMeta.inputs?.[0] || null
|
|
97
|
+
const outputSchema = fnMeta.outputs?.[0] || null
|
|
98
|
+
|
|
99
|
+
state.mcpEndpoints.files.add(node.getSourceFile().fileName)
|
|
100
|
+
|
|
101
|
+
state.mcpEndpoints.resourcesMeta[uriValue] = {
|
|
102
|
+
pikkuFuncName,
|
|
103
|
+
uri: uriValue,
|
|
104
|
+
title: titleValue,
|
|
105
|
+
description: descriptionValue,
|
|
106
|
+
...(streamingValue !== null && { streaming: streamingValue }),
|
|
107
|
+
tags,
|
|
108
|
+
inputSchema,
|
|
109
|
+
outputSchema,
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import * as ts from 'typescript'
|
|
2
|
+
import { getPropertyValue } from './get-property-value.js'
|
|
3
|
+
import { PikkuEventTypes } from '@pikku/core'
|
|
4
|
+
import { InspectorFilters, InspectorState } from './types.js'
|
|
5
|
+
import {
|
|
6
|
+
extractFunctionName,
|
|
7
|
+
getPropertyAssignmentInitializer,
|
|
8
|
+
matchesFilters,
|
|
9
|
+
} from './utils.js'
|
|
10
|
+
|
|
11
|
+
export const addMCPTool = (
|
|
12
|
+
node: ts.Node,
|
|
13
|
+
checker: ts.TypeChecker,
|
|
14
|
+
state: InspectorState,
|
|
15
|
+
filters: InspectorFilters
|
|
16
|
+
) => {
|
|
17
|
+
if (!ts.isCallExpression(node)) {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const args = node.arguments
|
|
22
|
+
const firstArg = args[0]
|
|
23
|
+
const expression = node.expression
|
|
24
|
+
|
|
25
|
+
// Check if the call is to addMCPTool
|
|
26
|
+
if (!ts.isIdentifier(expression) || expression.text !== 'addMCPTool') {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!firstArg) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
35
|
+
const obj = firstArg
|
|
36
|
+
|
|
37
|
+
const nameValue = getPropertyValue(obj, 'name') as string | null
|
|
38
|
+
const titleValue = getPropertyValue(obj, 'title') as string | null
|
|
39
|
+
const descriptionValue = getPropertyValue(obj, 'description') as
|
|
40
|
+
| string
|
|
41
|
+
| null
|
|
42
|
+
const streamingValue = getPropertyValue(obj, 'streaming') as boolean | null
|
|
43
|
+
const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
|
|
44
|
+
|
|
45
|
+
const funcInitializer = getPropertyAssignmentInitializer(
|
|
46
|
+
obj,
|
|
47
|
+
'func',
|
|
48
|
+
true,
|
|
49
|
+
checker
|
|
50
|
+
)
|
|
51
|
+
if (!funcInitializer) {
|
|
52
|
+
console.error(`• No valid 'func' property for MCP tool '${nameValue}'.`)
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const pikkuFuncName = extractFunctionName(
|
|
57
|
+
funcInitializer,
|
|
58
|
+
checker
|
|
59
|
+
).pikkuFuncName
|
|
60
|
+
|
|
61
|
+
if (!nameValue) {
|
|
62
|
+
console.error(`• MCP tool is missing the required 'name' property.`)
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!descriptionValue) {
|
|
67
|
+
console.error(`• MCP tool '${nameValue}' is missing a description.`)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (
|
|
72
|
+
!matchesFilters(
|
|
73
|
+
filters,
|
|
74
|
+
{ tags },
|
|
75
|
+
{ type: PikkuEventTypes.mcp, name: nameValue }
|
|
76
|
+
)
|
|
77
|
+
) {
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// lookup existing function metadata
|
|
82
|
+
const fnMeta = state.functions.meta[pikkuFuncName]
|
|
83
|
+
if (!fnMeta) {
|
|
84
|
+
console.error(`• No function metadata found for '${pikkuFuncName}'.`)
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
const inputSchema = fnMeta.inputs?.[0] || null
|
|
88
|
+
const outputSchema = fnMeta.outputs?.[0] || null
|
|
89
|
+
|
|
90
|
+
state.mcpEndpoints.files.add(node.getSourceFile().fileName)
|
|
91
|
+
|
|
92
|
+
state.mcpEndpoints.toolsMeta[nameValue] = {
|
|
93
|
+
pikkuFuncName,
|
|
94
|
+
name: nameValue,
|
|
95
|
+
title: titleValue || undefined,
|
|
96
|
+
description: descriptionValue,
|
|
97
|
+
...(streamingValue !== null && { streaming: streamingValue }),
|
|
98
|
+
tags,
|
|
99
|
+
inputSchema,
|
|
100
|
+
outputSchema,
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as ts from 'typescript'
|
|
2
|
+
import { getPropertyValue } from './get-property-value.js'
|
|
3
|
+
import { APIDocs, PikkuEventTypes } from '@pikku/core'
|
|
4
|
+
import { InspectorFilters, InspectorState } from './types.js'
|
|
5
|
+
import {
|
|
6
|
+
extractFunctionName,
|
|
7
|
+
getPropertyAssignmentInitializer,
|
|
8
|
+
matchesFilters,
|
|
9
|
+
} from './utils.js'
|
|
10
|
+
|
|
11
|
+
export const addQueueWorker = (
|
|
12
|
+
node: ts.Node,
|
|
13
|
+
checker: ts.TypeChecker,
|
|
14
|
+
state: InspectorState,
|
|
15
|
+
filters: InspectorFilters
|
|
16
|
+
) => {
|
|
17
|
+
if (!ts.isCallExpression(node)) {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const args = node.arguments
|
|
22
|
+
const firstArg = args[0]
|
|
23
|
+
const expression = node.expression
|
|
24
|
+
|
|
25
|
+
// Check if the call is to addQueueWorker
|
|
26
|
+
if (!ts.isIdentifier(expression) || expression.text !== 'addQueueWorker') {
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (!firstArg) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
35
|
+
const obj = firstArg
|
|
36
|
+
|
|
37
|
+
const queueName = getPropertyValue(obj, 'queueName') as string | null
|
|
38
|
+
const docs = (getPropertyValue(obj, 'docs') as APIDocs) || undefined
|
|
39
|
+
const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
|
|
40
|
+
|
|
41
|
+
// --- find the referenced function ---
|
|
42
|
+
const funcInitializer = getPropertyAssignmentInitializer(
|
|
43
|
+
obj,
|
|
44
|
+
'func',
|
|
45
|
+
true,
|
|
46
|
+
checker
|
|
47
|
+
)
|
|
48
|
+
if (!funcInitializer) {
|
|
49
|
+
console.error(
|
|
50
|
+
`• No valid 'func' property for queue processor '${queueName}'.`
|
|
51
|
+
)
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const pikkuFuncName = extractFunctionName(
|
|
56
|
+
funcInitializer,
|
|
57
|
+
checker
|
|
58
|
+
).pikkuFuncName
|
|
59
|
+
|
|
60
|
+
if (!queueName) {
|
|
61
|
+
console.error(
|
|
62
|
+
`• No 'queueName' provided for queue processor function '${pikkuFuncName}'.`
|
|
63
|
+
)
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (
|
|
68
|
+
!matchesFilters(
|
|
69
|
+
filters,
|
|
70
|
+
{ tags },
|
|
71
|
+
{ type: PikkuEventTypes.queue, name: queueName }
|
|
72
|
+
)
|
|
73
|
+
) {
|
|
74
|
+
console.info(
|
|
75
|
+
`• Skipping queue processor '${pikkuFuncName}' for queue '${queueName}' due to filter mismatch.`
|
|
76
|
+
)
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
state.queueWorkers.files.add(node.getSourceFile().fileName)
|
|
81
|
+
state.queueWorkers.meta[queueName] = {
|
|
82
|
+
pikkuFuncName,
|
|
83
|
+
queueName,
|
|
84
|
+
docs,
|
|
85
|
+
tags,
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
package/src/add-schedule.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import * as ts from 'typescript'
|
|
2
2
|
import { getPropertyValue } from './get-property-value.js'
|
|
3
|
-
import { APIDocs } from '@pikku/core'
|
|
3
|
+
import { APIDocs, PikkuEventTypes } from '@pikku/core'
|
|
4
4
|
import { InspectorFilters, InspectorState } from './types.js'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
extractFunctionName,
|
|
7
|
+
getPropertyAssignmentInitializer,
|
|
8
|
+
matchesFilters,
|
|
9
|
+
} from './utils.js'
|
|
6
10
|
|
|
7
11
|
export const addSchedule = (
|
|
8
12
|
node: ts.Node,
|
|
@@ -35,22 +39,21 @@ export const addSchedule = (
|
|
|
35
39
|
const docs = (getPropertyValue(obj, 'docs') as APIDocs) || undefined
|
|
36
40
|
const tags = (getPropertyValue(obj, 'tags') as string[]) || undefined
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
if (!funcProp || !ts.isIdentifier(funcProp.initializer)) {
|
|
42
|
+
const funcInitializer = getPropertyAssignmentInitializer(
|
|
43
|
+
obj,
|
|
44
|
+
'func',
|
|
45
|
+
true,
|
|
46
|
+
checker
|
|
47
|
+
)
|
|
48
|
+
if (!funcInitializer) {
|
|
47
49
|
console.error(
|
|
48
50
|
`• No valid 'func' property for scheduled task '${nameValue}'.`
|
|
49
51
|
)
|
|
50
52
|
return
|
|
51
53
|
}
|
|
54
|
+
|
|
52
55
|
const pikkuFuncName = extractFunctionName(
|
|
53
|
-
|
|
56
|
+
funcInitializer,
|
|
54
57
|
checker
|
|
55
58
|
).pikkuFuncName
|
|
56
59
|
|
|
@@ -59,7 +62,11 @@ export const addSchedule = (
|
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
if (
|
|
62
|
-
!matchesFilters(
|
|
65
|
+
!matchesFilters(
|
|
66
|
+
filters,
|
|
67
|
+
{ tags },
|
|
68
|
+
{ type: PikkuEventTypes.scheduled, name: nameValue }
|
|
69
|
+
)
|
|
63
70
|
) {
|
|
64
71
|
return
|
|
65
72
|
}
|
package/src/inspector.ts
CHANGED
|
@@ -42,7 +42,6 @@ export const inspect = (
|
|
|
42
42
|
files: new Set(),
|
|
43
43
|
},
|
|
44
44
|
channels: {
|
|
45
|
-
metaInputTypes: new Map(),
|
|
46
45
|
files: new Set(),
|
|
47
46
|
meta: {},
|
|
48
47
|
},
|
|
@@ -50,9 +49,19 @@ export const inspect = (
|
|
|
50
49
|
meta: {},
|
|
51
50
|
files: new Set(),
|
|
52
51
|
},
|
|
52
|
+
queueWorkers: {
|
|
53
|
+
meta: {},
|
|
54
|
+
files: new Set(),
|
|
55
|
+
},
|
|
53
56
|
rpc: {
|
|
54
57
|
meta: {},
|
|
55
58
|
},
|
|
59
|
+
mcpEndpoints: {
|
|
60
|
+
resourcesMeta: {},
|
|
61
|
+
toolsMeta: {},
|
|
62
|
+
promptsMeta: {},
|
|
63
|
+
files: new Set(),
|
|
64
|
+
},
|
|
56
65
|
}
|
|
57
66
|
|
|
58
67
|
// First sweep: add all functions
|
package/src/types.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { ChannelsMeta } from '@pikku/core/channel'
|
|
2
2
|
import { HTTPRoutesMeta } from '@pikku/core/http'
|
|
3
3
|
import { ScheduledTasksMeta } from '@pikku/core/scheduler'
|
|
4
|
+
import { queueWorkersMeta } from '@pikku/core/queue'
|
|
5
|
+
import { MCPResourceMeta, MCPToolMeta, MCPPromptMeta } from '@pikku/core'
|
|
4
6
|
import { TypesMap } from './types-map.js'
|
|
5
7
|
import { FunctionsMeta } from '@pikku/core'
|
|
6
|
-
import { RPCMeta } from '
|
|
8
|
+
import { RPCMeta } from '@pikku/core/rpc'
|
|
7
9
|
|
|
8
10
|
export type PathToNameAndType = Map<
|
|
9
11
|
string,
|
|
@@ -32,7 +34,6 @@ export interface InspectorFunctionState {
|
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
export interface InspectorChannelState {
|
|
35
|
-
metaInputTypes: MetaInputTypes
|
|
36
37
|
meta: ChannelsMeta
|
|
37
38
|
files: Set<string>
|
|
38
39
|
}
|
|
@@ -54,7 +55,17 @@ export interface InspectorState {
|
|
|
54
55
|
meta: ScheduledTasksMeta
|
|
55
56
|
files: Set<string>
|
|
56
57
|
}
|
|
58
|
+
queueWorkers: {
|
|
59
|
+
meta: queueWorkersMeta
|
|
60
|
+
files: Set<string>
|
|
61
|
+
}
|
|
57
62
|
rpc: {
|
|
58
63
|
meta: Record<string, RPCMeta>
|
|
59
64
|
}
|
|
65
|
+
mcpEndpoints: {
|
|
66
|
+
resourcesMeta: MCPResourceMeta
|
|
67
|
+
toolsMeta: MCPToolMeta
|
|
68
|
+
promptsMeta: MCPPromptMeta
|
|
69
|
+
files: Set<string>
|
|
70
|
+
}
|
|
60
71
|
}
|