@pikku/core 0.12.84 → 0.12.88

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 (577) hide show
  1. package/CHANGELOG.md +503 -0
  2. package/dist/bootstrap-compat/root.d.ts +20 -0
  3. package/dist/classification/column-form.d.ts +32 -0
  4. package/dist/classification/column-form.js +42 -0
  5. package/dist/classification/data-classification.d.ts +64 -0
  6. package/dist/classification/index.d.ts +13 -0
  7. package/dist/classification/index.js +2 -0
  8. package/dist/classification/secret-value.d.ts +56 -0
  9. package/dist/classification/secret-value.js +46 -0
  10. package/dist/crypto-utils.d.ts +1 -1
  11. package/dist/dev/hot-reload.d.ts +1 -1
  12. package/dist/dev/hot-reload.js +1 -1
  13. package/dist/ecosystem/agent-scorer.d.ts +1 -1
  14. package/dist/ecosystem/agent.d.ts +4 -1
  15. package/dist/ecosystem/channel/local.d.ts +2 -0
  16. package/dist/ecosystem/channel/local.js +2 -0
  17. package/dist/ecosystem/channel/serverless.d.ts +9 -0
  18. package/dist/ecosystem/channel/serverless.js +1 -0
  19. package/dist/ecosystem/channel.d.ts +3 -0
  20. package/dist/ecosystem/channel.js +1 -0
  21. package/dist/ecosystem/cli.d.ts +1 -1
  22. package/dist/ecosystem/cli.js +1 -1
  23. package/dist/ecosystem/credential.d.ts +1 -0
  24. package/dist/ecosystem/crypto-utils.d.ts +8 -0
  25. package/dist/ecosystem/crypto-utils.js +1 -0
  26. package/dist/ecosystem/dev.d.ts +1 -0
  27. package/dist/ecosystem/dev.js +1 -0
  28. package/{src/ecosystem/testing.ts → dist/ecosystem/errors.d.ts} +3 -3
  29. package/dist/ecosystem/errors.js +2 -0
  30. package/dist/ecosystem/function.d.ts +1 -1
  31. package/dist/ecosystem/function.js +1 -1
  32. package/dist/ecosystem/http.d.ts +3 -1
  33. package/dist/ecosystem/http.js +3 -1
  34. package/dist/ecosystem/mcp.d.ts +1 -1
  35. package/dist/ecosystem/mcp.js +1 -1
  36. package/dist/ecosystem/middleware.d.ts +2 -1
  37. package/dist/ecosystem/middleware.js +2 -1
  38. package/dist/ecosystem/persona.d.ts +4 -2
  39. package/dist/ecosystem/persona.js +2 -1
  40. package/dist/ecosystem/queue.d.ts +4 -2
  41. package/dist/ecosystem/queue.js +3 -1
  42. package/dist/ecosystem/role.d.ts +1 -0
  43. package/dist/ecosystem/rpc.d.ts +2 -0
  44. package/dist/ecosystem/rpc.js +1 -0
  45. package/dist/ecosystem/scenario.d.ts +8 -2
  46. package/dist/ecosystem/scenario.js +5 -1
  47. package/dist/ecosystem/scheduler.d.ts +2 -1
  48. package/dist/ecosystem/scheduler.js +2 -1
  49. package/dist/ecosystem/schema.d.ts +2 -1
  50. package/dist/ecosystem/schema.js +1 -1
  51. package/dist/ecosystem/scope.d.ts +2 -0
  52. package/dist/ecosystem/scope.js +1 -0
  53. package/dist/ecosystem/secret.d.ts +2 -0
  54. package/dist/ecosystem/secret.js +1 -0
  55. package/dist/ecosystem/services/local-content.d.ts +2 -1
  56. package/dist/ecosystem/services/local-content.js +1 -1
  57. package/dist/ecosystem/services/local-meta.d.ts +1 -0
  58. package/dist/ecosystem/services/local-meta.js +1 -0
  59. package/dist/ecosystem/services.d.ts +11 -3
  60. package/dist/ecosystem/services.js +7 -1
  61. package/dist/ecosystem/trigger.d.ts +1 -0
  62. package/dist/ecosystem/trigger.js +1 -1
  63. package/dist/ecosystem/types.d.ts +6 -3
  64. package/dist/ecosystem/types.js +3 -2
  65. package/dist/ecosystem/variable.d.ts +1 -0
  66. package/dist/ecosystem/virtual-user.d.ts +3 -0
  67. package/dist/ecosystem/virtual-user.js +3 -0
  68. package/dist/ecosystem/workflow.d.ts +2 -0
  69. package/dist/ecosystem/workflow.js +2 -0
  70. package/dist/errors/index.d.ts +8 -0
  71. package/dist/errors/index.js +1 -0
  72. package/dist/errors/serialized-error.d.ts +7 -0
  73. package/dist/function/function-meta.types.d.ts +139 -0
  74. package/dist/function/function-runner.d.ts +3 -2
  75. package/dist/function/function-runner.js +31 -11
  76. package/dist/function/functions.types.d.ts +10 -2
  77. package/dist/function/index.d.ts +8 -2
  78. package/dist/function/index.js +4 -1
  79. package/dist/function/pikku-request.d.ts +8 -0
  80. package/dist/function/pikku-request.js +15 -0
  81. package/dist/middleware/auth-apikey.d.ts +2 -10
  82. package/dist/middleware/auth-apikey.js +1 -1
  83. package/dist/middleware/auth-bearer.d.ts +2 -10
  84. package/dist/middleware/auth-bearer.js +1 -1
  85. package/dist/middleware/auth-cookie.d.ts +2 -10
  86. package/dist/middleware/auth-cookie.js +1 -1
  87. package/dist/middleware/cors.d.ts +5 -11
  88. package/dist/middleware/cors.js +13 -6
  89. package/dist/middleware/index.d.ts +3 -0
  90. package/dist/middleware/index.js +1 -0
  91. package/dist/middleware/middleware-factories.d.ts +9 -0
  92. package/dist/middleware/middleware-factories.js +19 -0
  93. package/dist/middleware/middleware.types.d.ts +27 -0
  94. package/dist/middleware/middleware.types.js +1 -0
  95. package/dist/middleware/remote-auth.d.ts +2 -2
  96. package/dist/middleware/remote-auth.js +1 -1
  97. package/dist/middleware/telemetry.d.ts +4 -20
  98. package/dist/middleware/telemetry.js +1 -1
  99. package/dist/middleware-runner.d.ts +2 -1
  100. package/dist/pikku-state.d.ts +2 -1
  101. package/dist/services/audit-service.d.ts +1 -1
  102. package/dist/services/credential-wire-service.js +1 -1
  103. package/dist/services/email-service.d.ts +1 -1
  104. package/dist/services/file-scenario-run-store.d.ts +58 -0
  105. package/dist/services/file-scenario-run-store.js +214 -0
  106. package/dist/services/in-memory-workflow-service.d.ts +1 -1
  107. package/dist/services/index.d.ts +5 -1
  108. package/dist/services/index.js +3 -0
  109. package/dist/services/local-secrets.d.ts +1 -1
  110. package/dist/services/local-secrets.js +1 -1
  111. package/dist/services/logger.d.ts +7 -7
  112. package/dist/services/meta-service.d.ts +2 -1
  113. package/dist/services/scoped-secret-service.d.ts +1 -1
  114. package/dist/services/secret-service.d.ts +1 -1
  115. package/dist/services/typed-secret-service.d.ts +16 -2
  116. package/dist/services/typed-secret-service.js +5 -0
  117. package/dist/services/webhook-service.d.ts +1 -1
  118. package/dist/services/workflow-service.d.ts +2 -1
  119. package/dist/testing/index.d.ts +1 -0
  120. package/dist/testing/index.js +1 -0
  121. package/dist/types/core.types.d.ts +30 -180
  122. package/dist/types/core.types.js +1 -19
  123. package/dist/types/index.d.ts +2 -0
  124. package/dist/types/index.js +1 -0
  125. package/dist/types/state.types.d.ts +3 -1
  126. package/dist/utils.d.ts +13 -0
  127. package/dist/utils.js +2 -0
  128. package/dist/wirings/addon/addon-runner.d.ts +17 -0
  129. package/dist/wirings/addon/addon-runner.js +150 -0
  130. package/dist/wirings/addon/index.d.ts +6 -0
  131. package/dist/wirings/addon/index.js +3 -0
  132. package/dist/wirings/addon/remote-addon-auth.d.ts +16 -0
  133. package/dist/wirings/addon/remote-addon-auth.js +39 -0
  134. package/dist/wirings/addon/wire-addon.d.ts +80 -0
  135. package/dist/wirings/addon/wire-addon.js +120 -0
  136. package/dist/wirings/addon/wire-remote-addon.d.ts +22 -0
  137. package/dist/wirings/addon/wire-remote-addon.js +11 -0
  138. package/dist/wirings/agent/agent-memory.d.ts +11 -0
  139. package/dist/wirings/agent/agent-memory.js +17 -2
  140. package/dist/wirings/agent/agent-prepare.d.ts +3 -3
  141. package/dist/wirings/agent/agent-prepare.js +1 -1
  142. package/dist/wirings/agent/agent-runner.js +2 -3
  143. package/dist/wirings/agent/agent-stream.js +117 -93
  144. package/dist/wirings/agent/agent-utils.d.ts +13 -0
  145. package/dist/wirings/agent/agent-utils.js +16 -0
  146. package/dist/wirings/agent/agent.types.d.ts +12 -10
  147. package/dist/wirings/agent/index.d.ts +1 -1
  148. package/dist/wirings/agent/voice-input.js +1 -1
  149. package/dist/wirings/agent/voice-output.js +1 -1
  150. package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +13 -0
  151. package/dist/wirings/agent-scorer/agent-scorer-judge.js +52 -0
  152. package/dist/wirings/agent-scorer/agent-scorer.d.ts +7 -1
  153. package/dist/wirings/agent-scorer/agent-scorer.js +1 -0
  154. package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +20 -0
  155. package/dist/wirings/agent-scorer/index.d.ts +1 -1
  156. package/dist/wirings/channel/channel-common.d.ts +2 -1
  157. package/dist/wirings/channel/channel-middleware-runner.d.ts +2 -1
  158. package/dist/wirings/channel/channel.types.d.ts +1 -1
  159. package/dist/wirings/channel/serverless/index.d.ts +1 -0
  160. package/dist/wirings/cli/channel/index.d.ts +1 -1
  161. package/dist/wirings/cli/cli-runner.d.ts +2 -1
  162. package/dist/wirings/cli/cli-runner.js +4 -1
  163. package/dist/wirings/cli/cli.types.d.ts +21 -2
  164. package/dist/wirings/cli/command-parser.js +157 -23
  165. package/dist/wirings/gateway/gateway.types.d.ts +2 -1
  166. package/dist/wirings/http/http-runner.d.ts +1 -1
  167. package/dist/wirings/http/http-runner.js +1 -1
  168. package/dist/wirings/http/http.types.d.ts +2 -2
  169. package/dist/wirings/http/index.d.ts +1 -0
  170. package/dist/wirings/http/index.js +1 -0
  171. package/dist/wirings/http/pikku-fetch-http-request.js +1 -1
  172. package/dist/wirings/http/pikku-fetch-http-response.js +2 -2
  173. package/dist/wirings/mcp/mcp.types.d.ts +1 -1
  174. package/dist/wirings/persona/index.d.ts +1 -1
  175. package/dist/wirings/persona/index.js +1 -1
  176. package/dist/wirings/persona/persona.types.d.ts +14 -0
  177. package/dist/wirings/queue/queue.types.d.ts +1 -1
  178. package/dist/wirings/queue/signed-queue-service.d.ts +1 -1
  179. package/dist/wirings/rpc/index.d.ts +0 -6
  180. package/dist/wirings/rpc/index.js +0 -3
  181. package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -1
  182. package/dist/wirings/rpc/remote-addon-auth.js +1 -1
  183. package/dist/wirings/rpc/rpc-runner.js +2 -2
  184. package/dist/wirings/rpc/wire-addon.d.ts +1 -1
  185. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -1
  186. package/dist/wirings/scope/index.d.ts +1 -0
  187. package/dist/wirings/scope/index.js +1 -0
  188. package/dist/wirings/secret/secret.types.d.ts +10 -0
  189. package/dist/wirings/secret/validate-secret-definitions.js +2 -0
  190. package/dist/wirings/variable/validate-variable-definitions.js +2 -0
  191. package/dist/wirings/variable/variable.types.d.ts +15 -0
  192. package/dist/wirings/virtual-user/index.d.ts +1 -1
  193. package/dist/wirings/virtual-user/index.js +1 -1
  194. package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +1 -1
  195. package/dist/wirings/virtual-user/virtual-user-derive.d.ts +1 -1
  196. package/dist/wirings/workflow/graph/graph-node.d.ts +9 -2
  197. package/dist/wirings/workflow/graph/graph-node.js +2 -0
  198. package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -0
  199. package/dist/wirings/workflow/graph/graph-runner.js +283 -31
  200. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +16 -1
  201. package/dist/wirings/workflow/index.d.ts +2 -0
  202. package/dist/wirings/workflow/index.js +1 -0
  203. package/dist/wirings/workflow/pikku-scenario-service.d.ts +15 -5
  204. package/dist/wirings/workflow/pikku-scenario-service.js +44 -16
  205. package/dist/wirings/workflow/pikku-workflow-service.d.ts +22 -7
  206. package/dist/wirings/workflow/pikku-workflow-service.js +28 -29
  207. package/dist/wirings/workflow/run-timeline.d.ts +1 -1
  208. package/dist/wirings/workflow/scenario-run.types.d.ts +171 -0
  209. package/dist/wirings/workflow/scenario-run.types.js +1 -0
  210. package/dist/wirings/workflow/scenario-step-guards.d.ts +1 -2
  211. package/dist/wirings/workflow/scenario-step-guards.js +0 -8
  212. package/dist/wirings/workflow/scenario-step.types.d.ts +27 -12
  213. package/dist/wirings/workflow/workflow-approval.js +2 -1
  214. package/dist/wirings/workflow/workflow-run-engine.types.d.ts +2 -1
  215. package/dist/wirings/workflow/workflow-step-claim.d.ts +16 -0
  216. package/dist/wirings/workflow/workflow-step-claim.js +27 -0
  217. package/dist/wirings/workflow/workflow.types.d.ts +2 -1
  218. package/knowledge/decisions/index.md +2 -0
  219. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +1 -1
  220. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +1 -1
  221. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +2 -2
  222. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +6 -6
  223. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +1 -1
  224. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +1 -1
  225. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +1 -1
  226. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +1 -1
  227. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +1 -1
  228. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +1 -1
  229. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +1 -1
  230. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +1 -1
  231. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +1 -1
  232. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +1 -1
  233. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +4 -4
  234. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +1 -1
  235. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +3 -3
  236. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +2 -2
  237. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +2 -2
  238. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +1 -1
  239. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +1 -1
  240. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +3 -3
  241. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +1 -1
  242. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +4 -4
  243. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +1 -1
  244. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +1 -1
  245. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +1 -1
  246. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +1 -1
  247. package/knowledge/decisions/internals/index.md +4 -2
  248. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +1 -1
  249. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +1 -1
  250. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +1 -1
  251. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +1 -1
  252. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +1 -1
  253. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +2 -2
  254. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +5 -5
  255. package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +1 -1
  256. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +1 -1
  257. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +43 -19
  258. package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +1 -1
  259. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +1 -1
  260. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +3 -3
  261. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +1 -1
  262. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +1 -1
  263. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +1 -1
  264. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +1 -1
  265. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +1 -1
  266. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +1 -1
  267. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +1 -1
  268. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +1 -1
  269. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +1 -1
  270. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +9 -5
  271. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
  272. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +2 -2
  273. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +1 -1
  274. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +1 -1
  275. package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +47 -0
  276. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +1 -1
  277. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +2 -3
  278. package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +1 -1
  279. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +1 -1
  280. package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +1 -1
  281. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +3 -3
  282. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +4 -3
  283. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +1 -1
  284. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +2 -2
  285. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +1 -1
  286. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +2 -2
  287. package/knowledge/decisions/security/index.md +4 -1
  288. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +1 -1
  289. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +3 -3
  290. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +1 -1
  291. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +8 -2
  292. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +1 -1
  293. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +2 -2
  294. package/knowledge/index.md +3 -1
  295. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +1 -1
  296. package/knowledge/questions/index.md +2 -0
  297. package/package.json +14 -13
  298. package/run-tests.sh +0 -0
  299. package/scripts/generate-api-report.d.mts +1 -1
  300. package/scripts/generate-api-report.mjs +67 -60
  301. package/scripts/generate-api-report.mts +11 -45
  302. package/src/api-report.test.ts +70 -1
  303. package/src/app-alias-surface.test.ts +179 -0
  304. package/src/app-leaf-surface.test.ts +217 -0
  305. package/src/bootstrap-compat/root.ts +20 -0
  306. package/src/{column-form.test.ts → classification/column-form.test.ts} +2 -2
  307. package/src/{data-classification.ts → classification/data-classification.ts} +1 -5
  308. package/src/classification/index.ts +38 -0
  309. package/src/{secret-value.test.ts → classification/secret-value.test.ts} +2 -2
  310. package/src/{secret-value.ts → classification/secret-value.ts} +1 -6
  311. package/src/crypto-utils.ts +1 -1
  312. package/src/dev/hot-reload.ts +1 -1
  313. package/src/dev/reload-meta.test.ts +1 -1
  314. package/src/errors/index.ts +9 -0
  315. package/src/errors/serialized-error.ts +9 -0
  316. package/src/factory-functions.test.ts +4 -2
  317. package/src/function/function-meta.types.ts +151 -0
  318. package/src/function/function-runner.test.ts +4 -2
  319. package/src/function/function-runner.ts +47 -14
  320. package/src/function/functions.types.ts +11 -7
  321. package/src/function/index.ts +24 -5
  322. package/src/function/list.types.ts +1 -3
  323. package/src/middleware/auth-apikey.ts +4 -2
  324. package/src/middleware/auth-bearer.test.ts +1 -1
  325. package/src/middleware/auth-bearer.ts +4 -2
  326. package/src/middleware/auth-cookie.ts +4 -1
  327. package/src/middleware/cors.test.ts +126 -5
  328. package/src/middleware/cors.ts +19 -8
  329. package/src/middleware/index.ts +16 -0
  330. package/src/middleware/middleware-factories.ts +62 -0
  331. package/src/middleware/middleware.types.ts +61 -0
  332. package/src/middleware/remote-auth.test.ts +1 -1
  333. package/src/middleware/remote-auth.ts +1 -1
  334. package/src/middleware/telemetry.ts +4 -2
  335. package/src/middleware-runner.test.ts +2 -3
  336. package/src/middleware-runner.ts +2 -2
  337. package/src/no-root-barrel.test.ts +114 -0
  338. package/src/permissions.ts +2 -4
  339. package/src/pikku-state.ts +3 -1
  340. package/src/public-surface.json +56 -241
  341. package/src/public-surface.json.README +3 -3
  342. package/src/public-surface.test.ts +5 -5
  343. package/src/remote.test.ts +1 -1
  344. package/src/removed-legacy-exports.test.ts +5 -1
  345. package/src/services/audit-service.ts +1 -1
  346. package/src/services/credential-wire-service.ts +1 -1
  347. package/src/services/email-service.ts +2 -4
  348. package/src/services/file-scenario-run-store.test.ts +349 -0
  349. package/src/services/file-scenario-run-store.ts +282 -0
  350. package/src/services/in-memory-workflow-service.ts +1 -1
  351. package/src/services/index.ts +13 -1
  352. package/src/services/local-content-request-handler.ts +1 -2
  353. package/src/services/local-secrets.ts +1 -1
  354. package/src/services/logger.ts +7 -7
  355. package/src/services/meta-service.ts +2 -2
  356. package/src/services/queue-webhook-service.test.ts +1 -1
  357. package/src/services/scoped-secret-service.ts +1 -1
  358. package/src/services/secret-service.ts +1 -1
  359. package/src/services/typed-secret-service.test.ts +52 -0
  360. package/src/services/typed-secret-service.ts +26 -2
  361. package/src/services/webhook-service.ts +1 -1
  362. package/src/services/workflow-service.ts +2 -1
  363. package/src/template-alias-surface.test.ts +240 -0
  364. package/src/testing/index.ts +1 -0
  365. package/src/types/core.types.ts +33 -285
  366. package/src/types/index.ts +25 -0
  367. package/src/types/state.types.ts +6 -5
  368. package/src/types/typed-credentials.test.ts +72 -0
  369. package/src/utils.ts +34 -0
  370. package/src/wirings/{rpc → addon}/addon-scopes.test.ts +1 -1
  371. package/src/wirings/addon/index.ts +12 -0
  372. package/src/wirings/{rpc → addon}/remote-addon-auth.ts +4 -1
  373. package/src/wirings/{rpc → addon}/wire-addon.ts +37 -2
  374. package/src/wirings/agent/agent-memory.test.ts +73 -0
  375. package/src/wirings/agent/agent-memory.ts +16 -2
  376. package/src/wirings/agent/agent-middleware.types.test.ts +41 -0
  377. package/src/wirings/agent/agent-prepare.ts +8 -5
  378. package/src/wirings/agent/agent-runner.ts +2 -3
  379. package/src/wirings/agent/agent-stream-delegate.test.ts +381 -0
  380. package/src/wirings/agent/agent-stream.ts +160 -81
  381. package/src/wirings/agent/agent-utils.ts +19 -0
  382. package/src/wirings/agent/agent.types.ts +12 -11
  383. package/src/wirings/agent/index.ts +1 -0
  384. package/src/wirings/agent/voice-input.ts +1 -1
  385. package/src/wirings/agent/voice-output.test.ts +2 -4
  386. package/src/wirings/agent/voice-output.ts +1 -1
  387. package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +145 -0
  388. package/src/wirings/agent-scorer/agent-scorer-judge.ts +60 -0
  389. package/src/wirings/agent-scorer/agent-scorer.ts +8 -0
  390. package/src/wirings/agent-scorer/agent-scorer.types.ts +21 -0
  391. package/src/wirings/agent-scorer/index.ts +1 -0
  392. package/src/wirings/channel/channel-common.ts +4 -2
  393. package/src/wirings/channel/channel-handler.ts +2 -5
  394. package/src/wirings/channel/channel-middleware-runner.ts +1 -1
  395. package/src/wirings/channel/channel-rpc.types.ts +1 -5
  396. package/src/wirings/channel/channel.types.ts +1 -2
  397. package/src/wirings/channel/local/local-channel-runner.test.ts +1 -2
  398. package/src/wirings/channel/serverless/index.ts +1 -0
  399. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +2 -2
  400. package/src/wirings/cli/channel/index.ts +1 -3
  401. package/src/wirings/cli/cli-runner.test.ts +1 -1
  402. package/src/wirings/cli/cli-runner.ts +11 -7
  403. package/src/wirings/cli/cli.types.ts +24 -3
  404. package/src/wirings/cli/command-parser.test.ts +388 -1
  405. package/src/wirings/cli/command-parser.ts +189 -29
  406. package/src/wirings/gateway/gateway-runner.test.ts +1 -2
  407. package/src/wirings/gateway/gateway-runner.ts +3 -6
  408. package/src/wirings/gateway/gateway.types.ts +5 -4
  409. package/src/wirings/http/http-routes.test.ts +1 -2
  410. package/src/wirings/http/http-runner-addon-ref.test.ts +238 -0
  411. package/src/wirings/http/http-runner.test.ts +3 -8
  412. package/src/wirings/http/http-runner.ts +9 -3
  413. package/src/wirings/http/http.types.ts +3 -12
  414. package/src/wirings/http/index.ts +1 -0
  415. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  416. package/src/wirings/http/pikku-fetch-http-response.ts +3 -2
  417. package/src/wirings/mcp/mcp-runner.test.ts +1 -1
  418. package/src/wirings/mcp/mcp.types.ts +1 -2
  419. package/src/wirings/persona/index.ts +1 -4
  420. package/src/wirings/persona/persona.types.ts +14 -0
  421. package/src/wirings/queue/queue-identity.test.ts +1 -1
  422. package/src/wirings/queue/queue.types.ts +2 -6
  423. package/src/wirings/queue/signed-queue-service.ts +1 -1
  424. package/src/wirings/rpc/index.ts +0 -12
  425. package/src/wirings/rpc/rpc-runner.test.ts +4 -4
  426. package/src/wirings/rpc/rpc-runner.ts +3 -3
  427. package/src/wirings/scheduler/scheduler.types.ts +2 -5
  428. package/src/wirings/scope/index.ts +1 -0
  429. package/src/wirings/secret/secret.types.ts +10 -0
  430. package/src/wirings/secret/validate-secret-definitions.test.ts +23 -0
  431. package/src/wirings/secret/validate-secret-definitions.ts +2 -0
  432. package/src/wirings/variable/validate-variable-definitions.test.ts +24 -0
  433. package/src/wirings/variable/validate-variable-definitions.ts +2 -0
  434. package/src/wirings/variable/variable.types.ts +15 -0
  435. package/src/wirings/virtual-user/index.ts +1 -4
  436. package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
  437. package/src/wirings/virtual-user/virtual-user-derive.test.ts +1 -1
  438. package/src/wirings/virtual-user/virtual-user-derive.ts +1 -1
  439. package/src/wirings/virtual-user/virtual-user.types.ts +1 -5
  440. package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +569 -0
  441. package/src/wirings/workflow/graph/graph-foreach.test.ts +626 -0
  442. package/src/wirings/workflow/graph/graph-node.ts +16 -1
  443. package/src/wirings/workflow/graph/graph-runner.ts +387 -61
  444. package/src/wirings/workflow/graph/workflow-graph.types.ts +28 -3
  445. package/src/wirings/workflow/index.ts +8 -0
  446. package/src/wirings/workflow/pikku-scenario-service.ts +83 -20
  447. package/src/wirings/workflow/pikku-workflow-service.ts +37 -35
  448. package/src/wirings/workflow/run-timeline.ts +1 -1
  449. package/src/wirings/workflow/scenario-expectations.test.ts +28 -13
  450. package/src/wirings/workflow/scenario-run.types.ts +186 -0
  451. package/src/wirings/workflow/scenario-step-guards.ts +1 -14
  452. package/src/wirings/workflow/scenario-step.test.ts +32 -7
  453. package/src/wirings/workflow/scenario-step.types.ts +27 -12
  454. package/src/wirings/workflow/workflow-approval-policy.test.ts +117 -47
  455. package/src/wirings/workflow/workflow-approval.ts +2 -1
  456. package/src/wirings/workflow/workflow-run-engine.types.ts +2 -1
  457. package/src/wirings/workflow/workflow-step-claim.ts +46 -0
  458. package/src/wirings/workflow/workflow.types.ts +4 -12
  459. package/src/wirings-stay-decoupled.test.ts +6 -3
  460. package/tsconfig.tsbuildinfo +1 -1
  461. package/tsconfig.type-tests.json +4 -2
  462. package/dist/ecosystem/ai-agent.d.ts +0 -18
  463. package/dist/ecosystem/ai-agent.js +0 -6
  464. package/dist/ecosystem/ai-scorer.d.ts +0 -12
  465. package/dist/ecosystem/ai-scorer.js +0 -5
  466. package/dist/services/ai-agent-runner-service.d.ts +0 -220
  467. package/dist/services/ai-run-state-service.d.ts +0 -29
  468. package/dist/services/ai-storage-service.d.ts +0 -18
  469. package/dist/services/in-memory-ai-run-state-service.d.ts +0 -19
  470. package/dist/services/in-memory-ai-run-state-service.js +0 -54
  471. package/dist/testing/service-tests/ai-storage-service-tests.d.ts +0 -3
  472. package/dist/testing/service-tests/ai-storage-service-tests.js +0 -302
  473. package/dist/wirings/ai-agent/agent-rpc.d.ts +0 -15
  474. package/dist/wirings/ai-agent/agent-rpc.js +0 -53
  475. package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -79
  476. package/dist/wirings/ai-agent/ai-agent-agui.js +0 -327
  477. package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +0 -58
  478. package/dist/wirings/ai-agent/ai-agent-finalize.js +0 -138
  479. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +0 -35
  480. package/dist/wirings/ai-agent/ai-agent-helpers.js +0 -47
  481. package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +0 -153
  482. package/dist/wirings/ai-agent/ai-agent-interrupt.js +0 -257
  483. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +0 -42
  484. package/dist/wirings/ai-agent/ai-agent-memory.js +0 -333
  485. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -16
  486. package/dist/wirings/ai-agent/ai-agent-model-config.js +0 -51
  487. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +0 -117
  488. package/dist/wirings/ai-agent/ai-agent-prepare.js +0 -728
  489. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +0 -16
  490. package/dist/wirings/ai-agent/ai-agent-registry.js +0 -51
  491. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +0 -7
  492. package/dist/wirings/ai-agent/ai-agent-runner.js +0 -580
  493. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +0 -41
  494. package/dist/wirings/ai-agent/ai-agent-stream.js +0 -1029
  495. package/dist/wirings/ai-agent/ai-agent-turn.d.ts +0 -57
  496. package/dist/wirings/ai-agent/ai-agent-turn.js +0 -82
  497. package/dist/wirings/ai-agent/ai-agent-utils.d.ts +0 -1
  498. package/dist/wirings/ai-agent/ai-agent-utils.js +0 -1
  499. package/dist/wirings/ai-agent/ai-agent.types.d.ts +0 -625
  500. package/dist/wirings/ai-agent/index.d.ts +0 -12
  501. package/dist/wirings/ai-agent/index.js +0 -10
  502. package/dist/wirings/ai-agent/voice-input.d.ts +0 -69
  503. package/dist/wirings/ai-agent/voice-input.js +0 -150
  504. package/dist/wirings/ai-agent/voice-output.d.ts +0 -85
  505. package/dist/wirings/ai-agent/voice-output.js +0 -196
  506. package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +0 -26
  507. package/dist/wirings/ai-scorer/ai-scorer-grade.js +0 -33
  508. package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +0 -17
  509. package/dist/wirings/ai-scorer/ai-scorer-judge.js +0 -92
  510. package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +0 -15
  511. package/dist/wirings/ai-scorer/ai-scorer-live.js +0 -38
  512. package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +0 -18
  513. package/dist/wirings/ai-scorer/ai-scorer-registry.js +0 -46
  514. package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +0 -8
  515. package/dist/wirings/ai-scorer/ai-scorer-sampling.js +0 -31
  516. package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +0 -10
  517. package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +0 -40
  518. package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +0 -15
  519. package/dist/wirings/ai-scorer/ai-scorer-worker.js +0 -58
  520. package/dist/wirings/ai-scorer/ai-scorer.d.ts +0 -39
  521. package/dist/wirings/ai-scorer/ai-scorer.js +0 -40
  522. package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +0 -90
  523. package/dist/wirings/ai-scorer/ai-scorer.types.js +0 -4
  524. package/dist/wirings/ai-scorer/index.d.ts +0 -6
  525. package/dist/wirings/ai-scorer/index.js +0 -5
  526. package/src/ecosystem/agent-scorer.ts +0 -24
  527. package/src/ecosystem/agent.ts +0 -42
  528. package/src/ecosystem/channel/local.ts +0 -1
  529. package/src/ecosystem/channel.ts +0 -22
  530. package/src/ecosystem/cli/channel.ts +0 -25
  531. package/src/ecosystem/cli.ts +0 -21
  532. package/src/ecosystem/credential.ts +0 -10
  533. package/src/ecosystem/dev.ts +0 -12
  534. package/src/ecosystem/function.ts +0 -28
  535. package/src/ecosystem/gateway.ts +0 -4
  536. package/src/ecosystem/hmac.ts +0 -1
  537. package/src/ecosystem/http.ts +0 -22
  538. package/src/ecosystem/mcp.ts +0 -17
  539. package/src/ecosystem/middleware.ts +0 -27
  540. package/src/ecosystem/node-host-resolver.ts +0 -1
  541. package/src/ecosystem/node.ts +0 -5
  542. package/src/ecosystem/oauth2.ts +0 -4
  543. package/src/ecosystem/persona.ts +0 -30
  544. package/src/ecosystem/queue.ts +0 -23
  545. package/src/ecosystem/remote.ts +0 -9
  546. package/src/ecosystem/role.ts +0 -13
  547. package/src/ecosystem/rpc.ts +0 -7
  548. package/src/ecosystem/safe-fetch.ts +0 -8
  549. package/src/ecosystem/scenario.ts +0 -32
  550. package/src/ecosystem/scheduler.ts +0 -5
  551. package/src/ecosystem/schema.ts +0 -1
  552. package/src/ecosystem/scope.ts +0 -14
  553. package/src/ecosystem/secret.ts +0 -15
  554. package/src/ecosystem/services/istanbul-coverage.ts +0 -1
  555. package/src/ecosystem/services/local-content-request-handler.ts +0 -16
  556. package/src/ecosystem/services/local-content.ts +0 -1
  557. package/src/ecosystem/services/v8-coverage.ts +0 -1
  558. package/src/ecosystem/services.ts +0 -82
  559. package/src/ecosystem/trigger.ts +0 -7
  560. package/src/ecosystem/types.ts +0 -34
  561. package/src/ecosystem/variable.ts +0 -14
  562. package/src/ecosystem/virtual-user.ts +0 -48
  563. package/src/ecosystem/workflow.ts +0 -68
  564. package/src/ecosystem.ts +0 -40
  565. package/src/index.ts +0 -244
  566. /package/dist/{services/ai-agent-runner-service.js → bootstrap-compat/root.js} +0 -0
  567. /package/dist/{services/ai-run-state-service.js → classification/data-classification.js} +0 -0
  568. /package/dist/{services/ai-storage-service.js → errors/serialized-error.js} +0 -0
  569. /package/dist/{wirings/ai-agent/ai-agent.types.js → function/function-meta.types.js} +0 -0
  570. /package/src/{column-form.ts → classification/column-form.ts} +0 -0
  571. /package/src/{pikku-request.test.ts → function/pikku-request.test.ts} +0 -0
  572. /package/src/{pikku-request.ts → function/pikku-request.ts} +0 -0
  573. /package/src/wirings/{rpc → addon}/addon-auth-tags.test.ts +0 -0
  574. /package/src/wirings/{rpc → addon}/addon-runner.ts +0 -0
  575. /package/src/wirings/{rpc → addon}/addon-secrets.test.ts +0 -0
  576. /package/src/wirings/{rpc → addon}/wire-addon.test.ts +0 -0
  577. /package/src/wirings/{rpc → addon}/wire-remote-addon.ts +0 -0
@@ -14,12 +14,14 @@ import { finalizeAgentRun, lastUserMessageText } from './agent-finalize.js'
14
14
  import { pikkuState, getSingletonServices } from '../../pikku-state.js'
15
15
  import { applyInputMiddleware } from './agent-turn.js'
16
16
  import { AIProviderNotConfiguredError } from '../../errors/errors.js'
17
- import { randomUUID } from './agent-utils.js'
17
+ import { deniedToolResult, randomUUID } from './agent-utils.js'
18
18
  import { SPOKEN_TRANSCRIPT } from './voice-input.js'
19
19
  import {
20
20
  combineChannelMiddleware,
21
21
  wrapChannelWithMiddleware,
22
22
  } from '../channel/channel-middleware-runner.js'
23
+ import type { CorePikkuChannelMiddleware } from '../channel/channel.types.js'
24
+ import type { CoreSingletonServices } from '../../types/core.types.js'
23
25
  import type { AgentStorageService } from '../../services/agent-storage-service.js'
24
26
  import type {
25
27
  AgentRunnerParams,
@@ -300,6 +302,64 @@ async function postStreamCleanup(
300
302
  })
301
303
  }
302
304
 
305
+ /**
306
+ * Adapts `modifyOutputStream` hooks to channel middleware, one closure per
307
+ * hook so each keeps its own `state` and event log for the whole run.
308
+ */
309
+ const toChannelStreamMiddleware = (
310
+ hooks: PikkuAgentMiddlewareHooks[],
311
+ sharedNotes: Record<string, unknown>,
312
+ signal: AbortSignal
313
+ ) =>
314
+ hooks
315
+ .filter((mw) => mw.modifyOutputStream)
316
+ .map((mw) => {
317
+ const state: Record<string, unknown> = {}
318
+ const allEvents: AgentStreamEvent[] = []
319
+ return async (services: any, event: any, next: any) => {
320
+ allEvents.push(event)
321
+ const result = await mw.modifyOutputStream!(services, {
322
+ event,
323
+ allEvents,
324
+ state,
325
+ shared: sharedNotes,
326
+ // Sends downstream directly, so a hook can hand back the fast event
327
+ // now and push the slow one when it is ready.
328
+ emit: next,
329
+ signal,
330
+ })
331
+ if (result == null) return
332
+ if (Array.isArray(result)) {
333
+ for (const r of result) await next(r)
334
+ } else {
335
+ await next(result)
336
+ }
337
+ }
338
+ })
339
+
340
+ /**
341
+ * The branch a delegating parent's own spoken text is routed down once it has
342
+ * handed off: the same working-memory hook instances as the main chain, so the
343
+ * in-band `<working_memory>` blocks are still collected, ending in a sink so
344
+ * neither the client, the thread history, nor user channel middleware sees
345
+ * text the parent was supposed to keep to itself.
346
+ *
347
+ * Routing at ingress rather than dropping further down the chain keeps the
348
+ * decision synchronous with the send: the working-memory hook is async, so a
349
+ * hand-off landing mid-flight would otherwise retroactively suppress text the
350
+ * parent spoke before it.
351
+ */
352
+ const createWorkingMemoryOnlyChannel = (
353
+ channel: AgentStreamChannel,
354
+ services: CoreSingletonServices,
355
+ workingMemoryMiddleware: readonly CorePikkuChannelMiddleware[]
356
+ ): AgentStreamChannel =>
357
+ wrapChannelWithMiddleware(
358
+ { channel: { ...channel, send: () => {} } as AgentStreamChannel },
359
+ services,
360
+ workingMemoryMiddleware
361
+ ).channel as AgentStreamChannel
362
+
303
363
  type StepLoopParams = {
304
364
  agent: CoreAgent
305
365
  runnerParams: AgentRunnerParams
@@ -720,13 +780,18 @@ export async function streamAgent(
720
780
  return ''
721
781
  }
722
782
 
723
- const agentMiddlewares: PikkuAgentMiddlewareHooks[] = [
724
- ...getWorkingMemoryMiddleware(memoryConfig, storage, {
783
+ const workingMemoryMiddleware = getWorkingMemoryMiddleware(
784
+ memoryConfig,
785
+ storage,
786
+ {
725
787
  threadId,
726
788
  workingMemorySchemaName,
727
789
  logger: singletonServices.logger,
728
790
  schemaService: singletonServices.schema,
729
- }),
791
+ }
792
+ )
793
+ const agentMiddlewares: PikkuAgentMiddlewareHooks[] = [
794
+ ...workingMemoryMiddleware,
730
795
  ...(agent.agentMiddleware ?? []),
731
796
  ]
732
797
 
@@ -785,45 +850,36 @@ export async function streamAgent(
785
850
  singletonServices.logger
786
851
  )
787
852
 
788
- const streamMiddleware = agentMiddlewares
789
- .filter((mw) => mw.modifyOutputStream)
790
- .map((mw) => {
791
- const state: Record<string, unknown> = {}
792
- const allEvents: AgentStreamEvent[] = []
793
- return async (services: any, event: any, next: any) => {
794
- allEvents.push(event)
795
- const result = await mw.modifyOutputStream!(services, {
796
- event,
797
- allEvents,
798
- state,
799
- shared: sharedNotes,
800
- // Sends downstream directly, so a hook can hand back the fast event
801
- // now and push the slow one when it is ready.
802
- emit: next,
803
- signal: interruptHandle.signal,
804
- })
805
- if (result == null) return
806
- if (Array.isArray(result)) {
807
- for (const r of result) await next(r)
808
- } else {
809
- await next(result)
810
- }
811
- }
812
- })
853
+ const workingMemoryStreamMiddleware = toChannelStreamMiddleware(
854
+ workingMemoryMiddleware,
855
+ sharedNotes,
856
+ interruptHandle.signal
857
+ )
858
+ const streamMiddleware = toChannelStreamMiddleware(
859
+ agent.agentMiddleware ?? [],
860
+ sharedNotes,
861
+ interruptHandle.signal
862
+ )
813
863
 
814
864
  const agentsMeta = pikkuState(packageName, 'agent', 'agentsMeta')
815
865
  const meta = agentsMeta[resolvedName]
816
- const allChannelMiddleware = combineChannelMiddleware(
817
- 'agent',
818
- `stream:${agentName}`,
819
- {
866
+
867
+ const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length
868
+ const delegateState = { delegated: false }
869
+ if (isDelegateMode) {
870
+ streamContext.delegateState = delegateState
871
+ }
872
+
873
+ const allChannelMiddleware = [
874
+ ...workingMemoryStreamMiddleware,
875
+ ...combineChannelMiddleware('agent', `stream:${agentName}`, {
820
876
  wireInheritedChannelMiddleware: meta?.channelMiddleware,
821
877
  wireChannelMiddleware: [
822
878
  ...(agent.channelMiddleware ?? []),
823
879
  ...streamMiddleware,
824
880
  ],
825
- }
826
- )
881
+ }),
882
+ ]
827
883
 
828
884
  const persistingChannel = createPersistingChannel(
829
885
  channel,
@@ -857,23 +913,27 @@ export async function streamAgent(
857
913
  },
858
914
  }
859
915
 
860
- const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length
861
- const delegateState = { delegated: false }
862
- if (isDelegateMode) {
863
- streamContext.delegateState = delegateState
864
- }
865
- const outputChannel = isDelegateMode
916
+ const workingMemoryOnlyChannel =
917
+ isDelegateMode && workingMemoryStreamMiddleware.length > 0
918
+ ? createWorkingMemoryOnlyChannel(
919
+ channel,
920
+ singletonServices,
921
+ workingMemoryStreamMiddleware
922
+ )
923
+ : undefined
924
+
925
+ const outputChannel: AgentStreamChannel = isDelegateMode
866
926
  ? {
867
927
  ...credentialFilteredChannel,
868
928
  send: (event: AgentStreamEvent) => {
869
929
  if (
870
930
  delegateState.delegated &&
871
931
  (event.type === 'text-delta' || event.type === 'reasoning-delta')
872
- )
873
- return
932
+ ) {
933
+ return workingMemoryOnlyChannel?.send(event)
934
+ }
874
935
  return credentialFilteredChannel.send(event)
875
936
  },
876
- delegateState,
877
937
  }
878
938
  : credentialFilteredChannel
879
939
 
@@ -1099,8 +1159,7 @@ export async function resumeAgent(
1099
1159
  await agentRunState.updateRun(pending.agentRunId, { status: 'failed' })
1100
1160
  }
1101
1161
 
1102
- const denialResult =
1103
- 'The user explicitly declined this action. Inform them that it was declined and do not retry.'
1162
+ const denialResult = deniedToolResult()
1104
1163
 
1105
1164
  if (storage) {
1106
1165
  await storage.saveMessages(run.threadId, [
@@ -1351,13 +1410,18 @@ async function continueAfterToolResult(
1351
1410
 
1352
1411
  const instructions = await buildInstructions(resolvedName, packageName)
1353
1412
 
1354
- const agentMiddlewares: PikkuAgentMiddlewareHooks[] = [
1355
- ...getWorkingMemoryMiddleware(memoryConfig, storage, {
1413
+ const workingMemoryMiddleware = getWorkingMemoryMiddleware(
1414
+ memoryConfig,
1415
+ storage,
1416
+ {
1356
1417
  threadId: run.threadId,
1357
1418
  workingMemorySchemaName,
1358
1419
  logger: singletonServices.logger,
1359
1420
  schemaService: singletonServices.schema,
1360
- }),
1421
+ }
1422
+ )
1423
+ const agentMiddlewares: PikkuAgentMiddlewareHooks[] = [
1424
+ ...workingMemoryMiddleware,
1361
1425
  ...(agent.agentMiddleware ?? []),
1362
1426
  ]
1363
1427
  // One bag per run, shared by every middleware — see PikkuAgentMiddlewareHooks.
@@ -1380,43 +1444,27 @@ async function continueAfterToolResult(
1380
1444
  singletonServices.logger
1381
1445
  )
1382
1446
 
1383
- const streamMiddleware = agentMiddlewares
1384
- .filter((mw) => mw.modifyOutputStream)
1385
- .map((mw) => {
1386
- const state: Record<string, unknown> = {}
1387
- const allEvents: AgentStreamEvent[] = []
1388
- return async (services: any, event: any, next: any) => {
1389
- allEvents.push(event)
1390
- const result = await mw.modifyOutputStream!(services, {
1391
- event,
1392
- allEvents,
1393
- state,
1394
- shared: sharedNotes,
1395
- // Sends downstream directly, so a hook can hand back the fast event
1396
- // now and push the slow one when it is ready.
1397
- emit: next,
1398
- signal: interruptHandle.signal,
1399
- })
1400
- if (result == null) return
1401
- if (Array.isArray(result)) {
1402
- for (const r of result) await next(r)
1403
- } else {
1404
- await next(result)
1405
- }
1406
- }
1407
- })
1447
+ const workingMemoryStreamMiddleware = toChannelStreamMiddleware(
1448
+ workingMemoryMiddleware,
1449
+ sharedNotes,
1450
+ interruptHandle.signal
1451
+ )
1452
+ const streamMiddleware = toChannelStreamMiddleware(
1453
+ agent.agentMiddleware ?? [],
1454
+ sharedNotes,
1455
+ interruptHandle.signal
1456
+ )
1408
1457
 
1409
- const allChannelMiddleware = combineChannelMiddleware(
1410
- 'agent',
1411
- `stream:${run.agentName}`,
1412
- {
1458
+ const allChannelMiddleware = [
1459
+ ...workingMemoryStreamMiddleware,
1460
+ ...combineChannelMiddleware('agent', `stream:${run.agentName}`, {
1413
1461
  wireInheritedChannelMiddleware: meta?.channelMiddleware,
1414
1462
  wireChannelMiddleware: [
1415
1463
  ...(agent.channelMiddleware ?? []),
1416
1464
  ...streamMiddleware,
1417
1465
  ],
1418
- }
1419
- )
1466
+ }),
1467
+ ]
1420
1468
 
1421
1469
  const persistingChannel = createPersistingChannel(
1422
1470
  channel,
@@ -1434,7 +1482,38 @@ async function continueAfterToolResult(
1434
1482
  ).channel as AgentStreamChannel)
1435
1483
  : persistingChannel
1436
1484
 
1485
+ const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length
1486
+ const delegateState = { delegated: false }
1487
+
1437
1488
  const streamContext: StreamContext = { channel, options }
1489
+ if (isDelegateMode) {
1490
+ streamContext.delegateState = delegateState
1491
+ }
1492
+
1493
+ const workingMemoryOnlyChannel =
1494
+ isDelegateMode && workingMemoryStreamMiddleware.length > 0
1495
+ ? createWorkingMemoryOnlyChannel(
1496
+ channel,
1497
+ singletonServices,
1498
+ workingMemoryStreamMiddleware
1499
+ )
1500
+ : undefined
1501
+
1502
+ const outputChannel: AgentStreamChannel = isDelegateMode
1503
+ ? {
1504
+ ...wrappedChannel,
1505
+ send: (event: AgentStreamEvent) => {
1506
+ if (
1507
+ delegateState.delegated &&
1508
+ (event.type === 'text-delta' || event.type === 'reasoning-delta')
1509
+ ) {
1510
+ return workingMemoryOnlyChannel?.send(event)
1511
+ }
1512
+ return wrappedChannel.send(event)
1513
+ },
1514
+ }
1515
+ : wrappedChannel
1516
+
1438
1517
  const resumeTools = (
1439
1518
  await buildToolDefs(
1440
1519
  params,
@@ -1473,7 +1552,7 @@ async function continueAfterToolResult(
1473
1552
  runnerParams,
1474
1553
  maxSteps,
1475
1554
  agentRunner,
1476
- streamChannel: wrappedChannel,
1555
+ streamChannel: outputChannel,
1477
1556
  persistingChannel,
1478
1557
  channel,
1479
1558
  agentMiddlewares,
@@ -1 +1,20 @@
1
1
  export const randomUUID = (): string => globalThis.crypto.randomUUID()
2
+
3
+ /**
4
+ * The tool result stored and streamed when a user denies an approval.
5
+ *
6
+ * Two readers, one string. The model needs the sentence — it has to tell the
7
+ * user the action was declined and not retry it. A client needs to know a
8
+ * denial when it sees one, so it can render the call as denied rather than as
9
+ * a successful call that happened to return prose; that is what `approved`
10
+ * carries, and it is the same flag a client sets optimistically the moment the
11
+ * deny button is clicked. Emitting only the sentence made the two disagree:
12
+ * live the call showed denied, and on any re-render from storage the same call
13
+ * came back green.
14
+ */
15
+ export const deniedToolResult = (): string =>
16
+ JSON.stringify({
17
+ approved: false,
18
+ message:
19
+ 'The user explicitly declined this action. Inform them that it was declined and do not retry.',
20
+ })
@@ -5,8 +5,9 @@ import type {
5
5
  import type {
6
6
  CorePikkuMiddleware,
7
7
  MiddlewareMetadata,
8
- PermissionMetadata,
9
- } from '../../types/core.types.js'
8
+ } from '../../middleware/middleware.types.js'
9
+ import type { CoreSingletonServices } from '../../types/core.types.js'
10
+ import type { PermissionMetadata } from '../../function/function-meta.types.js'
10
11
  import type { AIProviderOptions } from '../../services/agent-runner-service.js'
11
12
  import type { PikkuChannel } from '../channel/channel.types.js'
12
13
  import type { CorePikkuChannelMiddleware } from '../channel/channel.types.js'
@@ -180,10 +181,10 @@ export interface AgentToolDef extends Partial<ApprovalPolicy> {
180
181
 
181
182
  export interface PikkuAgentMiddlewareHooks<
182
183
  State extends Record<string, unknown> = Record<string, unknown>,
183
- Services = any,
184
+ SingletonServices extends CoreSingletonServices = CoreSingletonServices,
184
185
  > {
185
186
  modifyInput?: (
186
- services: Services,
187
+ services: SingletonServices,
187
188
  ctx: {
188
189
  messages: AgentMessage[]
189
190
  instructions: string
@@ -210,7 +211,7 @@ export interface PikkuAgentMiddlewareHooks<
210
211
  | { messages: AgentMessage[]; instructions: string }
211
212
 
212
213
  modifyOutputStream?: (
213
- services: Services,
214
+ services: SingletonServices,
214
215
  ctx: {
215
216
  event: AgentStreamEvent
216
217
  allEvents: readonly AgentStreamEvent[]
@@ -262,7 +263,7 @@ export interface PikkuAgentMiddlewareHooks<
262
263
  * leaves them untouched.
263
264
  */
264
265
  modifyOutput?: (
265
- services: Services,
266
+ services: SingletonServices,
266
267
  ctx: {
267
268
  text: string
268
269
  messages: AgentMessage[]
@@ -282,7 +283,7 @@ export interface PikkuAgentMiddlewareHooks<
282
283
  }
283
284
 
284
285
  beforeToolCall?: (
285
- services: Services,
286
+ services: SingletonServices,
286
287
  ctx: {
287
288
  toolName: string
288
289
  toolCallId: string
@@ -294,7 +295,7 @@ export interface PikkuAgentMiddlewareHooks<
294
295
  | void
295
296
 
296
297
  afterToolCall?: (
297
- services: Services,
298
+ services: SingletonServices,
298
299
  ctx: {
299
300
  toolName: string
300
301
  toolCallId: string
@@ -305,7 +306,7 @@ export interface PikkuAgentMiddlewareHooks<
305
306
  ) => Promise<{ result: unknown } | void> | { result: unknown } | void
306
307
 
307
308
  afterStep?: (
308
- services: Services,
309
+ services: SingletonServices,
309
310
  ctx: {
310
311
  stepNumber: number
311
312
  text: string
@@ -323,7 +324,7 @@ export interface PikkuAgentMiddlewareHooks<
323
324
  ) => Promise<void> | void
324
325
 
325
326
  onError?: (
326
- services: Services,
327
+ services: SingletonServices,
327
328
  ctx: {
328
329
  error: Error
329
330
  stepNumber: number
@@ -423,7 +424,7 @@ export type CoreAgent<
423
424
  * which OR together, a scope can only narrow access.
424
425
  *
425
426
  * Narrowed to the generated `ScopeId` union in a project's own
426
- * `pikku-types.gen.ts`, so an undeclared scope is a compile error.
427
+ * `#pikku/scopes`, so an undeclared scope is a compile error.
427
428
  */
428
429
  scopes?: Scope[]
429
430
  permissions?: CorePermissionGroup<PikkuPermission>
@@ -20,6 +20,7 @@ export {
20
20
  unspeakableScripts,
21
21
  voiceForText,
22
22
  type SpeakableScripts,
23
+ type VoiceOutputState,
23
24
  } from './voice-output.js'
24
25
  export { AgentInterruptedError, signalRunInterrupt } from './agent-interrupt.js'
25
26
  export type {
@@ -1,5 +1,5 @@
1
1
  import type { AgentRunnerService } from '../../services/agent-runner-service.js'
2
- import { pikkuAgentMiddleware } from '../../types/core.types.js'
2
+ import { pikkuAgentMiddleware } from '../../middleware/middleware-factories.js'
3
3
  import { safeFetch } from '../../utils/safe-fetch.js'
4
4
  import type { AgentContentPart } from './agent.types.js'
5
5
 
@@ -233,8 +233,7 @@ describe('voiceOutput', () => {
233
233
 
234
234
  assert.deepEqual(asked, [], 'nothing should have been sent for synthesis')
235
235
  const notice = stream.out.find((event) => event.type === 'data') as
236
- | { name: string; data: { scripts: string[] } }
237
- | undefined
236
+ { name: string; data: { scripts: string[] } } | undefined
238
237
  assert.equal(notice?.name, 'voice-unsupported')
239
238
  assert.deepEqual(notice?.data.scripts, ['arabic'])
240
239
  })
@@ -424,8 +423,7 @@ describe('voiceOutput', () => {
424
423
 
425
424
  assert.deepEqual(asked, [])
426
425
  const notice = stream.out.find((event) => event.type === 'data') as
427
- | { name: string; data: { scripts: string[] } }
428
- | undefined
426
+ { name: string; data: { scripts: string[] } } | undefined
429
427
  assert.deepEqual(notice?.data.scripts, ['arabic'])
430
428
  })
431
429
 
@@ -1,5 +1,5 @@
1
1
  import type { AgentRunnerService } from '../../services/agent-runner-service.js'
2
- import { pikkuAgentMiddleware } from '../../types/core.types.js'
2
+ import { pikkuAgentMiddleware } from '../../middleware/middleware-factories.js'
3
3
  import { SPOKEN_TURN } from './voice-input.js'
4
4
 
5
5
  export type VoiceOutputState = {
@@ -55,6 +55,151 @@ describe('buildJudgePrompt', () => {
55
55
  assert.match(prompt, /Grade helpfulness\./)
56
56
  })
57
57
 
58
+ test('shows which tools ran, so an answer is distinguishable from a guess', () => {
59
+ const scorer = pikkuAgentJudge({
60
+ name: 'helpfulness',
61
+ description: 'Is the answer useful',
62
+ model: 'claude-opus-5',
63
+ goal: 'Grade helpfulness.',
64
+ })
65
+
66
+ const prompt = buildJudgePrompt(
67
+ scorer.judge!,
68
+ input({
69
+ toolCalls: [
70
+ { name: 'listTodos', args: {}, result: { todos: ['Buy groceries'] } },
71
+ ],
72
+ })
73
+ )
74
+
75
+ assert.match(prompt, /Tools the assistant ran:\n- listTodos/)
76
+ })
77
+
78
+ test('the default disclosure sends the judge no arguments and no results', () => {
79
+ const scorer = pikkuAgentJudge({
80
+ name: 'helpfulness',
81
+ description: 'Is the answer useful',
82
+ model: 'claude-opus-5',
83
+ goal: 'Grade helpfulness.',
84
+ })
85
+
86
+ const prompt = buildJudgePrompt(
87
+ scorer.judge!,
88
+ input({
89
+ toolCalls: [
90
+ {
91
+ name: 'lookupCustomer',
92
+ args: { email: 'ada@example.com' },
93
+ result: { address: '12 Mill Lane' },
94
+ },
95
+ ],
96
+ })
97
+ )
98
+
99
+ assert.doesNotMatch(prompt, /ada@example\.com/)
100
+ assert.doesNotMatch(prompt, /Mill Lane/)
101
+ })
102
+
103
+ test('a run that called nothing gets no tool section rather than an empty one', () => {
104
+ const scorer = pikkuAgentJudge({
105
+ name: 'helpfulness',
106
+ description: 'Is the answer useful',
107
+ model: 'claude-opus-5',
108
+ goal: 'Grade helpfulness.',
109
+ })
110
+
111
+ assert.doesNotMatch(buildJudgePrompt(scorer.judge!, input()), /Tools the/)
112
+ })
113
+
114
+ test('a failed call is shown as failed, which is not the same as no call', () => {
115
+ const scorer = pikkuAgentJudge({
116
+ name: 'helpfulness',
117
+ description: 'Is the answer useful',
118
+ model: 'claude-opus-5',
119
+ goal: 'Grade helpfulness.',
120
+ })
121
+
122
+ const prompt = buildJudgePrompt(
123
+ scorer.judge!,
124
+ input({
125
+ toolCalls: [
126
+ {
127
+ name: 'listTodos',
128
+ args: {},
129
+ error: 'no such user ada@example.com',
130
+ },
131
+ ],
132
+ })
133
+ )
134
+
135
+ assert.match(prompt, /- listTodos \(failed\)/)
136
+ assert.doesNotMatch(prompt, /ada@example\.com/)
137
+ })
138
+
139
+ test("'full' shows the arguments and results, for a judge that grades against them", () => {
140
+ const scorer = pikkuAgentJudge({
141
+ name: 'helpfulness',
142
+ description: 'Is the answer useful',
143
+ model: 'claude-opus-5',
144
+ goal: 'Grade helpfulness.',
145
+ toolCalls: 'full',
146
+ })
147
+
148
+ const prompt = buildJudgePrompt(
149
+ scorer.judge!,
150
+ input({
151
+ toolCalls: [
152
+ { name: 'listTodos', args: {}, result: { todos: ['Buy groceries'] } },
153
+ { name: 'save', args: {}, error: 'store unreachable' },
154
+ ],
155
+ })
156
+ )
157
+
158
+ assert.match(
159
+ prompt,
160
+ /listTodos\(\{\}\) returned \{"todos":\["Buy groceries"\]\}/
161
+ )
162
+ assert.match(prompt, /save\(\{\}\) failed: store unreachable/)
163
+ })
164
+
165
+ test("'off' withholds the trajectory entirely, even from a run that used tools", () => {
166
+ const scorer = pikkuAgentJudge({
167
+ name: 'helpfulness',
168
+ description: 'Is the answer useful',
169
+ model: 'claude-opus-5',
170
+ goal: 'Grade helpfulness.',
171
+ toolCalls: 'off',
172
+ })
173
+
174
+ const prompt = buildJudgePrompt(
175
+ scorer.judge!,
176
+ input({ toolCalls: [{ name: 'listTodos', args: {}, result: {} }] })
177
+ )
178
+
179
+ assert.doesNotMatch(prompt, /Tools the/)
180
+ assert.doesNotMatch(prompt, /listTodos/)
181
+ })
182
+
183
+ test('a large tool result is truncated rather than crowding out the answer', () => {
184
+ const scorer = pikkuAgentJudge({
185
+ name: 'helpfulness',
186
+ description: 'Is the answer useful',
187
+ model: 'claude-opus-5',
188
+ goal: 'Grade helpfulness.',
189
+ toolCalls: 'full',
190
+ })
191
+
192
+ const prompt = buildJudgePrompt(
193
+ scorer.judge!,
194
+ input({
195
+ toolCalls: [{ name: 'search', args: {}, result: 'x'.repeat(5000) }],
196
+ })
197
+ )
198
+
199
+ assert.match(prompt, /… \(truncated\)/)
200
+ assert.ok(prompt.length < 1500, `prompt was ${prompt.length} characters`)
201
+ })
202
+
58
203
  test('a scorer that supplies its own prompt replaces the framing entirely', () => {
59
204
  const scorer = pikkuAgentJudge({
60
205
  name: 'custom',