@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.
Files changed (344) hide show
  1. package/CHANGELOG.md +33 -2
  2. package/dist/crypto-utils.d.ts +2 -0
  3. package/dist/crypto-utils.js +78 -0
  4. package/dist/errors/errors.d.ts +8 -0
  5. package/dist/errors/errors.js +16 -0
  6. package/dist/errors/index.d.ts +0 -1
  7. package/dist/errors/index.js +0 -1
  8. package/dist/function/function-runner.d.ts +7 -1
  9. package/dist/function/function-runner.js +82 -23
  10. package/dist/function/functions.types.d.ts +31 -87
  11. package/dist/function/functions.types.js +16 -46
  12. package/dist/function/index.d.ts +2 -2
  13. package/dist/function/index.js +1 -2
  14. package/dist/handle-error.js +1 -10
  15. package/dist/index.d.ts +28 -26
  16. package/dist/index.js +18 -29
  17. package/dist/middleware/auth-apikey.d.ts +2 -2
  18. package/dist/middleware/auth-apikey.js +3 -3
  19. package/dist/middleware/auth-bearer.d.ts +2 -2
  20. package/dist/middleware/auth-bearer.js +3 -6
  21. package/dist/middleware/auth-cookie.d.ts +2 -2
  22. package/dist/middleware/auth-cookie.js +6 -8
  23. package/dist/middleware/cors.d.ts +46 -0
  24. package/dist/middleware/cors.js +73 -0
  25. package/dist/middleware/index.d.ts +5 -3
  26. package/dist/middleware/index.js +5 -3
  27. package/dist/middleware/remote-auth.d.ts +5 -0
  28. package/dist/middleware/remote-auth.js +55 -0
  29. package/dist/middleware/timeout.d.ts +2 -2
  30. package/dist/middleware-runner.js +8 -10
  31. package/dist/permissions.js +11 -15
  32. package/dist/pikku-state.d.ts +1 -0
  33. package/dist/pikku-state.js +18 -8
  34. package/dist/schema.js +12 -11
  35. package/dist/services/ai-agent-runner-service.d.ts +24 -0
  36. package/dist/services/ai-agent-runner-service.js +1 -0
  37. package/dist/services/ai-run-state-service.d.ts +13 -0
  38. package/dist/services/ai-run-state-service.js +1 -0
  39. package/dist/services/ai-storage-service.d.ts +18 -0
  40. package/dist/services/ai-storage-service.js +1 -0
  41. package/dist/services/deployment-service.d.ts +19 -0
  42. package/dist/services/deployment-service.js +1 -0
  43. package/dist/services/gopass-secrets.d.ts +47 -0
  44. package/dist/services/gopass-secrets.js +94 -0
  45. package/dist/services/in-memory-trigger-service.d.ts +23 -0
  46. package/dist/services/in-memory-trigger-service.js +50 -0
  47. package/dist/services/in-memory-workflow-service.d.ts +59 -0
  48. package/dist/services/in-memory-workflow-service.js +287 -0
  49. package/dist/services/index.d.ts +25 -11
  50. package/dist/services/index.js +10 -13
  51. package/dist/services/local-secrets.d.ts +23 -0
  52. package/dist/services/local-secrets.js +45 -0
  53. package/dist/services/local-variables.d.ts +5 -0
  54. package/dist/services/local-variables.js +18 -0
  55. package/dist/services/scheduler-service.d.ts +21 -1
  56. package/dist/services/scheduler-service.js +14 -0
  57. package/dist/services/schema-service.d.ts +6 -0
  58. package/dist/services/scoped-secret-service.d.ts +16 -0
  59. package/dist/services/scoped-secret-service.js +35 -0
  60. package/dist/services/secret-service.d.ts +25 -4
  61. package/dist/services/trigger-service.d.ts +23 -0
  62. package/dist/services/trigger-service.js +1 -0
  63. package/dist/services/typed-secret-service.d.ts +30 -0
  64. package/dist/services/typed-secret-service.js +40 -0
  65. package/dist/services/typed-variables-service.d.ts +27 -0
  66. package/dist/services/typed-variables-service.js +46 -0
  67. package/dist/services/user-session-service.d.ts +13 -0
  68. package/dist/services/user-session-service.js +17 -0
  69. package/dist/services/variables-service.d.ts +5 -0
  70. package/dist/services/workflow-service.d.ts +9 -4
  71. package/dist/types/core.types.d.ts +48 -12
  72. package/dist/types/core.types.js +8 -1
  73. package/dist/types/state.types.d.ts +43 -51
  74. package/dist/utils.d.ts +3 -2
  75. package/dist/utils.js +15 -3
  76. package/dist/version.d.ts +6 -0
  77. package/dist/version.js +19 -0
  78. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +29 -0
  79. package/dist/wirings/ai-agent/ai-agent-memory.js +199 -0
  80. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +9 -0
  81. package/dist/wirings/ai-agent/ai-agent-model-config.js +36 -0
  82. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +60 -0
  83. package/dist/wirings/ai-agent/ai-agent-prepare.js +312 -0
  84. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +15 -0
  85. package/dist/wirings/ai-agent/ai-agent-registry.js +47 -0
  86. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +3 -0
  87. package/dist/wirings/ai-agent/ai-agent-runner.js +96 -0
  88. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +11 -0
  89. package/dist/wirings/ai-agent/ai-agent-stream.js +503 -0
  90. package/dist/wirings/ai-agent/ai-agent.types.d.ts +254 -0
  91. package/dist/wirings/ai-agent/ai-agent.types.js +1 -0
  92. package/dist/wirings/ai-agent/index.d.ts +5 -0
  93. package/dist/wirings/ai-agent/index.js +4 -0
  94. package/dist/wirings/channel/channel-common.d.ts +7 -4
  95. package/dist/wirings/channel/channel-common.js +15 -8
  96. package/dist/wirings/channel/channel-handler.js +12 -3
  97. package/dist/wirings/channel/channel-middleware-runner.d.ts +9 -0
  98. package/dist/wirings/channel/channel-middleware-runner.js +73 -0
  99. package/dist/wirings/channel/channel-runner.js +7 -7
  100. package/dist/wirings/channel/channel.types.d.ts +5 -1
  101. package/dist/wirings/channel/define-channel-routes.d.ts +21 -0
  102. package/dist/wirings/channel/define-channel-routes.js +23 -0
  103. package/dist/wirings/channel/index.d.ts +10 -8
  104. package/dist/wirings/channel/index.js +7 -8
  105. package/dist/wirings/channel/local/index.d.ts +3 -3
  106. package/dist/wirings/channel/local/index.js +3 -3
  107. package/dist/wirings/channel/local/local-channel-runner.js +18 -6
  108. package/dist/wirings/channel/serverless/index.d.ts +1 -1
  109. package/dist/wirings/channel/serverless/index.js +1 -1
  110. package/dist/wirings/channel/serverless/serverless-channel-runner.js +15 -4
  111. package/dist/wirings/cli/channel/index.d.ts +1 -1
  112. package/dist/wirings/cli/channel/index.js +1 -1
  113. package/dist/wirings/cli/cli-runner.d.ts +1 -1
  114. package/dist/wirings/cli/cli-runner.js +12 -8
  115. package/dist/wirings/cli/cli.types.d.ts +6 -6
  116. package/dist/wirings/cli/define-cli-commands.d.ts +19 -0
  117. package/dist/wirings/cli/define-cli-commands.js +20 -0
  118. package/dist/wirings/cli/index.d.ts +2 -3
  119. package/dist/wirings/cli/index.js +1 -3
  120. package/dist/wirings/http/http-routes.d.ts +69 -0
  121. package/dist/wirings/http/http-routes.js +139 -0
  122. package/dist/wirings/http/http-runner.js +49 -23
  123. package/dist/wirings/http/http.types.d.ts +78 -38
  124. package/dist/wirings/http/index.d.ts +5 -4
  125. package/dist/wirings/http/index.js +4 -3
  126. package/dist/wirings/mcp/index.d.ts +4 -3
  127. package/dist/wirings/mcp/index.js +3 -3
  128. package/dist/wirings/mcp/mcp-runner.d.ts +1 -3
  129. package/dist/wirings/mcp/mcp-runner.js +25 -39
  130. package/dist/wirings/mcp/mcp.types.d.ts +3 -3
  131. package/dist/wirings/node/index.d.ts +2 -0
  132. package/dist/wirings/node/index.js +1 -0
  133. package/dist/wirings/node/node.types.d.ts +20 -0
  134. package/dist/wirings/node/node.types.js +1 -0
  135. package/dist/wirings/oauth2/index.d.ts +3 -0
  136. package/dist/wirings/oauth2/index.js +2 -0
  137. package/dist/wirings/oauth2/oauth2-client.d.ts +47 -0
  138. package/dist/wirings/oauth2/oauth2-client.js +267 -0
  139. package/dist/wirings/oauth2/oauth2.types.d.ts +65 -0
  140. package/dist/wirings/oauth2/oauth2.types.js +4 -0
  141. package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +20 -0
  142. package/dist/wirings/oauth2/wire-oauth2-credential.js +21 -0
  143. package/dist/wirings/queue/index.d.ts +2 -2
  144. package/dist/wirings/queue/index.js +1 -1
  145. package/dist/wirings/queue/queue-runner.d.ts +7 -0
  146. package/dist/wirings/queue/queue-runner.js +17 -6
  147. package/dist/wirings/queue/queue.types.d.ts +8 -2
  148. package/dist/wirings/rpc/index.d.ts +1 -1
  149. package/dist/wirings/rpc/index.js +1 -1
  150. package/dist/wirings/rpc/rpc-runner.d.ts +33 -5
  151. package/dist/wirings/rpc/rpc-runner.js +134 -16
  152. package/dist/wirings/rpc/rpc-types.d.ts +8 -4
  153. package/dist/wirings/scheduler/index.d.ts +3 -3
  154. package/dist/wirings/scheduler/index.js +2 -3
  155. package/dist/wirings/scheduler/scheduler-runner.d.ts +5 -0
  156. package/dist/wirings/scheduler/scheduler-runner.js +23 -5
  157. package/dist/wirings/secret/index.d.ts +3 -0
  158. package/dist/wirings/secret/index.js +2 -0
  159. package/dist/wirings/secret/secret.types.d.ts +27 -0
  160. package/dist/wirings/secret/secret.types.js +1 -0
  161. package/dist/wirings/secret/validate-secret-definitions.d.ts +6 -0
  162. package/dist/wirings/secret/validate-secret-definitions.js +55 -0
  163. package/dist/wirings/trigger/index.d.ts +3 -2
  164. package/dist/wirings/trigger/index.js +2 -2
  165. package/dist/wirings/trigger/pikku-trigger-service.d.ts +26 -0
  166. package/dist/wirings/trigger/pikku-trigger-service.js +75 -0
  167. package/dist/wirings/trigger/trigger-runner.d.ts +21 -8
  168. package/dist/wirings/trigger/trigger-runner.js +46 -18
  169. package/dist/wirings/trigger/trigger.types.d.ts +99 -11
  170. package/dist/wirings/trigger/trigger.types.js +40 -1
  171. package/dist/wirings/variable/index.d.ts +3 -0
  172. package/dist/wirings/variable/index.js +2 -0
  173. package/dist/wirings/variable/validate-variable-definitions.d.ts +6 -0
  174. package/dist/wirings/variable/validate-variable-definitions.js +45 -0
  175. package/dist/wirings/variable/variable.types.d.ts +18 -0
  176. package/dist/wirings/variable/variable.types.js +1 -0
  177. package/dist/wirings/workflow/dsl/index.d.ts +1 -1
  178. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +7 -1
  179. package/dist/wirings/workflow/dsl/workflow-runner.js +3 -2
  180. package/dist/wirings/workflow/graph/graph-node.d.ts +1 -6
  181. package/dist/wirings/workflow/graph/graph-runner.d.ts +5 -31
  182. package/dist/wirings/workflow/graph/graph-runner.js +384 -296
  183. package/dist/wirings/workflow/graph/index.d.ts +4 -3
  184. package/dist/wirings/workflow/graph/index.js +3 -3
  185. package/dist/wirings/workflow/graph/template.d.ts +15 -0
  186. package/dist/wirings/workflow/graph/template.js +27 -0
  187. package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +15 -0
  188. package/dist/wirings/workflow/graph/wire-workflow-graph.js +8 -0
  189. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -13
  190. package/dist/wirings/workflow/index.d.ts +6 -6
  191. package/dist/wirings/workflow/index.js +6 -4
  192. package/dist/wirings/workflow/pikku-workflow-service.d.ts +28 -14
  193. package/dist/wirings/workflow/pikku-workflow-service.js +200 -56
  194. package/dist/wirings/workflow/workflow-helpers.d.ts +36 -0
  195. package/dist/wirings/workflow/workflow-helpers.js +38 -0
  196. package/dist/wirings/workflow/workflow-utils.d.ts +1 -23
  197. package/dist/wirings/workflow/workflow-utils.js +1 -66
  198. package/dist/wirings/workflow/workflow.types.d.ts +40 -93
  199. package/package.json +13 -15
  200. package/run-tests.sh +4 -1
  201. package/src/crypto-utils.ts +99 -0
  202. package/src/errors/errors.ts +17 -0
  203. package/src/errors/index.ts +0 -1
  204. package/src/factory-functions.test.ts +42 -2
  205. package/src/function/function-runner.test.ts +4 -11
  206. package/src/function/function-runner.ts +114 -29
  207. package/src/function/functions.types.ts +62 -132
  208. package/src/function/index.ts +5 -2
  209. package/src/handle-error.ts +2 -10
  210. package/src/index.ts +99 -25
  211. package/src/middleware/auth-apikey.test.ts +15 -12
  212. package/src/middleware/auth-apikey.ts +3 -3
  213. package/src/middleware/auth-bearer.test.ts +17 -14
  214. package/src/middleware/auth-bearer.ts +25 -27
  215. package/src/middleware/auth-cookie.test.ts +16 -13
  216. package/src/middleware/auth-cookie.ts +6 -8
  217. package/src/middleware/cors.ts +96 -0
  218. package/src/middleware/index.ts +5 -3
  219. package/src/middleware/remote-auth.ts +68 -0
  220. package/src/middleware-runner.test.ts +122 -0
  221. package/src/middleware-runner.ts +12 -12
  222. package/src/permissions.test.ts +81 -7
  223. package/src/permissions.ts +15 -17
  224. package/src/pikku-state.ts +20 -8
  225. package/src/run-tests-script.test.ts +49 -0
  226. package/src/schema.ts +18 -15
  227. package/src/services/ai-agent-runner-service.ts +29 -0
  228. package/src/services/ai-run-state-service.ts +20 -0
  229. package/src/services/ai-storage-service.ts +39 -0
  230. package/src/services/deployment-service.ts +22 -0
  231. package/src/services/gopass-secrets.ts +95 -0
  232. package/src/services/in-memory-trigger-service.ts +68 -0
  233. package/src/services/in-memory-workflow-service.ts +395 -0
  234. package/src/services/index.ts +49 -14
  235. package/src/services/local-secrets.ts +51 -0
  236. package/src/services/local-variables.ts +22 -0
  237. package/src/services/scheduler-service.ts +29 -1
  238. package/src/services/schema-service.ts +7 -0
  239. package/src/services/scoped-secret-service.ts +41 -0
  240. package/src/services/secret-service.ts +25 -4
  241. package/src/services/trigger-service.ts +38 -0
  242. package/src/services/typed-secret-service.ts +70 -0
  243. package/src/services/typed-variables-service.ts +81 -0
  244. package/src/services/user-session-service.ts +23 -0
  245. package/src/services/variables-service.ts +5 -0
  246. package/src/services/workflow-service.ts +22 -2
  247. package/src/types/core.types.ts +76 -11
  248. package/src/types/state.types.ts +37 -63
  249. package/src/utils.ts +20 -6
  250. package/src/version.test.ts +80 -0
  251. package/src/version.ts +25 -0
  252. package/src/wirings/ai-agent/ai-agent-memory.ts +300 -0
  253. package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
  254. package/src/wirings/ai-agent/ai-agent-prepare.ts +470 -0
  255. package/src/wirings/ai-agent/ai-agent-registry.test.ts +37 -0
  256. package/src/wirings/ai-agent/ai-agent-registry.ts +82 -0
  257. package/src/wirings/ai-agent/ai-agent-runner.test.ts +75 -0
  258. package/src/wirings/ai-agent/ai-agent-runner.ts +137 -0
  259. package/src/wirings/ai-agent/ai-agent-stream.test.ts +246 -0
  260. package/src/wirings/ai-agent/ai-agent-stream.ts +774 -0
  261. package/src/wirings/ai-agent/ai-agent.types.ts +273 -0
  262. package/src/wirings/ai-agent/index.ts +28 -0
  263. package/src/wirings/channel/channel-common.ts +32 -19
  264. package/src/wirings/channel/channel-handler.ts +17 -4
  265. package/src/wirings/channel/channel-middleware-runner.ts +119 -0
  266. package/src/wirings/channel/channel-runner.ts +9 -10
  267. package/src/wirings/channel/channel.types.ts +17 -1
  268. package/src/wirings/channel/define-channel-routes.ts +25 -0
  269. package/src/wirings/channel/index.ts +23 -8
  270. package/src/wirings/channel/local/index.ts +3 -3
  271. package/src/wirings/channel/local/local-channel-runner.test.ts +44 -1
  272. package/src/wirings/channel/local/local-channel-runner.ts +22 -6
  273. package/src/wirings/channel/serverless/index.ts +5 -1
  274. package/src/wirings/channel/serverless/serverless-channel-runner.ts +20 -4
  275. package/src/wirings/cli/channel/index.ts +1 -1
  276. package/src/wirings/cli/cli-runner.test.ts +9 -9
  277. package/src/wirings/cli/cli-runner.ts +17 -10
  278. package/src/wirings/cli/cli.types.ts +11 -11
  279. package/src/wirings/cli/command-parser.test.ts +8 -8
  280. package/src/wirings/cli/define-cli-commands.ts +24 -0
  281. package/src/wirings/cli/index.ts +10 -4
  282. package/src/wirings/http/http-routes.test.ts +322 -0
  283. package/src/wirings/http/http-routes.ts +198 -0
  284. package/src/wirings/http/http-runner.test.ts +3 -3
  285. package/src/wirings/http/http-runner.ts +63 -29
  286. package/src/wirings/http/http.types.ts +121 -37
  287. package/src/wirings/http/index.ts +16 -4
  288. package/src/wirings/mcp/index.ts +27 -3
  289. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +3 -3
  290. package/src/wirings/mcp/mcp-runner.ts +39 -50
  291. package/src/wirings/mcp/mcp.types.ts +3 -3
  292. package/src/wirings/node/index.ts +2 -0
  293. package/src/wirings/node/node.types.ts +23 -0
  294. package/src/wirings/oauth2/index.ts +3 -0
  295. package/src/wirings/oauth2/oauth2-client.test.ts +929 -0
  296. package/src/wirings/oauth2/oauth2-client.ts +335 -0
  297. package/src/wirings/oauth2/oauth2.types.ts +69 -0
  298. package/src/wirings/oauth2/wire-oauth2-credential.ts +23 -0
  299. package/src/wirings/queue/index.ts +14 -2
  300. package/src/wirings/queue/queue-runner.test.ts +97 -55
  301. package/src/wirings/queue/queue-runner.ts +33 -7
  302. package/src/wirings/queue/queue.types.ts +12 -2
  303. package/src/wirings/rpc/index.ts +1 -1
  304. package/src/wirings/rpc/rpc-runner.ts +187 -17
  305. package/src/wirings/rpc/rpc-types.ts +13 -4
  306. package/src/wirings/scheduler/index.ts +7 -4
  307. package/src/wirings/scheduler/scheduler-runner.test.ts +70 -26
  308. package/src/wirings/scheduler/scheduler-runner.ts +45 -5
  309. package/src/wirings/secret/index.ts +9 -0
  310. package/src/wirings/secret/secret.types.ts +32 -0
  311. package/src/wirings/secret/validate-secret-definitions.ts +82 -0
  312. package/src/wirings/trigger/index.ts +10 -2
  313. package/src/wirings/trigger/pikku-trigger-service.ts +134 -0
  314. package/src/wirings/trigger/trigger-runner.ts +80 -38
  315. package/src/wirings/trigger/trigger.types.ts +144 -22
  316. package/src/wirings/variable/index.ts +8 -0
  317. package/src/wirings/variable/validate-variable-definitions.ts +69 -0
  318. package/src/wirings/variable/variable.types.ts +22 -0
  319. package/src/wirings/workflow/dsl/index.ts +1 -0
  320. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +9 -1
  321. package/src/wirings/workflow/dsl/workflow-runner.ts +4 -3
  322. package/src/wirings/workflow/graph/graph-node.ts +1 -6
  323. package/src/wirings/workflow/graph/graph-runner.test.ts +495 -0
  324. package/src/wirings/workflow/graph/graph-runner.ts +496 -374
  325. package/src/wirings/workflow/graph/index.ts +14 -3
  326. package/src/wirings/workflow/graph/template.ts +42 -0
  327. package/src/wirings/workflow/graph/wire-workflow-graph.ts +29 -0
  328. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -22
  329. package/src/wirings/workflow/index.ts +21 -10
  330. package/src/wirings/workflow/pikku-workflow-service.test.ts +212 -0
  331. package/src/wirings/workflow/pikku-workflow-service.ts +285 -66
  332. package/src/wirings/workflow/workflow-helpers.ts +79 -0
  333. package/src/wirings/workflow/workflow-utils.ts +0 -120
  334. package/src/wirings/workflow/workflow.types.ts +45 -90
  335. package/tsconfig.tsbuildinfo +1 -1
  336. package/dist/wirings/forge-node/forge-node.types.d.ts +0 -120
  337. package/dist/wirings/forge-node/forge-node.types.js +0 -38
  338. package/dist/wirings/forge-node/index.d.ts +0 -1
  339. package/dist/wirings/forge-node/index.js +0 -1
  340. package/dist/wirings/workflow/wire-workflow.d.ts +0 -42
  341. package/dist/wirings/workflow/wire-workflow.js +0 -53
  342. package/src/wirings/forge-node/forge-node.types.ts +0 -135
  343. package/src/wirings/forge-node/index.ts +0 -1
  344. 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()
@@ -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 (pikkuFuncName) of the middleware function.
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
- // Look up tag middleware group from pikkuState
183
- const group = pikkuState(packageName, 'middleware', 'tagGroup')[
184
+ const groups = getTagGroups(
185
+ pikkuState(packageName, 'middleware', 'tagGroup'),
184
186
  meta.tag
185
- ]
186
- if (group) {
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
- // Look up tag middleware group from pikkuState
210
- const group = pikkuState(packageName, 'middleware', 'tagGroup')[
210
+ const groups = getTagGroups(
211
+ pikkuState(packageName, 'middleware', 'tagGroup'),
211
212
  meta.tag
212
- ]
213
- if (group) {
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
  }
@@ -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) wirePermissions funcInheritedPermissions (funcTag) → funcPermissions
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 () => {
@@ -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 (pikkuFuncName) of the permission function.
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
- // Look up tag permission group from pikkuState
197
- const group = pikkuState(packageName, 'permissions', 'tagGroup')[
198
+ const groups = getTagGroups(
199
+ pikkuState(packageName, 'permissions', 'tagGroup'),
198
200
  meta.tag
199
- ]
200
- if (group) {
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
- // Look up tag permission group from pikkuState
231
- const group = pikkuState(packageName, 'permissions', 'tagGroup')[
232
+ const groups = getTagGroups(
233
+ pikkuState(packageName, 'permissions', 'tagGroup'),
232
234
  meta.tag
233
- ]
234
- if (group) {
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
- permissioned = true
312
- // Continue executing all permissions (don't break early)
312
+ return
313
313
  }
314
314
  }
315
- if (!permissioned) {
316
- services.logger.debug('Permission denied - combined permissions')
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
  }
@@ -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
- tagGroupMeta: {},
123
- httpGroupMeta: {},
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 { UnprocessableContentError } from './errors/errors.js'
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 schemas = pikkuState(null, 'misc', 'schemas')
47
- for (const [name, schema] of schemas) {
48
- schemaService.compileSchema(name, schema)
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.pikkuFuncName]
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
- logger.debug(
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
- } else {
136
- logger.debug(
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(schemaName, schema)
142
- await schemaService.validateSchema(schemaName, data)
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
+ }