@pikku/core 0.12.14 → 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 +30 -0
- package/dist/errors/errors.d.ts +4 -0
- package/dist/errors/errors.js +12 -0
- package/dist/function/function-runner.js +2 -1
- 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 +1 -4
- package/dist/remote.d.ts +10 -0
- package/dist/remote.js +32 -0
- package/dist/schema.js +2 -0
- 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/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/workflow-service.d.ts +6 -1
- package/dist/testing/service-tests.js +0 -8
- package/dist/types/core.types.d.ts +8 -0
- package/dist/types/state.types.d.ts +2 -2
- package/dist/wirings/ai-agent/ai-agent-prepare.js +42 -21
- package/dist/wirings/ai-agent/ai-agent-registry.js +2 -2
- package/dist/wirings/ai-agent/ai-agent-runner.js +18 -1
- package/dist/wirings/ai-agent/ai-agent-stream.js +1 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +5 -3
- package/dist/wirings/channel/channel-runner.js +3 -3
- package/dist/wirings/cli/cli-runner.js +3 -2
- 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 -11
- 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 +7 -3
- package/dist/wirings/rpc/rpc-runner.js +56 -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-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 +216 -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 +17 -1
- package/package.json +4 -1
- package/src/errors/errors.ts +12 -0
- package/src/function/function-runner.ts +5 -4
- 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 +1 -5
- package/src/remote.ts +46 -0
- package/src/schema.ts +1 -0
- 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/logger-console.ts +127 -47
- package/src/services/logger.ts +6 -0
- package/src/services/meta-service.ts +523 -0
- package/src/services/workflow-service.ts +8 -0
- package/src/testing/service-tests.ts +0 -10
- package/src/types/core.types.ts +8 -0
- package/src/types/state.types.ts +2 -2
- package/src/wirings/ai-agent/ai-agent-prepare.ts +51 -40
- package/src/wirings/ai-agent/ai-agent-registry.ts +3 -3
- package/src/wirings/ai-agent/ai-agent-runner.ts +16 -1
- package/src/wirings/ai-agent/ai-agent-stream.ts +8 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +5 -3
- 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 +4 -3
- package/src/wirings/cli/command-parser.ts +8 -3
- package/src/wirings/http/http-runner.ts +27 -11
- package/src/wirings/http/http.types.ts +2 -0
- package/src/wirings/mcp/mcp-runner.ts +7 -9
- package/src/wirings/queue/queue-runner.test.ts +5 -11
- package/src/wirings/queue/queue-runner.ts +11 -3
- package/src/wirings/rpc/rpc-runner.ts +82 -115
- 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-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 +284 -24
- package/src/wirings/workflow/workflow-queue-workers.ts +85 -0
- package/src/wirings/workflow/workflow.types.ts +16 -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
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
import { readFile, readdir } from 'node:fs/promises'
|
|
2
|
+
import { join } from 'node:path'
|
|
3
|
+
import type { JSONSchema7 } from 'json-schema'
|
|
4
|
+
import type { HTTPWiringsMeta } from '../wirings/http/http.types.js'
|
|
5
|
+
import type { ChannelsMeta } from '../wirings/channel/channel.types.js'
|
|
6
|
+
import type { ScheduledTasksMeta } from '../wirings/scheduler/scheduler.types.js'
|
|
7
|
+
import type { QueueWorkersMeta } from '../wirings/queue/queue.types.js'
|
|
8
|
+
import type { CLIMeta } from '../wirings/cli/cli.types.js'
|
|
9
|
+
import type {
|
|
10
|
+
MCPResourceMeta,
|
|
11
|
+
MCPToolMeta,
|
|
12
|
+
MCPPromptMeta,
|
|
13
|
+
} from '../wirings/mcp/mcp.types.js'
|
|
14
|
+
import type { WorkflowsMeta } from '../wirings/workflow/workflow.types.js'
|
|
15
|
+
import type {
|
|
16
|
+
TriggerMeta,
|
|
17
|
+
TriggerSourceMeta,
|
|
18
|
+
} from '../wirings/trigger/trigger.types.js'
|
|
19
|
+
import type { SecretDefinitionsMeta } from '../wirings/secret/secret.types.js'
|
|
20
|
+
import type { CredentialDefinitionsMeta } from '../wirings/credential/credential.types.js'
|
|
21
|
+
import type { VariableDefinitionsMeta } from '../wirings/variable/variable.types.js'
|
|
22
|
+
import type {
|
|
23
|
+
FunctionMeta,
|
|
24
|
+
FunctionsMeta,
|
|
25
|
+
MiddlewareMetadata,
|
|
26
|
+
PermissionMetadata,
|
|
27
|
+
} from '../types/core.types.js'
|
|
28
|
+
import type { AIAgentMeta } from '../wirings/ai-agent/ai-agent.types.js'
|
|
29
|
+
|
|
30
|
+
// Re-export core types for consumers
|
|
31
|
+
export type {
|
|
32
|
+
FunctionMeta,
|
|
33
|
+
FunctionsMeta,
|
|
34
|
+
MiddlewareMetadata as MiddlewareMeta,
|
|
35
|
+
PermissionMetadata as PermissionMeta,
|
|
36
|
+
}
|
|
37
|
+
export type AgentsMeta = AIAgentMeta
|
|
38
|
+
export type AgentMeta = AIAgentMeta[string]
|
|
39
|
+
|
|
40
|
+
export interface MCPMeta {
|
|
41
|
+
resources: MCPResourceMeta
|
|
42
|
+
tools: MCPToolMeta
|
|
43
|
+
prompts: MCPPromptMeta
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type RPCMetaRecord = Record<string, string>
|
|
47
|
+
|
|
48
|
+
export interface ServiceMeta {
|
|
49
|
+
name: string
|
|
50
|
+
summary: string
|
|
51
|
+
description: string
|
|
52
|
+
package: string
|
|
53
|
+
path: string
|
|
54
|
+
version: string
|
|
55
|
+
interface: string
|
|
56
|
+
expandedProperties: Record<string, string>
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type ServicesMetaRecord = Record<string, ServiceMeta>
|
|
60
|
+
|
|
61
|
+
export interface MiddlewareDefinitionMeta {
|
|
62
|
+
services: { optimized: boolean; services: string[] }
|
|
63
|
+
sourceFile: string
|
|
64
|
+
position: number
|
|
65
|
+
exportedName: string | null
|
|
66
|
+
factory?: boolean
|
|
67
|
+
name?: string
|
|
68
|
+
description?: string
|
|
69
|
+
package?: string
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface MiddlewareInstanceMeta {
|
|
73
|
+
definitionId: string
|
|
74
|
+
sourceFile: string
|
|
75
|
+
position: number
|
|
76
|
+
isFactoryCall: boolean
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface GroupMeta {
|
|
80
|
+
exportName: string | null
|
|
81
|
+
sourceFile: string
|
|
82
|
+
position: number
|
|
83
|
+
services: { optimized: boolean; services: string[] }
|
|
84
|
+
count: number
|
|
85
|
+
instanceIds: string[]
|
|
86
|
+
isFactory: boolean
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface MiddlewareGroupsMeta {
|
|
90
|
+
definitions: Record<string, MiddlewareDefinitionMeta>
|
|
91
|
+
instances: Record<string, MiddlewareInstanceMeta>
|
|
92
|
+
httpGroups: Record<string, GroupMeta>
|
|
93
|
+
tagGroups: Record<string, GroupMeta>
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface PermissionDefinitionMeta {
|
|
97
|
+
services: { optimized: boolean; services: string[] }
|
|
98
|
+
sourceFile: string
|
|
99
|
+
position: number
|
|
100
|
+
exportedName: string | null
|
|
101
|
+
factory?: boolean
|
|
102
|
+
name?: string
|
|
103
|
+
description?: string
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface PermissionsGroupsMeta {
|
|
107
|
+
definitions: Record<string, PermissionDefinitionMeta>
|
|
108
|
+
httpGroups: Record<string, GroupMeta>
|
|
109
|
+
tagGroups: Record<string, GroupMeta>
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Abstraction over .pikku metadata file access.
|
|
114
|
+
* All paths are relative to the .pikku root directory.
|
|
115
|
+
*
|
|
116
|
+
* Node.js uses LocalMetaService (filesystem).
|
|
117
|
+
* Cloudflare uses an R2/KV implementation.
|
|
118
|
+
*/
|
|
119
|
+
export interface MetaService {
|
|
120
|
+
/** Base path for local filesystem implementations. Undefined for remote/non-local implementations. */
|
|
121
|
+
readonly basePath?: string
|
|
122
|
+
/** Read a file's content by relative path. Returns null if not found. */
|
|
123
|
+
readFile(relativePath: string): Promise<string | null>
|
|
124
|
+
/** List files in a directory by relative path. Returns empty array if not found. */
|
|
125
|
+
readDir(relativePath: string): Promise<string[]>
|
|
126
|
+
|
|
127
|
+
// -- Typed metadata accessors --
|
|
128
|
+
|
|
129
|
+
getHttpMeta(): Promise<HTTPWiringsMeta>
|
|
130
|
+
getChannelsMeta(): Promise<ChannelsMeta>
|
|
131
|
+
getSchedulerMeta(): Promise<ScheduledTasksMeta>
|
|
132
|
+
getQueueMeta(): Promise<QueueWorkersMeta>
|
|
133
|
+
getCliMeta(): Promise<CLIMeta>
|
|
134
|
+
getMcpMeta(): Promise<MCPMeta>
|
|
135
|
+
getRpcMeta(): Promise<RPCMetaRecord>
|
|
136
|
+
getWorkflowMeta(): Promise<WorkflowsMeta>
|
|
137
|
+
getTriggerMeta(): Promise<TriggerMeta>
|
|
138
|
+
getTriggerSourceMeta(): Promise<TriggerSourceMeta>
|
|
139
|
+
getFunctionsMeta(): Promise<FunctionsMeta>
|
|
140
|
+
getMiddlewareGroupsMeta(): Promise<MiddlewareGroupsMeta>
|
|
141
|
+
getPermissionsGroupsMeta(): Promise<PermissionsGroupsMeta>
|
|
142
|
+
getAgentsMeta(): Promise<AgentsMeta>
|
|
143
|
+
getSecretsMeta(): Promise<SecretDefinitionsMeta>
|
|
144
|
+
getCredentialsMeta(): Promise<CredentialDefinitionsMeta>
|
|
145
|
+
getVariablesMeta(): Promise<VariableDefinitionsMeta>
|
|
146
|
+
getServicesMeta(): Promise<ServicesMetaRecord>
|
|
147
|
+
|
|
148
|
+
getSchema(schemaName: string): Promise<JSONSchema7 | null>
|
|
149
|
+
getSchemas(schemaNames: string[]): Promise<Record<string, JSONSchema7 | null>>
|
|
150
|
+
|
|
151
|
+
clearCache(): void
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Node.js filesystem implementation of MetaService.
|
|
156
|
+
* Reads .gen.json files from a local .pikku directory.
|
|
157
|
+
*/
|
|
158
|
+
export class LocalMetaService implements MetaService {
|
|
159
|
+
public readonly basePath: string
|
|
160
|
+
|
|
161
|
+
private httpMetaCache: HTTPWiringsMeta | null = null
|
|
162
|
+
private channelsMetaCache: ChannelsMeta | null = null
|
|
163
|
+
private schedulerMetaCache: ScheduledTasksMeta | null = null
|
|
164
|
+
private queueMetaCache: QueueWorkersMeta | null = null
|
|
165
|
+
private cliMetaCache: CLIMeta | null = null
|
|
166
|
+
private mcpMetaCache: MCPMeta | null = null
|
|
167
|
+
private rpcMetaCache: RPCMetaRecord | null = null
|
|
168
|
+
private workflowMetaCache: WorkflowsMeta | null = null
|
|
169
|
+
private triggerMetaCache: TriggerMeta | null = null
|
|
170
|
+
private triggerSourceMetaCache: TriggerSourceMeta | null = null
|
|
171
|
+
private functionsMetaCache: FunctionsMeta | null = null
|
|
172
|
+
private servicesMetaCache: ServicesMetaRecord | null = null
|
|
173
|
+
private secretsMetaCache: SecretDefinitionsMeta | null = null
|
|
174
|
+
private credentialsMetaCache: CredentialDefinitionsMeta | null = null
|
|
175
|
+
private variablesMetaCache: VariableDefinitionsMeta | null = null
|
|
176
|
+
private middlewareGroupsMetaCache: MiddlewareGroupsMeta | null = null
|
|
177
|
+
private permissionsGroupsMetaCache: PermissionsGroupsMeta | null = null
|
|
178
|
+
private agentsMetaCache: AgentsMeta | null = null
|
|
179
|
+
private schemaCache = new Map<string, JSONSchema7>()
|
|
180
|
+
|
|
181
|
+
constructor(basePath: string) {
|
|
182
|
+
this.basePath = basePath
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async readFile(relativePath: string): Promise<string | null> {
|
|
186
|
+
try {
|
|
187
|
+
return await readFile(join(this.basePath, relativePath), 'utf-8')
|
|
188
|
+
} catch {
|
|
189
|
+
return null
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async readDir(relativePath: string): Promise<string[]> {
|
|
194
|
+
try {
|
|
195
|
+
return await readdir(join(this.basePath, relativePath))
|
|
196
|
+
} catch {
|
|
197
|
+
return []
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
clearCache(): void {
|
|
202
|
+
this.httpMetaCache = null
|
|
203
|
+
this.channelsMetaCache = null
|
|
204
|
+
this.schedulerMetaCache = null
|
|
205
|
+
this.queueMetaCache = null
|
|
206
|
+
this.cliMetaCache = null
|
|
207
|
+
this.mcpMetaCache = null
|
|
208
|
+
this.rpcMetaCache = null
|
|
209
|
+
this.workflowMetaCache = null
|
|
210
|
+
this.triggerMetaCache = null
|
|
211
|
+
this.triggerSourceMetaCache = null
|
|
212
|
+
this.functionsMetaCache = null
|
|
213
|
+
this.servicesMetaCache = null
|
|
214
|
+
this.secretsMetaCache = null
|
|
215
|
+
this.credentialsMetaCache = null
|
|
216
|
+
this.variablesMetaCache = null
|
|
217
|
+
this.middlewareGroupsMetaCache = null
|
|
218
|
+
this.permissionsGroupsMetaCache = null
|
|
219
|
+
this.agentsMetaCache = null
|
|
220
|
+
this.schemaCache.clear()
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// -- Private helpers --
|
|
224
|
+
|
|
225
|
+
private async readMetaJson<T>(
|
|
226
|
+
dir: string,
|
|
227
|
+
baseName: string
|
|
228
|
+
): Promise<string | null> {
|
|
229
|
+
const verbose = await this.readFile(`${dir}/${baseName}-verbose.gen.json`)
|
|
230
|
+
if (verbose) return verbose
|
|
231
|
+
const minimal = await this.readFile(`${dir}/${baseName}.gen.json`)
|
|
232
|
+
if (minimal) return minimal
|
|
233
|
+
return null
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// -- Typed metadata accessors --
|
|
237
|
+
|
|
238
|
+
async getHttpMeta(): Promise<HTTPWiringsMeta> {
|
|
239
|
+
if (this.httpMetaCache) return this.httpMetaCache
|
|
240
|
+
|
|
241
|
+
const content = await this.readMetaJson('http', 'pikku-http-wirings-meta')
|
|
242
|
+
this.httpMetaCache = content
|
|
243
|
+
? JSON.parse(content)
|
|
244
|
+
: {
|
|
245
|
+
get: {},
|
|
246
|
+
post: {},
|
|
247
|
+
put: {},
|
|
248
|
+
delete: {},
|
|
249
|
+
patch: {},
|
|
250
|
+
head: {},
|
|
251
|
+
options: {},
|
|
252
|
+
}
|
|
253
|
+
return this.httpMetaCache!
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async getChannelsMeta(): Promise<ChannelsMeta> {
|
|
257
|
+
if (this.channelsMetaCache) return this.channelsMetaCache
|
|
258
|
+
|
|
259
|
+
const content = await this.readMetaJson('channel', 'pikku-channels-meta')
|
|
260
|
+
this.channelsMetaCache = content ? JSON.parse(content) : {}
|
|
261
|
+
return this.channelsMetaCache!
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
async getSchedulerMeta(): Promise<ScheduledTasksMeta> {
|
|
265
|
+
if (this.schedulerMetaCache) return this.schedulerMetaCache
|
|
266
|
+
|
|
267
|
+
const content = await this.readMetaJson(
|
|
268
|
+
'scheduler',
|
|
269
|
+
'pikku-schedulers-wirings-meta'
|
|
270
|
+
)
|
|
271
|
+
this.schedulerMetaCache = content ? JSON.parse(content) : {}
|
|
272
|
+
return this.schedulerMetaCache!
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async getQueueMeta(): Promise<QueueWorkersMeta> {
|
|
276
|
+
if (this.queueMetaCache) return this.queueMetaCache
|
|
277
|
+
|
|
278
|
+
const content = await this.readMetaJson(
|
|
279
|
+
'queue',
|
|
280
|
+
'pikku-queue-workers-wirings-meta'
|
|
281
|
+
)
|
|
282
|
+
this.queueMetaCache = content ? JSON.parse(content) : {}
|
|
283
|
+
return this.queueMetaCache!
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
async getCliMeta(): Promise<CLIMeta> {
|
|
287
|
+
if (this.cliMetaCache) return this.cliMetaCache
|
|
288
|
+
|
|
289
|
+
const content = await this.readMetaJson('cli', 'pikku-cli-wirings-meta')
|
|
290
|
+
this.cliMetaCache = content
|
|
291
|
+
? JSON.parse(content)
|
|
292
|
+
: { programs: {}, renderers: {} }
|
|
293
|
+
return this.cliMetaCache!
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
async getMcpMeta(): Promise<MCPMeta> {
|
|
297
|
+
if (this.mcpMetaCache) return this.mcpMetaCache
|
|
298
|
+
|
|
299
|
+
const content = await this.readMetaJson('mcp', 'pikku-mcp-wirings-meta')
|
|
300
|
+
if (content) {
|
|
301
|
+
const mcpData = JSON.parse(content)
|
|
302
|
+
this.mcpMetaCache = {
|
|
303
|
+
resources: mcpData.resourcesMeta || {},
|
|
304
|
+
tools: mcpData.toolsMeta || {},
|
|
305
|
+
prompts: mcpData.promptsMeta || {},
|
|
306
|
+
}
|
|
307
|
+
} else {
|
|
308
|
+
this.mcpMetaCache = { resources: {}, tools: {}, prompts: {} }
|
|
309
|
+
}
|
|
310
|
+
return this.mcpMetaCache!
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
async getRpcMeta(): Promise<RPCMetaRecord> {
|
|
314
|
+
if (this.rpcMetaCache) return this.rpcMetaCache
|
|
315
|
+
|
|
316
|
+
try {
|
|
317
|
+
const content = await this.readFile('rpc/pikku-rpc-wirings-meta.gen.json')
|
|
318
|
+
this.rpcMetaCache = content ? JSON.parse(content) : {}
|
|
319
|
+
return this.rpcMetaCache!
|
|
320
|
+
} catch (error) {
|
|
321
|
+
console.error('Error reading RPC wirings metadata:', error)
|
|
322
|
+
this.rpcMetaCache = {}
|
|
323
|
+
return this.rpcMetaCache
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
async getWorkflowMeta(): Promise<WorkflowsMeta> {
|
|
328
|
+
if (this.workflowMetaCache) return this.workflowMetaCache
|
|
329
|
+
|
|
330
|
+
try {
|
|
331
|
+
const files = await this.readDir('workflow/meta')
|
|
332
|
+
const jsonFiles = files.filter((f) => f.endsWith('.gen.json'))
|
|
333
|
+
const verboseFiles = jsonFiles.filter((f) => f.includes('-verbose'))
|
|
334
|
+
const minimalFiles = jsonFiles.filter((f) => !f.includes('-verbose'))
|
|
335
|
+
const verboseNames = new Set(
|
|
336
|
+
verboseFiles.map((f) => f.replace('-verbose.gen.json', ''))
|
|
337
|
+
)
|
|
338
|
+
const filesToRead = [
|
|
339
|
+
...verboseFiles,
|
|
340
|
+
...minimalFiles.filter(
|
|
341
|
+
(f) => !verboseNames.has(f.replace('.gen.json', ''))
|
|
342
|
+
),
|
|
343
|
+
]
|
|
344
|
+
|
|
345
|
+
const result: WorkflowsMeta = {}
|
|
346
|
+
await Promise.all(
|
|
347
|
+
filesToRead.map(async (file) => {
|
|
348
|
+
const content = await this.readFile(`workflow/meta/${file}`)
|
|
349
|
+
if (content) {
|
|
350
|
+
const meta = JSON.parse(content)
|
|
351
|
+
result[meta.name] = meta
|
|
352
|
+
}
|
|
353
|
+
})
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
this.workflowMetaCache = result
|
|
357
|
+
return this.workflowMetaCache
|
|
358
|
+
} catch (error) {
|
|
359
|
+
console.error('Error reading Workflow wirings metadata:', error)
|
|
360
|
+
this.workflowMetaCache = {}
|
|
361
|
+
return this.workflowMetaCache
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
async getTriggerMeta(): Promise<TriggerMeta> {
|
|
366
|
+
if (this.triggerMetaCache) return this.triggerMetaCache
|
|
367
|
+
|
|
368
|
+
const content = await this.readMetaJson(
|
|
369
|
+
'trigger',
|
|
370
|
+
'pikku-trigger-wirings-meta'
|
|
371
|
+
)
|
|
372
|
+
this.triggerMetaCache = content ? JSON.parse(content) : {}
|
|
373
|
+
return this.triggerMetaCache!
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
async getTriggerSourceMeta(): Promise<TriggerSourceMeta> {
|
|
377
|
+
if (this.triggerSourceMetaCache) return this.triggerSourceMetaCache
|
|
378
|
+
|
|
379
|
+
const content = await this.readMetaJson(
|
|
380
|
+
'trigger',
|
|
381
|
+
'pikku-trigger-sources-meta'
|
|
382
|
+
)
|
|
383
|
+
this.triggerSourceMetaCache = content ? JSON.parse(content) : {}
|
|
384
|
+
return this.triggerSourceMetaCache!
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async getFunctionsMeta(): Promise<FunctionsMeta> {
|
|
388
|
+
if (this.functionsMetaCache) return this.functionsMetaCache
|
|
389
|
+
|
|
390
|
+
const content = await this.readMetaJson('function', 'pikku-functions-meta')
|
|
391
|
+
this.functionsMetaCache = content ? JSON.parse(content) : {}
|
|
392
|
+
return this.functionsMetaCache!
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
async getMiddlewareGroupsMeta(): Promise<MiddlewareGroupsMeta> {
|
|
396
|
+
if (this.middlewareGroupsMetaCache) return this.middlewareGroupsMetaCache
|
|
397
|
+
|
|
398
|
+
const content = await this.readMetaJson(
|
|
399
|
+
'middleware',
|
|
400
|
+
'pikku-middleware-groups-meta'
|
|
401
|
+
)
|
|
402
|
+
this.middlewareGroupsMetaCache = content
|
|
403
|
+
? JSON.parse(content)
|
|
404
|
+
: { definitions: {}, instances: {}, httpGroups: {}, tagGroups: {} }
|
|
405
|
+
return this.middlewareGroupsMetaCache!
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
async getPermissionsGroupsMeta(): Promise<PermissionsGroupsMeta> {
|
|
409
|
+
if (this.permissionsGroupsMetaCache) return this.permissionsGroupsMetaCache
|
|
410
|
+
|
|
411
|
+
const content = await this.readMetaJson(
|
|
412
|
+
'permissions',
|
|
413
|
+
'pikku-permissions-groups-meta'
|
|
414
|
+
)
|
|
415
|
+
this.permissionsGroupsMetaCache = content
|
|
416
|
+
? JSON.parse(content)
|
|
417
|
+
: { definitions: {}, httpGroups: {}, tagGroups: {} }
|
|
418
|
+
return this.permissionsGroupsMetaCache!
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
async getAgentsMeta(): Promise<AgentsMeta> {
|
|
422
|
+
if (this.agentsMetaCache) return this.agentsMetaCache
|
|
423
|
+
|
|
424
|
+
const content = await this.readMetaJson('agent', 'pikku-agent-wirings-meta')
|
|
425
|
+
if (content) {
|
|
426
|
+
const parsed = JSON.parse(content)
|
|
427
|
+
this.agentsMetaCache = parsed.agentsMeta || parsed
|
|
428
|
+
} else {
|
|
429
|
+
this.agentsMetaCache = {}
|
|
430
|
+
}
|
|
431
|
+
return this.agentsMetaCache!
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
async getSecretsMeta(): Promise<SecretDefinitionsMeta> {
|
|
435
|
+
if (this.secretsMetaCache) return this.secretsMetaCache
|
|
436
|
+
|
|
437
|
+
const content = await this.readFile('secrets/pikku-secrets-meta.gen.json')
|
|
438
|
+
this.secretsMetaCache = content ? JSON.parse(content) : {}
|
|
439
|
+
return this.secretsMetaCache!
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
async getCredentialsMeta(): Promise<CredentialDefinitionsMeta> {
|
|
443
|
+
if (this.credentialsMetaCache) return this.credentialsMetaCache
|
|
444
|
+
|
|
445
|
+
const content = await this.readFile(
|
|
446
|
+
'credentials/pikku-credentials-meta.gen.json'
|
|
447
|
+
)
|
|
448
|
+
this.credentialsMetaCache = content ? JSON.parse(content) : {}
|
|
449
|
+
return this.credentialsMetaCache!
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
async getVariablesMeta(): Promise<VariableDefinitionsMeta> {
|
|
453
|
+
if (this.variablesMetaCache) return this.variablesMetaCache
|
|
454
|
+
|
|
455
|
+
const content = await this.readFile(
|
|
456
|
+
'variables/pikku-variables-meta.gen.json'
|
|
457
|
+
)
|
|
458
|
+
this.variablesMetaCache = content ? JSON.parse(content) : {}
|
|
459
|
+
return this.variablesMetaCache!
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
async getServicesMeta(): Promise<ServicesMetaRecord> {
|
|
463
|
+
if (this.servicesMetaCache) return this.servicesMetaCache
|
|
464
|
+
|
|
465
|
+
try {
|
|
466
|
+
const files = await this.readDir('services')
|
|
467
|
+
const jsonFiles = files.filter((f) => f.endsWith('.gen.json'))
|
|
468
|
+
|
|
469
|
+
const result: ServicesMetaRecord = {}
|
|
470
|
+
await Promise.all(
|
|
471
|
+
jsonFiles.map(async (file) => {
|
|
472
|
+
const content = await this.readFile(`services/${file}`)
|
|
473
|
+
if (content) {
|
|
474
|
+
const meta: ServiceMeta = JSON.parse(content)
|
|
475
|
+
result[meta.name] = meta
|
|
476
|
+
}
|
|
477
|
+
})
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
this.servicesMetaCache = result
|
|
481
|
+
return this.servicesMetaCache
|
|
482
|
+
} catch (error) {
|
|
483
|
+
console.error('Error reading Services metadata:', error)
|
|
484
|
+
this.servicesMetaCache = {}
|
|
485
|
+
return this.servicesMetaCache
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
async getSchema(schemaName: string): Promise<JSONSchema7 | null> {
|
|
490
|
+
if (this.schemaCache.has(schemaName)) {
|
|
491
|
+
return this.schemaCache.get(schemaName)!
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (!/^[a-zA-Z0-9_\-\.]+$/.test(schemaName)) {
|
|
495
|
+
return null
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
try {
|
|
499
|
+
const content = await this.readFile(
|
|
500
|
+
`schemas/schemas/${schemaName}.schema.json`
|
|
501
|
+
)
|
|
502
|
+
if (!content) return null
|
|
503
|
+
const schema = JSON.parse(content) as JSONSchema7
|
|
504
|
+
this.schemaCache.set(schemaName, schema)
|
|
505
|
+
return schema
|
|
506
|
+
} catch (error) {
|
|
507
|
+
console.error(`Error reading schema ${schemaName}:`, error)
|
|
508
|
+
return null
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
async getSchemas(
|
|
513
|
+
schemaNames: string[]
|
|
514
|
+
): Promise<Record<string, JSONSchema7 | null>> {
|
|
515
|
+
const results: Record<string, JSONSchema7 | null> = {}
|
|
516
|
+
await Promise.all(
|
|
517
|
+
schemaNames.map(async (name) => {
|
|
518
|
+
results[name] = await this.getSchema(name)
|
|
519
|
+
})
|
|
520
|
+
)
|
|
521
|
+
return results
|
|
522
|
+
}
|
|
523
|
+
}
|
|
@@ -2,6 +2,7 @@ import type { SerializedError } from '../types/core.types.js'
|
|
|
2
2
|
import type {
|
|
3
3
|
WorkflowRun,
|
|
4
4
|
WorkflowRunWire,
|
|
5
|
+
WorkflowRunStatus,
|
|
5
6
|
StepState,
|
|
6
7
|
WorkflowStatus,
|
|
7
8
|
WorkflowVersionStatus,
|
|
@@ -21,6 +22,7 @@ export interface WorkflowService {
|
|
|
21
22
|
wire: WorkflowRunWire
|
|
22
23
|
): Promise<string>
|
|
23
24
|
getRun(id: string): Promise<WorkflowRun | null>
|
|
25
|
+
getRunStatus(id: string): Promise<WorkflowRunStatus | null>
|
|
24
26
|
getRunHistory(runId: string): Promise<Array<StepState & { stepName: string }>>
|
|
25
27
|
updateRunStatus(
|
|
26
28
|
id: string,
|
|
@@ -40,6 +42,12 @@ export interface WorkflowService {
|
|
|
40
42
|
rpcService: any,
|
|
41
43
|
options?: { inline?: boolean; startNode?: string }
|
|
42
44
|
): Promise<{ runId: string }>
|
|
45
|
+
runToCompletion<I>(
|
|
46
|
+
name: string,
|
|
47
|
+
input: I,
|
|
48
|
+
rpcService: any,
|
|
49
|
+
options?: { pollIntervalMs?: number; wire?: WorkflowRunWire }
|
|
50
|
+
): Promise<unknown>
|
|
43
51
|
runWorkflowJob(runId: string, rpcService: any): Promise<void>
|
|
44
52
|
orchestrateWorkflow(runId: string, rpcService: any): Promise<void>
|
|
45
53
|
executeWorkflowSleepCompleted(runId: string, stepId: string): Promise<void>
|
|
@@ -735,16 +735,6 @@ export function defineServiceTests(config: ServiceTestConfig): void {
|
|
|
735
735
|
endpoint: 'http://localhost:3000',
|
|
736
736
|
functions: ['funcA', 'funcB'],
|
|
737
737
|
})
|
|
738
|
-
|
|
739
|
-
const infos = await service.findFunction('funcA')
|
|
740
|
-
assert.ok(infos.length >= 1)
|
|
741
|
-
assert.equal(infos[0]!.deploymentId, 'deploy-1')
|
|
742
|
-
assert.equal(infos[0]!.endpoint, 'http://localhost:3000')
|
|
743
|
-
})
|
|
744
|
-
|
|
745
|
-
test('findFunction returns empty for unknown function', async () => {
|
|
746
|
-
const infos = await service.findFunction('unknown-func')
|
|
747
|
-
assert.deepEqual(infos, [])
|
|
748
738
|
})
|
|
749
739
|
})
|
|
750
740
|
}
|
package/src/types/core.types.ts
CHANGED
|
@@ -34,6 +34,7 @@ import type { AgentRunService } from '../wirings/ai-agent/ai-agent.types.js'
|
|
|
34
34
|
import type { PikkuAIMiddlewareHooks } from '../wirings/ai-agent/ai-agent.types.js'
|
|
35
35
|
import type { WorkflowRunService } from '../wirings/workflow/workflow.types.js'
|
|
36
36
|
import type { CredentialService } from '../services/credential-service.js'
|
|
37
|
+
import type { MetaService } from '../services/meta-service.js'
|
|
37
38
|
|
|
38
39
|
export type PikkuWiringTypes =
|
|
39
40
|
| 'http'
|
|
@@ -108,6 +109,7 @@ export type FunctionRuntimeMeta = {
|
|
|
108
109
|
remote?: boolean
|
|
109
110
|
mcp?: boolean
|
|
110
111
|
readonly?: boolean
|
|
112
|
+
deploy?: 'serverless' | 'server' | 'auto'
|
|
111
113
|
sessionless?: boolean
|
|
112
114
|
version?: number
|
|
113
115
|
approvalRequired?: boolean
|
|
@@ -130,6 +132,8 @@ export type FunctionMeta = FunctionRuntimeMeta &
|
|
|
130
132
|
middleware: MiddlewareMetadata[]
|
|
131
133
|
permissions: PermissionMetadata[]
|
|
132
134
|
isDirectFunction: boolean
|
|
135
|
+
sourceFile: string
|
|
136
|
+
exportedName: string
|
|
133
137
|
} & CommonWireMeta
|
|
134
138
|
>
|
|
135
139
|
|
|
@@ -230,6 +234,8 @@ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
|
|
|
230
234
|
workflowRunService?: WorkflowRunService
|
|
231
235
|
/** Credential service for dynamic/managed credentials (OAuth tokens, per-user API keys) */
|
|
232
236
|
credentialService?: CredentialService
|
|
237
|
+
/** Meta service for reading .pikku metadata files (filesystem on Node, R2/KV on CF) */
|
|
238
|
+
metaService?: MetaService
|
|
233
239
|
}
|
|
234
240
|
|
|
235
241
|
/**
|
|
@@ -248,6 +254,8 @@ export type PikkuWire<
|
|
|
248
254
|
> = Partial<{
|
|
249
255
|
wireType: PikkuWiringTypes
|
|
250
256
|
wireId: string
|
|
257
|
+
/** Trace ID for distributed tracing — propagated across remote RPC calls via x-trace-id header */
|
|
258
|
+
traceId: string
|
|
251
259
|
http: PikkuHTTP<In>
|
|
252
260
|
mcp: PikkuMCP<MCPTools>
|
|
253
261
|
rpc: TypedRPC
|
package/src/types/state.types.ts
CHANGED
|
@@ -182,12 +182,12 @@ export interface PikkuPackageState {
|
|
|
182
182
|
} | null
|
|
183
183
|
/** Cached singleton services for this package */
|
|
184
184
|
singletonServices: CoreSingletonServices | null
|
|
185
|
-
/** Absolute path to this package's .pikku directory */
|
|
186
|
-
metaDir: string | null
|
|
187
185
|
/** Credential metadata for this addon package */
|
|
188
186
|
credentialsMeta: Record<
|
|
189
187
|
string,
|
|
190
188
|
{ name: string; displayName: string; type: string; oauth2?: boolean }
|
|
191
189
|
> | null
|
|
190
|
+
/** Services this addon needs from the parent project */
|
|
191
|
+
requiredParentServices: string[] | null
|
|
192
192
|
}
|
|
193
193
|
}
|