@pikku/core 0.12.13 → 0.12.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/dist/errors/errors.d.ts +18 -0
- package/dist/errors/errors.js +33 -0
- package/dist/function/function-runner.d.ts +1 -1
- package/dist/function/function-runner.js +10 -5
- package/dist/function/functions.types.js +1 -0
- package/dist/function/index.d.ts +2 -1
- package/dist/function/index.js +1 -0
- package/dist/handle-error.d.ts +2 -2
- package/dist/handle-error.js +8 -8
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/middleware/index.d.ts +2 -0
- package/dist/middleware/index.js +2 -0
- package/dist/middleware/remote-auth.js +5 -2
- package/dist/permissions.d.ts +13 -1
- package/dist/permissions.js +51 -0
- package/dist/pikku-state.d.ts +0 -1
- package/dist/pikku-state.js +2 -4
- package/dist/remote.d.ts +10 -0
- package/dist/remote.js +32 -0
- package/dist/schema.js +2 -0
- package/dist/services/credential-service.d.ts +11 -0
- package/dist/services/credential-wire-service.d.ts +14 -3
- package/dist/services/credential-wire-service.js +49 -6
- package/dist/services/deployment-service.d.ts +12 -1
- package/dist/services/in-memory-queue-service.d.ts +7 -0
- package/dist/services/in-memory-queue-service.js +28 -0
- package/dist/services/index.d.ts +4 -1
- package/dist/services/index.js +2 -1
- package/dist/services/local-credential-service.d.ts +2 -0
- package/dist/services/local-credential-service.js +20 -0
- package/dist/services/logger-console.d.ts +26 -40
- package/dist/services/logger-console.js +102 -46
- package/dist/services/logger.d.ts +5 -0
- package/dist/services/meta-service.d.ts +175 -0
- package/dist/services/meta-service.js +310 -0
- package/dist/services/pikku-user-id.d.ts +3 -0
- package/dist/services/pikku-user-id.js +16 -0
- package/dist/services/typed-credential-service.d.ts +2 -0
- package/dist/services/typed-credential-service.js +6 -0
- package/dist/services/workflow-service.d.ts +6 -1
- package/dist/testing/service-tests.js +0 -8
- package/dist/types/core.types.d.ts +14 -2
- package/dist/types/state.types.d.ts +9 -2
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +21 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +90 -21
- package/dist/wirings/ai-agent/ai-agent-registry.js +2 -2
- package/dist/wirings/ai-agent/ai-agent-runner.js +24 -2
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-stream.js +61 -3
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +25 -4
- package/dist/wirings/ai-agent/index.d.ts +1 -1
- package/dist/wirings/ai-agent/index.js +1 -1
- package/dist/wirings/channel/channel-runner.js +3 -3
- package/dist/wirings/cli/cli-runner.js +4 -3
- package/dist/wirings/cli/command-parser.js +7 -3
- package/dist/wirings/http/http-runner.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +23 -15
- package/dist/wirings/http/http.types.d.ts +2 -0
- package/dist/wirings/mcp/mcp-runner.js +5 -3
- package/dist/wirings/queue/queue-runner.d.ts +3 -1
- package/dist/wirings/queue/queue-runner.js +8 -3
- package/dist/wirings/queue/queue.types.d.ts +6 -0
- package/dist/wirings/rpc/rpc-runner.js +57 -90
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -1
- package/dist/wirings/scheduler/scheduler-runner.js +9 -5
- package/dist/wirings/trigger/trigger-runner.js +4 -2
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +2 -0
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +1 -1
- package/dist/wirings/workflow/dsl/workflow-runner.js +6 -9
- package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -1
- package/dist/wirings/workflow/graph/graph-runner.js +18 -4
- package/dist/wirings/workflow/index.d.ts +4 -2
- package/dist/wirings/workflow/index.js +4 -2
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +16 -4
- package/dist/wirings/workflow/pikku-workflow-service.js +218 -24
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +40 -0
- package/dist/wirings/workflow/workflow-queue-workers.js +41 -0
- package/dist/wirings/workflow/workflow.types.d.ts +19 -1
- package/package.json +4 -1
- package/src/errors/errors.ts +44 -0
- package/src/function/function-runner.ts +24 -13
- package/src/function/functions.types.ts +1 -0
- package/src/function/index.ts +10 -0
- package/src/handle-error.test.ts +2 -2
- package/src/handle-error.ts +8 -8
- package/src/index.ts +1 -2
- package/src/middleware/index.ts +2 -0
- package/src/middleware/remote-auth.test.ts +4 -4
- package/src/middleware/remote-auth.ts +7 -2
- package/src/permissions.ts +70 -0
- package/src/pikku-state.test.ts +0 -26
- package/src/pikku-state.ts +2 -5
- package/src/remote.ts +46 -0
- package/src/schema.ts +1 -0
- package/src/services/credential-service.ts +13 -0
- package/src/services/credential-wire-service.test.ts +174 -0
- package/src/services/credential-wire-service.ts +52 -8
- package/src/services/deployment-service.ts +17 -1
- package/src/services/in-memory-queue-service.ts +46 -0
- package/src/services/index.ts +21 -1
- package/src/services/local-credential-service.ts +22 -0
- package/src/services/logger-console.ts +127 -47
- package/src/services/logger.ts +6 -0
- package/src/services/meta-service.ts +523 -0
- package/src/services/pikku-user-id.test.ts +62 -0
- package/src/services/pikku-user-id.ts +17 -0
- package/src/services/typed-credential-service.ts +8 -0
- package/src/services/workflow-service.ts +8 -0
- package/src/testing/service-tests.ts +0 -10
- package/src/types/core.types.ts +16 -2
- package/src/types/state.types.ts +7 -2
- package/src/wirings/ai-agent/ai-agent-prepare.ts +122 -41
- package/src/wirings/ai-agent/ai-agent-registry.ts +3 -3
- package/src/wirings/ai-agent/ai-agent-runner.ts +22 -3
- package/src/wirings/ai-agent/ai-agent-stream.ts +115 -3
- package/src/wirings/ai-agent/ai-agent.types.ts +27 -4
- package/src/wirings/ai-agent/index.ts +1 -0
- package/src/wirings/channel/channel-handler.ts +0 -1
- package/src/wirings/channel/channel-runner.ts +4 -5
- package/src/wirings/cli/cli-runner.test.ts +8 -7
- package/src/wirings/cli/cli-runner.ts +5 -4
- package/src/wirings/cli/command-parser.ts +8 -3
- package/src/wirings/http/http-runner.ts +27 -18
- package/src/wirings/http/http.types.ts +2 -0
- package/src/wirings/mcp/mcp-runner.ts +7 -10
- package/src/wirings/queue/queue-runner.test.ts +5 -11
- package/src/wirings/queue/queue-runner.ts +12 -4
- package/src/wirings/queue/queue.types.ts +6 -0
- package/src/wirings/rpc/rpc-runner.ts +91 -118
- package/src/wirings/scheduler/scheduler-runner.test.ts +5 -11
- package/src/wirings/scheduler/scheduler-runner.ts +13 -5
- package/src/wirings/trigger/trigger-runner.test.ts +10 -11
- package/src/wirings/trigger/trigger-runner.ts +6 -4
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +2 -0
- package/src/wirings/workflow/dsl/workflow-runner.ts +11 -10
- package/src/wirings/workflow/graph/graph-runner.ts +19 -4
- package/src/wirings/workflow/index.ts +17 -6
- package/src/wirings/workflow/pikku-workflow-service.ts +286 -24
- package/src/wirings/workflow/workflow-queue-workers.ts +85 -0
- package/src/wirings/workflow/workflow.types.ts +18 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/ai-agent/agent-dynamic-workflow.d.ts +0 -6
- package/dist/wirings/ai-agent/agent-dynamic-workflow.js +0 -468
- package/dist/wirings/workflow/workflow-helpers.d.ts +0 -36
- package/dist/wirings/workflow/workflow-helpers.js +0 -38
- package/src/wirings/ai-agent/agent-dynamic-workflow.ts +0 -610
- package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
- package/src/wirings/workflow/workflow-helpers.ts +0 -79
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Node.js filesystem implementation of MetaService.
|
|
5
|
+
* Reads .gen.json files from a local .pikku directory.
|
|
6
|
+
*/
|
|
7
|
+
export class LocalMetaService {
|
|
8
|
+
basePath;
|
|
9
|
+
httpMetaCache = null;
|
|
10
|
+
channelsMetaCache = null;
|
|
11
|
+
schedulerMetaCache = null;
|
|
12
|
+
queueMetaCache = null;
|
|
13
|
+
cliMetaCache = null;
|
|
14
|
+
mcpMetaCache = null;
|
|
15
|
+
rpcMetaCache = null;
|
|
16
|
+
workflowMetaCache = null;
|
|
17
|
+
triggerMetaCache = null;
|
|
18
|
+
triggerSourceMetaCache = null;
|
|
19
|
+
functionsMetaCache = null;
|
|
20
|
+
servicesMetaCache = null;
|
|
21
|
+
secretsMetaCache = null;
|
|
22
|
+
credentialsMetaCache = null;
|
|
23
|
+
variablesMetaCache = null;
|
|
24
|
+
middlewareGroupsMetaCache = null;
|
|
25
|
+
permissionsGroupsMetaCache = null;
|
|
26
|
+
agentsMetaCache = null;
|
|
27
|
+
schemaCache = new Map();
|
|
28
|
+
constructor(basePath) {
|
|
29
|
+
this.basePath = basePath;
|
|
30
|
+
}
|
|
31
|
+
async readFile(relativePath) {
|
|
32
|
+
try {
|
|
33
|
+
return await readFile(join(this.basePath, relativePath), 'utf-8');
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async readDir(relativePath) {
|
|
40
|
+
try {
|
|
41
|
+
return await readdir(join(this.basePath, relativePath));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
clearCache() {
|
|
48
|
+
this.httpMetaCache = null;
|
|
49
|
+
this.channelsMetaCache = null;
|
|
50
|
+
this.schedulerMetaCache = null;
|
|
51
|
+
this.queueMetaCache = null;
|
|
52
|
+
this.cliMetaCache = null;
|
|
53
|
+
this.mcpMetaCache = null;
|
|
54
|
+
this.rpcMetaCache = null;
|
|
55
|
+
this.workflowMetaCache = null;
|
|
56
|
+
this.triggerMetaCache = null;
|
|
57
|
+
this.triggerSourceMetaCache = null;
|
|
58
|
+
this.functionsMetaCache = null;
|
|
59
|
+
this.servicesMetaCache = null;
|
|
60
|
+
this.secretsMetaCache = null;
|
|
61
|
+
this.credentialsMetaCache = null;
|
|
62
|
+
this.variablesMetaCache = null;
|
|
63
|
+
this.middlewareGroupsMetaCache = null;
|
|
64
|
+
this.permissionsGroupsMetaCache = null;
|
|
65
|
+
this.agentsMetaCache = null;
|
|
66
|
+
this.schemaCache.clear();
|
|
67
|
+
}
|
|
68
|
+
// -- Private helpers --
|
|
69
|
+
async readMetaJson(dir, baseName) {
|
|
70
|
+
const verbose = await this.readFile(`${dir}/${baseName}-verbose.gen.json`);
|
|
71
|
+
if (verbose)
|
|
72
|
+
return verbose;
|
|
73
|
+
const minimal = await this.readFile(`${dir}/${baseName}.gen.json`);
|
|
74
|
+
if (minimal)
|
|
75
|
+
return minimal;
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
// -- Typed metadata accessors --
|
|
79
|
+
async getHttpMeta() {
|
|
80
|
+
if (this.httpMetaCache)
|
|
81
|
+
return this.httpMetaCache;
|
|
82
|
+
const content = await this.readMetaJson('http', 'pikku-http-wirings-meta');
|
|
83
|
+
this.httpMetaCache = content
|
|
84
|
+
? JSON.parse(content)
|
|
85
|
+
: {
|
|
86
|
+
get: {},
|
|
87
|
+
post: {},
|
|
88
|
+
put: {},
|
|
89
|
+
delete: {},
|
|
90
|
+
patch: {},
|
|
91
|
+
head: {},
|
|
92
|
+
options: {},
|
|
93
|
+
};
|
|
94
|
+
return this.httpMetaCache;
|
|
95
|
+
}
|
|
96
|
+
async getChannelsMeta() {
|
|
97
|
+
if (this.channelsMetaCache)
|
|
98
|
+
return this.channelsMetaCache;
|
|
99
|
+
const content = await this.readMetaJson('channel', 'pikku-channels-meta');
|
|
100
|
+
this.channelsMetaCache = content ? JSON.parse(content) : {};
|
|
101
|
+
return this.channelsMetaCache;
|
|
102
|
+
}
|
|
103
|
+
async getSchedulerMeta() {
|
|
104
|
+
if (this.schedulerMetaCache)
|
|
105
|
+
return this.schedulerMetaCache;
|
|
106
|
+
const content = await this.readMetaJson('scheduler', 'pikku-schedulers-wirings-meta');
|
|
107
|
+
this.schedulerMetaCache = content ? JSON.parse(content) : {};
|
|
108
|
+
return this.schedulerMetaCache;
|
|
109
|
+
}
|
|
110
|
+
async getQueueMeta() {
|
|
111
|
+
if (this.queueMetaCache)
|
|
112
|
+
return this.queueMetaCache;
|
|
113
|
+
const content = await this.readMetaJson('queue', 'pikku-queue-workers-wirings-meta');
|
|
114
|
+
this.queueMetaCache = content ? JSON.parse(content) : {};
|
|
115
|
+
return this.queueMetaCache;
|
|
116
|
+
}
|
|
117
|
+
async getCliMeta() {
|
|
118
|
+
if (this.cliMetaCache)
|
|
119
|
+
return this.cliMetaCache;
|
|
120
|
+
const content = await this.readMetaJson('cli', 'pikku-cli-wirings-meta');
|
|
121
|
+
this.cliMetaCache = content
|
|
122
|
+
? JSON.parse(content)
|
|
123
|
+
: { programs: {}, renderers: {} };
|
|
124
|
+
return this.cliMetaCache;
|
|
125
|
+
}
|
|
126
|
+
async getMcpMeta() {
|
|
127
|
+
if (this.mcpMetaCache)
|
|
128
|
+
return this.mcpMetaCache;
|
|
129
|
+
const content = await this.readMetaJson('mcp', 'pikku-mcp-wirings-meta');
|
|
130
|
+
if (content) {
|
|
131
|
+
const mcpData = JSON.parse(content);
|
|
132
|
+
this.mcpMetaCache = {
|
|
133
|
+
resources: mcpData.resourcesMeta || {},
|
|
134
|
+
tools: mcpData.toolsMeta || {},
|
|
135
|
+
prompts: mcpData.promptsMeta || {},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
this.mcpMetaCache = { resources: {}, tools: {}, prompts: {} };
|
|
140
|
+
}
|
|
141
|
+
return this.mcpMetaCache;
|
|
142
|
+
}
|
|
143
|
+
async getRpcMeta() {
|
|
144
|
+
if (this.rpcMetaCache)
|
|
145
|
+
return this.rpcMetaCache;
|
|
146
|
+
try {
|
|
147
|
+
const content = await this.readFile('rpc/pikku-rpc-wirings-meta.gen.json');
|
|
148
|
+
this.rpcMetaCache = content ? JSON.parse(content) : {};
|
|
149
|
+
return this.rpcMetaCache;
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
console.error('Error reading RPC wirings metadata:', error);
|
|
153
|
+
this.rpcMetaCache = {};
|
|
154
|
+
return this.rpcMetaCache;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async getWorkflowMeta() {
|
|
158
|
+
if (this.workflowMetaCache)
|
|
159
|
+
return this.workflowMetaCache;
|
|
160
|
+
try {
|
|
161
|
+
const files = await this.readDir('workflow/meta');
|
|
162
|
+
const jsonFiles = files.filter((f) => f.endsWith('.gen.json'));
|
|
163
|
+
const verboseFiles = jsonFiles.filter((f) => f.includes('-verbose'));
|
|
164
|
+
const minimalFiles = jsonFiles.filter((f) => !f.includes('-verbose'));
|
|
165
|
+
const verboseNames = new Set(verboseFiles.map((f) => f.replace('-verbose.gen.json', '')));
|
|
166
|
+
const filesToRead = [
|
|
167
|
+
...verboseFiles,
|
|
168
|
+
...minimalFiles.filter((f) => !verboseNames.has(f.replace('.gen.json', ''))),
|
|
169
|
+
];
|
|
170
|
+
const result = {};
|
|
171
|
+
await Promise.all(filesToRead.map(async (file) => {
|
|
172
|
+
const content = await this.readFile(`workflow/meta/${file}`);
|
|
173
|
+
if (content) {
|
|
174
|
+
const meta = JSON.parse(content);
|
|
175
|
+
result[meta.name] = meta;
|
|
176
|
+
}
|
|
177
|
+
}));
|
|
178
|
+
this.workflowMetaCache = result;
|
|
179
|
+
return this.workflowMetaCache;
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
console.error('Error reading Workflow wirings metadata:', error);
|
|
183
|
+
this.workflowMetaCache = {};
|
|
184
|
+
return this.workflowMetaCache;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async getTriggerMeta() {
|
|
188
|
+
if (this.triggerMetaCache)
|
|
189
|
+
return this.triggerMetaCache;
|
|
190
|
+
const content = await this.readMetaJson('trigger', 'pikku-trigger-wirings-meta');
|
|
191
|
+
this.triggerMetaCache = content ? JSON.parse(content) : {};
|
|
192
|
+
return this.triggerMetaCache;
|
|
193
|
+
}
|
|
194
|
+
async getTriggerSourceMeta() {
|
|
195
|
+
if (this.triggerSourceMetaCache)
|
|
196
|
+
return this.triggerSourceMetaCache;
|
|
197
|
+
const content = await this.readMetaJson('trigger', 'pikku-trigger-sources-meta');
|
|
198
|
+
this.triggerSourceMetaCache = content ? JSON.parse(content) : {};
|
|
199
|
+
return this.triggerSourceMetaCache;
|
|
200
|
+
}
|
|
201
|
+
async getFunctionsMeta() {
|
|
202
|
+
if (this.functionsMetaCache)
|
|
203
|
+
return this.functionsMetaCache;
|
|
204
|
+
const content = await this.readMetaJson('function', 'pikku-functions-meta');
|
|
205
|
+
this.functionsMetaCache = content ? JSON.parse(content) : {};
|
|
206
|
+
return this.functionsMetaCache;
|
|
207
|
+
}
|
|
208
|
+
async getMiddlewareGroupsMeta() {
|
|
209
|
+
if (this.middlewareGroupsMetaCache)
|
|
210
|
+
return this.middlewareGroupsMetaCache;
|
|
211
|
+
const content = await this.readMetaJson('middleware', 'pikku-middleware-groups-meta');
|
|
212
|
+
this.middlewareGroupsMetaCache = content
|
|
213
|
+
? JSON.parse(content)
|
|
214
|
+
: { definitions: {}, instances: {}, httpGroups: {}, tagGroups: {} };
|
|
215
|
+
return this.middlewareGroupsMetaCache;
|
|
216
|
+
}
|
|
217
|
+
async getPermissionsGroupsMeta() {
|
|
218
|
+
if (this.permissionsGroupsMetaCache)
|
|
219
|
+
return this.permissionsGroupsMetaCache;
|
|
220
|
+
const content = await this.readMetaJson('permissions', 'pikku-permissions-groups-meta');
|
|
221
|
+
this.permissionsGroupsMetaCache = content
|
|
222
|
+
? JSON.parse(content)
|
|
223
|
+
: { definitions: {}, httpGroups: {}, tagGroups: {} };
|
|
224
|
+
return this.permissionsGroupsMetaCache;
|
|
225
|
+
}
|
|
226
|
+
async getAgentsMeta() {
|
|
227
|
+
if (this.agentsMetaCache)
|
|
228
|
+
return this.agentsMetaCache;
|
|
229
|
+
const content = await this.readMetaJson('agent', 'pikku-agent-wirings-meta');
|
|
230
|
+
if (content) {
|
|
231
|
+
const parsed = JSON.parse(content);
|
|
232
|
+
this.agentsMetaCache = parsed.agentsMeta || parsed;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
this.agentsMetaCache = {};
|
|
236
|
+
}
|
|
237
|
+
return this.agentsMetaCache;
|
|
238
|
+
}
|
|
239
|
+
async getSecretsMeta() {
|
|
240
|
+
if (this.secretsMetaCache)
|
|
241
|
+
return this.secretsMetaCache;
|
|
242
|
+
const content = await this.readFile('secrets/pikku-secrets-meta.gen.json');
|
|
243
|
+
this.secretsMetaCache = content ? JSON.parse(content) : {};
|
|
244
|
+
return this.secretsMetaCache;
|
|
245
|
+
}
|
|
246
|
+
async getCredentialsMeta() {
|
|
247
|
+
if (this.credentialsMetaCache)
|
|
248
|
+
return this.credentialsMetaCache;
|
|
249
|
+
const content = await this.readFile('credentials/pikku-credentials-meta.gen.json');
|
|
250
|
+
this.credentialsMetaCache = content ? JSON.parse(content) : {};
|
|
251
|
+
return this.credentialsMetaCache;
|
|
252
|
+
}
|
|
253
|
+
async getVariablesMeta() {
|
|
254
|
+
if (this.variablesMetaCache)
|
|
255
|
+
return this.variablesMetaCache;
|
|
256
|
+
const content = await this.readFile('variables/pikku-variables-meta.gen.json');
|
|
257
|
+
this.variablesMetaCache = content ? JSON.parse(content) : {};
|
|
258
|
+
return this.variablesMetaCache;
|
|
259
|
+
}
|
|
260
|
+
async getServicesMeta() {
|
|
261
|
+
if (this.servicesMetaCache)
|
|
262
|
+
return this.servicesMetaCache;
|
|
263
|
+
try {
|
|
264
|
+
const files = await this.readDir('services');
|
|
265
|
+
const jsonFiles = files.filter((f) => f.endsWith('.gen.json'));
|
|
266
|
+
const result = {};
|
|
267
|
+
await Promise.all(jsonFiles.map(async (file) => {
|
|
268
|
+
const content = await this.readFile(`services/${file}`);
|
|
269
|
+
if (content) {
|
|
270
|
+
const meta = JSON.parse(content);
|
|
271
|
+
result[meta.name] = meta;
|
|
272
|
+
}
|
|
273
|
+
}));
|
|
274
|
+
this.servicesMetaCache = result;
|
|
275
|
+
return this.servicesMetaCache;
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
console.error('Error reading Services metadata:', error);
|
|
279
|
+
this.servicesMetaCache = {};
|
|
280
|
+
return this.servicesMetaCache;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
async getSchema(schemaName) {
|
|
284
|
+
if (this.schemaCache.has(schemaName)) {
|
|
285
|
+
return this.schemaCache.get(schemaName);
|
|
286
|
+
}
|
|
287
|
+
if (!/^[a-zA-Z0-9_\-\.]+$/.test(schemaName)) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
try {
|
|
291
|
+
const content = await this.readFile(`schemas/schemas/${schemaName}.schema.json`);
|
|
292
|
+
if (!content)
|
|
293
|
+
return null;
|
|
294
|
+
const schema = JSON.parse(content);
|
|
295
|
+
this.schemaCache.set(schemaName, schema);
|
|
296
|
+
return schema;
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
console.error(`Error reading schema ${schemaName}:`, error);
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async getSchemas(schemaNames) {
|
|
304
|
+
const results = {};
|
|
305
|
+
await Promise.all(schemaNames.map(async (name) => {
|
|
306
|
+
results[name] = await this.getSchema(name);
|
|
307
|
+
}));
|
|
308
|
+
return results;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const defaultPikkuUserIdResolver = (wire) => {
|
|
2
|
+
// Explicit pikkuUserId on wire (set by earlier middleware or runner)
|
|
3
|
+
if (wire.pikkuUserId)
|
|
4
|
+
return wire.pikkuUserId;
|
|
5
|
+
// Session userId (from auth middleware — user-defined session shape)
|
|
6
|
+
const session = wire.session;
|
|
7
|
+
if (session?.userId && typeof session.userId === 'string')
|
|
8
|
+
return session.userId;
|
|
9
|
+
// Queue job: carried in job metadata
|
|
10
|
+
if (wire.queue?.pikkuUserId)
|
|
11
|
+
return wire.queue.pikkuUserId;
|
|
12
|
+
// Workflow: carried in run wire metadata
|
|
13
|
+
if (wire.workflow?.pikkuUserId)
|
|
14
|
+
return wire.workflow.pikkuUserId;
|
|
15
|
+
return undefined;
|
|
16
|
+
};
|
|
@@ -22,6 +22,8 @@ export declare class TypedCredentialService<TMap = Record<string, unknown>> impl
|
|
|
22
22
|
delete(name: string, userId?: string): Promise<void>;
|
|
23
23
|
has(name: string, userId?: string): Promise<boolean>;
|
|
24
24
|
getAll(userId: string): Promise<Record<string, unknown>>;
|
|
25
|
+
getUsersWithCredential(name: string): Promise<string[]>;
|
|
26
|
+
getAllUsers(): Promise<string[]>;
|
|
25
27
|
getAllStatus(userId?: string): Promise<CredentialStatusInfo[]>;
|
|
26
28
|
getMissing(userId?: string): Promise<CredentialStatusInfo[]>;
|
|
27
29
|
}
|
|
@@ -20,6 +20,12 @@ export class TypedCredentialService {
|
|
|
20
20
|
async getAll(userId) {
|
|
21
21
|
return this.credentials.getAll(userId);
|
|
22
22
|
}
|
|
23
|
+
async getUsersWithCredential(name) {
|
|
24
|
+
return this.credentials.getUsersWithCredential(name);
|
|
25
|
+
}
|
|
26
|
+
async getAllUsers() {
|
|
27
|
+
return this.credentials.getAllUsers();
|
|
28
|
+
}
|
|
23
29
|
async getAllStatus(userId) {
|
|
24
30
|
const results = [];
|
|
25
31
|
for (const [name, meta] of Object.entries(this.credentialsMeta)) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SerializedError } from '../types/core.types.js';
|
|
2
|
-
import type { WorkflowRun, WorkflowRunWire, StepState, WorkflowStatus, WorkflowVersionStatus } from '../wirings/workflow/workflow.types.js';
|
|
2
|
+
import type { WorkflowRun, WorkflowRunWire, WorkflowRunStatus, StepState, WorkflowStatus, WorkflowVersionStatus } from '../wirings/workflow/workflow.types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Interface for workflow orchestration
|
|
5
5
|
* Handles workflow execution, replay, orchestration logic, and run-level state
|
|
@@ -7,6 +7,7 @@ import type { WorkflowRun, WorkflowRunWire, StepState, WorkflowStatus, WorkflowV
|
|
|
7
7
|
export interface WorkflowService {
|
|
8
8
|
createRun(workflowName: string, input: any, inline: boolean, graphHash: string, wire: WorkflowRunWire): Promise<string>;
|
|
9
9
|
getRun(id: string): Promise<WorkflowRun | null>;
|
|
10
|
+
getRunStatus(id: string): Promise<WorkflowRunStatus | null>;
|
|
10
11
|
getRunHistory(runId: string): Promise<Array<StepState & {
|
|
11
12
|
stepName: string;
|
|
12
13
|
}>>;
|
|
@@ -20,6 +21,10 @@ export interface WorkflowService {
|
|
|
20
21
|
}): Promise<{
|
|
21
22
|
runId: string;
|
|
22
23
|
}>;
|
|
24
|
+
runToCompletion<I>(name: string, input: I, rpcService: any, options?: {
|
|
25
|
+
pollIntervalMs?: number;
|
|
26
|
+
wire?: WorkflowRunWire;
|
|
27
|
+
}): Promise<unknown>;
|
|
23
28
|
runWorkflowJob(runId: string, rpcService: any): Promise<void>;
|
|
24
29
|
orchestrateWorkflow(runId: string, rpcService: any): Promise<void>;
|
|
25
30
|
executeWorkflowSleepCompleted(runId: string, stepId: string): Promise<void>;
|
|
@@ -482,14 +482,6 @@ export function defineServiceTests(config) {
|
|
|
482
482
|
endpoint: 'http://localhost:3000',
|
|
483
483
|
functions: ['funcA', 'funcB'],
|
|
484
484
|
});
|
|
485
|
-
const infos = await service.findFunction('funcA');
|
|
486
|
-
assert.ok(infos.length >= 1);
|
|
487
|
-
assert.equal(infos[0].deploymentId, 'deploy-1');
|
|
488
|
-
assert.equal(infos[0].endpoint, 'http://localhost:3000');
|
|
489
|
-
});
|
|
490
|
-
test('findFunction returns empty for unknown function', async () => {
|
|
491
|
-
const infos = await service.findFunction('unknown-func');
|
|
492
|
-
assert.deepEqual(infos, []);
|
|
493
485
|
});
|
|
494
486
|
});
|
|
495
487
|
}
|
|
@@ -24,6 +24,7 @@ import type { AgentRunService } from '../wirings/ai-agent/ai-agent.types.js';
|
|
|
24
24
|
import type { PikkuAIMiddlewareHooks } from '../wirings/ai-agent/ai-agent.types.js';
|
|
25
25
|
import type { WorkflowRunService } from '../wirings/workflow/workflow.types.js';
|
|
26
26
|
import type { CredentialService } from '../services/credential-service.js';
|
|
27
|
+
import type { MetaService } from '../services/meta-service.js';
|
|
27
28
|
export type PikkuWiringTypes = 'http' | 'scheduler' | 'trigger' | 'channel' | 'rpc' | 'queue' | 'mcp' | 'cli' | 'workflow' | 'agent' | 'gateway';
|
|
28
29
|
export interface FunctionServicesMeta {
|
|
29
30
|
optimized: boolean;
|
|
@@ -75,6 +76,7 @@ export type FunctionRuntimeMeta = {
|
|
|
75
76
|
remote?: boolean;
|
|
76
77
|
mcp?: boolean;
|
|
77
78
|
readonly?: boolean;
|
|
79
|
+
deploy?: 'serverless' | 'server' | 'auto';
|
|
78
80
|
sessionless?: boolean;
|
|
79
81
|
version?: number;
|
|
80
82
|
approvalRequired?: boolean;
|
|
@@ -94,6 +96,8 @@ export type FunctionMeta = FunctionRuntimeMeta & Partial<{
|
|
|
94
96
|
middleware: MiddlewareMetadata[];
|
|
95
97
|
permissions: PermissionMetadata[];
|
|
96
98
|
isDirectFunction: boolean;
|
|
99
|
+
sourceFile: string;
|
|
100
|
+
exportedName: string;
|
|
97
101
|
} & CommonWireMeta>;
|
|
98
102
|
export type FunctionsRuntimeMeta = Record<string, FunctionRuntimeMeta>;
|
|
99
103
|
export type FunctionsMeta = Record<string, FunctionMeta>;
|
|
@@ -175,6 +179,8 @@ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
|
|
|
175
179
|
workflowRunService?: WorkflowRunService;
|
|
176
180
|
/** Credential service for dynamic/managed credentials (OAuth tokens, per-user API keys) */
|
|
177
181
|
credentialService?: CredentialService;
|
|
182
|
+
/** Meta service for reading .pikku metadata files (filesystem on Node, R2/KV on CF) */
|
|
183
|
+
metaService?: MetaService;
|
|
178
184
|
}
|
|
179
185
|
/**
|
|
180
186
|
* Represents different forms of wire within Pikku and the outside world.
|
|
@@ -182,6 +188,8 @@ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
|
|
|
182
188
|
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> = Partial<{
|
|
183
189
|
wireType: PikkuWiringTypes;
|
|
184
190
|
wireId: string;
|
|
191
|
+
/** Trace ID for distributed tracing — propagated across remote RPC calls via x-trace-id header */
|
|
192
|
+
traceId: string;
|
|
185
193
|
http: PikkuHTTP<In>;
|
|
186
194
|
mcp: PikkuMCP<MCPTools>;
|
|
187
195
|
rpc: TypedRPC;
|
|
@@ -203,10 +211,14 @@ export type PikkuWire<In = unknown, Out = unknown, HasInitialSession extends boo
|
|
|
203
211
|
getSession: () => Promise<UserSession> | UserSession | undefined;
|
|
204
212
|
/** Whether the session was modified during this run */
|
|
205
213
|
hasSessionChanged: () => boolean;
|
|
214
|
+
/** The resolved user identity for credential lookups */
|
|
215
|
+
pikkuUserId: string;
|
|
206
216
|
/** Set a credential value (available in middleware) */
|
|
207
217
|
setCredential: (name: string, value: unknown) => void;
|
|
208
|
-
/** Get
|
|
209
|
-
|
|
218
|
+
/** Get a single credential by name — lazy-loads from CredentialService on first call, sync thereafter */
|
|
219
|
+
getCredential: <T = unknown>(name: string) => T | null | Promise<T | null>;
|
|
220
|
+
/** Get all resolved credentials — lazy-loads from CredentialService on first call, sync thereafter */
|
|
221
|
+
getCredentials: () => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
210
222
|
}>;
|
|
211
223
|
/**
|
|
212
224
|
* A function that can wrap an wire and be called before or after
|
|
@@ -130,7 +130,14 @@ export interface PikkuPackageState {
|
|
|
130
130
|
} | null;
|
|
131
131
|
/** Cached singleton services for this package */
|
|
132
132
|
singletonServices: CoreSingletonServices | null;
|
|
133
|
-
/**
|
|
134
|
-
|
|
133
|
+
/** Credential metadata for this addon package */
|
|
134
|
+
credentialsMeta: Record<string, {
|
|
135
|
+
name: string;
|
|
136
|
+
displayName: string;
|
|
137
|
+
type: string;
|
|
138
|
+
oauth2?: boolean;
|
|
139
|
+
}> | null;
|
|
140
|
+
/** Services this addon needs from the parent project */
|
|
141
|
+
requiredParentServices: string[] | null;
|
|
135
142
|
};
|
|
136
143
|
}
|
|
@@ -19,6 +19,27 @@ export declare class ToolApprovalRequired extends PikkuError {
|
|
|
19
19
|
readonly agentRunId?: string;
|
|
20
20
|
constructor(toolCallId: string, toolName: string, args: unknown, reason?: string, displayToolName?: string, displayArgs?: unknown, agentRunId?: string);
|
|
21
21
|
}
|
|
22
|
+
export declare class ToolCredentialRequired extends PikkuError {
|
|
23
|
+
readonly toolCallId: string;
|
|
24
|
+
readonly toolName: string;
|
|
25
|
+
readonly args: unknown;
|
|
26
|
+
readonly credentialName: string;
|
|
27
|
+
readonly credentialType: 'oauth2' | 'apikey';
|
|
28
|
+
readonly connectUrl?: string;
|
|
29
|
+
constructor(toolCallId: string, toolName: string, args: unknown, credentialName: string, credentialType: 'oauth2' | 'apikey', connectUrl?: string);
|
|
30
|
+
}
|
|
31
|
+
export interface AddonCredentialRequirement {
|
|
32
|
+
credentialName: string;
|
|
33
|
+
displayName: string;
|
|
34
|
+
addonNamespace: string;
|
|
35
|
+
type: 'wire';
|
|
36
|
+
oauth2: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Given a list of tool names (e.g. ["oauth-api:getProfile"]),
|
|
40
|
+
* returns the wire OAuth credentials required by their addons.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getAddonCredentialRequirements(toolNames: string[]): AddonCredentialRequirement[];
|
|
22
43
|
export type StreamContext = {
|
|
23
44
|
channel: AIStreamChannel;
|
|
24
45
|
options?: StreamAIAgentOptions;
|