@pikku/core 0.11.2 → 0.12.1

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 (436) hide show
  1. package/CHANGELOG.md +57 -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 +14 -0
  5. package/dist/errors/errors.js +26 -0
  6. package/dist/errors/index.d.ts +1 -1
  7. package/dist/errors/index.js +1 -1
  8. package/dist/function/function-runner.d.ts +10 -4
  9. package/dist/function/function-runner.js +126 -45
  10. package/dist/function/functions.types.d.ts +32 -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.d.ts +2 -2
  15. package/dist/handle-error.js +3 -12
  16. package/dist/index.d.ts +30 -26
  17. package/dist/index.js +19 -29
  18. package/dist/internal.d.ts +3 -0
  19. package/dist/internal.js +2 -0
  20. package/dist/middleware/auth-apikey.d.ts +2 -2
  21. package/dist/middleware/auth-apikey.js +3 -3
  22. package/dist/middleware/auth-bearer.d.ts +3 -3
  23. package/dist/middleware/auth-bearer.js +4 -7
  24. package/dist/middleware/auth-cookie.d.ts +4 -4
  25. package/dist/middleware/auth-cookie.js +7 -9
  26. package/dist/middleware/cors.d.ts +46 -0
  27. package/dist/middleware/cors.js +81 -0
  28. package/dist/middleware/index.d.ts +5 -3
  29. package/dist/middleware/index.js +5 -3
  30. package/dist/middleware/remote-auth.d.ts +5 -0
  31. package/dist/middleware/remote-auth.js +55 -0
  32. package/dist/middleware/timeout.d.ts +2 -2
  33. package/dist/middleware-runner.d.ts +1 -1
  34. package/dist/middleware-runner.js +8 -10
  35. package/dist/permissions.d.ts +2 -2
  36. package/dist/permissions.js +11 -15
  37. package/dist/pikku-state.d.ts +10 -8
  38. package/dist/pikku-state.js +48 -25
  39. package/dist/schema.d.ts +4 -4
  40. package/dist/schema.js +20 -15
  41. package/dist/services/ai-agent-runner-service.d.ts +43 -0
  42. package/dist/services/ai-agent-runner-service.js +1 -0
  43. package/dist/services/ai-run-state-service.d.ts +13 -0
  44. package/dist/services/ai-run-state-service.js +1 -0
  45. package/dist/services/ai-storage-service.d.ts +18 -0
  46. package/dist/services/ai-storage-service.js +1 -0
  47. package/dist/services/content-service.d.ts +6 -0
  48. package/dist/services/deployment-service.d.ts +19 -0
  49. package/dist/services/deployment-service.js +1 -0
  50. package/dist/services/gopass-secrets.d.ts +47 -0
  51. package/dist/services/gopass-secrets.js +97 -0
  52. package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
  53. package/dist/services/in-memory-ai-run-state-service.js +44 -0
  54. package/dist/services/in-memory-trigger-service.d.ts +22 -0
  55. package/dist/services/in-memory-trigger-service.js +48 -0
  56. package/dist/services/in-memory-workflow-service.d.ts +59 -0
  57. package/dist/services/in-memory-workflow-service.js +287 -0
  58. package/dist/services/index.d.ts +26 -11
  59. package/dist/services/index.js +11 -13
  60. package/dist/services/local-content.d.ts +2 -1
  61. package/dist/services/local-content.js +6 -1
  62. package/dist/services/local-secrets.d.ts +25 -2
  63. package/dist/services/local-secrets.js +45 -0
  64. package/dist/services/local-variables.d.ts +6 -1
  65. package/dist/services/local-variables.js +18 -0
  66. package/dist/services/logger-console.d.ts +2 -1
  67. package/dist/services/scheduler-service.d.ts +9 -1
  68. package/dist/services/scheduler-service.js +8 -0
  69. package/dist/services/schema-service.d.ts +6 -0
  70. package/dist/services/scoped-secret-service.d.ts +16 -0
  71. package/dist/services/scoped-secret-service.js +35 -0
  72. package/dist/services/secret-service.d.ts +25 -4
  73. package/dist/services/trigger-service.d.ts +16 -0
  74. package/dist/services/trigger-service.js +1 -0
  75. package/dist/services/typed-secret-service.d.ts +30 -0
  76. package/dist/services/typed-secret-service.js +40 -0
  77. package/dist/services/typed-variables-service.d.ts +27 -0
  78. package/dist/services/typed-variables-service.js +46 -0
  79. package/dist/services/user-session-service.d.ts +15 -2
  80. package/dist/services/user-session-service.js +17 -0
  81. package/dist/services/variables-service.d.ts +5 -0
  82. package/dist/services/workflow-service.d.ts +9 -5
  83. package/dist/types/core.types.d.ts +67 -25
  84. package/dist/types/core.types.js +8 -1
  85. package/dist/types/state.types.d.ts +53 -59
  86. package/dist/utils.d.ts +7 -6
  87. package/dist/utils.js +27 -12
  88. package/dist/version.d.ts +6 -0
  89. package/dist/version.js +19 -0
  90. package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
  91. package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +146 -0
  92. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
  93. package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
  94. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +29 -0
  95. package/dist/wirings/ai-agent/ai-agent-memory.js +199 -0
  96. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +9 -0
  97. package/dist/wirings/ai-agent/ai-agent-model-config.js +36 -0
  98. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +59 -0
  99. package/dist/wirings/ai-agent/ai-agent-prepare.js +348 -0
  100. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +15 -0
  101. package/dist/wirings/ai-agent/ai-agent-registry.js +47 -0
  102. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +3 -0
  103. package/dist/wirings/ai-agent/ai-agent-runner.js +195 -0
  104. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +12 -0
  105. package/dist/wirings/ai-agent/ai-agent-stream.js +662 -0
  106. package/dist/wirings/ai-agent/ai-agent.types.d.ts +313 -0
  107. package/dist/wirings/ai-agent/ai-agent.types.js +1 -0
  108. package/dist/wirings/ai-agent/index.d.ts +7 -0
  109. package/dist/wirings/ai-agent/index.js +6 -0
  110. package/dist/wirings/channel/channel-common.d.ts +8 -5
  111. package/dist/wirings/channel/channel-common.js +15 -8
  112. package/dist/wirings/channel/channel-handler.d.ts +3 -3
  113. package/dist/wirings/channel/channel-handler.js +15 -6
  114. package/dist/wirings/channel/channel-middleware-runner.d.ts +9 -0
  115. package/dist/wirings/channel/channel-middleware-runner.js +73 -0
  116. package/dist/wirings/channel/channel-runner.d.ts +5 -5
  117. package/dist/wirings/channel/channel-runner.js +10 -9
  118. package/dist/wirings/channel/channel-store.d.ts +1 -1
  119. package/dist/wirings/channel/channel.types.d.ts +9 -7
  120. package/dist/wirings/channel/define-channel-routes.d.ts +21 -0
  121. package/dist/wirings/channel/define-channel-routes.js +23 -0
  122. package/dist/wirings/channel/index.d.ts +10 -8
  123. package/dist/wirings/channel/index.js +7 -8
  124. package/dist/wirings/channel/local/index.d.ts +3 -3
  125. package/dist/wirings/channel/local/index.js +3 -3
  126. package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
  127. package/dist/wirings/channel/local/local-channel-runner.js +22 -9
  128. package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
  129. package/dist/wirings/channel/log-channels.d.ts +1 -1
  130. package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +1 -1
  131. package/dist/wirings/channel/serverless/index.d.ts +1 -1
  132. package/dist/wirings/channel/serverless/index.js +1 -1
  133. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +4 -4
  134. package/dist/wirings/channel/serverless/serverless-channel-runner.js +40 -23
  135. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
  136. package/dist/wirings/cli/channel/index.d.ts +1 -1
  137. package/dist/wirings/cli/channel/index.js +1 -1
  138. package/dist/wirings/cli/cli-runner.d.ts +3 -3
  139. package/dist/wirings/cli/cli-runner.js +12 -8
  140. package/dist/wirings/cli/cli.types.d.ts +9 -9
  141. package/dist/wirings/cli/command-parser.d.ts +1 -1
  142. package/dist/wirings/cli/define-cli-commands.d.ts +19 -0
  143. package/dist/wirings/cli/define-cli-commands.js +20 -0
  144. package/dist/wirings/cli/index.d.ts +2 -3
  145. package/dist/wirings/cli/index.js +1 -3
  146. package/dist/wirings/http/http-routes.d.ts +69 -0
  147. package/dist/wirings/http/http-routes.js +139 -0
  148. package/dist/wirings/http/http-runner.d.ts +9 -9
  149. package/dist/wirings/http/http-runner.js +79 -34
  150. package/dist/wirings/http/http.types.d.ts +77 -41
  151. package/dist/wirings/http/index.d.ts +5 -4
  152. package/dist/wirings/http/index.js +4 -3
  153. package/dist/wirings/http/log-http-routes.d.ts +1 -1
  154. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
  155. package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
  156. package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
  157. package/dist/wirings/http/routers/http-router.d.ts +1 -1
  158. package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
  159. package/dist/wirings/mcp/index.d.ts +4 -3
  160. package/dist/wirings/mcp/index.js +3 -3
  161. package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
  162. package/dist/wirings/mcp/mcp-runner.d.ts +1 -6
  163. package/dist/wirings/mcp/mcp-runner.js +28 -40
  164. package/dist/wirings/mcp/mcp.types.d.ts +5 -5
  165. package/dist/wirings/node/index.d.ts +2 -0
  166. package/dist/wirings/node/index.js +1 -0
  167. package/dist/wirings/node/node.types.d.ts +20 -0
  168. package/dist/wirings/node/node.types.js +1 -0
  169. package/dist/wirings/oauth2/index.d.ts +3 -0
  170. package/dist/wirings/oauth2/index.js +2 -0
  171. package/dist/wirings/oauth2/oauth2-client.d.ts +47 -0
  172. package/dist/wirings/oauth2/oauth2-client.js +267 -0
  173. package/dist/wirings/oauth2/oauth2.types.d.ts +65 -0
  174. package/dist/wirings/oauth2/oauth2.types.js +4 -0
  175. package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +20 -0
  176. package/dist/wirings/oauth2/wire-oauth2-credential.js +21 -0
  177. package/dist/wirings/queue/index.d.ts +1 -1
  178. package/dist/wirings/queue/queue-runner.d.ts +1 -5
  179. package/dist/wirings/queue/queue-runner.js +11 -8
  180. package/dist/wirings/queue/queue.types.d.ts +5 -5
  181. package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
  182. package/dist/wirings/queue/register-queue-helper.js +1 -1
  183. package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
  184. package/dist/wirings/rpc/index.d.ts +3 -1
  185. package/dist/wirings/rpc/index.js +2 -1
  186. package/dist/wirings/rpc/rpc-runner.d.ts +58 -8
  187. package/dist/wirings/rpc/rpc-runner.js +177 -31
  188. package/dist/wirings/rpc/rpc-types.d.ts +20 -4
  189. package/dist/wirings/rpc/wire-addon.d.ts +10 -0
  190. package/dist/wirings/rpc/wire-addon.js +9 -0
  191. package/dist/wirings/scheduler/index.d.ts +2 -2
  192. package/dist/wirings/scheduler/index.js +1 -2
  193. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
  194. package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -5
  195. package/dist/wirings/scheduler/scheduler-runner.js +11 -14
  196. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
  197. package/dist/wirings/secret/index.d.ts +3 -0
  198. package/dist/wirings/secret/index.js +2 -0
  199. package/dist/wirings/secret/secret.types.d.ts +27 -0
  200. package/dist/wirings/secret/secret.types.js +1 -0
  201. package/dist/wirings/secret/validate-secret-definitions.d.ts +6 -0
  202. package/dist/wirings/secret/validate-secret-definitions.js +55 -0
  203. package/dist/wirings/trigger/index.d.ts +3 -2
  204. package/dist/wirings/trigger/index.js +2 -2
  205. package/dist/wirings/trigger/pikku-trigger-service.d.ts +22 -0
  206. package/dist/wirings/trigger/pikku-trigger-service.js +70 -0
  207. package/dist/wirings/trigger/trigger-runner.d.ts +18 -9
  208. package/dist/wirings/trigger/trigger-runner.js +48 -19
  209. package/dist/wirings/trigger/trigger.types.d.ts +99 -11
  210. package/dist/wirings/trigger/trigger.types.js +40 -1
  211. package/dist/wirings/variable/index.d.ts +3 -0
  212. package/dist/wirings/variable/index.js +2 -0
  213. package/dist/wirings/variable/validate-variable-definitions.d.ts +6 -0
  214. package/dist/wirings/variable/validate-variable-definitions.js +45 -0
  215. package/dist/wirings/variable/variable.types.d.ts +18 -0
  216. package/dist/wirings/variable/variable.types.js +1 -0
  217. package/dist/wirings/workflow/dsl/index.d.ts +1 -1
  218. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +7 -1
  219. package/dist/wirings/workflow/dsl/workflow-runner.js +3 -2
  220. package/dist/wirings/workflow/graph/graph-node.d.ts +1 -6
  221. package/dist/wirings/workflow/graph/graph-runner.d.ts +5 -31
  222. package/dist/wirings/workflow/graph/graph-runner.js +384 -296
  223. package/dist/wirings/workflow/graph/index.d.ts +4 -3
  224. package/dist/wirings/workflow/graph/index.js +3 -3
  225. package/dist/wirings/workflow/graph/template.d.ts +15 -0
  226. package/dist/wirings/workflow/graph/template.js +27 -0
  227. package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +15 -0
  228. package/dist/wirings/workflow/graph/wire-workflow-graph.js +8 -0
  229. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -13
  230. package/dist/wirings/workflow/index.d.ts +6 -6
  231. package/dist/wirings/workflow/index.js +6 -4
  232. package/dist/wirings/workflow/pikku-workflow-service.d.ts +29 -19
  233. package/dist/wirings/workflow/pikku-workflow-service.js +217 -82
  234. package/dist/wirings/workflow/workflow-helpers.d.ts +36 -0
  235. package/dist/wirings/workflow/workflow-helpers.js +38 -0
  236. package/dist/wirings/workflow/workflow.types.d.ts +42 -95
  237. package/package.json +14 -15
  238. package/run-tests.sh +4 -1
  239. package/src/crypto-utils.test.ts +116 -0
  240. package/src/crypto-utils.ts +99 -0
  241. package/src/errors/error.test.ts +143 -2
  242. package/src/errors/errors.ts +27 -0
  243. package/src/errors/index.ts +1 -1
  244. package/src/factory-functions.test.ts +42 -2
  245. package/src/function/function-runner.test.ts +6 -13
  246. package/src/function/function-runner.ts +161 -53
  247. package/src/function/functions.types.ts +63 -132
  248. package/src/function/index.ts +5 -2
  249. package/src/handle-error.test.ts +361 -0
  250. package/src/handle-error.ts +6 -14
  251. package/src/index.ts +97 -30
  252. package/src/internal.ts +6 -0
  253. package/src/middleware/auth-apikey.test.ts +16 -13
  254. package/src/middleware/auth-apikey.ts +3 -3
  255. package/src/middleware/auth-bearer.test.ts +18 -15
  256. package/src/middleware/auth-bearer.ts +27 -32
  257. package/src/middleware/auth-cookie.test.ts +17 -14
  258. package/src/middleware/auth-cookie.ts +9 -13
  259. package/src/middleware/cors.test.ts +424 -0
  260. package/src/middleware/cors.ts +104 -0
  261. package/src/middleware/index.ts +5 -3
  262. package/src/middleware/remote-auth.test.ts +488 -0
  263. package/src/middleware/remote-auth.ts +68 -0
  264. package/src/middleware-runner.test.ts +123 -1
  265. package/src/middleware-runner.ts +13 -13
  266. package/src/permissions.test.ts +83 -9
  267. package/src/permissions.ts +17 -19
  268. package/src/pikku-state.test.ts +224 -0
  269. package/src/pikku-state.ts +59 -35
  270. package/src/run-tests-script.test.ts +49 -0
  271. package/src/schema.test.ts +198 -6
  272. package/src/schema.ts +28 -21
  273. package/src/services/ai-agent-runner-service.ts +41 -0
  274. package/src/services/ai-run-state-service.ts +20 -0
  275. package/src/services/ai-storage-service.ts +39 -0
  276. package/src/services/content-service.ts +7 -0
  277. package/src/services/deployment-service.ts +22 -0
  278. package/src/services/gopass-secrets.ts +98 -0
  279. package/src/services/in-memory-ai-run-state-service.ts +73 -0
  280. package/src/services/in-memory-trigger-service.ts +64 -0
  281. package/src/services/in-memory-workflow-service.test.ts +351 -0
  282. package/src/services/in-memory-workflow-service.ts +395 -0
  283. package/src/services/index.ts +50 -14
  284. package/src/services/local-content.ts +9 -3
  285. package/src/services/local-secrets.test.ts +80 -0
  286. package/src/services/local-secrets.ts +53 -2
  287. package/src/services/local-variables.test.ts +61 -0
  288. package/src/services/local-variables.ts +23 -1
  289. package/src/services/logger-console.test.ts +118 -0
  290. package/src/services/logger-console.ts +2 -1
  291. package/src/services/scheduler-service.ts +11 -1
  292. package/src/services/schema-service.ts +7 -0
  293. package/src/services/scoped-secret-service.test.ts +74 -0
  294. package/src/services/scoped-secret-service.ts +41 -0
  295. package/src/services/secret-service.ts +25 -4
  296. package/src/services/trigger-service.ts +17 -0
  297. package/src/services/typed-secret-service.test.ts +93 -0
  298. package/src/services/typed-secret-service.ts +70 -0
  299. package/src/services/typed-variables-service.test.ts +73 -0
  300. package/src/services/typed-variables-service.ts +81 -0
  301. package/src/services/user-session-service.test.ts +113 -0
  302. package/src/services/user-session-service.ts +25 -2
  303. package/src/services/variables-service.ts +5 -0
  304. package/src/services/workflow-service.ts +23 -13
  305. package/src/time-utils.test.ts +1 -1
  306. package/src/types/core.types.ts +95 -24
  307. package/src/types/state.types.ts +56 -73
  308. package/src/utils.test.ts +350 -0
  309. package/src/utils.ts +33 -18
  310. package/src/version.test.ts +80 -0
  311. package/src/version.ts +25 -0
  312. package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
  313. package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +214 -0
  314. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
  315. package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
  316. package/src/wirings/ai-agent/ai-agent-memory.ts +300 -0
  317. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
  318. package/src/wirings/ai-agent/ai-agent-model-config.ts +43 -0
  319. package/src/wirings/ai-agent/ai-agent-prepare.ts +504 -0
  320. package/src/wirings/ai-agent/ai-agent-registry.test.ts +37 -0
  321. package/src/wirings/ai-agent/ai-agent-registry.ts +82 -0
  322. package/src/wirings/ai-agent/ai-agent-runner.test.ts +317 -0
  323. package/src/wirings/ai-agent/ai-agent-runner.ts +251 -0
  324. package/src/wirings/ai-agent/ai-agent-stream.test.ts +652 -0
  325. package/src/wirings/ai-agent/ai-agent-stream.ts +1049 -0
  326. package/src/wirings/ai-agent/ai-agent.types.ts +328 -0
  327. package/src/wirings/ai-agent/index.ts +39 -0
  328. package/src/wirings/channel/channel-common.ts +33 -20
  329. package/src/wirings/channel/channel-handler.ts +26 -9
  330. package/src/wirings/channel/channel-middleware-runner.ts +119 -0
  331. package/src/wirings/channel/channel-runner.ts +15 -16
  332. package/src/wirings/channel/channel-store.ts +1 -1
  333. package/src/wirings/channel/channel.types.ts +21 -9
  334. package/src/wirings/channel/define-channel-routes.ts +25 -0
  335. package/src/wirings/channel/index.ts +23 -8
  336. package/src/wirings/channel/local/index.ts +3 -3
  337. package/src/wirings/channel/local/local-channel-runner.test.ts +57 -7
  338. package/src/wirings/channel/local/local-channel-runner.ts +40 -19
  339. package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
  340. package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
  341. package/src/wirings/channel/log-channels.ts +1 -1
  342. package/src/wirings/channel/pikku-abstract-channel-handler.ts +1 -1
  343. package/src/wirings/channel/serverless/index.ts +5 -1
  344. package/src/wirings/channel/serverless/serverless-channel-runner.ts +57 -36
  345. package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
  346. package/src/wirings/cli/channel/index.ts +1 -1
  347. package/src/wirings/cli/cli-runner.test.ts +10 -10
  348. package/src/wirings/cli/cli-runner.ts +28 -14
  349. package/src/wirings/cli/cli.types.ts +14 -14
  350. package/src/wirings/cli/command-parser.test.ts +9 -9
  351. package/src/wirings/cli/command-parser.ts +1 -1
  352. package/src/wirings/cli/define-cli-commands.ts +24 -0
  353. package/src/wirings/cli/index.ts +10 -4
  354. package/src/wirings/http/http-routes.test.ts +322 -0
  355. package/src/wirings/http/http-routes.ts +198 -0
  356. package/src/wirings/http/http-runner.test.ts +12 -20
  357. package/src/wirings/http/http-runner.ts +101 -51
  358. package/src/wirings/http/http.types.ts +119 -48
  359. package/src/wirings/http/index.ts +16 -4
  360. package/src/wirings/http/log-http-routes.ts +1 -1
  361. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  362. package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
  363. package/src/wirings/http/routers/http-router.ts +1 -1
  364. package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
  365. package/src/wirings/http/routers/path-to-regex.ts +4 -3
  366. package/src/wirings/mcp/index.ts +27 -3
  367. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +3 -3
  368. package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
  369. package/src/wirings/mcp/mcp-runner.ts +48 -65
  370. package/src/wirings/mcp/mcp.types.ts +5 -5
  371. package/src/wirings/node/index.ts +2 -0
  372. package/src/wirings/node/node.types.ts +23 -0
  373. package/src/wirings/oauth2/index.ts +3 -0
  374. package/src/wirings/oauth2/oauth2-client.test.ts +929 -0
  375. package/src/wirings/oauth2/oauth2-client.ts +335 -0
  376. package/src/wirings/oauth2/oauth2.types.ts +69 -0
  377. package/src/wirings/oauth2/wire-oauth2-credential.ts +23 -0
  378. package/src/wirings/queue/index.ts +13 -2
  379. package/src/wirings/queue/queue-runner.test.ts +142 -73
  380. package/src/wirings/queue/queue-runner.ts +18 -14
  381. package/src/wirings/queue/queue.types.ts +5 -5
  382. package/src/wirings/queue/register-queue-helper.ts +3 -5
  383. package/src/wirings/queue/validate-worker-config.test.ts +108 -0
  384. package/src/wirings/queue/validate-worker-config.ts +4 -1
  385. package/src/wirings/rpc/index.ts +3 -1
  386. package/src/wirings/rpc/rpc-runner.ts +254 -41
  387. package/src/wirings/rpc/rpc-types.ts +28 -4
  388. package/src/wirings/rpc/wire-addon.ts +20 -0
  389. package/src/wirings/scheduler/index.ts +6 -4
  390. package/src/wirings/scheduler/log-schedulers.ts +1 -1
  391. package/src/wirings/scheduler/scheduler-runner.test.ts +78 -45
  392. package/src/wirings/scheduler/scheduler-runner.ts +20 -27
  393. package/src/wirings/scheduler/scheduler.types.ts +2 -2
  394. package/src/wirings/secret/index.ts +9 -0
  395. package/src/wirings/secret/secret.types.ts +32 -0
  396. package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
  397. package/src/wirings/secret/validate-secret-definitions.ts +82 -0
  398. package/src/wirings/trigger/index.ts +10 -2
  399. package/src/wirings/trigger/pikku-trigger-service.ts +112 -0
  400. package/src/wirings/trigger/trigger-runner.test.ts +79 -0
  401. package/src/wirings/trigger/trigger-runner.ts +80 -41
  402. package/src/wirings/trigger/trigger.types.ts +144 -22
  403. package/src/wirings/variable/index.ts +8 -0
  404. package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
  405. package/src/wirings/variable/validate-variable-definitions.ts +69 -0
  406. package/src/wirings/variable/variable.types.ts +22 -0
  407. package/src/wirings/workflow/dsl/index.ts +1 -0
  408. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +9 -1
  409. package/src/wirings/workflow/dsl/workflow-runner.ts +4 -3
  410. package/src/wirings/workflow/graph/graph-node.ts +1 -6
  411. package/src/wirings/workflow/graph/graph-runner.test.ts +487 -0
  412. package/src/wirings/workflow/graph/graph-runner.ts +496 -374
  413. package/src/wirings/workflow/graph/index.ts +14 -3
  414. package/src/wirings/workflow/graph/template.test.ts +49 -0
  415. package/src/wirings/workflow/graph/template.ts +42 -0
  416. package/src/wirings/workflow/graph/wire-workflow-graph.ts +29 -0
  417. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -22
  418. package/src/wirings/workflow/index.ts +21 -10
  419. package/src/wirings/workflow/pikku-workflow-service.test.ts +200 -0
  420. package/src/wirings/workflow/pikku-workflow-service.ts +308 -105
  421. package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
  422. package/src/wirings/workflow/workflow-helpers.ts +79 -0
  423. package/src/wirings/workflow/workflow.types.ts +47 -92
  424. package/tsconfig.tsbuildinfo +1 -1
  425. package/dist/wirings/forge-node/forge-node.types.d.ts +0 -120
  426. package/dist/wirings/forge-node/forge-node.types.js +0 -38
  427. package/dist/wirings/forge-node/index.d.ts +0 -1
  428. package/dist/wirings/forge-node/index.js +0 -1
  429. package/dist/wirings/workflow/wire-workflow.d.ts +0 -42
  430. package/dist/wirings/workflow/wire-workflow.js +0 -53
  431. package/dist/wirings/workflow/workflow-utils.d.ts +0 -23
  432. package/dist/wirings/workflow/workflow-utils.js +0 -66
  433. package/src/wirings/forge-node/forge-node.types.ts +0 -135
  434. package/src/wirings/forge-node/index.ts +0 -1
  435. package/src/wirings/workflow/wire-workflow.ts +0 -94
  436. package/src/wirings/workflow/workflow-utils.ts +0 -120
@@ -1,8 +1,9 @@
1
1
  import { runPikkuFunc } from '../../function/function-runner.js';
2
- import { pikkuState } from '../../pikku-state.js';
2
+ import { getSingletonServices, getCreateWireServices, pikkuState, } from '../../pikku-state.js';
3
3
  import { getDurationInMilliseconds } from '../../time-utils.js';
4
- import { executeGraphStep, runWorkflowGraph } from './graph/graph-runner.js';
5
- import { PikkuError } from '../../errors/error-handler.js';
4
+ import { continueGraph, executeGraphStep, runWorkflowGraph, runFromMeta, } from './graph/graph-runner.js';
5
+ import { PikkuError, addError } from '../../errors/error-handler.js';
6
+ import { RPCNotFoundError } from '../rpc/rpc-runner.js';
6
7
  /**
7
8
  * Exception thrown when workflow needs to pause for async step
8
9
  */
@@ -29,6 +30,19 @@ export class WorkflowCancelledException extends Error {
29
30
  this.name = 'WorkflowCancelledException';
30
31
  }
31
32
  }
33
+ /**
34
+ * Exception thrown when workflow is suspended
35
+ */
36
+ export class WorkflowSuspendedException extends Error {
37
+ runId;
38
+ reason;
39
+ constructor(runId, reason) {
40
+ super(reason || 'Workflow suspended');
41
+ this.runId = runId;
42
+ this.reason = reason;
43
+ this.name = 'WorkflowSuspendedException';
44
+ }
45
+ }
32
46
  /**
33
47
  * Error class for workflow not found
34
48
  */
@@ -37,14 +51,19 @@ export class WorkflowNotFoundError extends PikkuError {
37
51
  super(`Workflow not found: ${name}`);
38
52
  }
39
53
  }
40
- /**
41
- * Error class for workflow not found
42
- */
43
- export class WorkflowRunNotFound extends PikkuError {
54
+ addError(WorkflowNotFoundError, {
55
+ status: 404,
56
+ message: 'Workflow not found.',
57
+ });
58
+ export class WorkflowRunNotFoundError extends PikkuError {
44
59
  constructor(runId) {
45
60
  super(`Workflow run not found: ${runId}`);
46
61
  }
47
62
  }
63
+ addError(WorkflowRunNotFoundError, {
64
+ status: 404,
65
+ message: 'Workflow run not found.',
66
+ });
48
67
  export class WorkflowServiceNotInitialized extends Error {
49
68
  }
50
69
  export class WorkflowStepNameNotString extends Error {
@@ -52,15 +71,18 @@ export class WorkflowStepNameNotString extends Error {
52
71
  super(`Workflow step name must be a string. Received: ${typeof stepName}`);
53
72
  }
54
73
  }
74
+ const WORKFLOW_END_STATES = new Set([
75
+ 'completed',
76
+ 'failed',
77
+ 'cancelled',
78
+ 'suspended',
79
+ ]);
55
80
  /**
56
81
  * Abstract workflow state service
57
82
  * Implementations provide pluggable storage backends (SQLite, PostgreSQL, etc.)
58
83
  * Combines orchestration and step execution
59
84
  */
60
85
  export class PikkuWorkflowService {
61
- config;
62
- singletonServices;
63
- createWireServices;
64
86
  inlineRuns = new Set();
65
87
  constructor() { }
66
88
  /**
@@ -81,16 +103,13 @@ export class PikkuWorkflowService {
81
103
  unregisterInlineRun(runId) {
82
104
  this.inlineRuns.delete(runId);
83
105
  }
84
- setServices(singletonServices, createWireServices, { workflow }) {
85
- this.singletonServices = singletonServices;
86
- this.createWireServices = createWireServices;
87
- this.config = {
88
- retries: workflow?.retries ?? 0,
89
- retryDelay: workflow?.retryDelay ?? 0,
90
- orchestratorQueueName: workflow?.orchestratorQueueName ?? 'pikku-workflow-orchestrator',
91
- stepWorkerQueueName: workflow?.stepWorkerQueueName ?? 'pikku-workflow-step-worker',
92
- sleeperRPCName: workflow?.sleeperRPCName ?? 'pikkuWorkflowSleeper',
93
- };
106
+ async registerWorkflowVersions() {
107
+ const allMeta = pikkuState(null, 'workflows', 'meta');
108
+ for (const [name, meta] of Object.entries(allMeta)) {
109
+ if (!meta.graphHash)
110
+ continue;
111
+ await this.upsertWorkflowVersion(name, meta.graphHash, meta, meta.source);
112
+ }
94
113
  }
95
114
  // ============================================================================
96
115
  // Workflow Lifecycle Methods
@@ -103,6 +122,15 @@ export class PikkuWorkflowService {
103
122
  const queueService = this.verifyQueueService();
104
123
  await queueService.add(this.getConfig().orchestratorQueueName, { runId });
105
124
  }
125
+ async queueStepWorker(runId, stepName, rpcName, data) {
126
+ const queueService = this.verifyQueueService();
127
+ await queueService.add(this.getConfig().stepWorkerQueueName, {
128
+ runId,
129
+ stepName,
130
+ rpcName,
131
+ data,
132
+ });
133
+ }
106
134
  /**
107
135
  * Execute a workflow sleep step completion
108
136
  * Sets the step result to null and resumes the workflow
@@ -127,7 +155,7 @@ export class PikkuWorkflowService {
127
155
  * @param options.inline - If true, execute workflow directly without queue service
128
156
  * @param options.startNode - Starting node ID for graph workflows (from wire config)
129
157
  */
130
- async startWorkflow(name, input, rpcService, options) {
158
+ async startWorkflow(name, input, wire, rpcService, options) {
131
159
  // Check meta to determine workflow type
132
160
  const meta = pikkuState(null, 'workflows', 'meta');
133
161
  const workflowMeta = meta[name];
@@ -136,8 +164,8 @@ export class PikkuWorkflowService {
136
164
  }
137
165
  // Check if this is a graph workflow (source === 'graph')
138
166
  if (workflowMeta.source === 'graph') {
139
- // Graph workflows use the graph scheduler
140
- return runWorkflowGraph(this, name, input, rpcService, options?.inline, options?.startNode);
167
+ const shouldInline = options?.inline || !getSingletonServices()?.queueService;
168
+ return runWorkflowGraph(this, name, input, rpcService, shouldInline, options?.startNode, wire);
141
169
  }
142
170
  // DSL workflow - check registration exists
143
171
  const registrations = pikkuState(null, 'workflows', 'registrations');
@@ -145,34 +173,63 @@ export class PikkuWorkflowService {
145
173
  if (!workflow) {
146
174
  throw new WorkflowNotFoundError(name);
147
175
  }
148
- // Create workflow run in state
149
- const runId = await this.createRun(name, input, options?.inline);
150
- // Register inline run for fast lookup
176
+ if (!workflowMeta.graphHash) {
177
+ throw new Error(`Missing workflow graphHash for '${name}'`);
178
+ }
179
+ const runId = await this.createRun(name, input, options?.inline ?? false, workflowMeta.graphHash, wire);
151
180
  if (options?.inline) {
152
181
  this.inlineRuns.add(runId);
153
182
  }
154
- try {
155
- // If inline mode or no queue service, execute directly
156
- // Otherwise, use remote execution (queue-based)
157
- if (options?.inline || !this.singletonServices?.queueService) {
158
- await this.runWorkflowJob(runId, rpcService);
159
- }
160
- else {
161
- await this.resumeWorkflow(runId);
162
- }
163
- return { runId };
183
+ if (options?.inline || !getSingletonServices()?.queueService) {
184
+ this.runWorkflowJob(runId, rpcService)
185
+ .catch(() => { })
186
+ .finally(() => {
187
+ if (options?.inline) {
188
+ this.inlineRuns.delete(runId);
189
+ }
190
+ });
191
+ }
192
+ else {
193
+ await this.resumeWorkflow(runId);
164
194
  }
165
- finally {
166
- // Clean up inline tracking
167
- if (options?.inline) {
168
- this.inlineRuns.delete(runId);
195
+ return { runId };
196
+ }
197
+ async runToCompletion(name, input, rpcService, options) {
198
+ const pollInterval = options?.pollIntervalMs ?? 1000;
199
+ const { runId } = await this.startWorkflow(name, input, options?.wire ?? { type: 'internal' }, rpcService, { inline: true });
200
+ while (true) {
201
+ const run = await this.getRun(runId);
202
+ if (!run) {
203
+ throw new WorkflowRunNotFoundError(runId);
169
204
  }
205
+ if (WORKFLOW_END_STATES.has(run.status)) {
206
+ if (run.status === 'failed') {
207
+ throw new Error(run.error?.message || 'Workflow failed');
208
+ }
209
+ if (run.status === 'cancelled') {
210
+ throw new Error('Workflow was cancelled');
211
+ }
212
+ return run.output;
213
+ }
214
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
170
215
  }
171
216
  }
172
217
  async runWorkflowJob(runId, rpcService) {
173
218
  const run = await this.getRun(runId);
174
219
  if (!run) {
175
- throw new WorkflowRunNotFound(runId);
220
+ throw new WorkflowRunNotFoundError(runId);
221
+ }
222
+ const meta = pikkuState(null, 'workflows', 'meta');
223
+ const workflowMeta = meta[run.workflow];
224
+ if (run.graphHash &&
225
+ workflowMeta?.graphHash &&
226
+ run.graphHash !== workflowMeta.graphHash) {
227
+ await this.runVersionMismatchFallback(run, workflowMeta, rpcService);
228
+ return;
229
+ }
230
+ if (workflowMeta?.source === 'graph') {
231
+ await continueGraph(this, runId, run.workflow);
232
+ return;
176
233
  }
177
234
  const registrations = pikkuState(null, 'workflows', 'registrations');
178
235
  const workflow = registrations.get(run.workflow);
@@ -180,27 +237,22 @@ export class PikkuWorkflowService {
180
237
  throw new WorkflowNotFoundError(run.workflow);
181
238
  }
182
239
  await this.withRunLock(runId, async () => {
183
- const meta = pikkuState(null, 'workflows', 'meta');
184
- const workflowMeta = meta[run.workflow];
185
240
  const workflowWire = this.createWorkflowWire(run.workflow, runId, rpcService);
186
241
  const wire = { workflow: workflowWire };
187
242
  try {
188
- const result = await runPikkuFunc('workflow', workflowMeta.name, workflowMeta.pikkuFuncName, {
189
- singletonServices: this.singletonServices,
243
+ const result = await runPikkuFunc('workflow', workflowMeta.name, workflowMeta.pikkuFuncId, {
244
+ singletonServices: getSingletonServices(),
190
245
  wire,
191
- createWireServices: this.createWireServices,
246
+ createWireServices: getCreateWireServices(),
192
247
  data: () => run.input,
193
248
  });
194
249
  await this.updateRunStatus(runId, 'completed', result);
195
250
  }
196
251
  catch (error) {
197
252
  if (error instanceof WorkflowAsyncException) {
198
- // Normal - workflow paused for step execution
199
253
  throw error;
200
254
  }
201
- // Check if it's a WorkflowCancelledException
202
255
  if (error instanceof WorkflowCancelledException) {
203
- // Workflow was cancelled - update status and rethrow
204
256
  await this.updateRunStatus(runId, 'cancelled', undefined, {
205
257
  message: error.message || 'Workflow cancelled',
206
258
  stack: '',
@@ -208,6 +260,14 @@ export class PikkuWorkflowService {
208
260
  });
209
261
  throw error;
210
262
  }
263
+ if (error instanceof WorkflowSuspendedException) {
264
+ await this.updateRunStatus(runId, 'suspended', undefined, {
265
+ message: error.message || 'Workflow suspended',
266
+ stack: '',
267
+ code: 'WORKFLOW_SUSPENDED',
268
+ });
269
+ throw error;
270
+ }
211
271
  await this.updateRunStatus(runId, 'failed', undefined, {
212
272
  message: error.message,
213
273
  stack: error.stack,
@@ -217,6 +277,27 @@ export class PikkuWorkflowService {
217
277
  }
218
278
  });
219
279
  }
280
+ async runVersionMismatchFallback(run, currentMeta, rpcService) {
281
+ const source = currentMeta.source;
282
+ if (source === 'complex') {
283
+ await this.updateRunStatus(run.id, 'failed', undefined, {
284
+ message: `Workflow '${run.workflow}' definition changed. Complex workflows with inline steps cannot be migrated.`,
285
+ stack: '',
286
+ code: 'VERSION_CONFLICT',
287
+ });
288
+ return;
289
+ }
290
+ const version = await this.getWorkflowVersion(run.workflow, run.graphHash);
291
+ if (!version) {
292
+ await this.updateRunStatus(run.id, 'failed', undefined, {
293
+ message: `Workflow '${run.workflow}' version '${run.graphHash}' not found. Cannot resume with changed definition.`,
294
+ stack: '',
295
+ code: 'VERSION_NOT_FOUND',
296
+ });
297
+ return;
298
+ }
299
+ await runFromMeta(this, run.id, version.graph, rpcService);
300
+ }
220
301
  /**
221
302
  * Execute a single workflow step (called by worker)
222
303
  * Handles idempotency, RPC execution, result storage, retry logic, and orchestrator triggering
@@ -239,25 +320,22 @@ export class PikkuWorkflowService {
239
320
  if (stepState.status === 'failed') {
240
321
  stepState = await this.createRetryAttempt(stepState.stepId, 'running');
241
322
  }
242
- if (stepState.status !== 'pending') {
243
- // Mark step as running (pending or failed status)
323
+ if (stepState.status === 'pending') {
324
+ // Mark pending step as running before execution
244
325
  await this.setStepRunning(stepState.stepId);
245
326
  }
246
327
  try {
247
328
  let result;
248
- // Check if this is a graph node step (step name starts with 'node:')
249
- if (stepName.startsWith('node:')) {
250
- // Get the graph name from the workflow run
251
- const run = await this.getRun(runId);
252
- if (!run) {
253
- throw new Error(`Workflow run not found: ${runId}`);
254
- }
255
- const graphName = run.workflow;
256
- // Execute as graph step with graph wire context
257
- result = await executeGraphStep(this, rpcService, runId, stepState.stepId, stepName, rpcName, data, graphName);
329
+ const run = await this.getRun(runId);
330
+ if (!run) {
331
+ throw new Error(`Workflow run not found: ${runId}`);
332
+ }
333
+ const meta = pikkuState(null, 'workflows', 'meta');
334
+ const workflowMeta = meta[run.workflow];
335
+ if (workflowMeta?.nodes && stepName in workflowMeta.nodes) {
336
+ result = await executeGraphStep(this, rpcService, runId, stepState.stepId, stepName, rpcName, data, run.workflow);
258
337
  }
259
338
  else {
260
- // Execute RPC with workflow step context (regular workflow)
261
339
  result = await rpcService.rpcWithWire(rpcName, data, {
262
340
  workflowStep: {
263
341
  runId,
@@ -272,6 +350,14 @@ export class PikkuWorkflowService {
272
350
  await this.resumeWorkflow(runId);
273
351
  }
274
352
  catch (error) {
353
+ if (error instanceof RPCNotFoundError) {
354
+ await this.setStepError(stepState.stepId, error);
355
+ await this.updateRunStatus(runId, 'suspended', undefined, {
356
+ message: `RPC '${rpcName}' not found. Deploy the missing function and resume.`,
357
+ code: 'RPC_NOT_FOUND',
358
+ });
359
+ return;
360
+ }
275
361
  // Store error and mark failed
276
362
  await this.setStepError(stepState.stepId, error);
277
363
  const maxAttempts = (stepState.retries ?? 0) + 1;
@@ -296,7 +382,8 @@ export class PikkuWorkflowService {
296
382
  }
297
383
  catch (error) {
298
384
  if (error.name === 'WorkflowAsyncException' ||
299
- error.name === 'WorkflowCancelledException') {
385
+ error.name === 'WorkflowCancelledException' ||
386
+ error.name === 'WorkflowSuspendedException') {
300
387
  return;
301
388
  }
302
389
  await this.updateRunStatus(runId, 'failed', undefined, {
@@ -308,10 +395,10 @@ export class PikkuWorkflowService {
308
395
  }
309
396
  }
310
397
  verifyQueueService() {
311
- if (!this.singletonServices?.queueService) {
398
+ if (!getSingletonServices()?.queueService) {
312
399
  throw new Error('QueueService not configured. Remote workflows require a queue service.');
313
400
  }
314
- return this.singletonServices.queueService;
401
+ return getSingletonServices().queueService;
315
402
  }
316
403
  async rpcStep(runId, stepName, rpcName, data, rpcService, stepOptions) {
317
404
  // Check if step already exists
@@ -344,11 +431,11 @@ export class PikkuWorkflowService {
344
431
  // Step is pending - schedule it
345
432
  await this.setStepScheduled(stepState.stepId);
346
433
  // Enqueue step worker (unless inline mode)
347
- if (!this.isInline(runId) && this.singletonServices.queueService) {
434
+ if (!this.isInline(runId) && getSingletonServices().queueService) {
348
435
  // Map step retry options to queue job options
349
436
  const retries = stepOptions?.retries ?? 0;
350
437
  const retryDelay = stepOptions?.retryDelay;
351
- await this.singletonServices.queueService.add(this.getConfig().stepWorkerQueueName, {
438
+ await getSingletonServices().queueService.add(this.getConfig().stepWorkerQueueName, {
352
439
  runId,
353
440
  stepName,
354
441
  rpcName,
@@ -385,6 +472,13 @@ export class PikkuWorkflowService {
385
472
  return result;
386
473
  }
387
474
  catch (error) {
475
+ if (error instanceof RPCNotFoundError) {
476
+ await this.updateRunStatus(runId, 'suspended', undefined, {
477
+ message: `RPC '${rpcName}' not found. Deploy the missing function and resume.`,
478
+ code: 'RPC_NOT_FOUND',
479
+ });
480
+ throw error;
481
+ }
388
482
  // Record the error (marks step as failed)
389
483
  await this.setStepError(currentStepState.stepId, error);
390
484
  // Check if we should retry
@@ -413,9 +507,7 @@ export class PikkuWorkflowService {
413
507
  }
414
508
  catch {
415
509
  // Step doesn't exist - create it (inline, no RPC)
416
- stepState = await this.insertStepState(runId, stepName, null, // No RPC for inline steps
417
- null, // No data for inline steps
418
- stepOptions);
510
+ stepState = await this.insertStepState(runId, stepName, null, null, stepOptions);
419
511
  }
420
512
  if (stepState.status === 'succeeded') {
421
513
  // Return cached result
@@ -488,10 +580,9 @@ export class PikkuWorkflowService {
488
580
  }
489
581
  catch {
490
582
  // Step doesn't exist - create it (sleep step, no RPC)
491
- stepState = await this.insertStepState(runId, stepName, null, // No RPC for sleep steps
492
- { duration }, // Store duration as data
493
- undefined // No retry options for sleep
494
- );
583
+ stepState = await this.insertStepState(runId, stepName, null, {
584
+ duration,
585
+ });
495
586
  }
496
587
  if (stepState.status === 'succeeded') {
497
588
  // Sleep already completed, return immediately
@@ -504,9 +595,9 @@ export class PikkuWorkflowService {
504
595
  // Step is pending - schedule it
505
596
  await this.setStepScheduled(stepState.stepId);
506
597
  // Check if inline mode or no scheduler service
507
- if (!this.isInline(runId) && this.singletonServices.schedulerService) {
598
+ if (!this.isInline(runId) && getSingletonServices().schedulerService) {
508
599
  // Remote mode - schedule sleep via scheduler service
509
- await this.singletonServices.schedulerService.scheduleRPC(duration, this.getConfig().sleeperRPCName, {
600
+ await getSingletonServices().schedulerService.scheduleRPC(duration, this.getConfig().sleeperRPCName, {
510
601
  runId,
511
602
  stepId: stepState.stepId,
512
603
  });
@@ -520,9 +611,45 @@ export class PikkuWorkflowService {
520
611
  return;
521
612
  }
522
613
  }
523
- createWorkflowWire(workflowName, runId, rpcService) {
614
+ getSuspendStepName(reason) {
615
+ if (!reason) {
616
+ return '__workflow_suspend';
617
+ }
618
+ return '__workflow_suspend';
619
+ }
620
+ async suspendStep(runId, reason) {
621
+ const stepName = this.getSuspendStepName(reason);
622
+ await this.withStepLock(runId, stepName, async () => {
623
+ let stepState;
624
+ try {
625
+ stepState = await this.getStepState(runId, stepName);
626
+ }
627
+ catch {
628
+ stepState = await this.insertStepState(runId, stepName, 'pikkuWorkflowSuspend', {
629
+ reason,
630
+ });
631
+ }
632
+ if (!stepState.stepId) {
633
+ stepState = await this.insertStepState(runId, stepName, 'pikkuWorkflowSuspend', {
634
+ reason,
635
+ });
636
+ }
637
+ if (stepState.status === 'succeeded') {
638
+ return;
639
+ }
640
+ if (stepState.status === 'pending') {
641
+ await this.setStepRunning(stepState.stepId);
642
+ }
643
+ await this.setStepResult(stepState.stepId, {
644
+ reason,
645
+ suspendedAt: new Date().toISOString(),
646
+ });
647
+ throw new WorkflowSuspendedException(runId, reason);
648
+ });
649
+ }
650
+ createWorkflowWire(name, runId, rpcService) {
524
651
  const workflowWire = {
525
- workflowName,
652
+ name,
526
653
  runId,
527
654
  getRun: async () => (await this.getRun(runId)),
528
655
  // Implement workflow.do() - RPC form
@@ -540,6 +667,9 @@ export class PikkuWorkflowService {
540
667
  this.verifyStepName(stepName);
541
668
  await this.sleepStep(runId, stepName, getDurationInMilliseconds(duration));
542
669
  },
670
+ suspend: async (reason) => {
671
+ await this.suspendStep(runId, reason || 'Workflow suspended');
672
+ },
543
673
  };
544
674
  return workflowWire;
545
675
  }
@@ -549,9 +679,14 @@ export class PikkuWorkflowService {
549
679
  }
550
680
  }
551
681
  getConfig() {
552
- if (!this.singletonServices || !this.config) {
553
- throw new WorkflowServiceNotInitialized();
554
- }
555
- return this.config;
682
+ const singletonServices = getSingletonServices();
683
+ const workflow = singletonServices.config?.workflow;
684
+ return {
685
+ retries: workflow?.retries ?? 0,
686
+ retryDelay: workflow?.retryDelay ?? 0,
687
+ orchestratorQueueName: workflow?.orchestratorQueueName ?? 'pikku-workflow-orchestrator',
688
+ stepWorkerQueueName: workflow?.stepWorkerQueueName ?? 'pikku-workflow-step-worker',
689
+ sleeperRPCName: workflow?.sleeperRPCName ?? 'pikkuWorkflowSleeper',
690
+ };
556
691
  }
557
692
  }
@@ -0,0 +1,36 @@
1
+ export declare function workflow<TWorkflowMap extends Record<string, {
2
+ input: any;
3
+ output: any;
4
+ }>>(workflowName: string & keyof TWorkflowMap, options?: {
5
+ pollIntervalMs?: number;
6
+ }): {
7
+ func: (services: any, data: any, wire: any) => Promise<any>;
8
+ };
9
+ export declare function workflowStart<TWorkflowMap extends Record<string, {
10
+ input: any;
11
+ output: any;
12
+ }>>(workflowName: string & keyof TWorkflowMap): {
13
+ func: (services: any, data: any, wire: any) => Promise<{
14
+ runId: string;
15
+ }>;
16
+ };
17
+ export declare function workflowStatus<TWorkflowMap extends Record<string, {
18
+ input: any;
19
+ output: any;
20
+ }>>(_workflowName: string & keyof TWorkflowMap): {
21
+ func: (services: any, data: {
22
+ runId: string;
23
+ }) => Promise<{
24
+ id: string;
25
+ status: 'running' | 'suspended' | 'completed' | 'failed' | 'cancelled';
26
+ output?: any;
27
+ error?: {
28
+ message?: string;
29
+ };
30
+ }>;
31
+ };
32
+ export declare function graphStart<TGraphsMap extends Record<string, Record<string, any>>>(graphName: string & keyof TGraphsMap, startNode: string): {
33
+ func: (services: any, data: any, wire: any) => Promise<{
34
+ runId: string;
35
+ }>;
36
+ };
@@ -0,0 +1,38 @@
1
+ import { WorkflowRunNotFoundError } from './pikku-workflow-service.js';
2
+ export function workflow(workflowName, options) {
3
+ return {
4
+ func: async (services, data, { rpc }) => {
5
+ return services.workflowService.runToCompletion(workflowName, data, rpc, options);
6
+ },
7
+ };
8
+ }
9
+ export function workflowStart(workflowName) {
10
+ return {
11
+ func: async (_services, data, { rpc }) => {
12
+ return rpc.startWorkflow(workflowName, data);
13
+ },
14
+ };
15
+ }
16
+ export function workflowStatus(_workflowName) {
17
+ return {
18
+ func: async (services, data) => {
19
+ const run = await services.workflowService.getRun(data.runId);
20
+ if (!run) {
21
+ throw new WorkflowRunNotFoundError(data.runId);
22
+ }
23
+ return {
24
+ id: run.id,
25
+ status: run.status,
26
+ output: run.output,
27
+ error: run.error ? { message: run.error.message } : undefined,
28
+ };
29
+ },
30
+ };
31
+ }
32
+ export function graphStart(graphName, startNode) {
33
+ return {
34
+ func: async (_services, data, { rpc }) => {
35
+ return rpc.startWorkflow(graphName, data, { startNode });
36
+ },
37
+ };
38
+ }