@pikku/core 0.11.2 → 0.12.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 +33 -2
- package/dist/crypto-utils.d.ts +2 -0
- package/dist/crypto-utils.js +78 -0
- package/dist/errors/errors.d.ts +8 -0
- package/dist/errors/errors.js +16 -0
- package/dist/errors/index.d.ts +0 -1
- package/dist/errors/index.js +0 -1
- package/dist/function/function-runner.d.ts +7 -1
- package/dist/function/function-runner.js +82 -23
- package/dist/function/functions.types.d.ts +31 -87
- package/dist/function/functions.types.js +16 -46
- package/dist/function/index.d.ts +2 -2
- package/dist/function/index.js +1 -2
- package/dist/handle-error.js +1 -10
- package/dist/index.d.ts +28 -26
- package/dist/index.js +18 -29
- package/dist/middleware/auth-apikey.d.ts +2 -2
- package/dist/middleware/auth-apikey.js +3 -3
- package/dist/middleware/auth-bearer.d.ts +2 -2
- package/dist/middleware/auth-bearer.js +3 -6
- package/dist/middleware/auth-cookie.d.ts +2 -2
- package/dist/middleware/auth-cookie.js +6 -8
- package/dist/middleware/cors.d.ts +46 -0
- package/dist/middleware/cors.js +73 -0
- package/dist/middleware/index.d.ts +5 -3
- package/dist/middleware/index.js +5 -3
- package/dist/middleware/remote-auth.d.ts +5 -0
- package/dist/middleware/remote-auth.js +55 -0
- package/dist/middleware/timeout.d.ts +2 -2
- package/dist/middleware-runner.js +8 -10
- package/dist/permissions.js +11 -15
- package/dist/pikku-state.d.ts +1 -0
- package/dist/pikku-state.js +18 -8
- package/dist/schema.js +12 -11
- package/dist/services/ai-agent-runner-service.d.ts +24 -0
- package/dist/services/ai-agent-runner-service.js +1 -0
- package/dist/services/ai-run-state-service.d.ts +13 -0
- package/dist/services/ai-run-state-service.js +1 -0
- package/dist/services/ai-storage-service.d.ts +18 -0
- package/dist/services/ai-storage-service.js +1 -0
- package/dist/services/deployment-service.d.ts +19 -0
- package/dist/services/deployment-service.js +1 -0
- package/dist/services/gopass-secrets.d.ts +47 -0
- package/dist/services/gopass-secrets.js +94 -0
- package/dist/services/in-memory-trigger-service.d.ts +23 -0
- package/dist/services/in-memory-trigger-service.js +50 -0
- package/dist/services/in-memory-workflow-service.d.ts +59 -0
- package/dist/services/in-memory-workflow-service.js +287 -0
- package/dist/services/index.d.ts +25 -11
- package/dist/services/index.js +10 -13
- package/dist/services/local-secrets.d.ts +23 -0
- package/dist/services/local-secrets.js +45 -0
- package/dist/services/local-variables.d.ts +5 -0
- package/dist/services/local-variables.js +18 -0
- package/dist/services/scheduler-service.d.ts +21 -1
- package/dist/services/scheduler-service.js +14 -0
- package/dist/services/schema-service.d.ts +6 -0
- package/dist/services/scoped-secret-service.d.ts +16 -0
- package/dist/services/scoped-secret-service.js +35 -0
- package/dist/services/secret-service.d.ts +25 -4
- package/dist/services/trigger-service.d.ts +23 -0
- package/dist/services/trigger-service.js +1 -0
- package/dist/services/typed-secret-service.d.ts +30 -0
- package/dist/services/typed-secret-service.js +40 -0
- package/dist/services/typed-variables-service.d.ts +27 -0
- package/dist/services/typed-variables-service.js +46 -0
- package/dist/services/user-session-service.d.ts +13 -0
- package/dist/services/user-session-service.js +17 -0
- package/dist/services/variables-service.d.ts +5 -0
- package/dist/services/workflow-service.d.ts +9 -4
- package/dist/types/core.types.d.ts +48 -12
- package/dist/types/core.types.js +8 -1
- package/dist/types/state.types.d.ts +43 -51
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +15 -3
- package/dist/version.d.ts +6 -0
- package/dist/version.js +19 -0
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +29 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +199 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +9 -0
- package/dist/wirings/ai-agent/ai-agent-model-config.js +36 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +60 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +312 -0
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +15 -0
- package/dist/wirings/ai-agent/ai-agent-registry.js +47 -0
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +3 -0
- package/dist/wirings/ai-agent/ai-agent-runner.js +96 -0
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +11 -0
- package/dist/wirings/ai-agent/ai-agent-stream.js +503 -0
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +254 -0
- package/dist/wirings/ai-agent/ai-agent.types.js +1 -0
- package/dist/wirings/ai-agent/index.d.ts +5 -0
- package/dist/wirings/ai-agent/index.js +4 -0
- package/dist/wirings/channel/channel-common.d.ts +7 -4
- package/dist/wirings/channel/channel-common.js +15 -8
- package/dist/wirings/channel/channel-handler.js +12 -3
- package/dist/wirings/channel/channel-middleware-runner.d.ts +9 -0
- package/dist/wirings/channel/channel-middleware-runner.js +73 -0
- package/dist/wirings/channel/channel-runner.js +7 -7
- package/dist/wirings/channel/channel.types.d.ts +5 -1
- package/dist/wirings/channel/define-channel-routes.d.ts +21 -0
- package/dist/wirings/channel/define-channel-routes.js +23 -0
- package/dist/wirings/channel/index.d.ts +10 -8
- package/dist/wirings/channel/index.js +7 -8
- package/dist/wirings/channel/local/index.d.ts +3 -3
- package/dist/wirings/channel/local/index.js +3 -3
- package/dist/wirings/channel/local/local-channel-runner.js +18 -6
- package/dist/wirings/channel/serverless/index.d.ts +1 -1
- package/dist/wirings/channel/serverless/index.js +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +15 -4
- package/dist/wirings/cli/channel/index.d.ts +1 -1
- package/dist/wirings/cli/channel/index.js +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +1 -1
- package/dist/wirings/cli/cli-runner.js +12 -8
- package/dist/wirings/cli/cli.types.d.ts +6 -6
- package/dist/wirings/cli/define-cli-commands.d.ts +19 -0
- package/dist/wirings/cli/define-cli-commands.js +20 -0
- package/dist/wirings/cli/index.d.ts +2 -3
- package/dist/wirings/cli/index.js +1 -3
- package/dist/wirings/http/http-routes.d.ts +69 -0
- package/dist/wirings/http/http-routes.js +139 -0
- package/dist/wirings/http/http-runner.js +49 -23
- package/dist/wirings/http/http.types.d.ts +78 -38
- package/dist/wirings/http/index.d.ts +5 -4
- package/dist/wirings/http/index.js +4 -3
- package/dist/wirings/mcp/index.d.ts +4 -3
- package/dist/wirings/mcp/index.js +3 -3
- package/dist/wirings/mcp/mcp-runner.d.ts +1 -3
- package/dist/wirings/mcp/mcp-runner.js +25 -39
- package/dist/wirings/mcp/mcp.types.d.ts +3 -3
- package/dist/wirings/node/index.d.ts +2 -0
- package/dist/wirings/node/index.js +1 -0
- package/dist/wirings/node/node.types.d.ts +20 -0
- package/dist/wirings/node/node.types.js +1 -0
- package/dist/wirings/oauth2/index.d.ts +3 -0
- package/dist/wirings/oauth2/index.js +2 -0
- package/dist/wirings/oauth2/oauth2-client.d.ts +47 -0
- package/dist/wirings/oauth2/oauth2-client.js +267 -0
- package/dist/wirings/oauth2/oauth2.types.d.ts +65 -0
- package/dist/wirings/oauth2/oauth2.types.js +4 -0
- package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +20 -0
- package/dist/wirings/oauth2/wire-oauth2-credential.js +21 -0
- package/dist/wirings/queue/index.d.ts +2 -2
- package/dist/wirings/queue/index.js +1 -1
- package/dist/wirings/queue/queue-runner.d.ts +7 -0
- package/dist/wirings/queue/queue-runner.js +17 -6
- package/dist/wirings/queue/queue.types.d.ts +8 -2
- 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 +33 -5
- package/dist/wirings/rpc/rpc-runner.js +134 -16
- package/dist/wirings/rpc/rpc-types.d.ts +8 -4
- package/dist/wirings/scheduler/index.d.ts +3 -3
- package/dist/wirings/scheduler/index.js +2 -3
- package/dist/wirings/scheduler/scheduler-runner.d.ts +5 -0
- package/dist/wirings/scheduler/scheduler-runner.js +23 -5
- package/dist/wirings/secret/index.d.ts +3 -0
- package/dist/wirings/secret/index.js +2 -0
- package/dist/wirings/secret/secret.types.d.ts +27 -0
- package/dist/wirings/secret/secret.types.js +1 -0
- package/dist/wirings/secret/validate-secret-definitions.d.ts +6 -0
- package/dist/wirings/secret/validate-secret-definitions.js +55 -0
- package/dist/wirings/trigger/index.d.ts +3 -2
- package/dist/wirings/trigger/index.js +2 -2
- package/dist/wirings/trigger/pikku-trigger-service.d.ts +26 -0
- package/dist/wirings/trigger/pikku-trigger-service.js +75 -0
- package/dist/wirings/trigger/trigger-runner.d.ts +21 -8
- package/dist/wirings/trigger/trigger-runner.js +46 -18
- package/dist/wirings/trigger/trigger.types.d.ts +99 -11
- package/dist/wirings/trigger/trigger.types.js +40 -1
- package/dist/wirings/variable/index.d.ts +3 -0
- package/dist/wirings/variable/index.js +2 -0
- package/dist/wirings/variable/validate-variable-definitions.d.ts +6 -0
- package/dist/wirings/variable/validate-variable-definitions.js +45 -0
- package/dist/wirings/variable/variable.types.d.ts +18 -0
- package/dist/wirings/variable/variable.types.js +1 -0
- package/dist/wirings/workflow/dsl/index.d.ts +1 -1
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +7 -1
- package/dist/wirings/workflow/dsl/workflow-runner.js +3 -2
- package/dist/wirings/workflow/graph/graph-node.d.ts +1 -6
- package/dist/wirings/workflow/graph/graph-runner.d.ts +5 -31
- package/dist/wirings/workflow/graph/graph-runner.js +384 -296
- package/dist/wirings/workflow/graph/index.d.ts +4 -3
- package/dist/wirings/workflow/graph/index.js +3 -3
- package/dist/wirings/workflow/graph/template.d.ts +15 -0
- package/dist/wirings/workflow/graph/template.js +27 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +15 -0
- package/dist/wirings/workflow/graph/wire-workflow-graph.js +8 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -13
- package/dist/wirings/workflow/index.d.ts +6 -6
- package/dist/wirings/workflow/index.js +6 -4
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +28 -14
- package/dist/wirings/workflow/pikku-workflow-service.js +200 -56
- package/dist/wirings/workflow/workflow-helpers.d.ts +36 -0
- package/dist/wirings/workflow/workflow-helpers.js +38 -0
- package/dist/wirings/workflow/workflow-utils.d.ts +1 -23
- package/dist/wirings/workflow/workflow-utils.js +1 -66
- package/dist/wirings/workflow/workflow.types.d.ts +40 -93
- package/package.json +13 -15
- package/run-tests.sh +4 -1
- package/src/crypto-utils.ts +99 -0
- package/src/errors/errors.ts +17 -0
- package/src/errors/index.ts +0 -1
- package/src/factory-functions.test.ts +42 -2
- package/src/function/function-runner.test.ts +4 -11
- package/src/function/function-runner.ts +114 -29
- package/src/function/functions.types.ts +62 -132
- package/src/function/index.ts +5 -2
- package/src/handle-error.ts +2 -10
- package/src/index.ts +99 -25
- package/src/middleware/auth-apikey.test.ts +15 -12
- package/src/middleware/auth-apikey.ts +3 -3
- package/src/middleware/auth-bearer.test.ts +17 -14
- package/src/middleware/auth-bearer.ts +25 -27
- package/src/middleware/auth-cookie.test.ts +16 -13
- package/src/middleware/auth-cookie.ts +6 -8
- package/src/middleware/cors.ts +96 -0
- package/src/middleware/index.ts +5 -3
- package/src/middleware/remote-auth.ts +68 -0
- package/src/middleware-runner.test.ts +122 -0
- package/src/middleware-runner.ts +12 -12
- package/src/permissions.test.ts +81 -7
- package/src/permissions.ts +15 -17
- package/src/pikku-state.ts +20 -8
- package/src/run-tests-script.test.ts +49 -0
- package/src/schema.ts +18 -15
- package/src/services/ai-agent-runner-service.ts +29 -0
- package/src/services/ai-run-state-service.ts +20 -0
- package/src/services/ai-storage-service.ts +39 -0
- package/src/services/deployment-service.ts +22 -0
- package/src/services/gopass-secrets.ts +95 -0
- package/src/services/in-memory-trigger-service.ts +68 -0
- package/src/services/in-memory-workflow-service.ts +395 -0
- package/src/services/index.ts +49 -14
- package/src/services/local-secrets.ts +51 -0
- package/src/services/local-variables.ts +22 -0
- package/src/services/scheduler-service.ts +29 -1
- package/src/services/schema-service.ts +7 -0
- package/src/services/scoped-secret-service.ts +41 -0
- package/src/services/secret-service.ts +25 -4
- package/src/services/trigger-service.ts +38 -0
- package/src/services/typed-secret-service.ts +70 -0
- package/src/services/typed-variables-service.ts +81 -0
- package/src/services/user-session-service.ts +23 -0
- package/src/services/variables-service.ts +5 -0
- package/src/services/workflow-service.ts +22 -2
- package/src/types/core.types.ts +76 -11
- package/src/types/state.types.ts +37 -63
- package/src/utils.ts +20 -6
- package/src/version.test.ts +80 -0
- package/src/version.ts +25 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +300 -0
- package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
- package/src/wirings/ai-agent/ai-agent-prepare.ts +470 -0
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +37 -0
- package/src/wirings/ai-agent/ai-agent-registry.ts +82 -0
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +75 -0
- package/src/wirings/ai-agent/ai-agent-runner.ts +137 -0
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +246 -0
- package/src/wirings/ai-agent/ai-agent-stream.ts +774 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +273 -0
- package/src/wirings/ai-agent/index.ts +28 -0
- package/src/wirings/channel/channel-common.ts +32 -19
- package/src/wirings/channel/channel-handler.ts +17 -4
- package/src/wirings/channel/channel-middleware-runner.ts +119 -0
- package/src/wirings/channel/channel-runner.ts +9 -10
- package/src/wirings/channel/channel.types.ts +17 -1
- package/src/wirings/channel/define-channel-routes.ts +25 -0
- package/src/wirings/channel/index.ts +23 -8
- package/src/wirings/channel/local/index.ts +3 -3
- package/src/wirings/channel/local/local-channel-runner.test.ts +44 -1
- package/src/wirings/channel/local/local-channel-runner.ts +22 -6
- package/src/wirings/channel/serverless/index.ts +5 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +20 -4
- package/src/wirings/cli/channel/index.ts +1 -1
- package/src/wirings/cli/cli-runner.test.ts +9 -9
- package/src/wirings/cli/cli-runner.ts +17 -10
- package/src/wirings/cli/cli.types.ts +11 -11
- package/src/wirings/cli/command-parser.test.ts +8 -8
- package/src/wirings/cli/define-cli-commands.ts +24 -0
- package/src/wirings/cli/index.ts +10 -4
- package/src/wirings/http/http-routes.test.ts +322 -0
- package/src/wirings/http/http-routes.ts +198 -0
- package/src/wirings/http/http-runner.test.ts +3 -3
- package/src/wirings/http/http-runner.ts +63 -29
- package/src/wirings/http/http.types.ts +121 -37
- package/src/wirings/http/index.ts +16 -4
- package/src/wirings/mcp/index.ts +27 -3
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +3 -3
- package/src/wirings/mcp/mcp-runner.ts +39 -50
- package/src/wirings/mcp/mcp.types.ts +3 -3
- package/src/wirings/node/index.ts +2 -0
- package/src/wirings/node/node.types.ts +23 -0
- package/src/wirings/oauth2/index.ts +3 -0
- package/src/wirings/oauth2/oauth2-client.test.ts +929 -0
- package/src/wirings/oauth2/oauth2-client.ts +335 -0
- package/src/wirings/oauth2/oauth2.types.ts +69 -0
- package/src/wirings/oauth2/wire-oauth2-credential.ts +23 -0
- package/src/wirings/queue/index.ts +14 -2
- package/src/wirings/queue/queue-runner.test.ts +97 -55
- package/src/wirings/queue/queue-runner.ts +33 -7
- package/src/wirings/queue/queue.types.ts +12 -2
- package/src/wirings/rpc/index.ts +1 -1
- package/src/wirings/rpc/rpc-runner.ts +187 -17
- package/src/wirings/rpc/rpc-types.ts +13 -4
- package/src/wirings/scheduler/index.ts +7 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +70 -26
- package/src/wirings/scheduler/scheduler-runner.ts +45 -5
- package/src/wirings/secret/index.ts +9 -0
- package/src/wirings/secret/secret.types.ts +32 -0
- package/src/wirings/secret/validate-secret-definitions.ts +82 -0
- package/src/wirings/trigger/index.ts +10 -2
- package/src/wirings/trigger/pikku-trigger-service.ts +134 -0
- package/src/wirings/trigger/trigger-runner.ts +80 -38
- package/src/wirings/trigger/trigger.types.ts +144 -22
- package/src/wirings/variable/index.ts +8 -0
- package/src/wirings/variable/validate-variable-definitions.ts +69 -0
- package/src/wirings/variable/variable.types.ts +22 -0
- package/src/wirings/workflow/dsl/index.ts +1 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +9 -1
- package/src/wirings/workflow/dsl/workflow-runner.ts +4 -3
- package/src/wirings/workflow/graph/graph-node.ts +1 -6
- package/src/wirings/workflow/graph/graph-runner.test.ts +495 -0
- package/src/wirings/workflow/graph/graph-runner.ts +496 -374
- package/src/wirings/workflow/graph/index.ts +14 -3
- package/src/wirings/workflow/graph/template.ts +42 -0
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +29 -0
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -22
- package/src/wirings/workflow/index.ts +21 -10
- package/src/wirings/workflow/pikku-workflow-service.test.ts +212 -0
- package/src/wirings/workflow/pikku-workflow-service.ts +285 -66
- package/src/wirings/workflow/workflow-helpers.ts +79 -0
- package/src/wirings/workflow/workflow-utils.ts +0 -120
- package/src/wirings/workflow/workflow.types.ts +45 -90
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/forge-node/forge-node.types.d.ts +0 -120
- package/dist/wirings/forge-node/forge-node.types.js +0 -38
- package/dist/wirings/forge-node/index.d.ts +0 -1
- package/dist/wirings/forge-node/index.js +0 -1
- package/dist/wirings/workflow/wire-workflow.d.ts +0 -42
- package/dist/wirings/workflow/wire-workflow.js +0 -53
- package/src/wirings/forge-node/forge-node.types.ts +0 -135
- package/src/wirings/forge-node/index.ts +0 -1
- package/src/wirings/workflow/wire-workflow.ts +0 -94
|
@@ -189,6 +189,128 @@ describe('combineMiddleware', () => {
|
|
|
189
189
|
assert.equal(result[1], middleware2)
|
|
190
190
|
})
|
|
191
191
|
|
|
192
|
+
test('should apply parent tag middleware to namespaced tag', () => {
|
|
193
|
+
const billingMiddleware: CorePikkuMiddleware = async (
|
|
194
|
+
services,
|
|
195
|
+
wire,
|
|
196
|
+
next
|
|
197
|
+
) => {
|
|
198
|
+
await next()
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
addMiddleware('billing', [billingMiddleware])
|
|
202
|
+
|
|
203
|
+
const result = combineMiddleware('http', Math.random().toString(), {
|
|
204
|
+
wireInheritedMiddleware: [{ type: 'tag', tag: 'billing:read' }],
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
assert.equal(result.length, 1)
|
|
208
|
+
assert.equal(result[0], billingMiddleware)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
test('should apply exact tag middleware for non-namespaced tag', () => {
|
|
212
|
+
const billingMiddleware: CorePikkuMiddleware = async (
|
|
213
|
+
services,
|
|
214
|
+
wire,
|
|
215
|
+
next
|
|
216
|
+
) => {
|
|
217
|
+
await next()
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
addMiddleware('billing', [billingMiddleware])
|
|
221
|
+
|
|
222
|
+
const result = combineMiddleware('http', Math.random().toString(), {
|
|
223
|
+
wireInheritedMiddleware: [{ type: 'tag', tag: 'billing' }],
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
assert.equal(result.length, 1)
|
|
227
|
+
assert.equal(result[0], billingMiddleware)
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
test('should apply both exact and parent tag middleware (specific first)', () => {
|
|
231
|
+
const billingMiddleware: CorePikkuMiddleware = async (
|
|
232
|
+
services,
|
|
233
|
+
wire,
|
|
234
|
+
next
|
|
235
|
+
) => {
|
|
236
|
+
await next()
|
|
237
|
+
}
|
|
238
|
+
const billingReadMiddleware: CorePikkuMiddleware = async (
|
|
239
|
+
services,
|
|
240
|
+
wire,
|
|
241
|
+
next
|
|
242
|
+
) => {
|
|
243
|
+
await next()
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
addMiddleware('billing', [billingMiddleware])
|
|
247
|
+
addMiddleware('billing:read', [billingReadMiddleware])
|
|
248
|
+
|
|
249
|
+
const result = combineMiddleware('http', Math.random().toString(), {
|
|
250
|
+
wireInheritedMiddleware: [{ type: 'tag', tag: 'billing:read' }],
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
assert.equal(result.length, 2)
|
|
254
|
+
assert.equal(result[0], billingReadMiddleware)
|
|
255
|
+
assert.equal(result[1], billingMiddleware)
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
test('should resolve multi-level namespace tags', () => {
|
|
259
|
+
const billingMiddleware: CorePikkuMiddleware = async (
|
|
260
|
+
services,
|
|
261
|
+
wire,
|
|
262
|
+
next
|
|
263
|
+
) => {
|
|
264
|
+
await next()
|
|
265
|
+
}
|
|
266
|
+
const billingReadMiddleware: CorePikkuMiddleware = async (
|
|
267
|
+
services,
|
|
268
|
+
wire,
|
|
269
|
+
next
|
|
270
|
+
) => {
|
|
271
|
+
await next()
|
|
272
|
+
}
|
|
273
|
+
const billingReadAdminMiddleware: CorePikkuMiddleware = async (
|
|
274
|
+
services,
|
|
275
|
+
wire,
|
|
276
|
+
next
|
|
277
|
+
) => {
|
|
278
|
+
await next()
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
addMiddleware('billing', [billingMiddleware])
|
|
282
|
+
addMiddleware('billing:read', [billingReadMiddleware])
|
|
283
|
+
addMiddleware('billing:read:admin', [billingReadAdminMiddleware])
|
|
284
|
+
|
|
285
|
+
const result = combineMiddleware('http', Math.random().toString(), {
|
|
286
|
+
wireInheritedMiddleware: [{ type: 'tag', tag: 'billing:read:admin' }],
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
assert.equal(result.length, 3)
|
|
290
|
+
assert.equal(result[0], billingReadAdminMiddleware)
|
|
291
|
+
assert.equal(result[1], billingReadMiddleware)
|
|
292
|
+
assert.equal(result[2], billingMiddleware)
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
test('should apply parent tag middleware via funcInheritedMiddleware', () => {
|
|
296
|
+
const billingMiddleware: CorePikkuMiddleware = async (
|
|
297
|
+
services,
|
|
298
|
+
wire,
|
|
299
|
+
next
|
|
300
|
+
) => {
|
|
301
|
+
await next()
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
addMiddleware('billing', [billingMiddleware])
|
|
305
|
+
|
|
306
|
+
const result = combineMiddleware('http', Math.random().toString(), {
|
|
307
|
+
funcInheritedMiddleware: [{ type: 'tag', tag: 'billing:write' }],
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
assert.equal(result.length, 1)
|
|
311
|
+
assert.equal(result[0], billingMiddleware)
|
|
312
|
+
})
|
|
313
|
+
|
|
192
314
|
test('should ignore non-existent tags', () => {
|
|
193
315
|
const middleware: CorePikkuMiddleware = async (services, wire, next) => {
|
|
194
316
|
await next()
|
package/src/middleware-runner.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
MiddlewareMetadata,
|
|
8
8
|
} from './types/core.types.js'
|
|
9
9
|
import { pikkuState } from './pikku-state.js'
|
|
10
|
-
import { freezeDedupe } from './utils.js'
|
|
10
|
+
import { freezeDedupe, getTagGroups } from './utils.js'
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Runs a chain of middleware functions in sequence before executing the main function.
|
|
@@ -96,7 +96,7 @@ export const addMiddleware = <PikkuMiddleware extends CorePikkuMiddleware>(
|
|
|
96
96
|
* This function looks up middleware that was registered with registerMiddleware.
|
|
97
97
|
* It's used internally by the framework to resolve middleware references in metadata.
|
|
98
98
|
*
|
|
99
|
-
* @param {string} name - The unique name (
|
|
99
|
+
* @param {string} name - The unique name (pikkuFuncId) of the middleware function.
|
|
100
100
|
* @returns {CorePikkuMiddleware | undefined} The middleware function, or undefined if not found.
|
|
101
101
|
*
|
|
102
102
|
* @internal
|
|
@@ -116,7 +116,9 @@ const middlewareCache: Record<
|
|
|
116
116
|
channel: {},
|
|
117
117
|
queue: {},
|
|
118
118
|
scheduler: {},
|
|
119
|
+
trigger: {},
|
|
119
120
|
mcp: {},
|
|
121
|
+
agent: {},
|
|
120
122
|
cli: {},
|
|
121
123
|
workflow: {},
|
|
122
124
|
}
|
|
@@ -179,12 +181,11 @@ export const combineMiddleware = (
|
|
|
179
181
|
resolved.push(...(group as CorePikkuMiddleware[]))
|
|
180
182
|
}
|
|
181
183
|
} else if (meta.type === 'tag') {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
+
const groups = getTagGroups(
|
|
185
|
+
pikkuState(packageName, 'middleware', 'tagGroup'),
|
|
184
186
|
meta.tag
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// At runtime, all factories should be resolved to middleware
|
|
187
|
+
)
|
|
188
|
+
for (const group of groups) {
|
|
188
189
|
resolved.push(...(group as CorePikkuMiddleware[]))
|
|
189
190
|
}
|
|
190
191
|
} else if (meta.type === 'wire') {
|
|
@@ -206,12 +207,11 @@ export const combineMiddleware = (
|
|
|
206
207
|
if (funcInheritedMiddleware) {
|
|
207
208
|
for (const meta of funcInheritedMiddleware) {
|
|
208
209
|
if (meta.type === 'tag') {
|
|
209
|
-
|
|
210
|
-
|
|
210
|
+
const groups = getTagGroups(
|
|
211
|
+
pikkuState(packageName, 'middleware', 'tagGroup'),
|
|
211
212
|
meta.tag
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
// At runtime, all factories should be resolved to middleware
|
|
213
|
+
)
|
|
214
|
+
for (const group of groups) {
|
|
215
215
|
resolved.push(...(group as CorePikkuMiddleware[]))
|
|
216
216
|
}
|
|
217
217
|
}
|
package/src/permissions.test.ts
CHANGED
|
@@ -82,6 +82,85 @@ describe('addPermission', () => {
|
|
|
82
82
|
assert.equal(permissions[0], mockPermissionGroup)
|
|
83
83
|
})
|
|
84
84
|
|
|
85
|
+
test('should apply parent tag permission to namespaced tag via runPermissions', async () => {
|
|
86
|
+
const billingPermission = async () => true
|
|
87
|
+
|
|
88
|
+
addPermission('billing', [billingPermission])
|
|
89
|
+
|
|
90
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
91
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'billing:write' }],
|
|
92
|
+
services: mockServices,
|
|
93
|
+
wire: {},
|
|
94
|
+
data: {},
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
test('should apply both parent and exact tag permissions', async () => {
|
|
99
|
+
const executionOrder: string[] = []
|
|
100
|
+
const billingPermission = async () => {
|
|
101
|
+
executionOrder.push('billing')
|
|
102
|
+
return true
|
|
103
|
+
}
|
|
104
|
+
const billingReadPermission = async () => {
|
|
105
|
+
executionOrder.push('billing:read')
|
|
106
|
+
return true
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
addPermission('billing', [billingPermission])
|
|
110
|
+
addPermission('billing:read', [billingReadPermission])
|
|
111
|
+
|
|
112
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
113
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'billing:read' }],
|
|
114
|
+
services: mockServices,
|
|
115
|
+
wire: {},
|
|
116
|
+
data: {},
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
assert.deepEqual(executionOrder, ['billing:read'])
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
test('should resolve multi-level namespace permissions', async () => {
|
|
123
|
+
const executionOrder: string[] = []
|
|
124
|
+
const billingPermission = async () => {
|
|
125
|
+
executionOrder.push('billing')
|
|
126
|
+
return false
|
|
127
|
+
}
|
|
128
|
+
const billingReadPermission = async () => {
|
|
129
|
+
executionOrder.push('billing:read')
|
|
130
|
+
return false
|
|
131
|
+
}
|
|
132
|
+
const billingReadAdminPermission = async () => {
|
|
133
|
+
executionOrder.push('billing:read:admin')
|
|
134
|
+
return true
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
addPermission('billing', [billingPermission])
|
|
138
|
+
addPermission('billing:read', [billingReadPermission])
|
|
139
|
+
addPermission('billing:read:admin', [billingReadAdminPermission])
|
|
140
|
+
|
|
141
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
142
|
+
wireInheritedPermissions: [{ type: 'tag', tag: 'billing:read:admin' }],
|
|
143
|
+
services: mockServices,
|
|
144
|
+
wire: {},
|
|
145
|
+
data: {},
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
assert.deepEqual(executionOrder, ['billing:read:admin'])
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
test('should apply parent tag permission via funcInheritedPermissions', async () => {
|
|
152
|
+
const billingPermission = async () => true
|
|
153
|
+
|
|
154
|
+
addPermission('billing', [billingPermission])
|
|
155
|
+
|
|
156
|
+
await runPermissions('rpc', Math.random().toString(), {
|
|
157
|
+
funcInheritedPermissions: [{ type: 'tag', tag: 'billing:delete' }],
|
|
158
|
+
services: mockServices,
|
|
159
|
+
wire: {},
|
|
160
|
+
data: {},
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
|
|
85
164
|
test('should throw error when tag already exists', () => {
|
|
86
165
|
const mockPermission = async () => true
|
|
87
166
|
|
|
@@ -171,13 +250,8 @@ describe('runPermissions', () => {
|
|
|
171
250
|
data: {},
|
|
172
251
|
})
|
|
173
252
|
|
|
174
|
-
// Order: wireInheritedPermissions (wiringTag)
|
|
175
|
-
assert.deepEqual(executionOrder, [
|
|
176
|
-
'wiringTag',
|
|
177
|
-
'wiringPermission',
|
|
178
|
-
'funcTag',
|
|
179
|
-
'funcPermission',
|
|
180
|
-
])
|
|
253
|
+
// Order: wireInheritedPermissions (wiringTag) only (short-circuit on first passing group)
|
|
254
|
+
assert.deepEqual(executionOrder, ['wiringTag'])
|
|
181
255
|
})
|
|
182
256
|
|
|
183
257
|
test('should implement "at least one must pass" logic for tag permissions', async () => {
|
package/src/permissions.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from './function/functions.types.js'
|
|
11
11
|
import { pikkuState } from './pikku-state.js'
|
|
12
12
|
import { ForbiddenError } from './errors/errors.js'
|
|
13
|
-
import { freezeDedupe } from './utils.js'
|
|
13
|
+
import { freezeDedupe, getTagGroups } from './utils.js'
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* This function validates permissions by iterating over permission groups and executing the corresponding permission functions. If all functions in at least one group return true, the permission is considered valid.
|
|
@@ -59,7 +59,7 @@ const verifyPermissions = async <Out = any>(
|
|
|
59
59
|
* This function looks up permissions that was registered with registerPermission.
|
|
60
60
|
* It's used internally by the framework to resolve permission references in metadata.
|
|
61
61
|
*
|
|
62
|
-
* @param {string} name - The unique name (
|
|
62
|
+
* @param {string} name - The unique name (pikkuFuncId) of the permission function.
|
|
63
63
|
* @returns {CorePikkuPermission | undefined} The permission function, or undefined if not found.
|
|
64
64
|
*
|
|
65
65
|
* @internal
|
|
@@ -125,7 +125,9 @@ const combinedPermissionsCache: Record<
|
|
|
125
125
|
channel: {},
|
|
126
126
|
queue: {},
|
|
127
127
|
scheduler: {},
|
|
128
|
+
trigger: {},
|
|
128
129
|
mcp: {},
|
|
130
|
+
agent: {},
|
|
129
131
|
cli: {},
|
|
130
132
|
workflow: {},
|
|
131
133
|
}
|
|
@@ -193,11 +195,11 @@ const combinePermissions = (
|
|
|
193
195
|
}
|
|
194
196
|
}
|
|
195
197
|
} else if (meta.type === 'tag') {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
const groups = getTagGroups(
|
|
199
|
+
pikkuState(packageName, 'permissions', 'tagGroup'),
|
|
198
200
|
meta.tag
|
|
199
|
-
|
|
200
|
-
|
|
201
|
+
)
|
|
202
|
+
for (const group of groups) {
|
|
201
203
|
if (Array.isArray(group)) {
|
|
202
204
|
resolved.push(...group)
|
|
203
205
|
} else {
|
|
@@ -227,11 +229,11 @@ const combinePermissions = (
|
|
|
227
229
|
if (funcInheritedPermissions) {
|
|
228
230
|
for (const meta of funcInheritedPermissions) {
|
|
229
231
|
if (meta.type === 'tag') {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
const groups = getTagGroups(
|
|
233
|
+
pikkuState(packageName, 'permissions', 'tagGroup'),
|
|
232
234
|
meta.tag
|
|
233
|
-
|
|
234
|
-
|
|
235
|
+
)
|
|
236
|
+
for (const group of groups) {
|
|
235
237
|
if (Array.isArray(group)) {
|
|
236
238
|
resolved.push(...group)
|
|
237
239
|
} else {
|
|
@@ -299,7 +301,6 @@ export const runPermissions = async (
|
|
|
299
301
|
|
|
300
302
|
// Check all combined permissions - at least one must pass if any exist
|
|
301
303
|
if (allPermissions.length > 0) {
|
|
302
|
-
let permissioned = false
|
|
303
304
|
for (const permission of allPermissions) {
|
|
304
305
|
const result = await verifyPermissions(
|
|
305
306
|
typeof permission === 'function' ? { permission } : permission,
|
|
@@ -308,13 +309,10 @@ export const runPermissions = async (
|
|
|
308
309
|
wire
|
|
309
310
|
)
|
|
310
311
|
if (result) {
|
|
311
|
-
|
|
312
|
-
// Continue executing all permissions (don't break early)
|
|
312
|
+
return
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
throw new ForbiddenError('Permission denied')
|
|
318
|
-
}
|
|
315
|
+
services.logger.debug('Permission denied - combined permissions')
|
|
316
|
+
throw new ForbiddenError('Permission denied')
|
|
319
317
|
}
|
|
320
318
|
}
|
package/src/pikku-state.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
MCPToolMeta,
|
|
6
6
|
MCPPromptMeta,
|
|
7
7
|
} from './wirings/mcp/mcp.types.js'
|
|
8
|
+
import { AIAgentMeta } from './wirings/ai-agent/ai-agent.types.js'
|
|
8
9
|
import { ScheduledTasksMeta } from './wirings/scheduler/scheduler.types.js'
|
|
9
10
|
import { TriggerMeta } from './wirings/trigger/trigger.types.js'
|
|
10
11
|
|
|
@@ -95,23 +96,26 @@ const createEmptyPackageState = (): PikkuPackageState => ({
|
|
|
95
96
|
},
|
|
96
97
|
workflows: {
|
|
97
98
|
registrations: new Map(),
|
|
98
|
-
graphRegistrations: new Map(),
|
|
99
|
-
wirings: new Map(),
|
|
100
|
-
graphWirings: new Map(),
|
|
101
99
|
meta: {},
|
|
102
100
|
},
|
|
103
101
|
trigger: {
|
|
102
|
+
functions: new Map(),
|
|
104
103
|
triggers: new Map(),
|
|
104
|
+
triggerSources: new Map(),
|
|
105
105
|
meta: {} as TriggerMeta,
|
|
106
|
+
sourceMeta: {},
|
|
106
107
|
},
|
|
107
108
|
mcp: {
|
|
108
109
|
resources: new Map(),
|
|
109
110
|
resourcesMeta: {} as MCPResourceMeta,
|
|
110
|
-
tools: new Map(),
|
|
111
111
|
toolsMeta: {} as MCPToolMeta,
|
|
112
112
|
prompts: new Map(),
|
|
113
113
|
promptsMeta: {} as MCPPromptMeta,
|
|
114
114
|
},
|
|
115
|
+
agent: {
|
|
116
|
+
agents: new Map(),
|
|
117
|
+
agentsMeta: {} as AIAgentMeta,
|
|
118
|
+
},
|
|
115
119
|
cli: {
|
|
116
120
|
meta: { programs: {}, renderers: {} },
|
|
117
121
|
programs: {},
|
|
@@ -119,24 +123,28 @@ const createEmptyPackageState = (): PikkuPackageState => ({
|
|
|
119
123
|
middleware: {
|
|
120
124
|
tagGroup: {},
|
|
121
125
|
httpGroup: {},
|
|
122
|
-
|
|
123
|
-
|
|
126
|
+
},
|
|
127
|
+
channelMiddleware: {
|
|
128
|
+
tagGroup: {},
|
|
124
129
|
},
|
|
125
130
|
permissions: {
|
|
126
131
|
tagGroup: {},
|
|
127
132
|
httpGroup: {},
|
|
128
|
-
tagGroupMeta: {},
|
|
129
|
-
httpGroupMeta: {},
|
|
130
133
|
},
|
|
131
134
|
misc: {
|
|
132
135
|
errors: new Map(),
|
|
133
136
|
schemas: new Map(),
|
|
134
137
|
middleware: {},
|
|
138
|
+
channelMiddleware: {},
|
|
135
139
|
permissions: {},
|
|
136
140
|
},
|
|
141
|
+
models: {
|
|
142
|
+
config: null,
|
|
143
|
+
},
|
|
137
144
|
package: {
|
|
138
145
|
factories: null,
|
|
139
146
|
singletonServices: null,
|
|
147
|
+
metaDir: null,
|
|
140
148
|
},
|
|
141
149
|
})
|
|
142
150
|
|
|
@@ -170,6 +178,10 @@ if (!globalThis.pikkuState) {
|
|
|
170
178
|
resetPikkuState()
|
|
171
179
|
}
|
|
172
180
|
|
|
181
|
+
export const getPikkuMetaDir = (packageName?: string | null): string | null => {
|
|
182
|
+
return pikkuState(packageName ?? null, 'package', 'metaDir')
|
|
183
|
+
}
|
|
184
|
+
|
|
173
185
|
/**
|
|
174
186
|
* Register service factories for an external package.
|
|
175
187
|
* These factories are used to create services when the package's functions are invoked.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { describe, test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import os from 'node:os'
|
|
5
|
+
import path from 'node:path'
|
|
6
|
+
import { spawnSync } from 'node:child_process'
|
|
7
|
+
import { fileURLToPath } from 'node:url'
|
|
8
|
+
|
|
9
|
+
const thisDir = path.dirname(fileURLToPath(import.meta.url))
|
|
10
|
+
const packageRoot = path.resolve(thisDir, '..')
|
|
11
|
+
const runTestsScriptPath = path.join(packageRoot, 'run-tests.sh')
|
|
12
|
+
|
|
13
|
+
describe('run-tests.sh discovery behavior', () => {
|
|
14
|
+
test('returns success by default when no tests are found', () => {
|
|
15
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pikku-core-tests-'))
|
|
16
|
+
const srcDir = path.join(tempDir, 'src')
|
|
17
|
+
fs.mkdirSync(srcDir, { recursive: true })
|
|
18
|
+
fs.copyFileSync(runTestsScriptPath, path.join(tempDir, 'run-tests.sh'))
|
|
19
|
+
|
|
20
|
+
const result = spawnSync('bash', ['run-tests.sh'], {
|
|
21
|
+
cwd: tempDir,
|
|
22
|
+
encoding: 'utf8',
|
|
23
|
+
env: { ...process.env, CI: 'false' },
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
assert.equal(result.status, 0)
|
|
27
|
+
assert.match(result.stdout, /No test files found matching pattern/)
|
|
28
|
+
|
|
29
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test('returns failure in strict mode when no tests are found', () => {
|
|
33
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pikku-core-tests-'))
|
|
34
|
+
const srcDir = path.join(tempDir, 'src')
|
|
35
|
+
fs.mkdirSync(srcDir, { recursive: true })
|
|
36
|
+
fs.copyFileSync(runTestsScriptPath, path.join(tempDir, 'run-tests.sh'))
|
|
37
|
+
|
|
38
|
+
const result = spawnSync('bash', ['run-tests.sh'], {
|
|
39
|
+
cwd: tempDir,
|
|
40
|
+
encoding: 'utf8',
|
|
41
|
+
env: { ...process.env, STRICT_TEST_DISCOVERY: '1' },
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
assert.equal(result.status, 1)
|
|
45
|
+
assert.match(result.stdout, /No test files found matching pattern/)
|
|
46
|
+
|
|
47
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
48
|
+
})
|
|
49
|
+
})
|
package/src/schema.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { Logger } from './services/logger.js'
|
|
2
2
|
import { SchemaService } from './services/schema-service.js'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
MissingSchemaError,
|
|
5
|
+
UnprocessableContentError,
|
|
6
|
+
} from './errors/errors.js'
|
|
4
7
|
import { pikkuState } from './pikku-state.js'
|
|
5
8
|
|
|
9
|
+
const schemaKey = (name: string, packageName: string | null): string =>
|
|
10
|
+
packageName ? `${packageName}:${name}` : name
|
|
11
|
+
|
|
6
12
|
/**
|
|
7
13
|
* Adds a schema to the schemas map for a specific package.
|
|
8
14
|
* @param name - The name of the schema.
|
|
@@ -43,9 +49,11 @@ export const compileAllSchemas = (
|
|
|
43
49
|
if (!schemaService) {
|
|
44
50
|
throw new Error('SchemaService needs to be defined to load schemas')
|
|
45
51
|
}
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
for (const [pkgName, packageState] of globalThis.pikkuState!) {
|
|
53
|
+
const resolvedPkgName = pkgName === '__main__' ? null : pkgName
|
|
54
|
+
for (const [name, schema] of packageState.misc.schemas) {
|
|
55
|
+
schemaService.compileSchema(schemaKey(name, resolvedPkgName), schema)
|
|
56
|
+
}
|
|
49
57
|
}
|
|
50
58
|
validateAllSchemasLoaded(logger, schemaService)
|
|
51
59
|
}
|
|
@@ -61,7 +69,7 @@ const validateAllSchemasLoaded = (
|
|
|
61
69
|
|
|
62
70
|
for (const routePaths of Object.values(routesMeta)) {
|
|
63
71
|
for (const meta of Object.values(routePaths)) {
|
|
64
|
-
const inputs = pikkuState(null, 'function', 'meta')[meta.
|
|
72
|
+
const inputs = pikkuState(null, 'function', 'meta')[meta.pikkuFuncId]
|
|
65
73
|
?.inputs
|
|
66
74
|
const input = inputs?.[0]
|
|
67
75
|
if (!input || validators.has(input)) {
|
|
@@ -121,10 +129,7 @@ export const validateSchema = async (
|
|
|
121
129
|
return
|
|
122
130
|
}
|
|
123
131
|
}
|
|
124
|
-
|
|
125
|
-
`[validateSchema] Validating schema '${schemaName}' for package '${packageName ?? 'main'}' with data:`,
|
|
126
|
-
JSON.stringify(data)
|
|
127
|
-
)
|
|
132
|
+
const key = schemaKey(schemaName, packageName)
|
|
128
133
|
const schemas = pikkuState(packageName, 'misc', 'schemas')
|
|
129
134
|
const schema = schemas.get(schemaName)
|
|
130
135
|
if (schema === undefined) {
|
|
@@ -132,13 +137,11 @@ export const validateSchema = async (
|
|
|
132
137
|
logger.error(
|
|
133
138
|
`Schema '${schemaName}' not found for package '${packageName ?? 'main'}'. Available schemas: ${availableSchemas.join(', ') || '(none)'}`
|
|
134
139
|
)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
`[validateSchema] Found schema '${schemaName}':`,
|
|
138
|
-
JSON.stringify(schema)
|
|
140
|
+
throw new MissingSchemaError(
|
|
141
|
+
`Schema '${schemaName}' not found. Ensure schema generation has been run.`
|
|
139
142
|
)
|
|
140
143
|
}
|
|
141
|
-
await schemaService.compileSchema(
|
|
142
|
-
await schemaService.validateSchema(
|
|
144
|
+
await schemaService.compileSchema(key, schema)
|
|
145
|
+
await schemaService.validateSchema(key, data)
|
|
143
146
|
}
|
|
144
147
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AIMessage,
|
|
3
|
+
AIAgentStep,
|
|
4
|
+
AIAgentToolDef,
|
|
5
|
+
AIStreamChannel,
|
|
6
|
+
} from '../wirings/ai-agent/ai-agent.types.js'
|
|
7
|
+
|
|
8
|
+
export type AIAgentRunnerParams = {
|
|
9
|
+
model: string
|
|
10
|
+
temperature?: number
|
|
11
|
+
instructions: string
|
|
12
|
+
messages: AIMessage[]
|
|
13
|
+
tools: AIAgentToolDef[]
|
|
14
|
+
maxSteps: number
|
|
15
|
+
toolChoice: 'auto' | 'required' | 'none'
|
|
16
|
+
outputSchema?: Record<string, unknown>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type AIAgentRunnerResult = {
|
|
20
|
+
text: string
|
|
21
|
+
object?: unknown
|
|
22
|
+
steps: AIAgentStep[]
|
|
23
|
+
usage: { inputTokens: number; outputTokens: number }
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface AIAgentRunnerService {
|
|
27
|
+
stream(params: AIAgentRunnerParams, channel: AIStreamChannel): Promise<void>
|
|
28
|
+
run(params: AIAgentRunnerParams): Promise<AIAgentRunnerResult>
|
|
29
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentRunState,
|
|
3
|
+
PendingApproval,
|
|
4
|
+
} from '../wirings/ai-agent/ai-agent.types.js'
|
|
5
|
+
|
|
6
|
+
export type CreateRunInput = Omit<AgentRunState, 'runId'>
|
|
7
|
+
|
|
8
|
+
export interface AIRunStateService {
|
|
9
|
+
createRun(run: CreateRunInput): Promise<string>
|
|
10
|
+
updateRun(runId: string, updates: Partial<AgentRunState>): Promise<void>
|
|
11
|
+
getRun(runId: string): Promise<AgentRunState | null>
|
|
12
|
+
getRunsByThread(threadId: string): Promise<AgentRunState[]>
|
|
13
|
+
resolveApproval(
|
|
14
|
+
toolCallId: string,
|
|
15
|
+
status: 'approved' | 'denied'
|
|
16
|
+
): Promise<void>
|
|
17
|
+
findRunByToolCallId(
|
|
18
|
+
toolCallId: string
|
|
19
|
+
): Promise<{ run: AgentRunState; approval: PendingApproval } | null>
|
|
20
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { AIThread, AIMessage } from '../wirings/ai-agent/ai-agent.types.js'
|
|
2
|
+
|
|
3
|
+
export interface AIStorageService {
|
|
4
|
+
createThread(
|
|
5
|
+
resourceId: string,
|
|
6
|
+
options?: {
|
|
7
|
+
threadId?: string
|
|
8
|
+
title?: string
|
|
9
|
+
metadata?: Record<string, unknown>
|
|
10
|
+
}
|
|
11
|
+
): Promise<AIThread>
|
|
12
|
+
|
|
13
|
+
getThread(threadId: string): Promise<AIThread>
|
|
14
|
+
|
|
15
|
+
getThreads(resourceId: string): Promise<AIThread[]>
|
|
16
|
+
|
|
17
|
+
deleteThread(threadId: string): Promise<void>
|
|
18
|
+
|
|
19
|
+
getMessages(
|
|
20
|
+
threadId: string,
|
|
21
|
+
options?: {
|
|
22
|
+
lastN?: number
|
|
23
|
+
cursor?: string
|
|
24
|
+
}
|
|
25
|
+
): Promise<AIMessage[]>
|
|
26
|
+
|
|
27
|
+
saveMessages(threadId: string, messages: AIMessage[]): Promise<void>
|
|
28
|
+
|
|
29
|
+
getWorkingMemory(
|
|
30
|
+
id: string,
|
|
31
|
+
scope: 'resource' | 'thread'
|
|
32
|
+
): Promise<Record<string, unknown> | null>
|
|
33
|
+
|
|
34
|
+
saveWorkingMemory(
|
|
35
|
+
id: string,
|
|
36
|
+
scope: 'resource' | 'thread',
|
|
37
|
+
data: Record<string, unknown>
|
|
38
|
+
): Promise<void>
|
|
39
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface DeploymentServiceConfig {
|
|
2
|
+
heartbeatInterval?: number
|
|
3
|
+
heartbeatTtl?: number
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface DeploymentConfig {
|
|
7
|
+
deploymentId: string
|
|
8
|
+
endpoint: string
|
|
9
|
+
functions?: string[]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface DeploymentInfo {
|
|
13
|
+
deploymentId: string
|
|
14
|
+
endpoint: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface DeploymentService {
|
|
18
|
+
init(): Promise<void>
|
|
19
|
+
start(config: DeploymentConfig): Promise<void>
|
|
20
|
+
stop(): Promise<void>
|
|
21
|
+
findFunction(name: string): Promise<DeploymentInfo[]>
|
|
22
|
+
}
|