@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
@@ -0,0 +1,120 @@
1
+ import { pikkuState } from '../../pikku-state.js';
2
+ import { getTagGroups } from '../../utils.js';
3
+ export const wireAddon = (config) => {
4
+ pikkuState(null, 'addons', 'packages').set(config.name, {
5
+ package: config.package,
6
+ rpcEndpoint: config.rpcEndpoint,
7
+ auth: config.auth,
8
+ tags: config.tags,
9
+ ...(config.scopes ? { scopes: config.scopes } : {}),
10
+ ...(config.secretOverrides
11
+ ? { secretOverrides: config.secretOverrides }
12
+ : {}),
13
+ ...(config.variableOverrides
14
+ ? { variableOverrides: config.variableOverrides }
15
+ : {}),
16
+ ...(config.credentialOverrides
17
+ ? { credentialOverrides: config.credentialOverrides }
18
+ : {}),
19
+ ...(config.secretGrants ? { secretGrants: config.secretGrants } : {}),
20
+ ...(config.credentialGrants
21
+ ? { credentialGrants: config.credentialGrants }
22
+ : {}),
23
+ ...(config.globalSecrets ? { globalSecrets: config.globalSecrets } : {}),
24
+ ...(config.globalCredentials
25
+ ? { globalCredentials: config.globalCredentials }
26
+ : {}),
27
+ });
28
+ };
29
+ /**
30
+ * The addon configs a running function is governed by: the named instance when
31
+ * the caller resolved one, every instance of the package otherwise.
32
+ *
33
+ * knowledge: decisions/security/addon-scopes-are-resolved-where-the-function-runs.md
34
+ */
35
+ const governingAddonConfigs = (packageName, namespace) => {
36
+ if (!packageName) {
37
+ return [];
38
+ }
39
+ const addons = pikkuState(null, 'addons', 'packages');
40
+ if (!addons) {
41
+ return [];
42
+ }
43
+ if (namespace) {
44
+ const config = addons.get(namespace);
45
+ if (config?.package === packageName) {
46
+ return [config];
47
+ }
48
+ }
49
+ return [...addons.values()].filter((config) => config?.package === packageName);
50
+ };
51
+ const unionOf = (packageName, namespace, field) => {
52
+ const values = new Set();
53
+ for (const config of governingAddonConfigs(packageName, namespace)) {
54
+ for (const value of config[field] ?? []) {
55
+ values.add(value);
56
+ }
57
+ }
58
+ return [...values];
59
+ };
60
+ /**
61
+ * knowledge: decisions/security/addon-scopes-are-resolved-where-the-function-runs.md
62
+ */
63
+ export const resolveAddonScopes = (packageName, namespace) => unionOf(packageName, namespace, 'scopes');
64
+ /**
65
+ * knowledge: decisions/security/addon-auth-and-tags-only-tighten.md
66
+ */
67
+ export const resolveAddonTags = (packageName, namespace) => unionOf(packageName, namespace, 'tags');
68
+ /**
69
+ * True when any governing instance requires a session. `auth: false` is not
70
+ * honoured here — on a direct wiring it would weaken the wiring's own gate.
71
+ *
72
+ * knowledge: decisions/security/addon-auth-and-tags-only-tighten.md
73
+ */
74
+ export const resolveAddonAuth = (packageName, namespace) => governingAddonConfigs(packageName, namespace).some((config) => config.auth === true);
75
+ /**
76
+ * The package a namespaced function id belongs to, and the name that package
77
+ * publishes it under.
78
+ *
79
+ * A wiring that points at an addon function through `ref('ns:fn')` records
80
+ * `ns:fn` as its own function id — the same id every other wire type records —
81
+ * but the addon publishes its metadata under the bare `fn`, in its own package
82
+ * state. Without this the wire finds the function it registered and no metadata
83
+ * to run it by.
84
+ *
85
+ * The wiring itself stays the consuming app's, so `packageName` is the package
86
+ * the *wire* runs in, not the target's: it is null for a `ref()` the app wired,
87
+ * and only narrows the lookup when a wire really does run inside the addon.
88
+ */
89
+ export const resolveAddonFunctionTarget = (funcName, packageName) => {
90
+ const separator = funcName.indexOf(':');
91
+ if (separator === -1) {
92
+ return null;
93
+ }
94
+ const namespace = funcName.slice(0, separator);
95
+ const config = pikkuState(null, 'addons', 'packages').get(namespace);
96
+ if (!config) {
97
+ return null;
98
+ }
99
+ if (packageName && config.package !== packageName) {
100
+ return null;
101
+ }
102
+ return {
103
+ packageName: config.package,
104
+ localName: funcName.slice(separator + 1),
105
+ };
106
+ };
107
+ /**
108
+ * Addon tags name middleware the *consuming app* registered, so they resolve
109
+ * against the root tag groups rather than the addon package's own.
110
+ *
111
+ * knowledge: decisions/security/addon-auth-and-tags-only-tighten.md
112
+ */
113
+ export const resolveAddonTagMiddleware = (packageName, namespace) => {
114
+ const tags = resolveAddonTags(packageName, namespace);
115
+ if (tags.length === 0) {
116
+ return [];
117
+ }
118
+ const tagGroups = pikkuState(null, 'middleware', 'tagGroup');
119
+ return tags.flatMap((tag) => getTagGroups(tagGroups, tag).flat());
120
+ };
@@ -0,0 +1,22 @@
1
+ import type { CoreServices, PikkuWire } from '../../types/core.types.js';
2
+ /** Sent as `Authorization: Bearer <token>`; a non-default header is declared by the addon. */
3
+ export type RemoteAddonAuth = {
4
+ credentialId: string;
5
+ } | {
6
+ secretId: string;
7
+ } | {
8
+ resolve: (services: CoreServices, wire: PikkuWire) => string | Promise<string>;
9
+ };
10
+ export type WireRemoteAddonConfig = {
11
+ /** Consumer-facing namespace, e.g. `registry` → `rpc('registry:getOpenApi')` */
12
+ name: string;
13
+ /** Must be installed as a devDependency — `pikku verify` enforces this. */
14
+ package: string;
15
+ serverUrl: string | ((services: CoreServices) => string | Promise<string>);
16
+ /** Omit when the addon declares its remote surface public. */
17
+ auth?: RemoteAddonAuth;
18
+ /** Map a consumer-facing fn name → the remote fn name, when they differ (rare). */
19
+ remoteName?: (fn: string) => string;
20
+ tags?: string[];
21
+ };
22
+ export declare const wireRemoteAddon: (config: WireRemoteAddonConfig) => void;
@@ -0,0 +1,11 @@
1
+ import { pikkuState } from '../../pikku-state.js';
2
+ export const wireRemoteAddon = (config) => {
3
+ pikkuState(null, 'addons', 'packages').set(config.name, {
4
+ package: config.package,
5
+ tags: config.tags,
6
+ remote: true,
7
+ serverUrl: config.serverUrl,
8
+ ...(config.auth ? { remoteAuth: config.auth } : {}),
9
+ ...(config.remoteName ? { remoteName: config.remoteName } : {}),
10
+ });
11
+ };
@@ -8,6 +8,17 @@ export declare function resolveMemoryServices(agent: CoreAgent, singletonService
8
8
  storage: AgentStorageService | undefined;
9
9
  };
10
10
  export declare function isWorkingMemoryEnabled(memoryConfig: AgentMemoryConfig | undefined, storage: AgentStorageService | undefined): boolean;
11
+ /**
12
+ * Merges a model-emitted working memory update into the stored state.
13
+ *
14
+ * Objects merge key by key, and `null` deletes a key. Arrays are replaced
15
+ * wholesale — deliberately, not as a side effect of the object guard below.
16
+ * The full state is echoed back to the model every turn by
17
+ * {@link buildWorkingMemoryPrompt}, so it can always re-emit an array in full,
18
+ * and appending instead would duplicate every item each time it did.
19
+ * `buildWorkingMemoryPrompt` states this contract to the model; the two must
20
+ * stay in agreement.
21
+ */
11
22
  export declare function deepMergeWorkingMemory(existing: Record<string, unknown>, updates: Record<string, unknown>): Record<string, unknown>;
12
23
  export declare function buildWorkingMemoryPrompt(currentState: Record<string, unknown> | null, jsonSchema?: Record<string, unknown>): string;
13
24
  export declare function loadContextMessages(memoryConfig: AgentMemoryConfig | undefined, storage: AgentStorageService | undefined, input: AgentInput, workingMemoryJsonSchema?: Record<string, unknown>): Promise<AgentMessage[]>;
@@ -11,6 +11,17 @@ export function resolveMemoryServices(agent, singletonServices) {
11
11
  export function isWorkingMemoryEnabled(memoryConfig, storage) {
12
12
  return !!memoryConfig?.workingMemory && !!storage;
13
13
  }
14
+ /**
15
+ * Merges a model-emitted working memory update into the stored state.
16
+ *
17
+ * Objects merge key by key, and `null` deletes a key. Arrays are replaced
18
+ * wholesale — deliberately, not as a side effect of the object guard below.
19
+ * The full state is echoed back to the model every turn by
20
+ * {@link buildWorkingMemoryPrompt}, so it can always re-emit an array in full,
21
+ * and appending instead would duplicate every item each time it did.
22
+ * `buildWorkingMemoryPrompt` states this contract to the model; the two must
23
+ * stay in agreement.
24
+ */
14
25
  export function deepMergeWorkingMemory(existing, updates) {
15
26
  const result = { ...existing };
16
27
  for (const key of Object.keys(updates)) {
@@ -21,8 +32,10 @@ export function deepMergeWorkingMemory(existing, updates) {
21
32
  if (value === null) {
22
33
  delete result[key];
23
34
  }
35
+ else if (Array.isArray(value)) {
36
+ result[key] = value;
37
+ }
24
38
  else if (typeof value === 'object' &&
25
- !Array.isArray(value) &&
26
39
  typeof result[key] === 'object' &&
27
40
  result[key] !== null &&
28
41
  !Array.isArray(result[key])) {
@@ -56,7 +69,9 @@ export function buildWorkingMemoryPrompt(currentState, jsonSchema) {
56
69
  parts.push('When you learn new information, output a partial JSON update in <working_memory> tags. ' +
57
70
  'Only include durable facts you have actually derived or the user has confirmed. ' +
58
71
  'Do not output templates, placeholders, or narration. ' +
59
- 'Only include changed fields. Leave unknown fields untouched. Set a field to null to delete it.');
72
+ 'Only include changed fields. Leave unknown fields untouched. Set a field to null to delete it. ' +
73
+ 'Arrays are replaced, not merged: to change one, repeat every item you want to keep alongside the new ones, ' +
74
+ 'because any item you leave out is deleted.');
60
75
  return parts.join('\n\n');
61
76
  }
62
77
  export async function loadContextMessages(memoryConfig, storage, input, workingMemoryJsonSchema) {
@@ -1,4 +1,4 @@
1
- import type { CoreUserSession } from '../../types/core.types.js';
1
+ import type { CoreUserSession, GetCredential } from '../../types/core.types.js';
2
2
  import type { CoreAgent, AgentInput, AgentToolDef, AgentMessage, AgentStreamChannel, PikkuAgentMiddlewareHooks, SessionScope } from './agent.types.js';
3
3
  import type { AgentRunnerParams } from '../../services/agent-runner-service.js';
4
4
  import { PikkuError } from '../../errors/error-handler.js';
@@ -6,7 +6,7 @@ import type { SessionService } from '../../services/user-session-service.js';
6
6
  export type RunAgentParams = {
7
7
  sessionService?: SessionService<CoreUserSession>;
8
8
  /** Credential accessor for the current request — used to read per-user overrides (e.g. AI_API_KEY). */
9
- getCredential?: <T = unknown>(name: string) => T | null | Promise<T | null>;
9
+ getCredential?: GetCredential;
10
10
  /** Ephemeral owner identity minted for a sessionless request; never client-supplied, never reused across requests. */
11
11
  anonymousOwnerResourceId?: string;
12
12
  };
@@ -105,7 +105,7 @@ export declare function prepareAgentRun(agentName: string, input: AgentInput, pa
105
105
  packageName: string | null;
106
106
  resolvedName: string;
107
107
  agentRunner: import("../../services/agent-runner-service.js").AgentRunnerService;
108
- storage: import("../../index.js").AgentStorageService | undefined;
108
+ storage: import("../../services/agent-storage-service.js").AgentStorageService | undefined;
109
109
  memoryConfig: import("./agent.types.js").AgentMemoryConfig | undefined;
110
110
  threadId: string;
111
111
  userMessage: AgentMessage;
@@ -10,7 +10,7 @@ import { awaitPendingInterruptNote } from './agent-interrupt.js';
10
10
  import { streamAgent } from './agent-stream.js';
11
11
  import { runAgent } from './agent-runner.js';
12
12
  import { resolveNamespace, ContextAwareRPCService, } from '../../wirings/rpc/rpc-runner.js';
13
- import { getOrCreatePackageSingletonServices } from '../../wirings/rpc/addon-runner.js';
13
+ import { getOrCreatePackageSingletonServices } from '../../wirings/addon/addon-runner.js';
14
14
  import { resolveMemoryServices, loadContextMessages, trimMessages, } from './agent-memory.js';
15
15
  import { resolveModelConfig } from './agent-model-config.js';
16
16
  export function resolveSessionPrincipal(params, sessionScope) {
@@ -7,7 +7,7 @@ import { applyInputMiddleware, describeApprovals, notifyAfterStep, toAccumulated
7
7
  import { applyOutputMiddleware, finalizeAgentRun, lastUserMessageText, } from './agent-finalize.js';
8
8
  import { resolveModelConfig } from './agent-model-config.js';
9
9
  import { AIProviderNotConfiguredError } from '../../errors/errors.js';
10
- import { randomUUID } from './agent-utils.js';
10
+ import { deniedToolResult, randomUUID } from './agent-utils.js';
11
11
  function stripNulls(obj) {
12
12
  if (obj === null)
13
13
  return undefined;
@@ -306,8 +306,7 @@ export async function resumeAgentSync(runId, approvals, params, expectedAgentNam
306
306
  let resultStr;
307
307
  let toolError;
308
308
  if (rejectedIds.has(toolCallId)) {
309
- resultStr =
310
- 'The user explicitly declined this action. Inform them that it was declined and do not retry.';
309
+ resultStr = deniedToolResult();
311
310
  }
312
311
  else if (approvedIds.has(toolCallId)) {
313
312
  const matchingTool = tools.find((t) => t.name === pending.toolName);
@@ -2,7 +2,7 @@ import { finalizeAgentRun, lastUserMessageText } from './agent-finalize.js';
2
2
  import { pikkuState, getSingletonServices } from '../../pikku-state.js';
3
3
  import { applyInputMiddleware } from './agent-turn.js';
4
4
  import { AIProviderNotConfiguredError } from '../../errors/errors.js';
5
- import { randomUUID } from './agent-utils.js';
5
+ import { deniedToolResult, randomUUID } from './agent-utils.js';
6
6
  import { SPOKEN_TRANSCRIPT } from './voice-input.js';
7
7
  import { combineChannelMiddleware, wrapChannelWithMiddleware, } from '../channel/channel-middleware-runner.js';
8
8
  import { resolveMemoryServices, loadContextMessages, trimMessages, getWorkingMemoryMiddleware, } from './agent-memory.js';
@@ -203,6 +203,51 @@ async function postStreamCleanup(persistingChannel, agentRunState, runId, run) {
203
203
  usage: persistingChannel.totalUsage,
204
204
  });
205
205
  }
206
+ /**
207
+ * Adapts `modifyOutputStream` hooks to channel middleware, one closure per
208
+ * hook so each keeps its own `state` and event log for the whole run.
209
+ */
210
+ const toChannelStreamMiddleware = (hooks, sharedNotes, signal) => hooks
211
+ .filter((mw) => mw.modifyOutputStream)
212
+ .map((mw) => {
213
+ const state = {};
214
+ const allEvents = [];
215
+ return async (services, event, next) => {
216
+ allEvents.push(event);
217
+ const result = await mw.modifyOutputStream(services, {
218
+ event,
219
+ allEvents,
220
+ state,
221
+ shared: sharedNotes,
222
+ // Sends downstream directly, so a hook can hand back the fast event
223
+ // now and push the slow one when it is ready.
224
+ emit: next,
225
+ signal,
226
+ });
227
+ if (result == null)
228
+ return;
229
+ if (Array.isArray(result)) {
230
+ for (const r of result)
231
+ await next(r);
232
+ }
233
+ else {
234
+ await next(result);
235
+ }
236
+ };
237
+ });
238
+ /**
239
+ * The branch a delegating parent's own spoken text is routed down once it has
240
+ * handed off: the same working-memory hook instances as the main chain, so the
241
+ * in-band `<working_memory>` blocks are still collected, ending in a sink so
242
+ * neither the client, the thread history, nor user channel middleware sees
243
+ * text the parent was supposed to keep to itself.
244
+ *
245
+ * Routing at ingress rather than dropping further down the chain keeps the
246
+ * decision synchronous with the send: the working-memory hook is async, so a
247
+ * hand-off landing mid-flight would otherwise retroactively suppress text the
248
+ * parent spoke before it.
249
+ */
250
+ const createWorkingMemoryOnlyChannel = (channel, services, workingMemoryMiddleware) => wrapChannelWithMiddleware({ channel: { ...channel, send: () => { } } }, services, workingMemoryMiddleware).channel;
206
251
  async function runStreamStepLoop(params) {
207
252
  const { agent, runnerParams, maxSteps, agentRunner, streamChannel, channel, agentMiddlewares, } = params;
208
253
  const singletonServices = getSingletonServices();
@@ -446,13 +491,14 @@ export async function streamAgent(agentName, input, channel, params, agentSessio
446
491
  channel.send({ type: 'done' });
447
492
  return '';
448
493
  }
494
+ const workingMemoryMiddleware = getWorkingMemoryMiddleware(memoryConfig, storage, {
495
+ threadId,
496
+ workingMemorySchemaName,
497
+ logger: singletonServices.logger,
498
+ schemaService: singletonServices.schema,
499
+ });
449
500
  const agentMiddlewares = [
450
- ...getWorkingMemoryMiddleware(memoryConfig, storage, {
451
- threadId,
452
- workingMemorySchemaName,
453
- logger: singletonServices.logger,
454
- schemaService: singletonServices.schema,
455
- }),
501
+ ...workingMemoryMiddleware,
456
502
  ...(agent.agentMiddleware ?? []),
457
503
  ];
458
504
  // One bag per run, shared by every middleware — see PikkuAgentMiddlewareHooks.
@@ -491,43 +537,25 @@ export async function streamAgent(agentName, input, channel, params, agentSessio
491
537
  await storage.saveMessages(threadId, [persistedUserMessage]);
492
538
  }
493
539
  warnUnstreamedOutputHooks(agentName, agentMiddlewares, singletonServices.logger);
494
- const streamMiddleware = agentMiddlewares
495
- .filter((mw) => mw.modifyOutputStream)
496
- .map((mw) => {
497
- const state = {};
498
- const allEvents = [];
499
- return async (services, event, next) => {
500
- allEvents.push(event);
501
- const result = await mw.modifyOutputStream(services, {
502
- event,
503
- allEvents,
504
- state,
505
- shared: sharedNotes,
506
- // Sends downstream directly, so a hook can hand back the fast event
507
- // now and push the slow one when it is ready.
508
- emit: next,
509
- signal: interruptHandle.signal,
510
- });
511
- if (result == null)
512
- return;
513
- if (Array.isArray(result)) {
514
- for (const r of result)
515
- await next(r);
516
- }
517
- else {
518
- await next(result);
519
- }
520
- };
521
- });
540
+ const workingMemoryStreamMiddleware = toChannelStreamMiddleware(workingMemoryMiddleware, sharedNotes, interruptHandle.signal);
541
+ const streamMiddleware = toChannelStreamMiddleware(agent.agentMiddleware ?? [], sharedNotes, interruptHandle.signal);
522
542
  const agentsMeta = pikkuState(packageName, 'agent', 'agentsMeta');
523
543
  const meta = agentsMeta[resolvedName];
524
- const allChannelMiddleware = combineChannelMiddleware('agent', `stream:${agentName}`, {
525
- wireInheritedChannelMiddleware: meta?.channelMiddleware,
526
- wireChannelMiddleware: [
527
- ...(agent.channelMiddleware ?? []),
528
- ...streamMiddleware,
529
- ],
530
- });
544
+ const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length;
545
+ const delegateState = { delegated: false };
546
+ if (isDelegateMode) {
547
+ streamContext.delegateState = delegateState;
548
+ }
549
+ const allChannelMiddleware = [
550
+ ...workingMemoryStreamMiddleware,
551
+ ...combineChannelMiddleware('agent', `stream:${agentName}`, {
552
+ wireInheritedChannelMiddleware: meta?.channelMiddleware,
553
+ wireChannelMiddleware: [
554
+ ...(agent.channelMiddleware ?? []),
555
+ ...streamMiddleware,
556
+ ],
557
+ }),
558
+ ];
531
559
  const persistingChannel = createPersistingChannel(channel, storage, threadId, singletonServices.logger);
532
560
  const wrappedChannel = allChannelMiddleware.length > 0
533
561
  ? wrapChannelWithMiddleware({ channel: persistingChannel }, singletonServices, allChannelMiddleware).channel
@@ -545,21 +573,19 @@ export async function streamAgent(agentName, input, channel, params, agentSessio
545
573
  return wrappedChannel.send(event);
546
574
  },
547
575
  };
548
- const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length;
549
- const delegateState = { delegated: false };
550
- if (isDelegateMode) {
551
- streamContext.delegateState = delegateState;
552
- }
576
+ const workingMemoryOnlyChannel = isDelegateMode && workingMemoryStreamMiddleware.length > 0
577
+ ? createWorkingMemoryOnlyChannel(channel, singletonServices, workingMemoryStreamMiddleware)
578
+ : undefined;
553
579
  const outputChannel = isDelegateMode
554
580
  ? {
555
581
  ...credentialFilteredChannel,
556
582
  send: (event) => {
557
583
  if (delegateState.delegated &&
558
- (event.type === 'text-delta' || event.type === 'reasoning-delta'))
559
- return;
584
+ (event.type === 'text-delta' || event.type === 'reasoning-delta')) {
585
+ return workingMemoryOnlyChannel?.send(event);
586
+ }
560
587
  return credentialFilteredChannel.send(event);
561
588
  },
562
- delegateState,
563
589
  }
564
590
  : credentialFilteredChannel;
565
591
  try {
@@ -717,7 +743,7 @@ export async function resumeAgent(input, channel, params, options) {
717
743
  if (pending.type === 'agent-call') {
718
744
  await agentRunState.updateRun(pending.agentRunId, { status: 'failed' });
719
745
  }
720
- const denialResult = 'The user explicitly declined this action. Inform them that it was declined and do not retry.';
746
+ const denialResult = deniedToolResult();
721
747
  if (storage) {
722
748
  await storage.saveMessages(run.threadId, [
723
749
  {
@@ -880,13 +906,14 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
880
906
  const allMessages = [...contextMessages, ...messages];
881
907
  const trimmedMessages = trimMessages(allMessages);
882
908
  const instructions = await buildInstructions(resolvedName, packageName);
909
+ const workingMemoryMiddleware = getWorkingMemoryMiddleware(memoryConfig, storage, {
910
+ threadId: run.threadId,
911
+ workingMemorySchemaName,
912
+ logger: singletonServices.logger,
913
+ schemaService: singletonServices.schema,
914
+ });
883
915
  const agentMiddlewares = [
884
- ...getWorkingMemoryMiddleware(memoryConfig, storage, {
885
- threadId: run.threadId,
886
- workingMemorySchemaName,
887
- logger: singletonServices.logger,
888
- schemaService: singletonServices.schema,
889
- }),
916
+ ...workingMemoryMiddleware,
890
917
  ...(agent.agentMiddleware ?? []),
891
918
  ];
892
919
  // One bag per run, shared by every middleware — see PikkuAgentMiddlewareHooks.
@@ -895,46 +922,43 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
895
922
  // knowledge: decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md
896
923
  const interruptHandle = registerInterruptibleRun(run.runId);
897
924
  warnUnstreamedOutputHooks(run.agentName, agentMiddlewares, singletonServices.logger);
898
- const streamMiddleware = agentMiddlewares
899
- .filter((mw) => mw.modifyOutputStream)
900
- .map((mw) => {
901
- const state = {};
902
- const allEvents = [];
903
- return async (services, event, next) => {
904
- allEvents.push(event);
905
- const result = await mw.modifyOutputStream(services, {
906
- event,
907
- allEvents,
908
- state,
909
- shared: sharedNotes,
910
- // Sends downstream directly, so a hook can hand back the fast event
911
- // now and push the slow one when it is ready.
912
- emit: next,
913
- signal: interruptHandle.signal,
914
- });
915
- if (result == null)
916
- return;
917
- if (Array.isArray(result)) {
918
- for (const r of result)
919
- await next(r);
920
- }
921
- else {
922
- await next(result);
923
- }
924
- };
925
- });
926
- const allChannelMiddleware = combineChannelMiddleware('agent', `stream:${run.agentName}`, {
927
- wireInheritedChannelMiddleware: meta?.channelMiddleware,
928
- wireChannelMiddleware: [
929
- ...(agent.channelMiddleware ?? []),
930
- ...streamMiddleware,
931
- ],
932
- });
925
+ const workingMemoryStreamMiddleware = toChannelStreamMiddleware(workingMemoryMiddleware, sharedNotes, interruptHandle.signal);
926
+ const streamMiddleware = toChannelStreamMiddleware(agent.agentMiddleware ?? [], sharedNotes, interruptHandle.signal);
927
+ const allChannelMiddleware = [
928
+ ...workingMemoryStreamMiddleware,
929
+ ...combineChannelMiddleware('agent', `stream:${run.agentName}`, {
930
+ wireInheritedChannelMiddleware: meta?.channelMiddleware,
931
+ wireChannelMiddleware: [
932
+ ...(agent.channelMiddleware ?? []),
933
+ ...streamMiddleware,
934
+ ],
935
+ }),
936
+ ];
933
937
  const persistingChannel = createPersistingChannel(channel, storage, run.threadId, singletonServices.logger);
934
938
  const wrappedChannel = allChannelMiddleware.length > 0
935
939
  ? wrapChannelWithMiddleware({ channel: persistingChannel }, singletonServices, allChannelMiddleware).channel
936
940
  : persistingChannel;
941
+ const isDelegateMode = agent.agentMode !== 'supervise' && meta?.agents?.length;
942
+ const delegateState = { delegated: false };
937
943
  const streamContext = { channel, options };
944
+ if (isDelegateMode) {
945
+ streamContext.delegateState = delegateState;
946
+ }
947
+ const workingMemoryOnlyChannel = isDelegateMode && workingMemoryStreamMiddleware.length > 0
948
+ ? createWorkingMemoryOnlyChannel(channel, singletonServices, workingMemoryStreamMiddleware)
949
+ : undefined;
950
+ const outputChannel = isDelegateMode
951
+ ? {
952
+ ...wrappedChannel,
953
+ send: (event) => {
954
+ if (delegateState.delegated &&
955
+ (event.type === 'text-delta' || event.type === 'reasoning-delta')) {
956
+ return workingMemoryOnlyChannel?.send(event);
957
+ }
958
+ return wrappedChannel.send(event);
959
+ },
960
+ }
961
+ : wrappedChannel;
938
962
  const resumeTools = (await buildToolDefs(params, new Map(), run.resourceId, resolvedName, packageName, streamContext, agentMiddlewares)).tools;
939
963
  const resolved = resolveModelConfig(resolvedName, agent);
940
964
  const maxSteps = resolved.maxSteps ?? 10;
@@ -959,7 +983,7 @@ async function continueAfterToolResult(run, agent, packageName, resolvedName, st
959
983
  runnerParams,
960
984
  maxSteps,
961
985
  agentRunner,
962
- streamChannel: wrappedChannel,
986
+ streamChannel: outputChannel,
963
987
  persistingChannel,
964
988
  channel,
965
989
  agentMiddlewares,
@@ -1 +1,14 @@
1
1
  export declare const randomUUID: () => string;
2
+ /**
3
+ * The tool result stored and streamed when a user denies an approval.
4
+ *
5
+ * Two readers, one string. The model needs the sentence — it has to tell the
6
+ * user the action was declined and not retry it. A client needs to know a
7
+ * denial when it sees one, so it can render the call as denied rather than as
8
+ * a successful call that happened to return prose; that is what `approved`
9
+ * carries, and it is the same flag a client sets optimistically the moment the
10
+ * deny button is clicked. Emitting only the sentence made the two disagree:
11
+ * live the call showed denied, and on any re-render from storage the same call
12
+ * came back green.
13
+ */
14
+ export declare const deniedToolResult: () => string;
@@ -1 +1,17 @@
1
1
  export const randomUUID = () => globalThis.crypto.randomUUID();
2
+ /**
3
+ * The tool result stored and streamed when a user denies an approval.
4
+ *
5
+ * Two readers, one string. The model needs the sentence — it has to tell the
6
+ * user the action was declined and not retry it. A client needs to know a
7
+ * denial when it sees one, so it can render the call as denied rather than as
8
+ * a successful call that happened to return prose; that is what `approved`
9
+ * carries, and it is the same flag a client sets optimistically the moment the
10
+ * deny button is clicked. Emitting only the sentence made the two disagree:
11
+ * live the call showed denied, and on any re-render from storage the same call
12
+ * came back green.
13
+ */
14
+ export const deniedToolResult = () => JSON.stringify({
15
+ approved: false,
16
+ message: 'The user explicitly declined this action. Inform them that it was declined and do not retry.',
17
+ });