@pikku/core 0.12.72 → 0.12.74

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 (811) hide show
  1. package/CHANGELOG.md +793 -0
  2. package/dist/crypto-utils.d.ts +30 -5
  3. package/dist/crypto-utils.js +146 -41
  4. package/dist/dev/hot-reload.js +11 -30
  5. package/dist/dev/module-runner.d.ts +3 -7
  6. package/dist/dev/module-runner.js +4 -10
  7. package/dist/dev/reload-meta.d.ts +8 -20
  8. package/dist/dev/reload-meta.js +9 -29
  9. package/dist/errors/error-handler.d.ts +5 -30
  10. package/dist/errors/error-handler.js +16 -32
  11. package/dist/errors/errors.d.ts +32 -151
  12. package/dist/errors/errors.js +55 -157
  13. package/dist/function/abort-scope.d.ts +47 -0
  14. package/dist/function/abort-scope.js +63 -0
  15. package/dist/function/function-runner.js +37 -32
  16. package/dist/function/functions.types.d.ts +44 -136
  17. package/dist/function/functions.types.js +0 -58
  18. package/dist/function/list.types.d.ts +12 -62
  19. package/dist/function/list.types.js +4 -25
  20. package/dist/handle-error.d.ts +0 -13
  21. package/dist/handle-error.js +0 -18
  22. package/dist/index.d.ts +5 -2
  23. package/dist/index.js +4 -1
  24. package/dist/middleware/auth-apikey.d.ts +3 -18
  25. package/dist/middleware/auth-apikey.js +0 -17
  26. package/dist/middleware/auth-bearer.d.ts +6 -41
  27. package/dist/middleware/auth-bearer.js +3 -40
  28. package/dist/middleware/auth-cookie.d.ts +5 -27
  29. package/dist/middleware/auth-cookie.js +2 -26
  30. package/dist/middleware/cors.d.ts +7 -34
  31. package/dist/middleware/cors.js +7 -34
  32. package/dist/middleware/remote-auth.d.ts +3 -1
  33. package/dist/middleware/remote-auth.js +3 -2
  34. package/dist/middleware/telemetry.d.ts +8 -33
  35. package/dist/middleware/telemetry.js +2 -31
  36. package/dist/middleware-runner.d.ts +4 -55
  37. package/dist/middleware-runner.js +5 -74
  38. package/dist/permissions.d.ts +3 -44
  39. package/dist/permissions.js +19 -71
  40. package/dist/pikku-request.d.ts +0 -6
  41. package/dist/pikku-request.js +0 -6
  42. package/dist/pikku-state.d.ts +0 -26
  43. package/dist/pikku-state.js +2 -30
  44. package/dist/remote.d.ts +3 -5
  45. package/dist/remote.js +8 -7
  46. package/dist/schema.d.ts +5 -39
  47. package/dist/schema.js +5 -39
  48. package/dist/scopes.d.ts +4 -23
  49. package/dist/scopes.js +7 -48
  50. package/dist/services/ai-agent-runner-service.d.ts +20 -0
  51. package/dist/services/ai-embedding-service.d.ts +2 -25
  52. package/dist/services/audit-service.js +1 -2
  53. package/dist/services/content-service.d.ts +1 -46
  54. package/dist/services/credential-service.d.ts +3 -40
  55. package/dist/services/deployment-service.d.ts +3 -9
  56. package/dist/services/gateway-service.d.ts +0 -15
  57. package/dist/services/http-personas.d.ts +80 -0
  58. package/dist/services/http-personas.js +233 -0
  59. package/dist/services/in-memory-queue-service.d.ts +0 -14
  60. package/dist/services/in-memory-queue-service.js +1 -15
  61. package/dist/services/in-memory-trigger-service.d.ts +0 -18
  62. package/dist/services/in-memory-trigger-service.js +1 -18
  63. package/dist/services/in-memory-workflow-service.d.ts +0 -16
  64. package/dist/services/in-memory-workflow-service.js +4 -33
  65. package/dist/services/index.d.ts +5 -6
  66. package/dist/services/index.js +2 -5
  67. package/dist/services/istanbul-coverage-service.d.ts +1 -5
  68. package/dist/services/istanbul-coverage-service.js +2 -8
  69. package/dist/services/jwt-service.d.ts +1 -16
  70. package/dist/services/local-content.d.ts +13 -2
  71. package/dist/services/local-content.js +40 -13
  72. package/dist/services/local-gateway-service.d.ts +0 -16
  73. package/dist/services/local-gateway-service.js +2 -17
  74. package/dist/services/local-secrets.d.ts +0 -4
  75. package/dist/services/local-secrets.js +0 -4
  76. package/dist/services/logger-console.d.ts +3 -7
  77. package/dist/services/logger-console.js +3 -7
  78. package/dist/services/logger.d.ts +2 -37
  79. package/dist/services/meta-service.d.ts +23 -26
  80. package/dist/services/meta-service.js +22 -36
  81. package/dist/services/personas-service.d.ts +134 -0
  82. package/dist/services/personas-service.js +40 -0
  83. package/dist/services/pikku-user-id.js +0 -4
  84. package/dist/services/queue-webhook-service.d.ts +2 -36
  85. package/dist/services/queue-webhook-service.js +9 -41
  86. package/dist/services/scheduler-service.d.ts +1 -50
  87. package/dist/services/scheduler-service.js +0 -10
  88. package/dist/services/schema-service.d.ts +1 -24
  89. package/dist/services/scope-service.d.ts +49 -34
  90. package/dist/services/scoped-secret-service.d.ts +0 -4
  91. package/dist/services/scoped-secret-service.js +0 -4
  92. package/dist/services/secret-host-binding.d.ts +8 -0
  93. package/dist/services/secret-host-binding.js +36 -0
  94. package/dist/services/secret-service.d.ts +5 -33
  95. package/dist/services/secretless.d.ts +6 -0
  96. package/dist/services/secretless.js +21 -0
  97. package/dist/services/stub-tracker.d.ts +7 -18
  98. package/dist/services/stub-tracker.js +8 -18
  99. package/dist/services/system-role-guard.d.ts +33 -0
  100. package/dist/services/system-role-guard.js +38 -0
  101. package/dist/services/trigger-service.d.ts +0 -12
  102. package/dist/services/typed-secret-service.d.ts +0 -7
  103. package/dist/services/typed-secret-service.js +1 -7
  104. package/dist/services/v8-coverage-service.d.ts +2 -3
  105. package/dist/services/v8-coverage-service.js +1 -2
  106. package/dist/services/variables-service.d.ts +1 -8
  107. package/dist/services/webhook-service.d.ts +19 -63
  108. package/dist/services/webhook-service.js +6 -20
  109. package/dist/services/workflow-service.d.ts +3 -15
  110. package/dist/testing/service-tests.js +0 -17
  111. package/dist/time-utils.d.ts +0 -16
  112. package/dist/time-utils.js +1 -19
  113. package/dist/types/core.types.d.ts +99 -219
  114. package/dist/types/core.types.js +0 -42
  115. package/dist/types/state.types.d.ts +4 -9
  116. package/dist/utils/hmac.d.ts +4 -10
  117. package/dist/utils/hmac.js +4 -10
  118. package/dist/utils/safe-fetch.d.ts +7 -35
  119. package/dist/utils/safe-fetch.js +13 -53
  120. package/dist/utils.d.ts +1 -6
  121. package/dist/utils.js +6 -15
  122. package/dist/wirings/actor-flow/actor-flow.types.d.ts +1 -34
  123. package/dist/wirings/actor-flow/index.d.ts +0 -9
  124. package/dist/wirings/actor-flow/run-conversation.d.ts +5 -5
  125. package/dist/wirings/actor-flow/run-conversation.js +14 -7
  126. package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -5
  127. package/dist/wirings/ai-agent/ai-agent-agui.js +34 -12
  128. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +7 -0
  129. package/dist/wirings/ai-agent/ai-agent-helpers.js +7 -0
  130. package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +153 -0
  131. package/dist/wirings/ai-agent/ai-agent-interrupt.js +256 -0
  132. package/dist/wirings/ai-agent/ai-agent-memory.js +0 -2
  133. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -9
  134. package/dist/wirings/ai-agent/ai-agent-model-config.js +1 -9
  135. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -99
  136. package/dist/wirings/ai-agent/ai-agent-prepare.js +58 -131
  137. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +2 -1
  138. package/dist/wirings/ai-agent/ai-agent-registry.js +5 -1
  139. package/dist/wirings/ai-agent/ai-agent-runner.js +49 -20
  140. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
  141. package/dist/wirings/ai-agent/ai-agent-stream.js +153 -63
  142. package/dist/wirings/ai-agent/ai-agent.types.d.ts +84 -4
  143. package/dist/wirings/ai-agent/index.d.ts +6 -4
  144. package/dist/wirings/ai-agent/index.js +5 -4
  145. package/dist/wirings/ai-agent/voice-input.d.ts +39 -1
  146. package/dist/wirings/ai-agent/voice-input.js +46 -3
  147. package/dist/wirings/ai-agent/voice-output.d.ts +54 -1
  148. package/dist/wirings/ai-agent/voice-output.js +153 -50
  149. package/dist/wirings/channel/channel-common.d.ts +7 -20
  150. package/dist/wirings/channel/channel-common.js +7 -21
  151. package/dist/wirings/channel/channel-handler.js +25 -6
  152. package/dist/wirings/channel/channel-host-rpc.d.ts +25 -0
  153. package/dist/wirings/channel/channel-host-rpc.js +38 -0
  154. package/dist/wirings/channel/channel-middleware-runner.d.ts +0 -12
  155. package/dist/wirings/channel/channel-middleware-runner.js +0 -12
  156. package/dist/wirings/channel/channel-rpc-registry.d.ts +31 -0
  157. package/dist/wirings/channel/channel-rpc-registry.js +89 -0
  158. package/dist/wirings/channel/channel-rpc-responder.d.ts +15 -0
  159. package/dist/wirings/channel/channel-rpc-responder.js +71 -0
  160. package/dist/wirings/channel/channel-rpc-service.d.ts +40 -0
  161. package/dist/wirings/channel/channel-rpc-service.js +106 -0
  162. package/dist/wirings/channel/channel-rpc-validators.d.ts +14 -0
  163. package/dist/wirings/channel/channel-rpc-validators.js +30 -0
  164. package/dist/wirings/channel/channel-rpc.d.ts +5 -0
  165. package/dist/wirings/channel/channel-rpc.js +5 -0
  166. package/dist/wirings/channel/channel-rpc.types.d.ts +90 -0
  167. package/dist/wirings/channel/channel-rpc.types.js +50 -0
  168. package/dist/wirings/channel/channel-runner.d.ts +0 -4
  169. package/dist/wirings/channel/channel-runner.js +0 -14
  170. package/dist/wirings/channel/channel-store.d.ts +0 -10
  171. package/dist/wirings/channel/channel.types.d.ts +12 -1
  172. package/dist/wirings/channel/define-channel-routes.d.ts +0 -20
  173. package/dist/wirings/channel/define-channel-routes.js +0 -20
  174. package/dist/wirings/channel/eventhub-service.d.ts +0 -18
  175. package/dist/wirings/channel/index.d.ts +4 -1
  176. package/dist/wirings/channel/index.js +2 -0
  177. package/dist/wirings/channel/local/local-channel-runner.js +3 -1
  178. package/dist/wirings/channel/local/local-eventhub-service.d.ts +0 -33
  179. package/dist/wirings/channel/local/local-eventhub-service.js +2 -36
  180. package/dist/wirings/channel/log-channels.d.ts +0 -4
  181. package/dist/wirings/channel/log-channels.js +0 -4
  182. package/dist/wirings/channel/pikku-abstract-channel-handler.js +6 -0
  183. package/dist/wirings/channel/serverless/serverless-channel-runner.js +2 -5
  184. package/dist/wirings/cli/channel/cli-approval.d.ts +41 -0
  185. package/dist/wirings/cli/channel/cli-approval.js +81 -0
  186. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +0 -4
  187. package/dist/wirings/cli/channel/cli-channel-runner.js +3 -25
  188. package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +47 -9
  189. package/dist/wirings/cli/channel/cli-raw-channel-runner.js +24 -16
  190. package/dist/wirings/cli/channel/cli-raw-client-runner.d.ts +20 -0
  191. package/dist/wirings/cli/channel/cli-raw-client-runner.js +121 -0
  192. package/dist/wirings/cli/channel/index.d.ts +4 -0
  193. package/dist/wirings/cli/channel/index.js +2 -0
  194. package/dist/wirings/cli/cli-runner.d.ts +20 -20
  195. package/dist/wirings/cli/cli-runner.js +28 -89
  196. package/dist/wirings/cli/cli.types.d.ts +14 -3
  197. package/dist/wirings/cli/command-parser.d.ts +1 -10
  198. package/dist/wirings/cli/command-parser.js +10 -87
  199. package/dist/wirings/cli/define-cli-commands.d.ts +1 -17
  200. package/dist/wirings/cli/define-cli-commands.js +1 -17
  201. package/dist/wirings/credential/credential.types.d.ts +0 -12
  202. package/dist/wirings/credential/define-credential.d.ts +48 -0
  203. package/dist/wirings/credential/define-credential.js +47 -0
  204. package/dist/wirings/credential/index.d.ts +1 -1
  205. package/dist/wirings/credential/index.js +1 -1
  206. package/dist/wirings/credential/validate-credential-definitions.d.ts +2 -4
  207. package/dist/wirings/gateway/gateway-runner.d.ts +1 -20
  208. package/dist/wirings/gateway/gateway-runner.js +8 -105
  209. package/dist/wirings/gateway/gateway.types.d.ts +7 -80
  210. package/dist/wirings/http/http-routes.d.ts +0 -63
  211. package/dist/wirings/http/http-routes.js +0 -63
  212. package/dist/wirings/http/http-runner.d.ts +0 -99
  213. package/dist/wirings/http/http-runner.js +9 -165
  214. package/dist/wirings/http/http.types.d.ts +14 -55
  215. package/dist/wirings/http/log-http-routes.d.ts +0 -4
  216. package/dist/wirings/http/log-http-routes.js +0 -4
  217. package/dist/wirings/http/pikku-fetch-http-request.d.ts +0 -40
  218. package/dist/wirings/http/pikku-fetch-http-request.js +0 -58
  219. package/dist/wirings/http/pikku-fetch-http-response.js +0 -3
  220. package/dist/wirings/http/routers/path-to-regex.js +2 -13
  221. package/dist/wirings/http/web-request.d.ts +0 -8
  222. package/dist/wirings/http/web-request.js +25 -17
  223. package/dist/wirings/mcp/mcp-runner.d.ts +1 -4
  224. package/dist/wirings/mcp/mcp-runner.js +1 -14
  225. package/dist/wirings/mcp/mcp.types.d.ts +2 -35
  226. package/dist/wirings/oauth2/oauth2.types.d.ts +0 -28
  227. package/dist/wirings/oauth2/oauth2.types.js +0 -3
  228. package/dist/wirings/persona/define-personas.d.ts +28 -0
  229. package/dist/wirings/persona/define-personas.js +27 -0
  230. package/dist/wirings/persona/index.d.ts +21 -0
  231. package/dist/wirings/persona/index.js +17 -0
  232. package/dist/wirings/persona/persona-email.d.ts +37 -0
  233. package/dist/wirings/persona/persona-email.js +69 -0
  234. package/dist/wirings/persona/persona-environments.d.ts +45 -0
  235. package/dist/wirings/persona/persona-environments.js +81 -0
  236. package/dist/wirings/persona/persona-mailbox.d.ts +101 -0
  237. package/dist/wirings/persona/persona-mailbox.js +53 -0
  238. package/dist/wirings/persona/persona.types.d.ts +125 -0
  239. package/dist/wirings/persona/persona.types.js +1 -0
  240. package/dist/wirings/persona/validate-personas.d.ts +53 -0
  241. package/dist/wirings/persona/validate-personas.js +94 -0
  242. package/dist/wirings/queue/index.d.ts +3 -0
  243. package/dist/wirings/queue/index.js +2 -3
  244. package/dist/wirings/queue/queue-identity.d.ts +28 -0
  245. package/dist/wirings/queue/queue-identity.js +102 -0
  246. package/dist/wirings/queue/queue-runner.d.ts +0 -19
  247. package/dist/wirings/queue/queue-runner.js +9 -30
  248. package/dist/wirings/queue/queue.types.d.ts +18 -89
  249. package/dist/wirings/queue/register-queue-helper.d.ts +0 -12
  250. package/dist/wirings/queue/register-queue-helper.js +0 -11
  251. package/dist/wirings/queue/signed-queue-service.d.ts +16 -0
  252. package/dist/wirings/queue/signed-queue-service.js +42 -0
  253. package/dist/wirings/queue/validate-worker-config.d.ts +2 -23
  254. package/dist/wirings/queue/validate-worker-config.js +0 -14
  255. package/dist/wirings/role/define-system-role.d.ts +32 -0
  256. package/dist/wirings/role/define-system-role.js +31 -0
  257. package/dist/wirings/role/index.d.ts +3 -0
  258. package/dist/wirings/role/index.js +2 -0
  259. package/dist/wirings/role/role.types.d.ts +43 -0
  260. package/dist/wirings/role/role.types.js +1 -0
  261. package/dist/wirings/role/validate-role-definitions.d.ts +21 -0
  262. package/dist/wirings/role/validate-role-definitions.js +71 -0
  263. package/dist/wirings/rpc/addon-runner.d.ts +0 -19
  264. package/dist/wirings/rpc/addon-runner.js +0 -51
  265. package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -12
  266. package/dist/wirings/rpc/remote-addon-auth.js +1 -9
  267. package/dist/wirings/rpc/rpc-runner.d.ts +11 -18
  268. package/dist/wirings/rpc/rpc-runner.js +88 -105
  269. package/dist/wirings/rpc/rpc-types.d.ts +7 -6
  270. package/dist/wirings/rpc/wire-addon.d.ts +25 -0
  271. package/dist/wirings/rpc/wire-addon.js +62 -0
  272. package/dist/wirings/rpc/wire-remote-addon.d.ts +3 -28
  273. package/dist/wirings/rpc/wire-remote-addon.js +0 -8
  274. package/dist/wirings/scheduler/log-schedulers.d.ts +0 -4
  275. package/dist/wirings/scheduler/log-schedulers.js +0 -4
  276. package/dist/wirings/scheduler/scheduler-runner.d.ts +0 -1
  277. package/dist/wirings/scheduler/scheduler-runner.js +0 -1
  278. package/dist/wirings/scheduler/scheduler.types.d.ts +1 -14
  279. package/dist/wirings/scope/define-scope.d.ts +32 -0
  280. package/dist/wirings/scope/define-scope.js +31 -0
  281. package/dist/wirings/scope/index.d.ts +1 -1
  282. package/dist/wirings/scope/index.js +1 -1
  283. package/dist/wirings/scope/scope.types.d.ts +7 -9
  284. package/dist/wirings/scope/validate-scope-definitions.d.ts +2 -21
  285. package/dist/wirings/scope/validate-scope-definitions.js +3 -21
  286. package/dist/wirings/secret/index.d.ts +1 -1
  287. package/dist/wirings/secret/index.js +1 -1
  288. package/dist/wirings/secret/secret.types.d.ts +19 -15
  289. package/dist/wirings/secret/secret.types.js +1 -1
  290. package/dist/wirings/secret/validate-secret-definitions.d.ts +2 -4
  291. package/dist/wirings/trigger/trigger-runner.d.ts +0 -27
  292. package/dist/wirings/trigger/trigger-runner.js +1 -24
  293. package/dist/wirings/trigger/trigger.types.d.ts +1 -82
  294. package/dist/wirings/trigger/trigger.types.js +0 -34
  295. package/dist/wirings/variable/index.d.ts +1 -1
  296. package/dist/wirings/variable/index.js +1 -1
  297. package/dist/wirings/variable/validate-variable-definitions.d.ts +2 -4
  298. package/dist/wirings/variable/variable.types.d.ts +1 -13
  299. package/dist/wirings/variable/variable.types.js +1 -1
  300. package/dist/wirings/virtual-user/index.d.ts +27 -0
  301. package/dist/wirings/virtual-user/index.js +8 -0
  302. package/dist/wirings/virtual-user/run-virtual-user.d.ts +92 -0
  303. package/dist/wirings/virtual-user/run-virtual-user.js +478 -0
  304. package/dist/wirings/virtual-user/virtual-user-agents.d.ts +38 -0
  305. package/dist/wirings/virtual-user/virtual-user-agents.js +24 -0
  306. package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +92 -0
  307. package/dist/wirings/virtual-user/virtual-user-catalogue.js +134 -0
  308. package/dist/wirings/virtual-user/virtual-user-derive.d.ts +26 -0
  309. package/dist/wirings/virtual-user/virtual-user-derive.js +137 -0
  310. package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +79 -0
  311. package/dist/wirings/virtual-user/virtual-user-dispositions.js +128 -0
  312. package/dist/wirings/virtual-user/virtual-user-intents.d.ts +78 -0
  313. package/dist/wirings/virtual-user/virtual-user-intents.js +142 -0
  314. package/dist/wirings/virtual-user/virtual-user-rng.d.ts +24 -0
  315. package/dist/wirings/virtual-user/virtual-user-rng.js +44 -0
  316. package/dist/wirings/virtual-user/virtual-user-target.d.ts +21 -0
  317. package/dist/wirings/virtual-user/virtual-user-target.js +34 -0
  318. package/dist/wirings/virtual-user/virtual-user.types.d.ts +199 -0
  319. package/dist/wirings/virtual-user/virtual-user.types.js +8 -0
  320. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +5 -5
  321. package/dist/wirings/workflow/dsl/workflow-runner.d.ts +0 -4
  322. package/dist/wirings/workflow/dsl/workflow-runner.js +0 -4
  323. package/dist/wirings/workflow/feature.d.ts +0 -19
  324. package/dist/wirings/workflow/feature.js +0 -19
  325. package/dist/wirings/workflow/graph/graph-node.d.ts +0 -98
  326. package/dist/wirings/workflow/graph/graph-node.js +0 -34
  327. package/dist/wirings/workflow/graph/graph-runner.js +6 -41
  328. package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +0 -4
  329. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -58
  330. package/dist/wirings/workflow/graph/workflow-graph.types.js +0 -6
  331. package/dist/wirings/workflow/index.d.ts +5 -7
  332. package/dist/wirings/workflow/index.js +3 -17
  333. package/dist/wirings/workflow/pikku-scenario-service.d.ts +87 -5
  334. package/dist/wirings/workflow/pikku-scenario-service.js +204 -42
  335. package/dist/wirings/workflow/pikku-workflow-service.d.ts +7 -459
  336. package/dist/wirings/workflow/pikku-workflow-service.js +58 -551
  337. package/dist/wirings/workflow/run-timeline.d.ts +0 -47
  338. package/dist/wirings/workflow/run-timeline.js +0 -22
  339. package/dist/wirings/workflow/scenario-cookie-jar.d.ts +0 -23
  340. package/dist/wirings/workflow/scenario-cookie-jar.js +0 -16
  341. package/dist/wirings/workflow/scenario-poll.d.ts +0 -15
  342. package/dist/wirings/workflow/scenario-poll.js +0 -12
  343. package/dist/wirings/workflow/scenario-prose.d.ts +0 -28
  344. package/dist/wirings/workflow/scenario-prose.js +0 -18
  345. package/dist/wirings/workflow/scenario-step-guards.d.ts +0 -13
  346. package/dist/wirings/workflow/scenario-step-guards.js +1 -14
  347. package/dist/wirings/workflow/scenario-step.types.d.ts +72 -6
  348. package/dist/wirings/workflow/scenario-step.types.js +5 -1
  349. package/dist/wirings/workflow/scenario-surface.d.ts +16 -0
  350. package/dist/wirings/workflow/scenario-surface.js +56 -0
  351. package/dist/wirings/workflow/workflow-invocation-id.d.ts +0 -18
  352. package/dist/wirings/workflow/workflow-invocation-id.js +2 -22
  353. package/dist/wirings/workflow/workflow-queue-workers.d.ts +0 -20
  354. package/dist/wirings/workflow/workflow-queue-workers.js +0 -19
  355. package/dist/wirings/workflow/workflow.types.d.ts +0 -197
  356. package/knowledge/decisions/index.md +19 -0
  357. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +49 -0
  358. package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +23 -0
  359. package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +24 -0
  360. package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +25 -0
  361. package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +26 -0
  362. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +33 -0
  363. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +28 -0
  364. package/knowledge/decisions/internals/ai-agent-agui-bridge-obeys-the-client-ordering-contract.md +29 -0
  365. package/knowledge/decisions/internals/ai-agent-audio-chunks-carry-the-format-the-provider-returned.md +20 -0
  366. package/knowledge/decisions/internals/ai-agent-credential-suspensions-hide-the-tool-result.md +26 -0
  367. package/knowledge/decisions/internals/ai-agent-delegate-and-supervise-hide-different-text.md +26 -0
  368. package/knowledge/decisions/internals/ai-agent-llm-tool-arguments-have-nulls-stripped.md +23 -0
  369. package/knowledge/decisions/internals/ai-agent-model-config-stays-a-single-resolution-seam.md +25 -0
  370. package/knowledge/decisions/internals/ai-agent-onerror-hooks-cannot-change-the-failure.md +22 -0
  371. package/knowledge/decisions/internals/ai-agent-runner-methods-must-keep-their-receiver.md +22 -0
  372. package/knowledge/decisions/internals/ai-agent-stream-persistence-is-best-effort.md +27 -0
  373. package/knowledge/decisions/internals/ai-agent-sub-agents-inherit-the-parent-context-block.md +26 -0
  374. package/knowledge/decisions/internals/ai-agent-tool-execute-failures-are-logged-unconditionally.md +25 -0
  375. package/knowledge/decisions/internals/ai-agent-voice-input-transcribes-audio-parts-in-place.md +22 -0
  376. package/knowledge/decisions/internals/ai-agent-working-memory-is-persisted-only-when-valid.md +25 -0
  377. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +30 -0
  378. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +31 -0
  379. package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +29 -0
  380. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +28 -0
  381. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +27 -0
  382. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +28 -0
  383. package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +34 -0
  384. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +29 -0
  385. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +34 -0
  386. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +44 -0
  387. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +39 -0
  388. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +42 -0
  389. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +39 -0
  390. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +43 -0
  391. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +38 -0
  392. package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +44 -0
  393. package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +27 -0
  394. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +32 -0
  395. package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +28 -0
  396. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +31 -0
  397. package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +26 -0
  398. package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +32 -0
  399. package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +28 -0
  400. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +30 -0
  401. package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +26 -0
  402. package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +28 -0
  403. package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +32 -0
  404. package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +26 -0
  405. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +25 -0
  406. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +26 -0
  407. package/knowledge/decisions/internals/index.md +113 -0
  408. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +25 -0
  409. package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +26 -0
  410. package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +24 -0
  411. package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +28 -0
  412. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +27 -0
  413. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +31 -0
  414. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +32 -0
  415. package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +27 -0
  416. package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +26 -0
  417. package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +27 -0
  418. package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +30 -0
  419. package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +28 -0
  420. package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +30 -0
  421. package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +29 -0
  422. package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +27 -0
  423. package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +40 -0
  424. package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +26 -0
  425. package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +33 -0
  426. package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +26 -0
  427. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +26 -0
  428. package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +25 -0
  429. package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +58 -0
  430. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +34 -0
  431. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +42 -0
  432. package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +38 -0
  433. package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +29 -0
  434. package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +42 -0
  435. package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +25 -0
  436. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +29 -0
  437. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +43 -0
  438. package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +29 -0
  439. package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +42 -0
  440. package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +33 -0
  441. package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +32 -0
  442. package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +31 -0
  443. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +39 -0
  444. package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +29 -0
  445. package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +33 -0
  446. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +37 -0
  447. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +50 -0
  448. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +43 -0
  449. package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +32 -0
  450. package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +18 -0
  451. package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +34 -0
  452. package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +26 -0
  453. package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +33 -0
  454. package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +27 -0
  455. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +34 -0
  456. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +38 -0
  457. package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +30 -0
  458. package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +26 -0
  459. package/knowledge/decisions/security/actor-flow-missing-approval-decisions-default-to-denied.md +22 -0
  460. package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +27 -0
  461. package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +27 -0
  462. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +43 -0
  463. package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +52 -0
  464. package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +46 -0
  465. package/knowledge/decisions/security/ai-agent-approval-forwarding-requires-a-symbol-brand.md +27 -0
  466. package/knowledge/decisions/security/ai-agent-credential-requests-are-symbol-branded.md +37 -0
  467. package/knowledge/decisions/security/ai-agent-gate-requires-a-session-only-when-auth-is-true.md +31 -0
  468. package/knowledge/decisions/security/ai-agent-ownership-failures-never-echo-the-resource.md +23 -0
  469. package/knowledge/decisions/security/ai-agent-resume-re-runs-the-authorization-gate.md +22 -0
  470. package/knowledge/decisions/security/ai-agent-sessionless-deployments-have-no-thread-ownership.md +39 -0
  471. package/knowledge/decisions/security/ai-agent-thread-ownership-composes-the-session-principal.md +30 -0
  472. package/knowledge/decisions/security/ai-agent-tool-filtering-reads-the-live-function-config.md +24 -0
  473. package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +30 -0
  474. package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +49 -0
  475. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +76 -0
  476. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +39 -0
  477. package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +37 -0
  478. package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +31 -0
  479. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +30 -0
  480. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +40 -0
  481. package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +33 -0
  482. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +46 -0
  483. package/knowledge/decisions/security/index.md +55 -0
  484. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +27 -0
  485. package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +40 -0
  486. package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +31 -0
  487. package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +26 -0
  488. package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +69 -0
  489. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +39 -0
  490. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +34 -0
  491. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +49 -0
  492. package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +30 -0
  493. package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +28 -0
  494. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +34 -0
  495. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +37 -0
  496. package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +25 -0
  497. package/knowledge/decisions/security/workflow-actor-steps-always-use-the-real-transport.md +34 -0
  498. package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +40 -0
  499. package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +32 -0
  500. package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md +32 -0
  501. package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +31 -0
  502. package/knowledge/index.md +24 -0
  503. package/knowledge/questions/index.md +15 -0
  504. package/package.json +4 -1
  505. package/run-tests.sh +0 -0
  506. package/src/crypto-utils.test.ts +460 -19
  507. package/src/crypto-utils.ts +283 -55
  508. package/src/data-classification.ts +1 -7
  509. package/src/dev/hot-reload.test.ts +0 -4
  510. package/src/dev/hot-reload.ts +11 -30
  511. package/src/dev/module-runner.ts +7 -32
  512. package/src/dev/reload-meta.ts +9 -29
  513. package/src/errors/error-handler.ts +20 -35
  514. package/src/errors/error.test.ts +30 -1
  515. package/src/errors/errors.ts +73 -157
  516. package/src/function/abort-scope.test.ts +97 -0
  517. package/src/function/abort-scope.ts +80 -0
  518. package/src/function/function-runner.test.ts +0 -7
  519. package/src/function/function-runner.ts +62 -32
  520. package/src/function/functions.types.ts +56 -136
  521. package/src/function/list.types.test.ts +3 -25
  522. package/src/function/list.types.ts +12 -62
  523. package/src/handle-error.ts +0 -18
  524. package/src/index.ts +60 -1
  525. package/src/middleware/auth-apikey.test.ts +0 -1
  526. package/src/middleware/auth-apikey.ts +0 -17
  527. package/src/middleware/auth-bearer.test.ts +0 -3
  528. package/src/middleware/auth-bearer.ts +3 -40
  529. package/src/middleware/auth-cookie.test.ts +0 -6
  530. package/src/middleware/auth-cookie.ts +2 -26
  531. package/src/middleware/cors.test.ts +34 -0
  532. package/src/middleware/cors.ts +12 -33
  533. package/src/middleware/remote-auth.test.ts +24 -9
  534. package/src/middleware/remote-auth.ts +10 -2
  535. package/src/middleware/telemetry.ts +2 -31
  536. package/src/middleware-runner.test.ts +0 -2
  537. package/src/middleware-runner.ts +5 -74
  538. package/src/permissions.test.ts +30 -0
  539. package/src/permissions.ts +24 -74
  540. package/src/pikku-request.ts +0 -6
  541. package/src/pikku-state.ts +2 -30
  542. package/src/production-barrels-stay-lean.test.ts +110 -0
  543. package/src/remote.test.ts +172 -0
  544. package/src/remote.ts +17 -7
  545. package/src/schema.ts +5 -39
  546. package/src/scopes.ts +7 -48
  547. package/src/services/ai-agent-runner-service.ts +20 -0
  548. package/src/services/ai-embedding-service.ts +3 -25
  549. package/src/services/audit-service.ts +1 -2
  550. package/src/services/content-service.ts +1 -46
  551. package/src/services/credential-service.ts +3 -40
  552. package/src/services/credential-wire-service.test.ts +0 -2
  553. package/src/services/deployment-service.ts +3 -9
  554. package/src/services/gateway-service.ts +0 -15
  555. package/src/services/{http-scenario-actors-converse.test.ts → http-personas-converse.test.ts} +38 -9
  556. package/src/services/{http-scenario-actors.test.ts → http-personas.test.ts} +39 -22
  557. package/src/services/{http-scenario-actors.ts → http-personas.ts} +85 -45
  558. package/src/services/in-memory-queue-service.ts +1 -15
  559. package/src/services/in-memory-trigger-service.ts +1 -18
  560. package/src/services/in-memory-workflow-service.test.ts +0 -13
  561. package/src/services/in-memory-workflow-service.ts +4 -38
  562. package/src/services/index.ts +20 -15
  563. package/src/services/istanbul-coverage-service.ts +2 -8
  564. package/src/services/jwt-service.ts +1 -16
  565. package/src/services/local-content.test.ts +159 -27
  566. package/src/services/local-content.ts +55 -23
  567. package/src/services/local-gateway-service.ts +2 -17
  568. package/src/services/local-secrets.ts +0 -4
  569. package/src/services/logger-console.test.ts +0 -1
  570. package/src/services/logger-console.ts +3 -7
  571. package/src/services/logger.ts +2 -37
  572. package/src/services/meta-service.test.ts +1 -5
  573. package/src/services/meta-service.ts +41 -61
  574. package/src/services/{scenario-actors-service.ts → personas-service.ts} +48 -43
  575. package/src/services/pikku-user-id.ts +0 -4
  576. package/src/services/queue-webhook-service.ts +9 -41
  577. package/src/services/scheduler-service.ts +1 -50
  578. package/src/services/schema-service.ts +1 -24
  579. package/src/services/scope-service.ts +50 -34
  580. package/src/services/scoped-secret-service.ts +0 -4
  581. package/src/services/secret-host-binding.test.ts +138 -0
  582. package/src/services/secret-host-binding.ts +51 -0
  583. package/src/services/secret-service.ts +5 -33
  584. package/src/services/secretless.test.ts +54 -0
  585. package/src/services/secretless.ts +29 -0
  586. package/src/services/stub-tracker.ts +8 -18
  587. package/src/services/system-role-guard.test.ts +93 -0
  588. package/src/services/system-role-guard.ts +71 -0
  589. package/src/services/trigger-service.ts +0 -12
  590. package/src/services/typed-secret-service.ts +1 -7
  591. package/src/services/v8-coverage-service.ts +3 -6
  592. package/src/services/variables-service.ts +1 -8
  593. package/src/services/webhook-service.ts +19 -63
  594. package/src/services/workflow-service.ts +3 -20
  595. package/src/testing/service-tests.ts +0 -26
  596. package/src/time-utils.ts +1 -19
  597. package/src/types/core.types.ts +116 -229
  598. package/src/types/state.types.ts +7 -9
  599. package/src/utils/hmac.ts +4 -10
  600. package/src/utils/safe-fetch.ts +13 -54
  601. package/src/utils.test.ts +11 -2
  602. package/src/utils.ts +6 -15
  603. package/src/wirings/actor-flow/actor-flow.types.ts +1 -34
  604. package/src/wirings/actor-flow/index.ts +0 -9
  605. package/src/wirings/actor-flow/run-conversation.test.ts +11 -6
  606. package/src/wirings/actor-flow/run-conversation.ts +19 -12
  607. package/src/wirings/ai-agent/ai-agent-agui.test.ts +75 -10
  608. package/src/wirings/ai-agent/ai-agent-agui.ts +36 -17
  609. package/src/wirings/ai-agent/ai-agent-helpers.ts +20 -0
  610. package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +842 -0
  611. package/src/wirings/ai-agent/ai-agent-interrupt.ts +399 -0
  612. package/src/wirings/ai-agent/ai-agent-memory.ts +0 -2
  613. package/src/wirings/ai-agent/ai-agent-model-config.ts +1 -9
  614. package/src/wirings/ai-agent/ai-agent-prepare.test.ts +202 -31
  615. package/src/wirings/ai-agent/ai-agent-prepare.ts +82 -138
  616. package/src/wirings/ai-agent/ai-agent-registry.test.ts +191 -6
  617. package/src/wirings/ai-agent/ai-agent-registry.ts +18 -1
  618. package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +0 -2
  619. package/src/wirings/ai-agent/ai-agent-runner.test.ts +11 -9
  620. package/src/wirings/ai-agent/ai-agent-runner.ts +67 -33
  621. package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
  622. package/src/wirings/ai-agent/ai-agent-stream.ts +192 -75
  623. package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
  624. package/src/wirings/ai-agent/ai-agent.types.ts +85 -4
  625. package/src/wirings/ai-agent/index.ts +35 -3
  626. package/src/wirings/ai-agent/voice-input.test.ts +72 -7
  627. package/src/wirings/ai-agent/voice-input.ts +48 -3
  628. package/src/wirings/ai-agent/voice-output.test.ts +422 -0
  629. package/src/wirings/ai-agent/voice-output.ts +216 -56
  630. package/src/wirings/channel/channel-common.ts +15 -20
  631. package/src/wirings/channel/channel-handler.test.ts +50 -0
  632. package/src/wirings/channel/channel-handler.ts +32 -11
  633. package/src/wirings/channel/channel-host-rpc.test.ts +150 -0
  634. package/src/wirings/channel/channel-host-rpc.ts +69 -0
  635. package/src/wirings/channel/channel-middleware-runner.test.ts +0 -1
  636. package/src/wirings/channel/channel-middleware-runner.ts +0 -12
  637. package/src/wirings/channel/channel-rpc-registry.ts +116 -0
  638. package/src/wirings/channel/channel-rpc-responder.ts +117 -0
  639. package/src/wirings/channel/channel-rpc-service.ts +146 -0
  640. package/src/wirings/channel/channel-rpc-validators.ts +65 -0
  641. package/src/wirings/channel/channel-rpc.test.ts +820 -0
  642. package/src/wirings/channel/channel-rpc.ts +5 -0
  643. package/src/wirings/channel/channel-rpc.types.ts +150 -0
  644. package/src/wirings/channel/channel-runner.ts +0 -14
  645. package/src/wirings/channel/channel-store.ts +0 -10
  646. package/src/wirings/channel/channel.types.ts +19 -8
  647. package/src/wirings/channel/define-channel-routes.ts +0 -20
  648. package/src/wirings/channel/eventhub-service.ts +0 -18
  649. package/src/wirings/channel/index.ts +35 -0
  650. package/src/wirings/channel/local/local-channel-handler.ts +3 -1
  651. package/src/wirings/channel/local/local-channel-runner.test.ts +0 -10
  652. package/src/wirings/channel/local/local-channel-runner.ts +3 -1
  653. package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -13
  654. package/src/wirings/channel/local/local-eventhub-service.ts +2 -37
  655. package/src/wirings/channel/log-channels.ts +0 -4
  656. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +83 -2
  657. package/src/wirings/channel/pikku-abstract-channel-handler.ts +7 -0
  658. package/src/wirings/channel/serverless/serverless-channel-runner.ts +2 -5
  659. package/src/wirings/cli/channel/cli-approval.test.ts +177 -0
  660. package/src/wirings/cli/channel/cli-approval.ts +135 -0
  661. package/src/wirings/cli/channel/cli-channel-runner.ts +4 -26
  662. package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +169 -0
  663. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +59 -16
  664. package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +480 -0
  665. package/src/wirings/cli/channel/cli-raw-client-runner.ts +155 -0
  666. package/src/wirings/cli/channel/index.ts +9 -0
  667. package/src/wirings/cli/cli-runner.test.ts +0 -1
  668. package/src/wirings/cli/cli-runner.ts +46 -88
  669. package/src/wirings/cli/cli.types.ts +14 -3
  670. package/src/wirings/cli/command-parser.test.ts +0 -4
  671. package/src/wirings/cli/command-parser.ts +11 -91
  672. package/src/wirings/cli/define-cli-commands.ts +1 -17
  673. package/src/wirings/credential/credential.types.ts +0 -12
  674. package/src/wirings/credential/{wire-credential.ts → define-credential.ts} +7 -7
  675. package/src/wirings/credential/index.ts +1 -1
  676. package/src/wirings/credential/validate-credential-definitions.ts +2 -4
  677. package/src/wirings/gateway/gateway-runner.test.ts +1 -21
  678. package/src/wirings/gateway/gateway-runner.ts +8 -110
  679. package/src/wirings/gateway/gateway.types.ts +7 -80
  680. package/src/wirings/http/http-routes.test.ts +0 -3
  681. package/src/wirings/http/http-routes.ts +0 -86
  682. package/src/wirings/http/http-runner.test.ts +0 -1
  683. package/src/wirings/http/http-runner.ts +8 -167
  684. package/src/wirings/http/http.types.ts +15 -62
  685. package/src/wirings/http/log-http-routes.ts +0 -4
  686. package/src/wirings/http/pikku-fetch-http-request.test.ts +2 -10
  687. package/src/wirings/http/pikku-fetch-http-request.ts +0 -58
  688. package/src/wirings/http/pikku-fetch-http-response.test.ts +1 -1
  689. package/src/wirings/http/pikku-fetch-http-response.ts +0 -3
  690. package/src/wirings/http/routers/path-to-regex.test.ts +4 -17
  691. package/src/wirings/http/routers/path-to-regex.ts +2 -13
  692. package/src/wirings/http/web-request.test.ts +33 -2
  693. package/src/wirings/http/web-request.ts +30 -17
  694. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -1
  695. package/src/wirings/mcp/mcp-runner.ts +2 -17
  696. package/src/wirings/mcp/mcp.types.ts +7 -42
  697. package/src/wirings/oauth2/oauth2.types.ts +0 -30
  698. package/src/wirings/persona/define-personas.ts +29 -0
  699. package/src/wirings/persona/index.ts +62 -0
  700. package/src/wirings/persona/persona-email.ts +87 -0
  701. package/src/wirings/persona/persona-environments.test.ts +183 -0
  702. package/src/wirings/persona/persona-environments.ts +138 -0
  703. package/src/wirings/persona/persona-mailbox.ts +156 -0
  704. package/src/wirings/persona/persona.test.ts +220 -0
  705. package/src/wirings/persona/persona.types.ts +131 -0
  706. package/src/wirings/persona/validate-personas.ts +133 -0
  707. package/src/wirings/queue/index.ts +13 -3
  708. package/src/wirings/queue/queue-identity.test.ts +453 -0
  709. package/src/wirings/queue/queue-identity.ts +173 -0
  710. package/src/wirings/queue/queue-runner.ts +12 -31
  711. package/src/wirings/queue/queue.types.ts +19 -89
  712. package/src/wirings/queue/register-queue-helper.ts +0 -14
  713. package/src/wirings/queue/signed-queue-service.ts +59 -0
  714. package/src/wirings/queue/validate-worker-config.ts +2 -28
  715. package/src/wirings/role/define-system-role.ts +33 -0
  716. package/src/wirings/role/index.ts +13 -0
  717. package/src/wirings/role/role.test.ts +104 -0
  718. package/src/wirings/role/role.types.ts +47 -0
  719. package/src/wirings/role/validate-role-definitions.ts +93 -0
  720. package/src/wirings/rpc/addon-auth-tags.test.ts +223 -0
  721. package/src/wirings/rpc/addon-runner.ts +0 -56
  722. package/src/wirings/rpc/addon-scopes.test.ts +225 -0
  723. package/src/wirings/rpc/remote-addon-auth.ts +1 -13
  724. package/src/wirings/rpc/rpc-runner.test.ts +186 -2
  725. package/src/wirings/rpc/rpc-runner.ts +145 -127
  726. package/src/wirings/rpc/rpc-types.ts +11 -6
  727. package/src/wirings/rpc/wire-addon.test.ts +43 -1
  728. package/src/wirings/rpc/wire-addon.ts +99 -0
  729. package/src/wirings/rpc/wire-remote-addon.ts +9 -29
  730. package/src/wirings/scheduler/log-schedulers.ts +0 -4
  731. package/src/wirings/scheduler/scheduler-runner.test.ts +1 -8
  732. package/src/wirings/scheduler/scheduler-runner.ts +0 -2
  733. package/src/wirings/scheduler/scheduler.types.ts +1 -14
  734. package/src/wirings/scope/{wire-scope.ts → define-scope.ts} +5 -6
  735. package/src/wirings/scope/index.ts +1 -1
  736. package/src/wirings/scope/scope.test.ts +1 -2
  737. package/src/wirings/scope/scope.types.ts +7 -9
  738. package/src/wirings/scope/validate-scope-definitions.ts +3 -21
  739. package/src/wirings/secret/index.ts +1 -1
  740. package/src/wirings/secret/secret.types.ts +19 -15
  741. package/src/wirings/secret/validate-secret-definitions.ts +2 -4
  742. package/src/wirings/trigger/trigger-runner.ts +1 -27
  743. package/src/wirings/trigger/trigger.types.ts +1 -82
  744. package/src/wirings/variable/index.ts +1 -1
  745. package/src/wirings/variable/validate-variable-definitions.ts +2 -4
  746. package/src/wirings/variable/variable.types.ts +1 -13
  747. package/src/wirings/virtual-user/index.ts +76 -0
  748. package/src/wirings/virtual-user/run-virtual-user.test.ts +765 -0
  749. package/src/wirings/virtual-user/run-virtual-user.ts +671 -0
  750. package/src/wirings/virtual-user/virtual-user-agents.test.ts +65 -0
  751. package/src/wirings/virtual-user/virtual-user-agents.ts +57 -0
  752. package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +215 -0
  753. package/src/wirings/virtual-user/virtual-user-catalogue.ts +184 -0
  754. package/src/wirings/virtual-user/virtual-user-derive.test.ts +398 -0
  755. package/src/wirings/virtual-user/virtual-user-derive.ts +173 -0
  756. package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +63 -0
  757. package/src/wirings/virtual-user/virtual-user-dispositions.ts +213 -0
  758. package/src/wirings/virtual-user/virtual-user-intents.test.ts +208 -0
  759. package/src/wirings/virtual-user/virtual-user-intents.ts +185 -0
  760. package/src/wirings/virtual-user/virtual-user-rng.test.ts +72 -0
  761. package/src/wirings/virtual-user/virtual-user-rng.ts +50 -0
  762. package/src/wirings/virtual-user/virtual-user-target.ts +47 -0
  763. package/src/wirings/virtual-user/virtual-user.types.ts +219 -0
  764. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +5 -4
  765. package/src/wirings/workflow/dsl/workflow-runner.ts +0 -4
  766. package/src/wirings/workflow/feature.ts +0 -19
  767. package/src/wirings/workflow/graph/graph-node.ts +0 -136
  768. package/src/wirings/workflow/graph/graph-runner.test.ts +20 -19
  769. package/src/wirings/workflow/graph/graph-runner.ts +6 -41
  770. package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -4
  771. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -58
  772. package/src/wirings/workflow/index.ts +10 -44
  773. package/src/wirings/workflow/pikku-scenario-service.ts +235 -52
  774. package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -39
  775. package/src/wirings/workflow/pikku-workflow-service.ts +77 -674
  776. package/src/wirings/workflow/run-timeline.test.ts +7 -19
  777. package/src/wirings/workflow/run-timeline.ts +0 -56
  778. package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -1
  779. package/src/wirings/workflow/scenario-cookie-jar.ts +0 -25
  780. package/src/wirings/workflow/scenario-expectations.test.ts +2 -7
  781. package/src/wirings/workflow/scenario-hooks.test.ts +2 -7
  782. package/src/wirings/workflow/scenario-poll.test.ts +0 -2
  783. package/src/wirings/workflow/scenario-poll.ts +0 -15
  784. package/src/wirings/workflow/scenario-prose.ts +0 -28
  785. package/src/wirings/workflow/scenario-service.test.ts +2 -9
  786. package/src/wirings/workflow/scenario-step-guards.ts +1 -14
  787. package/src/wirings/workflow/scenario-step.test.ts +159 -14
  788. package/src/wirings/workflow/scenario-step.types.ts +82 -6
  789. package/src/wirings/workflow/scenario-surface.test.ts +145 -0
  790. package/src/wirings/workflow/scenario-surface.ts +71 -0
  791. package/src/wirings/workflow/workflow-dispatch-durability.test.ts +14 -15
  792. package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -4
  793. package/src/wirings/workflow/workflow-inline-authority.test.ts +169 -0
  794. package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -2
  795. package/src/wirings/workflow/workflow-invocation-id.ts +2 -22
  796. package/src/wirings/workflow/workflow-mirror.test.ts +0 -7
  797. package/src/wirings/workflow/workflow-on-error.test.ts +0 -9
  798. package/src/wirings/workflow/workflow-queue-workers.ts +0 -21
  799. package/src/wirings/workflow/workflow-replay-snapshot.test.ts +8 -7
  800. package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -5
  801. package/src/wirings/workflow/workflow-run-context.test.ts +5 -10
  802. package/src/wirings/workflow/workflow-run-polling.test.ts +0 -5
  803. package/src/wirings/workflow/workflow-step-ordinal.test.ts +19 -4
  804. package/src/wirings/workflow/workflow-step-session.test.ts +0 -7
  805. package/src/wirings/workflow/workflow.types.ts +0 -203
  806. package/tsconfig.tsbuildinfo +1 -1
  807. package/src/middleware/timeout.ts +0 -22
  808. package/src/pikku-response.ts +0 -5
  809. package/src/wirings/mcp/mcp-endpoint-registry.test.d.ts +0 -1
  810. package/src/wirings/workflow/dsl/index.ts +0 -36
  811. package/src/wirings/workflow/graph/index.ts +0 -15
@@ -3,8 +3,9 @@ import { AIProviderNotConfiguredError } from '../../errors/errors.js';
3
3
  import { randomUUID } from './ai-agent-utils.js';
4
4
  import { combineChannelMiddleware, wrapChannelWithMiddleware, } from '../channel/channel-middleware-runner.js';
5
5
  import { resolveMemoryServices, loadContextMessages, trimMessages, getWorkingMemoryMiddleware, } from './ai-agent-memory.js';
6
- import { prepareAgentRun, resolveAgent, buildInstructions, buildToolDefs, createScopedChannel, resolveOwnerResourceId, agentSessionScope, assertResourceOwner, assertAgentAuthorized, ToolApprovalRequired, ToolCredentialRequired, APPROVAL_REQUIRED, } from './ai-agent-prepare.js';
6
+ import { prepareAgentRun, resolveAgent, buildInstructions, buildToolDefs, createScopedChannel, resolveOwnerResourceId, agentSessionScope, assertResourceOwner, assertResourcePrincipalOwner, assertAgentAuthorized, ToolApprovalRequired, ToolCredentialRequired, APPROVAL_REQUIRED, CREDENTIAL_REQUIRED, } from './ai-agent-prepare.js';
7
7
  import { resolveModelConfig } from './ai-agent-model-config.js';
8
+ import { getInFlightTools, isAbortError, persistOrphanedToolResults, registerInterruptibleRun, signalRunInterrupt, trackInterruptNote, trackToolExecution, } from './ai-agent-interrupt.js';
8
9
  function createPersistingChannel(parent, storage, threadId, logger) {
9
10
  let fullText = '';
10
11
  let stepText = '';
@@ -15,7 +16,7 @@ function createPersistingChannel(parent, storage, threadId, logger) {
15
16
  inputTokens: 0,
16
17
  outputTokens: 0,
17
18
  };
18
- const flushStep = async () => {
19
+ const flushStep = async (opts) => {
19
20
  if (!storage)
20
21
  return;
21
22
  const text = stepText;
@@ -37,6 +38,7 @@ function createPersistingChannel(parent, storage, threadId, logger) {
37
38
  ]
38
39
  : text || undefined,
39
40
  toolCalls: calls.length > 0 ? calls : undefined,
41
+ ...(opts?.interrupted ? { interrupted: true } : {}),
40
42
  createdAt: new Date(),
41
43
  };
42
44
  const messages = [assistantMsg];
@@ -51,14 +53,6 @@ function createPersistingChannel(parent, storage, threadId, logger) {
51
53
  await storage.saveMessages(threadId, messages);
52
54
  }
53
55
  };
54
- /**
55
- * `send` is synchronous and so cannot await the flush. A rejection would have
56
- * nothing to propagate to and would take the process down as an unhandled
57
- * rejection — a model reusing a toolCallId, which is a primary key in AI
58
- * storage, is enough to trigger it. Persistence from inside `send` is
59
- * therefore best-effort: the run carries on, and the awaited `flush()` on the
60
- * suspend paths still surfaces failures to its caller.
61
- */
62
56
  const flushDetached = () => {
63
57
  void flushStep().catch((error) => {
64
58
  logger?.error('Failed to persist agent messages', {
@@ -83,11 +77,15 @@ function createPersistingChannel(parent, storage, threadId, logger) {
83
77
  close: () => parent.close(),
84
78
  sendBinary: (data) => parent.sendBinary(data),
85
79
  send: (event) => {
80
+ // Accumulated whether or not storage is configured: `fullText` is what
81
+ // the client was streamed, and an interrupted run has to be able to
82
+ // report the fragment it got through even with persistence turned off.
83
+ if (event.type === 'text-delta')
84
+ fullText += event.text;
86
85
  if (storage) {
87
86
  switch (event.type) {
88
87
  case 'text-delta':
89
88
  stepText += event.text;
90
- fullText += event.text;
91
89
  break;
92
90
  case 'tool-call':
93
91
  stepToolCalls.push({
@@ -125,6 +123,7 @@ function createPersistingChannel(parent, storage, threadId, logger) {
125
123
  setState: (s) => parent.setState(s),
126
124
  getState: () => parent.getState(),
127
125
  clearState: () => parent.clearState(),
126
+ remote: (funcName, data) => parent.remote(funcName, data),
128
127
  };
129
128
  return channel;
130
129
  }
@@ -161,7 +160,7 @@ async function postStreamCleanup(persistingChannel, aiMiddlewares, singletonServ
161
160
  });
162
161
  }
163
162
  async function runStreamStepLoop(params) {
164
- const { agent, runnerParams, maxSteps, agentRunner, streamChannel, channel, runId, aiMiddlewares, } = params;
163
+ const { agent, runnerParams, maxSteps, agentRunner, streamChannel, channel, aiMiddlewares, } = params;
165
164
  const singletonServices = getSingletonServices();
166
165
  for (let step = 0; step < maxSteps; step++) {
167
166
  if (agent.prepareStep) {
@@ -195,25 +194,21 @@ async function runStreamStepLoop(params) {
195
194
  }
196
195
  if (stepResult.toolCalls.length === 0)
197
196
  break;
198
- const approvalsNeeded = checkForApprovals(stepResult, runnerParams.tools, runId);
197
+ const approvalsNeeded = checkForApprovals(stepResult, runnerParams.tools);
199
198
  if (approvalsNeeded.length > 0) {
200
- // For each approval, call approvalDescriptionFn if available
201
199
  for (const approval of approvalsNeeded) {
202
200
  const toolDef = runnerParams.tools.find((t) => t.name === approval.toolName);
203
201
  if (toolDef?.approvalDescriptionFn && !approval.reason) {
204
202
  try {
205
203
  approval.reason = await toolDef.approvalDescriptionFn(approval.args);
206
204
  }
207
- catch {
208
- // If description generation fails, continue without it
209
- }
205
+ catch { }
210
206
  }
211
207
  }
212
208
  return { outcome: 'approval', approvals: approvalsNeeded };
213
209
  }
214
- const credentialRequests = checkForCredentialRequests(stepResult, runId);
210
+ const credentialRequests = checkForCredentialRequests(stepResult);
215
211
  if (credentialRequests.length > 0) {
216
- // Append step messages so the tool result is preserved for resume
217
212
  appendStepMessages(runnerParams, stepResult);
218
213
  return { outcome: 'credential', credentialRequests };
219
214
  }
@@ -221,7 +216,7 @@ async function runStreamStepLoop(params) {
221
216
  }
222
217
  return { outcome: 'done' };
223
218
  }
224
- export function checkForApprovals(stepResult, tools, runId) {
219
+ export function checkForApprovals(stepResult, tools) {
225
220
  const approvals = [];
226
221
  for (const tc of stepResult.toolCalls) {
227
222
  const toolDef = tools.find((t) => t.name === tc.toolName);
@@ -229,12 +224,6 @@ export function checkForApprovals(stepResult, tools, runId) {
229
224
  approvals.push(new ToolApprovalRequired(tc.toolCallId, tc.toolName, tc.args));
230
225
  continue;
231
226
  }
232
- // The approval marker is only trusted from a framework tool declared with
233
- // `forwardsApproval` (the sub-agent delegating tools) AND carrying the
234
- // non-forgeable `APPROVAL_REQUIRED` Symbol brand. A plain tool's output — or
235
- // a delegating tool's LLM-shaped `result.object`, which an attacker can
236
- // influence — is plain JSON and can never carry the Symbol, so it can never
237
- // forge an approval/suspension.
238
227
  if (!toolDef?.forwardsApproval) {
239
228
  continue;
240
229
  }
@@ -255,12 +244,13 @@ export function checkForApprovals(stepResult, tools, runId) {
255
244
  }
256
245
  return approvals;
257
246
  }
258
- export function checkForCredentialRequests(stepResult, runId) {
247
+ export function checkForCredentialRequests(stepResult) {
259
248
  const requests = [];
260
249
  for (const tr of stepResult.toolResults) {
250
+ // knowledge: decisions/security/ai-agent-credential-requests-are-symbol-branded.md
261
251
  if (tr.result &&
262
252
  typeof tr.result === 'object' &&
263
- '__credentialRequired' in tr.result) {
253
+ CREDENTIAL_REQUIRED in tr.result) {
264
254
  const r = tr.result;
265
255
  const tc = stepResult.toolCalls.find((t) => t.toolCallId === tr.toolCallId);
266
256
  requests.push(new ToolCredentialRequired(tr.toolCallId, tc?.toolName ?? 'unknown', tc?.args ?? {}, r.credentialName, r.credentialType, r.connectUrl));
@@ -366,10 +356,6 @@ function handleCredentialRequests(requests, runId, channel, aiRunState, persisti
366
356
  suspendReason: 'credential',
367
357
  pendingApprovals,
368
358
  });
369
- // The __credentialRequired tool result is suppressed from the stream, so
370
- // credential-request events (with the runId needed for /resume) are the
371
- // client's signal to show Connect/Ignore buttons — mirroring how
372
- // approval-request suspensions work.
373
359
  for (const req of requests) {
374
360
  channel.send({
375
361
  type: 'credential-request',
@@ -393,7 +379,6 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
393
379
  resourceId: resolveOwnerResourceId(params, agentSessionScope(agentName), input.resourceId),
394
380
  };
395
381
  const streamContext = { channel, options };
396
- // delegateState is attached after prepareAgentRun resolves the agent config
397
382
  const { agent, packageName, resolvedName, agentRunner, storage, memoryConfig, threadId, userMessage, runnerParams, maxSteps, missingRpcs, workingMemorySchemaName, } = await prepareAgentRun(agentName, normalizedInput, params, sessionMap, streamContext);
398
383
  runnerParams.agentId = agentName;
399
384
  const singletonServices = getSingletonServices();
@@ -450,6 +435,12 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
450
435
  updatedAt: new Date(),
451
436
  });
452
437
  options?.onRunCreated?.(runId);
438
+ // Registered before the first model call and released in `finally`, so the
439
+ // window in which an interrupt can land is exactly the window in which there
440
+ // is something to interrupt.
441
+ const interruptHandle = registerInterruptibleRun(runId);
442
+ runnerParams.abortSignal = interruptHandle.signal;
443
+ runnerParams.tools = trackToolExecution(runnerParams.tools, interruptHandle);
453
444
  if (storage) {
454
445
  await storage.saveMessages(threadId, [userMessage]);
455
446
  }
@@ -464,6 +455,10 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
464
455
  event,
465
456
  allEvents,
466
457
  state,
458
+ // Sends downstream directly, so a hook can hand back the fast event
459
+ // now and push the slow one when it is ready.
460
+ emit: next,
461
+ signal: interruptHandle.signal,
467
462
  });
468
463
  if (result == null)
469
464
  return;
@@ -489,12 +484,12 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
489
484
  const wrappedChannel = allChannelMiddleware.length > 0
490
485
  ? wrapChannelWithMiddleware({ channel: persistingChannel }, singletonServices, allChannelMiddleware).channel
491
486
  : persistingChannel;
492
- // Tool results carrying the __credentialRequired marker must never reach
493
- // the client or persisted history: the run suspends with credential-request
494
- // events instead (mirroring approvals), and leaving the tool call
495
- // unresulted is what lets the client resume it after connecting.
496
487
  const credentialFilteredChannel = {
497
488
  ...wrappedChannel,
489
+ // Returns what the inner send returns. Middleware runs asynchronously, so
490
+ // swallowing the promise here makes every `await channel.send(...)` upstream
491
+ // a no-op — including the one that waits for a buffering hook to flush
492
+ // before the channel closes.
498
493
  send: (event) => {
499
494
  if (event.type === 'tool-result' &&
500
495
  event.result !== null &&
@@ -502,14 +497,10 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
502
497
  '__credentialRequired' in event.result) {
503
498
  return;
504
499
  }
505
- wrappedChannel.send(event);
500
+ return wrappedChannel.send(event);
506
501
  },
507
502
  };
508
- // In delegate mode (default), suppress parent's text from reaching the client
509
- // AFTER a sub-agent has been called. If the parent responds directly (no delegation),
510
- // its text goes through normally. Sub-agent text bypasses this path entirely
511
- // (goes through subChannel → channel directly).
512
- const isDelegateMode = agent.agentMode !== 'supervise' && meta.agents?.length;
503
+ const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length;
513
504
  const delegateState = { delegated: false };
514
505
  if (isDelegateMode) {
515
506
  streamContext.delegateState = delegateState;
@@ -521,7 +512,7 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
521
512
  if (delegateState.delegated &&
522
513
  (event.type === 'text-delta' || event.type === 'reasoning-delta'))
523
514
  return;
524
- credentialFilteredChannel.send(event);
515
+ return credentialFilteredChannel.send(event);
525
516
  },
526
517
  delegateState,
527
518
  }
@@ -535,7 +526,6 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
535
526
  streamChannel: outputChannel,
536
527
  persistingChannel,
537
528
  channel,
538
- runId,
539
529
  aiMiddlewares,
540
530
  });
541
531
  if (loopResult.outcome === 'approval') {
@@ -547,11 +537,38 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
547
537
  return persistingChannel.fullText;
548
538
  }
549
539
  await postStreamCleanup(persistingChannel, aiMiddlewares, singletonServices, runnerParams.messages, aiRunState, runId);
550
- channel.send({ type: 'done' });
540
+ // Through the middleware rather than straight at the channel, and awaited.
541
+ // `done` is the only signal a stream hook gets that the reply is over, and
542
+ // the ones that buffer need it: `voiceOutput` speaks a trailing fragment
543
+ // that never reached a full stop, and waits for audio it has already paid
544
+ // to synthesize. Sent raw, that work is discarded by the `close()` below.
545
+ await outputChannel.send({ type: 'done' });
551
546
  channel.close();
552
547
  return persistingChannel.fullText;
553
548
  }
554
549
  catch (err) {
550
+ // An interrupt is not a failure: the truncated text is real output the user
551
+ // already heard part of, so it is persisted and marked rather than dropped.
552
+ const interruption = interruptHandle.interruption;
553
+ if (interruption || isAbortError(err)) {
554
+ await persistingChannel.flush({ interrupted: true });
555
+ await aiRunState.updateRun(runId, { status: 'interrupted' });
556
+ // Deliberately not awaited. A tool still running must not hold the stream
557
+ // open — the whole point of barge-in is that the agent stops now — so the
558
+ // note lands later and the next run on this thread waits for it instead.
559
+ if (storage) {
560
+ trackInterruptNote(threadId, persistOrphanedToolResults(interruptHandle, storage, threadId));
561
+ }
562
+ channel.send({
563
+ type: 'interrupted',
564
+ runId,
565
+ text: persistingChannel.fullText,
566
+ reason: interruption?.reason ?? 'user',
567
+ });
568
+ channel.send({ type: 'done' });
569
+ channel.close();
570
+ return persistingChannel.fullText;
571
+ }
555
572
  for (const mw of aiMiddlewares) {
556
573
  if (mw.onError) {
557
574
  try {
@@ -561,9 +578,7 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
561
578
  messages: runnerParams.messages,
562
579
  });
563
580
  }
564
- catch {
565
- // onError hooks must not affect error flow
566
- }
581
+ catch { }
567
582
  }
568
583
  }
569
584
  await aiRunState.updateRun(runId, {
@@ -578,6 +593,54 @@ export async function streamAIAgent(agentName, input, channel, params, agentSess
578
593
  channel.close();
579
594
  return persistingChannel.fullText;
580
595
  }
596
+ finally {
597
+ interruptHandle.release();
598
+ }
599
+ }
600
+ /**
601
+ * Stop an in-flight run on behalf of a caller, after checking the run is theirs.
602
+ *
603
+ * Unlike {@link resumeAIAgent} this needs no channel: it does not continue the
604
+ * stream, it ends one. The `interrupted` event and the truncated message are
605
+ * emitted by the original {@link streamAIAgent} call on its own channel, so this
606
+ * can be reached over a plain RPC while the stream is held open elsewhere —
607
+ * which is exactly the shape a voice barge-in needs.
608
+ *
609
+ * Ownership is the whole gate, deliberately without {@link assertAgentAuthorized}.
610
+ * Resuming re-enters the agent and approves a tool call, so a revoked grant must
611
+ * block it; stopping is the opposite — if a caller's access to an agent was
612
+ * revoked mid-run, being able to stop their own run is harmless and arguably
613
+ * what you want.
614
+ *
615
+ * Returns `false` when there was nothing to stop. Racing a run that finishes on
616
+ * its own is the normal case in voice, so it is not an error.
617
+ */
618
+ export async function interruptAIAgent(input, params) {
619
+ const { aiRunState, logger } = getSingletonServices();
620
+ if (!aiRunState) {
621
+ throw new Error('AIRunStateService not available in singletonServices');
622
+ }
623
+ const run = await aiRunState.getRun(input.runId);
624
+ if (!run) {
625
+ throw new Error(`No run found for runId ${input.runId}`);
626
+ }
627
+ assertResourceOwner(resolveOwnerResourceId(params, agentSessionScope(run.agentName), run.resourceId), run.resourceId, 'run');
628
+ const stopped = signalRunInterrupt(input.runId, {
629
+ reason: input.reason ?? 'user',
630
+ });
631
+ // A run still marked `running` that this process cannot abort is executing on
632
+ // another instance. Returning a bare `false` there is indistinguishable from
633
+ // "it already finished", so the one deployment shape this registry does not
634
+ // cover fails silently — an agent that simply refuses to shut up, with nothing
635
+ // in the logs. Say so instead. See `signalRunInterrupt` for the fix (fan the
636
+ // interrupt out over eventHub so every instance tries locally).
637
+ if (!stopped && run.status === 'running') {
638
+ logger?.warn(`Could not interrupt run ${input.runId}: it is running in another process. ` +
639
+ 'Interrupts are process-local; fan them out over eventHub to support multiple instances.');
640
+ }
641
+ // Reported after the abort so it names what is *still* running: aborting the
642
+ // model call does nothing to a tool already executing.
643
+ return { stopped, inFlightTools: getInFlightTools(input.runId) };
581
644
  }
582
645
  export async function resumeAIAgent(input, channel, params, options) {
583
646
  const singletonServices = getSingletonServices();
@@ -589,16 +652,12 @@ export async function resumeAIAgent(input, channel, params, options) {
589
652
  if (!run) {
590
653
  throw new Error(`No run found for runId ${input.runId}`);
591
654
  }
592
- assertResourceOwner(resolveOwnerResourceId(params, agentSessionScope(run.agentName), run.resourceId), run.resourceId, 'run');
655
+ assertResourcePrincipalOwner(params, agentSessionScope(run.agentName), run.resourceId, 'run');
593
656
  const pending = run.pendingApprovals?.find((p) => p.toolCallId === input.toolCallId);
594
657
  if (!pending) {
595
658
  throw new Error(`No pending approval for toolCallId ${input.toolCallId} on run ${input.runId}`);
596
659
  }
597
660
  const { agent, packageName, resolvedName } = resolveAgent(run.agentName);
598
- // Gate before resolving the approval: recording it is a persisted side
599
- // effect, so an unauthorized caller must not reach it. Run ownership alone is
600
- // not enough — a grant revoked while the run was suspended must stop the
601
- // caller from approving its pending tool calls.
602
661
  await assertAgentAuthorized(agent, params, packageName);
603
662
  await aiRunState.resolveApproval(input.toolCallId, input.approved ? 'approved' : 'denied');
604
663
  const { storage } = resolveMemoryServices(agent, singletonServices);
@@ -639,11 +698,9 @@ export async function resumeAIAgent(input, channel, params, options) {
639
698
  : pending.agentName,
640
699
  result: denialResult,
641
700
  });
642
- // Check remaining pending approvals
643
701
  const updatedRun = await aiRunState.getRun(run.runId);
644
702
  const remaining = updatedRun?.pendingApprovals ?? [];
645
703
  if (remaining.length > 0) {
646
- // Still waiting for more approvals - don't continue step loop
647
704
  channel.send({ type: 'done' });
648
705
  channel.close();
649
706
  return;
@@ -748,11 +805,9 @@ export async function resumeAIAgent(input, channel, params, options) {
748
805
  ...(isError ? { isError: true } : {}),
749
806
  });
750
807
  }
751
- // Check remaining pending approvals after processing this one
752
808
  const updatedRun = await aiRunState.getRun(run.runId);
753
809
  const remaining = updatedRun?.pendingApprovals ?? [];
754
810
  if (remaining.length > 0) {
755
- // Still waiting for more approvals - don't continue step loop
756
811
  channel.send({ type: 'done' });
757
812
  channel.close();
758
813
  return;
@@ -798,6 +853,11 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
798
853
  modifiedInstructions = result.instructions;
799
854
  }
800
855
  }
856
+ // Resuming is as interruptible as the first turn. It is the same person
857
+ // listening to the same voice, and after an approval it is where most of the
858
+ // reply actually gets spoken — an approved delete is followed by the agent
859
+ // talking about it, and that is a normal thing to talk over.
860
+ const interruptHandle = registerInterruptibleRun(run.runId);
801
861
  const streamMiddleware = aiMiddlewares
802
862
  .filter((mw) => mw.modifyOutputStream)
803
863
  .map((mw) => {
@@ -809,6 +869,10 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
809
869
  event,
810
870
  allEvents,
811
871
  state,
872
+ // Sends downstream directly, so a hook can hand back the fast event
873
+ // now and push the slow one when it is ready.
874
+ emit: next,
875
+ signal: interruptHandle.signal,
812
876
  });
813
877
  if (result == null)
814
878
  return;
@@ -844,10 +908,13 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
844
908
  tools: resumeTools,
845
909
  maxSteps: 1,
846
910
  toolChoice: (agent.toolChoice ?? 'auto'),
911
+ providerOptions: agent.providerOptions,
847
912
  outputSchema: meta?.outputSchema
848
913
  ? pikkuState(packageName, 'misc', 'schemas').get(meta.outputSchema)
849
914
  : undefined,
850
915
  };
916
+ runnerParams.abortSignal = interruptHandle.signal;
917
+ runnerParams.tools = trackToolExecution(runnerParams.tools, interruptHandle);
851
918
  try {
852
919
  const loopResult = await runStreamStepLoop({
853
920
  agent,
@@ -857,7 +924,6 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
857
924
  streamChannel: wrappedChannel,
858
925
  persistingChannel,
859
926
  channel,
860
- runId: run.runId,
861
927
  aiMiddlewares,
862
928
  });
863
929
  if (loopResult.outcome === 'approval') {
@@ -869,10 +935,33 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
869
935
  return;
870
936
  }
871
937
  await postStreamCleanup(persistingChannel, aiMiddlewares, singletonServices, runnerParams.messages, aiRunState, run.runId);
872
- channel.send({ type: 'done' });
938
+ // Through the middleware, for the same reason as the first turn — and it
939
+ // matters more here. After an approval, most of what gets spoken is the
940
+ // agent talking about what it just did, so this is the half of the reply a
941
+ // dropped flush would silence.
942
+ await wrappedChannel.send({ type: 'done' });
873
943
  channel.close();
874
944
  }
875
945
  catch (err) {
946
+ // Same reasoning as the first turn: an interrupt is not a failure, and the
947
+ // part of the reply the user already heard is real output.
948
+ const interruption = interruptHandle.interruption;
949
+ if (interruption || isAbortError(err)) {
950
+ await persistingChannel.flush({ interrupted: true });
951
+ await aiRunState.updateRun(run.runId, { status: 'interrupted' });
952
+ if (storage) {
953
+ trackInterruptNote(run.threadId, persistOrphanedToolResults(interruptHandle, storage, run.threadId));
954
+ }
955
+ channel.send({
956
+ type: 'interrupted',
957
+ runId: run.runId,
958
+ text: persistingChannel.fullText,
959
+ reason: interruption?.reason ?? 'user',
960
+ });
961
+ channel.send({ type: 'done' });
962
+ channel.close();
963
+ return;
964
+ }
876
965
  for (const mw of aiMiddlewares) {
877
966
  if (mw.onError) {
878
967
  try {
@@ -882,9 +971,7 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
882
971
  messages: runnerParams.messages,
883
972
  });
884
973
  }
885
- catch {
886
- // onError hooks must not affect error flow
887
- }
974
+ catch { }
888
975
  }
889
976
  }
890
977
  await aiRunState.updateRun(run.runId, {
@@ -898,4 +985,7 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
898
985
  channel.send({ type: 'done' });
899
986
  channel.close();
900
987
  }
988
+ finally {
989
+ interruptHandle.release();
990
+ }
901
991
  }
@@ -1,7 +1,9 @@
1
1
  import type { CorePermissionGroup, CorePikkuPermission } from '../../function/functions.types.js';
2
2
  import type { CorePikkuMiddleware, MiddlewareMetadata, PermissionMetadata } from '../../types/core.types.js';
3
+ import type { AIProviderOptions } from '../../services/ai-agent-runner-service.js';
3
4
  import type { PikkuChannel } from '../channel/channel.types.js';
4
5
  import type { CorePikkuChannelMiddleware } from '../channel/channel.types.js';
6
+ import type { ApprovalPolicy } from '../channel/channel-rpc.js';
5
7
  export interface AIThread {
6
8
  id: string;
7
9
  resourceId: string;
@@ -49,6 +51,23 @@ export interface AIMessage {
49
51
  toolCalls?: AIToolCall[];
50
52
  toolResults?: AIToolResult[];
51
53
  reasoningContent?: string;
54
+ /**
55
+ * Set on an assistant message whose generation was cut short by
56
+ * an interrupt — the text is a mid-sentence fragment, not a reply.
57
+ * Carried into the next turn's context so the model can see it said only
58
+ * this much before being talked over, and decide for itself whether to
59
+ * resume, restate or move on. Storage that drops unknown fields loses the
60
+ * marker but keeps the fragment, which degrades to a truncated reply.
61
+ */
62
+ interrupted?: boolean;
63
+ /**
64
+ * Set on a tool message whose result arrived after the run was interrupted,
65
+ * so the model never got to describe it. The work happened; only the reply
66
+ * about it was lost. It is ordinary thread context on the next turn — the
67
+ * model raises it unprompted ("that deploy did go through") rather than the
68
+ * result being silently dropped or replayed as a fresh tool call.
69
+ */
70
+ undelivered?: boolean;
52
71
  createdAt: Date;
53
72
  }
54
73
  export interface AIAgentStep {
@@ -113,13 +132,24 @@ export interface AIAgentOutput {
113
132
  * another user's or org's threads.
114
133
  */
115
134
  export type SessionScope = 'user' | 'org';
116
- export interface AIAgentToolDef {
135
+ /**
136
+ * `ApprovalPolicy` is shared with channel capabilities, but `Partial` here:
137
+ * absent `needsApproval` means "do not ask", which is safe because a tool is
138
+ * written by whoever runs the server it executes on. A capability runs on
139
+ * someone else's machine, so it requires the field instead.
140
+ */
141
+ export interface AIAgentToolDef extends Partial<ApprovalPolicy> {
117
142
  name: string;
118
143
  description: string;
119
144
  inputSchema: Record<string, unknown>;
120
145
  execute: (input: unknown) => Promise<unknown>;
121
- needsApproval?: boolean;
122
- approvalDescriptionFn?: (input: unknown) => Promise<string>;
146
+ /**
147
+ * Mirrors the pikku function's `readonly` flag. A read that gets interrupted
148
+ * is discarded rather than reported: nothing changed, and by the next turn
149
+ * the data may be stale anyway — re-reading is cheaper than explaining a
150
+ * result the user never asked to hear about.
151
+ */
152
+ readonly?: boolean;
123
153
  /**
124
154
  * Set only by the framework on sub-agent delegating tools. Such a tool may
125
155
  * legitimately return an `__approvalRequired` marker to forward a nested
@@ -144,6 +174,27 @@ export interface PikkuAIMiddlewareHooks<State extends Record<string, unknown> =
144
174
  event: AIStreamEvent;
145
175
  allEvents: readonly AIStreamEvent[];
146
176
  state: State;
177
+ /**
178
+ * Push an event into the stream *after* this call has returned.
179
+ *
180
+ * Returning events blocks the stream until the hook resolves, which is
181
+ * right for anything derived from the event and wrong for anything slow.
182
+ * Speech is the motivating case: awaiting a text-to-speech call before
183
+ * returning the text delta stalls the reader at every full stop and
184
+ * serialises synthesis behind playback. Return the text immediately,
185
+ * start the slow work, and `emit` its result when it lands.
186
+ *
187
+ * Ordering among emitted events is the caller's problem — chain them if
188
+ * it matters — and a hook that emits must make sure anything still
189
+ * outstanding has landed before it lets `done` through.
190
+ */
191
+ emit: (event: AIStreamEvent) => Promise<void>;
192
+ /**
193
+ * Aborts when the run is interrupted. Pass it to any provider call the
194
+ * hook makes: work started for a reply the user has already talked over
195
+ * is billed but never heard.
196
+ */
197
+ signal?: AbortSignal;
147
198
  }) => Promise<AIStreamEvent | AIStreamEvent[] | null> | AIStreamEvent | AIStreamEvent[] | null;
148
199
  modifyOutput?: (services: Services, ctx: {
149
200
  text: string;
@@ -216,8 +267,19 @@ export type CoreAIAgent<PikkuPermission = CorePikkuPermission<any, any>, PikkuMi
216
267
  description: string;
217
268
  summary?: string;
218
269
  errors?: string[];
270
+ /**
271
+ * The three fields below are the system prompt. `buildInstructions` joins
272
+ * whichever are set with a blank line, always in this order — role, then
273
+ * personality, then goal — and appends the tool-usage rules if the agent has
274
+ * tools. Nothing checks them against each other: the split is there to keep a
275
+ * prompt legible, and text put in the wrong one still reaches the model.
276
+ *
277
+ * Who the agent is. 'You are a support engineer triaging inbound bugs.'
278
+ */
219
279
  role?: string;
280
+ /** How it should sound: tone, vocabulary, how much it says at a time. */
220
281
  personality?: string;
282
+ /** What it is for — the only one of the three that is required. */
221
283
  goal: string;
222
284
  model: string;
223
285
  temperature?: number;
@@ -230,6 +292,16 @@ export type CoreAIAgent<PikkuPermission = CorePikkuPermission<any, any>, PikkuMi
230
292
  memory?: AIAgentMemoryConfig;
231
293
  maxSteps?: number;
232
294
  toolChoice?: 'auto' | 'required' | 'none';
295
+ /**
296
+ * Per-provider model settings, keyed by provider id and passed through
297
+ * untouched — for anything only one vendor offers, which the fields above
298
+ * deliberately do not try to unify.
299
+ *
300
+ * `{ openai: { reasoningEffort: 'minimal' } }` is the one that matters for
301
+ * voice: on gpt-5-mini it measured 0.9s to first token against 2.5s at the
302
+ * default, and a spoken reply is waited through rather than skimmed.
303
+ */
304
+ providerOptions?: AIProviderOptions;
233
305
  input?: unknown;
234
306
  output?: unknown;
235
307
  tags?: string[];
@@ -361,6 +433,14 @@ export type AIStreamEvent = {
361
433
  type: 'suspended';
362
434
  reason: 'rpc-missing';
363
435
  missingRpcs: string[];
436
+ } | {
437
+ type: 'interrupted';
438
+ runId: string;
439
+ /** The truncated assistant text at the moment generation stopped. */
440
+ text: string;
441
+ reason: 'speech' | 'user' | 'timeout';
442
+ agent?: string;
443
+ session?: string;
364
444
  } | {
365
445
  type: 'done';
366
446
  };
@@ -392,7 +472,7 @@ export interface AgentRunState {
392
472
  agentName: string;
393
473
  threadId: string;
394
474
  resourceId: string;
395
- status: 'running' | 'suspended' | 'completed' | 'failed';
475
+ status: 'running' | 'suspended' | 'completed' | 'failed' | 'interrupted';
396
476
  errorMessage?: string;
397
477
  suspendReason?: 'approval' | 'credential' | 'rpc-missing';
398
478
  missingRpcs?: string[];
@@ -1,9 +1,11 @@
1
- export { agent, agentStream, agentResume, agentApprove, } from './ai-agent-helpers.js';
1
+ export { agent, agentStream, agentResume, agentApprove, agentInterrupt, } from './ai-agent-helpers.js';
2
2
  export { wrapChannelWithAGUI, type AGUIEvent } from './ai-agent-agui.js';
3
3
  export { runAIAgent, resumeAIAgentSync } from './ai-agent-runner.js';
4
- export { streamAIAgent, resumeAIAgent } from './ai-agent-stream.js';
5
- export { voiceInput } from './voice-input.js';
6
- export { voiceOutput } from './voice-output.js';
4
+ export { streamAIAgent, resumeAIAgent, interruptAIAgent, } from './ai-agent-stream.js';
5
+ export { voiceInput, readsAsNonSpeech, NoSpeechDetectedError, } from './voice-input.js';
6
+ export { voiceOutput, unspeakableScripts, voiceForText, type SpeakableScripts, } from './voice-output.js';
7
+ export { AgentInterruptedError, awaitPendingInterruptNote, getInFlightTools, isAbortError, isRunInterruptible, persistOrphanedToolResults, registerInterruptibleRun, signalRunInterrupt, trackInterruptNote, trackToolExecution, } from './ai-agent-interrupt.js';
8
+ export type { AgentInterruption, AgentInterruptResult, InterruptibleRunHandle, OrphanedToolResult, } from './ai-agent-interrupt.js';
7
9
  export { type RunAIAgentParams, type StreamAIAgentOptions, ToolApprovalRequired, ToolCredentialRequired, canAccessThread, isOwnedByPrincipal, sessionPrincipals, threadOwnerConstraint, } from './ai-agent-prepare.js';
8
10
  export { addAIAgent, approveAIAgent, getAIAgents, getAIAgentsMeta, } from './ai-agent-registry.js';
9
11
  export type { AIAgentInput, AIAgentInputAttachment, AIAgentMeta, AIAgentMemoryConfig, AIAgentStep, AIContentPart, AgentRunRow, AgentRunService, AgentRunState, AIMessage, AIStreamChannel, AIStreamEvent, AIThread, CoreAIAgent, PendingApproval, PikkuAIMiddlewareHooks, } from './ai-agent.types.js';
@@ -1,8 +1,9 @@
1
- export { agent, agentStream, agentResume, agentApprove, } from './ai-agent-helpers.js';
1
+ export { agent, agentStream, agentResume, agentApprove, agentInterrupt, } from './ai-agent-helpers.js';
2
2
  export { wrapChannelWithAGUI } from './ai-agent-agui.js';
3
3
  export { runAIAgent, resumeAIAgentSync } from './ai-agent-runner.js';
4
- export { streamAIAgent, resumeAIAgent } from './ai-agent-stream.js';
5
- export { voiceInput } from './voice-input.js';
6
- export { voiceOutput } from './voice-output.js';
4
+ export { streamAIAgent, resumeAIAgent, interruptAIAgent, } from './ai-agent-stream.js';
5
+ export { voiceInput, readsAsNonSpeech, NoSpeechDetectedError, } from './voice-input.js';
6
+ export { voiceOutput, unspeakableScripts, voiceForText, } from './voice-output.js';
7
+ export { AgentInterruptedError, awaitPendingInterruptNote, getInFlightTools, isAbortError, isRunInterruptible, persistOrphanedToolResults, registerInterruptibleRun, signalRunInterrupt, trackInterruptNote, trackToolExecution, } from './ai-agent-interrupt.js';
7
8
  export { ToolApprovalRequired, ToolCredentialRequired, canAccessThread, isOwnedByPrincipal, sessionPrincipals, threadOwnerConstraint, } from './ai-agent-prepare.js';
8
9
  export { addAIAgent, approveAIAgent, getAIAgents, getAIAgentsMeta, } from './ai-agent-registry.js';