@pikku/core 0.12.79 → 0.12.80

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 (330) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/dist/dev/hot-reload.js +1 -6
  3. package/dist/ecosystem.d.ts +27 -0
  4. package/dist/ecosystem.js +26 -0
  5. package/dist/errors/error-handler.js +4 -2
  6. package/dist/function/function-runner.js +20 -42
  7. package/dist/function/functions.types.d.ts +9 -5
  8. package/dist/index.d.ts +4 -9
  9. package/dist/index.js +3 -8
  10. package/dist/middleware/auth-cookie.d.ts +0 -4
  11. package/dist/middleware/auth-cookie.js +38 -2
  12. package/dist/middleware/cors.js +1 -0
  13. package/dist/middleware/index.d.ts +1 -1
  14. package/dist/middleware/index.js +1 -1
  15. package/dist/middleware/remote-auth.js +14 -3
  16. package/dist/permissions.d.ts +8 -10
  17. package/dist/permissions.js +0 -11
  18. package/dist/pikku-state.js +12 -5
  19. package/dist/schema.js +35 -1
  20. package/dist/services/ai-run-state-service.d.ts +7 -1
  21. package/dist/services/in-memory-ai-run-state-service.d.ts +1 -1
  22. package/dist/services/in-memory-ai-run-state-service.js +2 -1
  23. package/dist/services/in-memory-workflow-service.js +2 -0
  24. package/dist/services/local-content-request-handler.d.ts +21 -0
  25. package/dist/services/local-content-request-handler.js +72 -53
  26. package/dist/services/local-content.d.ts +6 -0
  27. package/dist/services/local-content.js +14 -1
  28. package/dist/services/workflow-service.d.ts +4 -2
  29. package/dist/testing/service-tests/agent-run-service-tests.d.ts +10 -0
  30. package/dist/testing/service-tests/agent-run-service-tests.js +72 -0
  31. package/dist/testing/service-tests/ai-storage-service-tests.d.ts +3 -0
  32. package/dist/testing/service-tests/ai-storage-service-tests.js +226 -0
  33. package/dist/testing/service-tests/channel-store-tests.d.ts +3 -0
  34. package/dist/testing/service-tests/channel-store-tests.js +72 -0
  35. package/dist/testing/service-tests/credential-service-tests.d.ts +3 -0
  36. package/dist/testing/service-tests/credential-service-tests.js +109 -0
  37. package/dist/testing/service-tests/deployment-service-tests.d.ts +3 -0
  38. package/dist/testing/service-tests/deployment-service-tests.js +21 -0
  39. package/dist/testing/service-tests/event-hub-store-tests.d.ts +3 -0
  40. package/dist/testing/service-tests/event-hub-store-tests.js +34 -0
  41. package/dist/testing/service-tests/secret-service-tests.d.ts +3 -0
  42. package/dist/testing/service-tests/secret-service-tests.js +80 -0
  43. package/dist/testing/service-tests/session-store-tests.d.ts +3 -0
  44. package/dist/testing/service-tests/session-store-tests.js +43 -0
  45. package/dist/testing/service-tests/workflow-run-service-tests.d.ts +3 -0
  46. package/dist/testing/service-tests/workflow-run-service-tests.js +42 -0
  47. package/dist/testing/service-tests/workflow-service-tests.d.ts +3 -0
  48. package/dist/testing/service-tests/workflow-service-tests.js +150 -0
  49. package/dist/testing/service-tests.d.ts +6 -0
  50. package/dist/testing/service-tests.js +26 -791
  51. package/dist/types/core.types.d.ts +11 -1
  52. package/dist/types/state.types.d.ts +1 -1
  53. package/dist/wirings/actor-flow/run-conversation.js +1 -6
  54. package/dist/wirings/ai-agent/agent-rpc.d.ts +15 -0
  55. package/dist/wirings/ai-agent/agent-rpc.js +53 -0
  56. package/dist/wirings/ai-agent/ai-agent-agui.js +1 -5
  57. package/dist/wirings/ai-agent/ai-agent-memory.js +3 -1
  58. package/dist/wirings/ai-agent/ai-agent-prepare.js +3 -9
  59. package/dist/wirings/ai-agent/ai-agent-runner.js +28 -107
  60. package/dist/wirings/ai-agent/ai-agent-stream.js +20 -61
  61. package/dist/wirings/ai-agent/ai-agent-turn.d.ts +56 -0
  62. package/dist/wirings/ai-agent/ai-agent-turn.js +81 -0
  63. package/dist/wirings/ai-agent/ai-agent.types.d.ts +1 -1
  64. package/dist/wirings/ai-agent/voice-input.js +1 -6
  65. package/dist/wirings/ai-agent/voice-output.js +2 -12
  66. package/dist/wirings/channel/channel-common.js +1 -0
  67. package/dist/wirings/channel/channel-handler.js +3 -5
  68. package/dist/wirings/channel/channel-rpc-service.d.ts +0 -6
  69. package/dist/wirings/channel/channel-rpc-service.js +0 -8
  70. package/dist/wirings/channel/channel-rpc.types.d.ts +6 -0
  71. package/dist/wirings/channel/channel-rpc.types.js +8 -0
  72. package/dist/wirings/channel/channel-runner.d.ts +1 -3
  73. package/dist/wirings/channel/channel-runner.js +16 -8
  74. package/dist/wirings/channel/channel.types.d.ts +2 -0
  75. package/dist/wirings/channel/pikku-abstract-channel-handler.js +1 -0
  76. package/dist/wirings/channel/serverless/serverless-channel-runner.js +3 -0
  77. package/dist/wirings/cli/channel/cli-channel-runner.js +2 -0
  78. package/dist/wirings/cli/cli-runner.js +4 -2
  79. package/dist/wirings/cli/cli.types.d.ts +0 -8
  80. package/dist/wirings/cli/command-parser.js +13 -0
  81. package/dist/wirings/gateway/gateway-runner.js +9 -2
  82. package/dist/wirings/http/http-routes.js +2 -0
  83. package/dist/wirings/http/http-runner.d.ts +0 -10
  84. package/dist/wirings/http/http-runner.js +6 -13
  85. package/dist/wirings/http/http.types.d.ts +0 -10
  86. package/dist/wirings/http/index.d.ts +1 -1
  87. package/dist/wirings/http/index.js +1 -1
  88. package/dist/wirings/mcp/mcp-runner.d.ts +0 -7
  89. package/dist/wirings/mcp/mcp-runner.js +0 -6
  90. package/dist/wirings/rpc/rpc-runner.d.ts +8 -51
  91. package/dist/wirings/rpc/rpc-runner.js +53 -86
  92. package/dist/wirings/rpc/rpc-types.d.ts +3 -0
  93. package/dist/wirings/secret/validate-secret-definitions.js +2 -2
  94. package/dist/wirings/trigger/pikku-trigger-service.d.ts +0 -4
  95. package/dist/wirings/trigger/trigger-runner.js +1 -0
  96. package/dist/wirings/virtual-user/run-virtual-user.js +11 -11
  97. package/dist/wirings/virtual-user/virtual-user-derive.js +4 -25
  98. package/dist/wirings/virtual-user/virtual-user-dispositions.js +1 -4
  99. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +29 -2
  100. package/dist/wirings/workflow/feature.js +7 -4
  101. package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -2
  102. package/dist/wirings/workflow/graph/graph-runner.js +8 -7
  103. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -4
  104. package/dist/wirings/workflow/index.d.ts +7 -2
  105. package/dist/wirings/workflow/index.js +5 -1
  106. package/dist/wirings/workflow/pikku-scenario-service.d.ts +17 -3
  107. package/dist/wirings/workflow/pikku-scenario-service.js +38 -10
  108. package/dist/wirings/workflow/pikku-workflow-service.d.ts +28 -147
  109. package/dist/wirings/workflow/pikku-workflow-service.js +71 -493
  110. package/dist/wirings/workflow/workflow-approval.d.ts +39 -0
  111. package/dist/wirings/workflow/workflow-approval.js +114 -0
  112. package/dist/wirings/workflow/workflow-constants.d.ts +26 -0
  113. package/dist/wirings/workflow/workflow-constants.js +35 -0
  114. package/dist/wirings/workflow/workflow-errors.d.ts +58 -0
  115. package/dist/wirings/workflow/workflow-errors.js +112 -0
  116. package/dist/wirings/workflow/workflow-meta-resolver.d.ts +11 -0
  117. package/dist/wirings/workflow/workflow-meta-resolver.js +31 -0
  118. package/dist/wirings/workflow/workflow-queue-routing.d.ts +8 -0
  119. package/dist/wirings/workflow/workflow-queue-routing.js +38 -0
  120. package/dist/wirings/workflow/workflow-queue-wiring.d.ts +20 -0
  121. package/dist/wirings/workflow/workflow-queue-wiring.js +79 -0
  122. package/dist/wirings/workflow/workflow-recovery.d.ts +68 -0
  123. package/dist/wirings/workflow/workflow-recovery.js +101 -0
  124. package/dist/wirings/workflow/workflow-run-engine.types.d.ts +54 -0
  125. package/dist/wirings/workflow/workflow-run-engine.types.js +1 -0
  126. package/dist/wirings/workflow/workflow-run-ownership.d.ts +16 -0
  127. package/dist/wirings/workflow/workflow-run-ownership.js +29 -0
  128. package/dist/wirings/workflow/workflow-suspend.d.ts +12 -0
  129. package/dist/wirings/workflow/workflow-suspend.js +33 -0
  130. package/dist/wirings/workflow/workflow.types.d.ts +7 -0
  131. package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-airunstate-too.md +22 -0
  132. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +20 -0
  133. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +21 -0
  134. package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +21 -0
  135. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +46 -0
  136. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +45 -0
  137. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +21 -0
  138. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +22 -0
  139. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +23 -0
  140. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +25 -0
  141. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +22 -0
  142. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +20 -0
  143. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +22 -0
  144. package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +66 -0
  145. package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +33 -0
  146. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +43 -0
  147. package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +26 -0
  148. package/knowledge/decisions/internals/index.md +38 -26
  149. package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +21 -0
  150. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +24 -0
  151. package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +34 -0
  152. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +24 -0
  153. package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +22 -0
  154. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +26 -0
  155. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +43 -0
  156. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +58 -0
  157. package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +40 -0
  158. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +40 -0
  159. package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +28 -0
  160. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +25 -0
  161. package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +21 -0
  162. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +22 -0
  163. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +25 -0
  164. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +21 -0
  165. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +24 -0
  166. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +35 -0
  167. package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +4 -2
  168. package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +33 -0
  169. package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +33 -0
  170. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +37 -0
  171. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +28 -0
  172. package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +34 -0
  173. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +33 -0
  174. package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +24 -0
  175. package/knowledge/decisions/security/index.md +7 -0
  176. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +35 -0
  177. package/knowledge/questions/index.md +2 -1
  178. package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +44 -0
  179. package/package.json +13 -3
  180. package/scripts/generate-api-report.d.mts +1 -0
  181. package/scripts/generate-api-report.mjs +89 -0
  182. package/scripts/generate-api-report.mts +218 -0
  183. package/src/api-report.test.ts +69 -0
  184. package/src/column-form.ts +1 -4
  185. package/src/crypto-utils.test.ts +15 -2
  186. package/src/dev/hot-reload.ts +2 -7
  187. package/src/ecosystem.ts +40 -0
  188. package/src/errors/error-handler.ts +5 -3
  189. package/src/errors/error.test.ts +4 -1
  190. package/src/function/function-runner.test.ts +1 -1
  191. package/src/function/function-runner.ts +28 -39
  192. package/src/function/functions.types.ts +15 -9
  193. package/src/handle-error.ts +1 -1
  194. package/src/index.ts +3 -22
  195. package/src/middleware/auth-cookie.test.ts +50 -0
  196. package/src/middleware/auth-cookie.ts +38 -2
  197. package/src/middleware/cors.ts +2 -1
  198. package/src/middleware/index.ts +1 -1
  199. package/src/middleware/remote-auth.test.ts +43 -0
  200. package/src/middleware/remote-auth.ts +17 -3
  201. package/src/middleware-runner.ts +4 -2
  202. package/src/no-any-casts.test.ts +57 -0
  203. package/src/permissions.test.ts +3 -1
  204. package/src/permissions.ts +22 -24
  205. package/src/pikku-state.ts +17 -6
  206. package/src/public-surface.json +578 -0
  207. package/src/public-surface.json.README +25 -0
  208. package/src/public-surface.test.ts +105 -0
  209. package/src/removed-legacy-exports.test.ts +62 -0
  210. package/src/schema.test.ts +78 -0
  211. package/src/schema.ts +36 -1
  212. package/src/services/ai-run-state-service.ts +7 -1
  213. package/src/services/audit-service.ts +2 -2
  214. package/src/services/in-memory-ai-run-state-service.ts +3 -2
  215. package/src/services/in-memory-workflow-service.ts +2 -0
  216. package/src/services/index.ts +1 -4
  217. package/src/services/local-content-request-handler.test.ts +43 -5
  218. package/src/services/local-content-request-handler.ts +103 -74
  219. package/src/services/local-content.ts +15 -1
  220. package/src/services/local-email-service.ts +5 -1
  221. package/src/services/system-role-guard.test.ts +4 -1
  222. package/src/services/workflow-service.ts +9 -2
  223. package/src/side-effects-are-declared.test.ts +84 -0
  224. package/src/source-files-stay-composable.test.ts +41 -0
  225. package/src/testing/service-tests/agent-run-service-tests.ts +98 -0
  226. package/src/testing/service-tests/ai-storage-service-tests.ts +286 -0
  227. package/src/testing/service-tests/channel-store-tests.ts +98 -0
  228. package/src/testing/service-tests/credential-service-tests.ts +143 -0
  229. package/src/testing/service-tests/deployment-service-tests.ts +33 -0
  230. package/src/testing/service-tests/event-hub-store-tests.ts +48 -0
  231. package/src/testing/service-tests/secret-service-tests.ts +105 -0
  232. package/src/testing/service-tests/session-store-tests.ts +62 -0
  233. package/src/testing/service-tests/workflow-run-service-tests.ts +59 -0
  234. package/src/testing/service-tests/workflow-service-tests.ts +308 -0
  235. package/src/testing/service-tests.ts +31 -1111
  236. package/src/types/core.types.ts +15 -1
  237. package/src/types/state.types.ts +1 -1
  238. package/src/wirings/actor-flow/run-conversation.ts +1 -6
  239. package/src/wirings/ai-agent/agent-rpc.ts +120 -0
  240. package/src/wirings/ai-agent/ai-agent-agui.ts +1 -5
  241. package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +2 -1
  242. package/src/wirings/ai-agent/ai-agent-memory.ts +8 -1
  243. package/src/wirings/ai-agent/ai-agent-prepare.ts +10 -12
  244. package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +1 -0
  245. package/src/wirings/ai-agent/ai-agent-runner.test.ts +82 -2
  246. package/src/wirings/ai-agent/ai-agent-runner.ts +49 -120
  247. package/src/wirings/ai-agent/ai-agent-stream.test.ts +2 -0
  248. package/src/wirings/ai-agent/ai-agent-stream.ts +36 -63
  249. package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +1 -1
  250. package/src/wirings/ai-agent/ai-agent-turn.ts +121 -0
  251. package/src/wirings/ai-agent/ai-agent.types.ts +1 -1
  252. package/src/wirings/ai-agent/voice-input.ts +1 -6
  253. package/src/wirings/ai-agent/voice-output.ts +2 -12
  254. package/src/wirings/channel/channel-common.ts +5 -2
  255. package/src/wirings/channel/channel-handler-shapes.test.ts +72 -0
  256. package/src/wirings/channel/channel-handler.ts +7 -7
  257. package/src/wirings/channel/channel-rpc-service.ts +0 -14
  258. package/src/wirings/channel/channel-rpc.test.ts +25 -4
  259. package/src/wirings/channel/channel-rpc.types.ts +14 -0
  260. package/src/wirings/channel/channel-runner.ts +33 -20
  261. package/src/wirings/channel/channel.types.ts +2 -0
  262. package/src/wirings/channel/local/local-channel-runner.ts +1 -1
  263. package/src/wirings/channel/pikku-abstract-channel-handler.ts +2 -1
  264. package/src/wirings/channel/serverless/serverless-channel-runner.ts +6 -3
  265. package/src/wirings/cli/channel/cli-channel-runner.ts +3 -1
  266. package/src/wirings/cli/channel/cli-raw-client-runner.ts +4 -1
  267. package/src/wirings/cli/cli-runner.ts +7 -4
  268. package/src/wirings/cli/cli.types.ts +0 -39
  269. package/src/wirings/cli/command-parser.test.ts +19 -0
  270. package/src/wirings/cli/command-parser.ts +17 -1
  271. package/src/wirings/gateway/gateway-channel-meta.test.ts +44 -0
  272. package/src/wirings/gateway/gateway-runner.ts +27 -19
  273. package/src/wirings/http/http-routes.ts +4 -1
  274. package/src/wirings/http/http-runner.ts +11 -26
  275. package/src/wirings/http/http.types.ts +0 -15
  276. package/src/wirings/http/index.ts +1 -7
  277. package/src/wirings/http/pikku-fetch-http-request.ts +2 -2
  278. package/src/wirings/http/web-request.ts +1 -1
  279. package/src/wirings/mcp/mcp-runner.ts +2 -16
  280. package/src/wirings/persona/persona-environments.test.ts +14 -3
  281. package/src/wirings/persona/persona.test.ts +13 -3
  282. package/src/wirings/persona/validate-personas.ts +5 -1
  283. package/src/wirings/queue/queue-runner.ts +1 -1
  284. package/src/wirings/rpc/addon-auth-tags.test.ts +1 -5
  285. package/src/wirings/rpc/rpc-runner.ts +58 -136
  286. package/src/wirings/rpc/rpc-types.ts +7 -0
  287. package/src/wirings/rpc/wire-addon.ts +3 -1
  288. package/src/wirings/secret/validate-secret-definitions.test.ts +22 -0
  289. package/src/wirings/secret/validate-secret-definitions.ts +2 -2
  290. package/src/wirings/trigger/pikku-trigger-service.ts +0 -5
  291. package/src/wirings/trigger/trigger-runner.ts +7 -5
  292. package/src/wirings/virtual-user/run-virtual-user.test.ts +18 -9
  293. package/src/wirings/virtual-user/run-virtual-user.ts +28 -15
  294. package/src/wirings/virtual-user/virtual-user-agents.test.ts +4 -1
  295. package/src/wirings/virtual-user/virtual-user-derive.ts +4 -25
  296. package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +7 -2
  297. package/src/wirings/virtual-user/virtual-user-dispositions.ts +1 -4
  298. package/src/wirings/virtual-user/virtual-user-intents.test.ts +13 -3
  299. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +35 -2
  300. package/src/wirings/workflow/feature.ts +7 -4
  301. package/src/wirings/workflow/graph/graph-node.ts +1 -1
  302. package/src/wirings/workflow/graph/graph-runner.test.ts +4 -2
  303. package/src/wirings/workflow/graph/graph-runner.ts +13 -16
  304. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -5
  305. package/src/wirings/workflow/index.ts +12 -4
  306. package/src/wirings/workflow/pikku-scenario-service.ts +54 -25
  307. package/src/wirings/workflow/pikku-workflow-service.test.ts +2 -2
  308. package/src/wirings/workflow/pikku-workflow-service.ts +190 -743
  309. package/src/wirings/workflow/scenario-hooks.test.ts +51 -0
  310. package/src/wirings/workflow/workflow-approval.ts +185 -0
  311. package/src/wirings/workflow/workflow-child-run-session.test.ts +89 -0
  312. package/src/wirings/workflow/workflow-constants.ts +47 -0
  313. package/src/wirings/workflow/workflow-dispatch-durability.test.ts +1 -1
  314. package/src/wirings/workflow/workflow-errors.ts +128 -0
  315. package/src/wirings/workflow/workflow-inline-authority.test.ts +12 -6
  316. package/src/wirings/workflow/workflow-meta-resolver.ts +45 -0
  317. package/src/wirings/workflow/workflow-missing-meta.test.ts +92 -0
  318. package/src/wirings/workflow/workflow-queue-routing.ts +85 -0
  319. package/src/wirings/workflow/workflow-queue-wiring.ts +149 -0
  320. package/src/wirings/workflow/workflow-recovery.ts +162 -0
  321. package/src/wirings/workflow/workflow-retry-policy.test.ts +1 -1
  322. package/src/wirings/workflow/workflow-run-authority.test.ts +215 -0
  323. package/src/wirings/workflow/workflow-run-engine.types.ts +91 -0
  324. package/src/wirings/workflow/workflow-run-ownership.ts +36 -0
  325. package/src/wirings/workflow/workflow-suspend.ts +61 -0
  326. package/src/wirings/workflow/workflow.types.ts +7 -0
  327. package/src/wirings-stay-decoupled.test.ts +123 -0
  328. package/tsconfig.json +1 -1
  329. package/tsconfig.tsbuildinfo +1 -1
  330. package/src/internal.ts +0 -10
@@ -5,7 +5,7 @@ import { closeWireServices } from '../../utils.js';
5
5
  import { PikkuError, addError } from '../../errors/error-handler.js';
6
6
  import { InMemoryWorkflowService } from '../../services/in-memory-workflow-service.js';
7
7
  import { runScheduledTask } from '../scheduler/scheduler-runner.js';
8
- import { WorkflowStepNameNotString, } from './pikku-workflow-service.js';
8
+ import { WorkflowStepNameNotString } from './workflow-errors.js';
9
9
  import { resolveScenarioSurfaces, witnessesAgree } from './scenario-surface.js';
10
10
  /**
11
11
  * A workflow service with the scenario capability attached — the two lines
@@ -176,6 +176,10 @@ export class PikkuScenarioService {
176
176
  // Scenario actors per run: live authenticated clients (cookie jars) are
177
177
  // process-local by nature, so they ride this map, never the persisted wire.
178
178
  runActors = new Map();
179
+ // What each run has accumulated so far. Process-local like the actors above:
180
+ // a scenario is a single in-process run, so the body and its hooks share one
181
+ // object rather than reading it back off the persisted wire.
182
+ runContexts = new Map();
179
183
  scenarioBrowserProvider;
180
184
  scenarioEnvironment;
181
185
  runSurface = 'default';
@@ -222,9 +226,35 @@ export class PikkuScenarioService {
222
226
  if (actors) {
223
227
  this.runActors.set(runId, actors);
224
228
  }
229
+ if (workflowMeta.source === 'scenario') {
230
+ this.runContexts.set(runId, {});
231
+ }
225
232
  }
226
233
  detachRunContext(runId) {
227
234
  this.runActors.delete(runId);
235
+ this.runContexts.delete(runId);
236
+ }
237
+ /**
238
+ * What the run has accumulated, for a reporter that wants to say what a
239
+ * failed scenario left behind. Undefined for a plain workflow.
240
+ */
241
+ getRunContext(runId) {
242
+ return this.runContexts.get(runId);
243
+ }
244
+ /**
245
+ * The run's context, created on demand.
246
+ *
247
+ * `attachRunContext` seeds it for an ordinary scenario run, but the wire is
248
+ * also built on paths that skip attach; without this the body would be
249
+ * writing to an `undefined` and teardown would read nothing.
250
+ */
251
+ contextForRun(runId) {
252
+ let runContext = this.runContexts.get(runId);
253
+ if (!runContext) {
254
+ runContext = {};
255
+ this.runContexts.set(runId, runContext);
256
+ }
257
+ return runContext;
228
258
  }
229
259
  decorateRunWire(wire, context) {
230
260
  wire.scenario =
@@ -367,6 +397,10 @@ export class PikkuScenarioService {
367
397
  rpcService,
368
398
  });
369
399
  Object.assign(workflowWire, {
400
+ // One object per run, resolved through the map rather than created here,
401
+ // so the body and its before/after hooks share the same scratch even
402
+ // though the hooks are separate functions that cannot see its locals.
403
+ context: this.contextForRun(runId),
370
404
  // Durable polling step: invoke an RPC (as an actor when options.as is
371
405
  // set) until the predicate passes or `within` elapses. The whole poll is
372
406
  // ONE recorded step, so replay returns the cached outcome.
@@ -451,12 +485,7 @@ export class PikkuScenarioService {
451
485
  }
452
486
  }, options);
453
487
  },
454
- // Scenario steps: a named `pikkuScenarioStep` run as one durable step.
455
- // `given`/`when` are sugar for each other, differing only in the
456
- // prose a reporter renders. `then` is not: the phase is what decides
457
- // whether the step's bindings are alternatives or witnesses, so the same
458
- // step function called two ways runs differently. See
459
- // {@link resolveScenarioSurfaces}.
488
+ // knowledge: decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md
460
489
  given: (stepName, stepFunc, data, options) => this.scenarioStep('given', scenarioStepContext(), stepName, stepFunc, data, options),
461
490
  when: (stepName, stepFunc, data, options) => this.scenarioStep('when', scenarioStepContext(), stepName, stepFunc, data, options),
462
491
  then: (stepName, stepFunc, data, options) => this.scenarioStep('then', scenarioStepContext(), stepName, stepFunc, data, options),
@@ -466,7 +495,7 @@ export class PikkuScenarioService {
466
495
  });
467
496
  }
468
497
  async scenarioStep(phase, context, stepName, stepFunc, data, options) {
469
- const { runId, workflowName, addonNamespace, workflowWire, rpcService } = context;
498
+ const { runId, workflowName, addonNamespace, workflowWire } = context;
470
499
  // Also the guard for `then` being a wire member: an accidental
471
500
  // `await scenario` calls it with a resolve function, which lands here as a
472
501
  // loud, named error instead of a silent hang.
@@ -486,11 +515,10 @@ export class PikkuScenarioService {
486
515
  const resolution = resolveScenarioSurfaces(phase, declared, this.runSurface);
487
516
  return await this.engine.inlineStep(runId, stepName, async () => {
488
517
  const runOnSurface = async (surface) => {
518
+ // No `rpc` yet — runPikkuFunc attaches it lazily for the invocation.
489
519
  const wire = {
490
520
  workflow: workflowWire,
491
521
  scenario: workflowWire,
492
- rpc: rpcService?.wire?.rpc,
493
- session: rpcService?.wire?.session,
494
522
  pikkuUserId: workflowWire.pikkuUserId,
495
523
  actors: this.runActors.get(runId),
496
524
  scenarioStep: {
@@ -1,91 +1,11 @@
1
- import type { PikkuWire, SerializedError } from '../../types/core.types.js';
2
- import type { ApprovalOutcome, CoreWorkflow, PikkuWorkflowWire, StepState, StepStatus, WorkflowPlannedStep, WorkflowRun, WorkflowRunMirror, WorkflowRunStatus, WorkflowRunWire, WorkflowStatus, WorkflowVersionStatus, WorkflowQueueOptions, WorkflowStepOptions } from './workflow.types.js';
1
+ import type { CoreUserSession, SerializedError } from '../../types/core.types.js';
2
+ import type { GroupConcurrencyConfig, JobGroup, JobOptions } from '../queue/queue.types.js';
3
+ import type { PikkuWorkflowWire, StepState, StepStatus, WorkflowPlannedStep, WorkflowRun, WorkflowRunMirror, WorkflowRunStatus, WorkflowRunWire, WorkflowStatus, WorkflowVersionStatus, WorkflowQueueOptions, WorkflowStepOptions } from './workflow.types.js';
3
4
  import type { WorkflowService } from '../../services/workflow-service.js';
4
5
  import type { ScenarioPersonas } from '../../services/personas-service.js';
5
- import { PikkuError } from '../../errors/error-handler.js';
6
+ import type { PikkuRPC } from '../rpc/rpc-types.js';
6
7
  import { type RunTimeline, type ReconstructedRunState } from './run-timeline.js';
7
- import type { GroupConcurrencyConfig, JobGroup, JobOptions } from '../queue/queue.types.js';
8
- export declare const DEFAULT_STEP_RETRIES = 5;
9
- export declare class WorkflowAsyncException extends Error {
10
- readonly runId: string;
11
- readonly stepName: string;
12
- constructor(runId: string, stepName: string);
13
- }
14
- export declare class WorkflowCancelledException extends Error {
15
- readonly runId: string;
16
- readonly reason?: string | undefined;
17
- constructor(runId: string, reason?: string | undefined);
18
- }
19
- export declare class WorkflowSuspendedException extends Error {
20
- readonly runId: string;
21
- readonly reason: string;
22
- constructor(runId: string, reason: string);
23
- }
24
- export declare class WorkflowDispatchException extends Error {
25
- readonly runId: string;
26
- readonly stepName: string;
27
- constructor(runId: string, stepName: string, options?: {
28
- cause?: unknown;
29
- });
30
- }
31
- export declare class WorkflowNotFoundError extends PikkuError {
32
- constructor(name: string);
33
- }
34
- export declare class WorkflowRunNotFoundError extends PikkuError {
35
- constructor(runId: string);
36
- }
37
- export declare class WorkflowRunFailedError extends PikkuError {
38
- payload: {
39
- message?: string;
40
- };
41
- constructor(message?: string);
42
- }
43
- export declare class WorkflowRunCancelledError extends PikkuError {
44
- constructor();
45
- }
46
- export declare class WorkflowApprovalResolvedError extends PikkuError {
47
- payload: {
48
- reason: string;
49
- outcome: ApprovalOutcome<unknown>['status'];
50
- };
51
- constructor(reason: string, outcome: ApprovalOutcome<unknown>['status']);
52
- }
53
- export declare class WorkflowServiceNotInitialized extends Error {
54
- }
55
- export declare class WorkflowStepNameNotString extends Error {
56
- constructor(stepName: any);
57
- }
58
- export interface RunLifecycleContext {
59
- runId: string;
60
- run: WorkflowRun;
61
- workflowMeta: any;
62
- workflow: CoreWorkflow;
63
- wire: PikkuWire;
64
- packageName: string | null;
65
- }
66
- export interface WorkflowRunEngine {
67
- inlineStep(runId: string, logicalStepName: string, fn: Function, stepOptions?: WorkflowStepOptions, data?: any, funcName?: string): Promise<any>;
68
- updateRunStatus(runId: string, status: WorkflowStatus, output?: any, error?: SerializedError): Promise<void>;
69
- onChildWorkflowFailed(run: WorkflowRun, error: unknown): Promise<void>;
70
- verifyStepName(stepName: unknown): void;
71
- }
72
- export interface WorkflowRunExtension {
73
- attachRunContext(runId: string, workflowMeta: any, options?: Record<string, any>): Promise<void>;
74
- detachRunContext(runId: string): void;
75
- decorateRunWire(wire: PikkuWire, context: {
76
- runId: string;
77
- workflowMeta: any;
78
- workflowWire: PikkuWorkflowWire;
79
- }): void;
80
- decorateWorkflowWire(workflowWire: PikkuWorkflowWire, context: {
81
- name: string;
82
- runId: string;
83
- rpcService: any;
84
- addonNamespace?: string | null;
85
- }): void;
86
- onBeforeRunFunc(context: RunLifecycleContext): Promise<void>;
87
- onAfterRunFunc(context: RunLifecycleContext, outcome: 'completed' | 'failed' | 'interrupted', failure: unknown): Promise<void>;
88
- }
8
+ import type { WorkflowRunEngine, WorkflowRunExtension } from './workflow-run-engine.types.js';
89
9
  export declare abstract class PikkuWorkflowService implements WorkflowService {
90
10
  private runExtension?;
91
11
  private runContexts;
@@ -178,31 +98,6 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
178
98
  * `recoverStalledRuns`.
179
99
  */
180
100
  protected findStalledRunIds(_before: Date, _limit: number): Promise<string[]>;
181
- /**
182
- * Re-drive runs whose next move was lost, and report which were resumed.
183
- *
184
- * Arming a step is two writes to two systems — the step row, then the queue
185
- * or scheduler job — so a process that dies between them leaves a run that is
186
- * `running` with nothing in flight. Nothing notices: the run parks on a step
187
- * that will never complete and never error, so it neither finishes nor fails.
188
- * (Seen on a `workflow.sleep()`: a deploy restart landed between the sleep
189
- * step's insert and its timer, parking the run permanently.)
190
- *
191
- * Replay is the recovery — `resumeWorkflow` re-orchestrates from persisted
192
- * step state, and every settled step is memoized, so resuming a run that was
193
- * not actually stuck costs an orchestration pass and changes nothing. That
194
- * idempotence is what makes an idle-time heuristic safe here; a run that is
195
- * legitimately mid-sleep is excluded anyway, since its step is `scheduled`.
196
- *
197
- * This is not self-starting. Call it from a scheduled task at whatever
198
- * interval suits the workload.
199
- */
200
- recoverStalledRuns(options?: {
201
- stalledAfterMs?: number;
202
- limit?: number;
203
- }): Promise<{
204
- resumed: string[];
205
- }>;
206
101
  /**
207
102
  * Runs holding a step that has sat `pending` since before `before`, paired
208
103
  * with the step that flagged them.
@@ -220,30 +115,22 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
220
115
  runId: string;
221
116
  stepId: string;
222
117
  }>>;
118
+ private readonly redispatchBackoff;
119
+ private get sweepDeps();
223
120
  /**
224
- * Re-drive steps whose dispatch was lost, and report which runs were nudged.
225
- *
226
- * Arming a step is two writes to two systems: the step row lands `pending`,
227
- * then a queue or scheduler job is published. Nothing spans both, so a crash
228
- * in between leaves a durable row that nothing will ever pick up — the run
229
- * neither finishes nor fails. (Seen on a `workflow.sleep()`: a deploy restart
230
- * landed between the sleep step's insert and its timer.)
231
- *
232
- * The row is the outbox record and this is the relay. Age is the only signal
233
- * available — a step `pending` because its dispatch was lost is
234
- * indistinguishable from one whose job is merely still queuedso a step
235
- * past `undispatchedAfterMs` is re-dispatched regardless, and correctness
236
- * rests on the claim rather than on the guess being right. A redundant
237
- * dispatch costs one queue message: the loser reads `running` and returns
238
- * without invoking anything.
239
- *
240
- * Re-dispatches back off per step (doubling from 30s, capped at 10m) so a
241
- * genuine queue backlog is not amplified by a tick that keeps firing at the
242
- * steps the backlog is already delaying. The backoff is per process and
243
- * advisory — losing it on restart costs extra dispatches, never correctness.
244
- *
245
- * This is not self-starting. Call it from a scheduled task; ~30s suits a
246
- * queue whose `pending`→`running` latency is well under that.
121
+ * Re-drive runs whose next move was lost. Not self-starting call it from a
122
+ * scheduled task at whatever interval suits the workload.
123
+ */
124
+ recoverStalledRuns(options?: {
125
+ stalledAfterMs?: number;
126
+ limit?: number;
127
+ }): Promise<{
128
+ resumed: string[];
129
+ }>;
130
+ /**
131
+ * Re-drive steps whose dispatch was lost. Not self-startingcall it from a
132
+ * scheduled task; ~30s suits a queue whose `pending`→`running` latency is
133
+ * well under that.
247
134
  */
248
135
  relayUndispatchedSteps(options?: {
249
136
  undispatchedAfterMs?: number;
@@ -251,10 +138,6 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
251
138
  }): Promise<{
252
139
  redispatched: string[];
253
140
  }>;
254
- /** Advisory, per-process record of when a run may next be re-dispatched. */
255
- private readonly redispatchBackoff;
256
- private readonly redispatchDelays;
257
- private noteRedispatch;
258
141
  protected resolveStepJobOptions(stepOptions?: WorkflowStepOptions): JobOptions;
259
142
  queueStepWorker(runId: string, stepName: string, rpcName: string, data: any, stepOptions?: WorkflowStepOptions, fromStepName?: string): Promise<void>;
260
143
  executeWorkflowSleepCompleted(runId: string, stepId: string): Promise<void>;
@@ -263,7 +146,7 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
263
146
  protected scheduleSleep(runId: string, stepId: string, duration: number | string): Promise<boolean>;
264
147
  setRunExtension<T extends WorkflowRunExtension>(create: (engine: WorkflowRunEngine) => T): T;
265
148
  getRunExtension(): WorkflowRunExtension | undefined;
266
- startWorkflow<I>(name: string, input: I, wire: WorkflowRunWire, rpcService: any, options?: {
149
+ startWorkflow<I>(name: string, input: I, wire: WorkflowRunWire, rpcService: PikkuRPC, options?: {
267
150
  inline?: boolean;
268
151
  startNode?: string;
269
152
  actors?: ScenarioPersonas;
@@ -271,7 +154,7 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
271
154
  }): Promise<{
272
155
  runId: string;
273
156
  }>;
274
- runToCompletion<I>(name: string, input: I, rpcService: any, options?: {
157
+ runToCompletion<I>(name: string, input: I, rpcService: PikkuRPC, options?: {
275
158
  pollIntervalMs?: number;
276
159
  wire?: WorkflowRunWire;
277
160
  }): Promise<any>;
@@ -286,14 +169,14 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
286
169
  private getRunIdentity;
287
170
  private lastStepName;
288
171
  private nextStepKey;
289
- runWorkflowJob(runId: string, rpcService: any): Promise<void>;
172
+ runWorkflowJob(runId: string, rpcService: PikkuRPC): Promise<void>;
290
173
  private runWorkflowJobInner;
291
174
  private onChildWorkflowCompleted;
292
175
  protected onChildWorkflowFailed(childRun: WorkflowRun, error: Error): Promise<void>;
293
176
  private runVersionMismatchFallback;
294
- executeWorkflowStep(runId: string, stepName: string, rpcName: string, data: any, rpcService: any): Promise<void>;
177
+ executeWorkflowStep(runId: string, stepName: string, rpcName: string, data: any, rpcService: PikkuRPC): Promise<void>;
295
178
  private executeWorkflowStepInner;
296
- orchestrateWorkflow(runId: string, rpcService: any): Promise<void>;
179
+ orchestrateWorkflow(runId: string, rpcService: PikkuRPC): Promise<void>;
297
180
  private verifyQueueService;
298
181
  private invokeStepRpc;
299
182
  private runInlineRetryLoop;
@@ -301,14 +184,12 @@ export declare abstract class PikkuWorkflowService implements WorkflowService {
301
184
  private rpcStep;
302
185
  protected inlineStep(runId: string, logicalStepName: string, fn: Function, stepOptions?: WorkflowStepOptions, data?: any, rpcName?: string | null): Promise<any>;
303
186
  private sleepStep;
304
- private getSuspendStepName;
305
187
  private suspendStep;
306
188
  private scheduleRunWake;
307
- private getApprovalStepName;
308
- private approvalStateKey;
309
- approveStep(runId: string, reason: string, decision: unknown): Promise<void>;
189
+ private get approvalStore();
190
+ approveStep(runId: string, reason: string, decision: unknown, session?: CoreUserSession): Promise<void>;
310
191
  private approvalStep;
311
- createWorkflowWire(name: string, runId: string, rpcService: any, addonNamespace?: string | null): PikkuWorkflowWire;
192
+ createWorkflowWire(name: string, runId: string, rpcService: PikkuRPC, addonNamespace?: string | null): PikkuWorkflowWire;
312
193
  protected verifyStepName(stepName: string): void;
313
194
  private getConfig;
314
195
  protected getOrchestratorQueueName(workflowName?: string): string;