@pikku/core 0.12.83 → 0.12.84

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 (343) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +1 -1
  3. package/dist/ecosystem/agent-scorer.d.ts +12 -0
  4. package/dist/ecosystem/agent-scorer.js +5 -0
  5. package/dist/ecosystem/agent.d.ts +18 -0
  6. package/dist/ecosystem/agent.js +6 -0
  7. package/dist/ecosystem/ai-agent.d.ts +18 -0
  8. package/dist/ecosystem/ai-agent.js +6 -0
  9. package/dist/ecosystem/ai-scorer.d.ts +12 -0
  10. package/dist/ecosystem/ai-scorer.js +5 -0
  11. package/dist/ecosystem/channel/local.d.ts +1 -0
  12. package/dist/ecosystem/channel/local.js +1 -0
  13. package/dist/ecosystem/channel.d.ts +12 -0
  14. package/dist/ecosystem/channel.js +4 -0
  15. package/dist/ecosystem/cli/channel.d.ts +16 -0
  16. package/dist/ecosystem/cli/channel.js +2 -0
  17. package/dist/ecosystem/cli.d.ts +9 -0
  18. package/dist/ecosystem/cli.js +2 -0
  19. package/dist/ecosystem/credential.d.ts +9 -0
  20. package/dist/ecosystem/credential.js +1 -0
  21. package/dist/ecosystem/dev.d.ts +8 -0
  22. package/dist/ecosystem/dev.js +1 -0
  23. package/dist/ecosystem/function.d.ts +13 -0
  24. package/dist/ecosystem/function.js +2 -0
  25. package/dist/ecosystem/gateway.d.ts +1 -0
  26. package/dist/ecosystem/gateway.js +1 -0
  27. package/dist/ecosystem/hmac.d.ts +1 -0
  28. package/dist/ecosystem/hmac.js +1 -0
  29. package/dist/ecosystem/http.d.ts +11 -0
  30. package/dist/ecosystem/http.js +3 -0
  31. package/dist/ecosystem/mcp.d.ts +3 -0
  32. package/dist/ecosystem/mcp.js +2 -0
  33. package/dist/ecosystem/middleware.d.ts +17 -0
  34. package/dist/ecosystem/middleware.js +6 -0
  35. package/dist/ecosystem/node-host-resolver.d.ts +1 -0
  36. package/dist/ecosystem/node-host-resolver.js +1 -0
  37. package/dist/ecosystem/node.d.ts +1 -0
  38. package/dist/ecosystem/node.js +1 -0
  39. package/dist/ecosystem/oauth2.d.ts +1 -0
  40. package/dist/ecosystem/oauth2.js +1 -0
  41. package/dist/ecosystem/persona.d.ts +15 -0
  42. package/dist/ecosystem/persona.js +4 -0
  43. package/dist/ecosystem/queue.d.ts +11 -0
  44. package/dist/ecosystem/queue.js +2 -0
  45. package/dist/ecosystem/remote.d.ts +8 -0
  46. package/dist/ecosystem/remote.js +1 -0
  47. package/dist/ecosystem/role.d.ts +3 -0
  48. package/dist/ecosystem/role.js +2 -0
  49. package/dist/ecosystem/rpc.d.ts +4 -0
  50. package/dist/ecosystem/rpc.js +2 -0
  51. package/dist/ecosystem/safe-fetch.d.ts +7 -0
  52. package/dist/ecosystem/safe-fetch.js +1 -0
  53. package/dist/ecosystem/scenario.d.ts +15 -0
  54. package/dist/ecosystem/scenario.js +4 -0
  55. package/dist/ecosystem/scheduler.d.ts +2 -0
  56. package/dist/ecosystem/scheduler.js +1 -0
  57. package/dist/ecosystem/schema.d.ts +1 -0
  58. package/dist/ecosystem/schema.js +1 -0
  59. package/dist/ecosystem/scope.d.ts +3 -0
  60. package/dist/ecosystem/scope.js +2 -0
  61. package/dist/ecosystem/secret.d.ts +9 -0
  62. package/dist/ecosystem/secret.js +1 -0
  63. package/dist/ecosystem/services/istanbul-coverage.d.ts +1 -0
  64. package/dist/ecosystem/services/istanbul-coverage.js +1 -0
  65. package/dist/ecosystem/services/local-content-request-handler.d.ts +9 -0
  66. package/dist/ecosystem/services/local-content-request-handler.js +1 -0
  67. package/dist/ecosystem/services/local-content.d.ts +1 -0
  68. package/dist/ecosystem/services/local-content.js +1 -0
  69. package/dist/ecosystem/services/v8-coverage.d.ts +1 -0
  70. package/dist/ecosystem/services/v8-coverage.js +1 -0
  71. package/dist/ecosystem/services.d.ts +28 -0
  72. package/dist/ecosystem/services.js +6 -0
  73. package/dist/ecosystem/testing.d.ts +7 -0
  74. package/dist/ecosystem/testing.js +1 -0
  75. package/dist/ecosystem/trigger.d.ts +1 -0
  76. package/dist/ecosystem/trigger.js +1 -0
  77. package/dist/ecosystem/types.d.ts +9 -0
  78. package/dist/ecosystem/types.js +5 -0
  79. package/dist/ecosystem/variable.d.ts +8 -0
  80. package/dist/ecosystem/variable.js +1 -0
  81. package/dist/ecosystem/virtual-user.d.ts +21 -0
  82. package/dist/ecosystem/virtual-user.js +5 -0
  83. package/dist/ecosystem/workflow.d.ts +18 -0
  84. package/dist/ecosystem/workflow.js +4 -0
  85. package/dist/index.d.ts +8 -8
  86. package/dist/index.js +3 -3
  87. package/dist/middleware/auth-apikey.d.ts +1 -1
  88. package/dist/middleware/auth-bearer.d.ts +1 -1
  89. package/dist/middleware/auth-cookie.d.ts +1 -1
  90. package/dist/middleware/cors.d.ts +1 -1
  91. package/dist/middleware/remote-auth.d.ts +1 -1
  92. package/dist/middleware/telemetry.d.ts +2 -2
  93. package/dist/services/agent-run-state-service.d.ts +29 -0
  94. package/dist/services/agent-run-state-service.js +1 -0
  95. package/dist/services/agent-runner-service.d.ts +220 -0
  96. package/dist/services/agent-runner-service.js +1 -0
  97. package/dist/services/agent-storage-service.d.ts +18 -0
  98. package/dist/services/agent-storage-service.js +1 -0
  99. package/dist/services/http-personas.d.ts +1 -1
  100. package/dist/services/http-personas.js +3 -3
  101. package/dist/services/in-memory-agent-run-state-service.d.ts +19 -0
  102. package/dist/services/in-memory-agent-run-state-service.js +54 -0
  103. package/dist/services/index.d.ts +4 -4
  104. package/dist/services/index.js +1 -1
  105. package/dist/services/meta-service.d.ts +3 -3
  106. package/dist/testing/service-tests/agent-run-service-tests.d.ts +1 -1
  107. package/dist/testing/service-tests/agent-run-service-tests.js +3 -3
  108. package/dist/testing/service-tests/agent-storage-service-tests.d.ts +3 -0
  109. package/dist/testing/service-tests/agent-storage-service-tests.js +302 -0
  110. package/dist/testing/service-tests.d.ts +4 -4
  111. package/dist/testing/service-tests.js +4 -4
  112. package/dist/types/core.types.d.ts +10 -10
  113. package/dist/types/core.types.js +1 -1
  114. package/dist/types/state.types.d.ts +5 -5
  115. package/dist/wirings/actor-flow/run-conversation.d.ts +2 -2
  116. package/dist/wirings/agent/agent-agui.d.ts +79 -0
  117. package/dist/wirings/agent/agent-agui.js +327 -0
  118. package/dist/wirings/agent/agent-finalize.d.ts +58 -0
  119. package/dist/wirings/agent/agent-finalize.js +138 -0
  120. package/dist/wirings/agent/agent-helpers.d.ts +35 -0
  121. package/dist/wirings/agent/agent-helpers.js +47 -0
  122. package/dist/wirings/agent/agent-interrupt.d.ts +153 -0
  123. package/dist/wirings/agent/agent-interrupt.js +257 -0
  124. package/dist/wirings/agent/agent-memory.d.ts +42 -0
  125. package/dist/wirings/agent/agent-memory.js +333 -0
  126. package/dist/wirings/agent/agent-model-config.d.ts +16 -0
  127. package/dist/wirings/agent/agent-model-config.js +51 -0
  128. package/dist/wirings/agent/agent-prepare.d.ts +117 -0
  129. package/dist/wirings/agent/agent-prepare.js +728 -0
  130. package/dist/wirings/agent/agent-registry.d.ts +16 -0
  131. package/dist/wirings/agent/agent-registry.js +51 -0
  132. package/dist/wirings/agent/agent-rpc.d.ts +15 -0
  133. package/dist/wirings/agent/agent-rpc.js +53 -0
  134. package/dist/wirings/agent/agent-runner.d.ts +7 -0
  135. package/dist/wirings/agent/agent-runner.js +580 -0
  136. package/dist/wirings/agent/agent-stream.d.ts +41 -0
  137. package/dist/wirings/agent/agent-stream.js +1029 -0
  138. package/dist/wirings/agent/agent-turn.d.ts +57 -0
  139. package/dist/wirings/agent/agent-turn.js +82 -0
  140. package/dist/wirings/agent/agent-utils.d.ts +1 -0
  141. package/dist/wirings/agent/agent-utils.js +1 -0
  142. package/dist/wirings/agent/agent.types.d.ts +625 -0
  143. package/dist/wirings/agent/agent.types.js +1 -0
  144. package/dist/wirings/agent/index.d.ts +12 -0
  145. package/dist/wirings/agent/index.js +10 -0
  146. package/dist/wirings/agent/voice-input.d.ts +69 -0
  147. package/dist/wirings/agent/voice-input.js +150 -0
  148. package/dist/wirings/agent/voice-output.d.ts +85 -0
  149. package/dist/wirings/agent/voice-output.js +196 -0
  150. package/dist/wirings/agent-scorer/agent-scorer-grade.d.ts +26 -0
  151. package/dist/wirings/agent-scorer/agent-scorer-grade.js +33 -0
  152. package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +17 -0
  153. package/dist/wirings/agent-scorer/agent-scorer-judge.js +92 -0
  154. package/dist/wirings/agent-scorer/agent-scorer-live.d.ts +15 -0
  155. package/dist/wirings/agent-scorer/agent-scorer-live.js +38 -0
  156. package/dist/wirings/agent-scorer/agent-scorer-registry.d.ts +18 -0
  157. package/dist/wirings/agent-scorer/agent-scorer-registry.js +46 -0
  158. package/dist/wirings/agent-scorer/agent-scorer-sampling.d.ts +8 -0
  159. package/dist/wirings/agent-scorer/agent-scorer-sampling.js +31 -0
  160. package/dist/wirings/agent-scorer/agent-scorer-snapshots.d.ts +10 -0
  161. package/dist/wirings/agent-scorer/agent-scorer-snapshots.js +40 -0
  162. package/dist/wirings/agent-scorer/agent-scorer-worker.d.ts +15 -0
  163. package/dist/wirings/agent-scorer/agent-scorer-worker.js +60 -0
  164. package/dist/wirings/agent-scorer/agent-scorer.d.ts +39 -0
  165. package/dist/wirings/agent-scorer/agent-scorer.js +40 -0
  166. package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +90 -0
  167. package/dist/wirings/agent-scorer/agent-scorer.types.js +4 -0
  168. package/dist/wirings/agent-scorer/index.d.ts +6 -0
  169. package/dist/wirings/agent-scorer/index.js +5 -0
  170. package/dist/wirings/ai-agent/voice-output.d.ts +1 -2
  171. package/dist/wirings/channel/channel-rpc.types.d.ts +2 -2
  172. package/dist/wirings/rpc/rpc-runner.d.ts +1 -1
  173. package/dist/wirings/rpc/rpc-runner.js +2 -2
  174. package/dist/wirings/rpc/rpc-types.d.ts +1 -1
  175. package/dist/wirings/virtual-user/prepare-virtual-user-run.js +1 -1
  176. package/dist/wirings/virtual-user/virtual-user-agents.d.ts +1 -1
  177. package/dist/wirings/workflow/run-timeline.d.ts +1 -2
  178. package/knowledge/decisions/internals/{a-non-streaming-agent-run-registers-with-airunstate-too.md → a-non-streaming-agent-run-registers-with-agentrunstate-too.md} +6 -6
  179. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +1 -1
  180. package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +1 -1
  181. package/knowledge/decisions/internals/{ai-agent-agui-bridge-obeys-the-client-ordering-contract.md → agent-agui-bridge-obeys-the-client-ordering-contract.md} +5 -5
  182. package/knowledge/decisions/internals/{ai-agent-audio-chunks-carry-the-format-the-provider-returned.md → agent-audio-chunks-carry-the-format-the-provider-returned.md} +2 -2
  183. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +1 -1
  184. package/knowledge/decisions/internals/{ai-agent-credential-suspensions-hide-the-tool-result.md → agent-credential-suspensions-hide-the-tool-result.md} +2 -2
  185. package/knowledge/decisions/internals/{ai-agent-delegate-and-supervise-hide-different-text.md → agent-delegate-and-supervise-hide-different-text.md} +4 -4
  186. package/knowledge/decisions/internals/{ai-agent-llm-tool-arguments-have-nulls-stripped.md → agent-llm-tool-arguments-have-nulls-stripped.md} +3 -3
  187. package/knowledge/decisions/internals/{ai-agent-model-config-stays-a-single-resolution-seam.md → agent-model-config-stays-a-single-resolution-seam.md} +3 -3
  188. package/knowledge/decisions/internals/{ai-agent-onerror-hooks-cannot-change-the-failure.md → agent-onerror-hooks-cannot-change-the-failure.md} +6 -6
  189. package/knowledge/decisions/internals/{ai-agent-runner-methods-must-keep-their-receiver.md → agent-runner-methods-must-keep-their-receiver.md} +4 -4
  190. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +1 -1
  191. package/knowledge/decisions/internals/{ai-agent-stream-persistence-is-best-effort.md → agent-stream-persistence-is-best-effort.md} +4 -4
  192. package/knowledge/decisions/internals/{ai-agent-sub-agents-inherit-the-parent-context-block.md → agent-sub-agents-inherit-the-parent-context-block.md} +3 -3
  193. package/knowledge/decisions/internals/{ai-agent-tool-execute-failures-are-logged-unconditionally.md → agent-tool-execute-failures-are-logged-unconditionally.md} +3 -3
  194. package/knowledge/decisions/internals/{ai-agent-voice-input-transcribes-audio-parts-in-place.md → agent-voice-input-transcribes-audio-parts-in-place.md} +2 -2
  195. package/knowledge/decisions/internals/{ai-agent-working-memory-is-persisted-only-when-valid.md → agent-working-memory-is-persisted-only-when-valid.md} +2 -2
  196. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +2 -2
  197. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +3 -3
  198. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +2 -2
  199. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +1 -1
  200. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +1 -1
  201. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +1 -1
  202. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +1 -1
  203. package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +1 -1
  204. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +5 -5
  205. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +2 -2
  206. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +2 -2
  207. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +1 -1
  208. package/knowledge/decisions/security/{ai-agent-approval-forwarding-requires-a-symbol-brand.md → agent-approval-forwarding-requires-a-symbol-brand.md} +3 -3
  209. package/knowledge/decisions/security/{ai-agent-credential-requests-are-symbol-branded.md → agent-credential-requests-are-symbol-branded.md} +4 -4
  210. package/knowledge/decisions/security/{ai-agent-gate-requires-a-session-only-when-auth-is-true.md → agent-gate-requires-a-session-only-when-auth-is-true.md} +3 -3
  211. package/knowledge/decisions/security/{ai-agent-ownership-failures-never-echo-the-resource.md → agent-ownership-failures-never-echo-the-resource.md} +2 -2
  212. package/knowledge/decisions/security/{ai-agent-resume-re-runs-the-authorization-gate.md → agent-resume-re-runs-the-authorization-gate.md} +4 -4
  213. package/knowledge/decisions/security/{ai-agent-sessionless-deployments-have-no-thread-ownership.md → agent-sessionless-deployments-have-no-thread-ownership.md} +5 -5
  214. package/knowledge/decisions/security/{ai-agent-thread-ownership-composes-the-session-principal.md → agent-thread-ownership-composes-the-session-principal.md} +2 -2
  215. package/knowledge/decisions/security/{ai-agent-tool-filtering-reads-the-live-function-config.md → agent-tool-filtering-reads-the-live-function-config.md} +2 -2
  216. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +3 -3
  217. package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +3 -3
  218. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +20 -13
  219. package/knowledge/decisions/security/index.md +1 -2
  220. package/package.json +4 -3
  221. package/scripts/generate-api-report.mts +32 -8
  222. package/src/agent-naming.test.ts +68 -0
  223. package/src/ecosystem/agent-scorer.ts +24 -0
  224. package/src/ecosystem/agent.ts +42 -0
  225. package/src/ecosystem/channel/local.ts +1 -0
  226. package/src/ecosystem/channel.ts +22 -0
  227. package/src/ecosystem/cli/channel.ts +25 -0
  228. package/src/ecosystem/cli.ts +21 -0
  229. package/src/ecosystem/credential.ts +10 -0
  230. package/src/ecosystem/dev.ts +12 -0
  231. package/src/ecosystem/function.ts +28 -0
  232. package/src/ecosystem/gateway.ts +4 -0
  233. package/src/ecosystem/hmac.ts +1 -0
  234. package/src/ecosystem/http.ts +22 -0
  235. package/src/ecosystem/mcp.ts +17 -0
  236. package/src/ecosystem/middleware.ts +27 -0
  237. package/src/ecosystem/node-host-resolver.ts +1 -0
  238. package/src/ecosystem/node.ts +5 -0
  239. package/src/ecosystem/oauth2.ts +4 -0
  240. package/src/ecosystem/persona.ts +30 -0
  241. package/src/ecosystem/queue.ts +23 -0
  242. package/src/ecosystem/remote.ts +9 -0
  243. package/src/ecosystem/role.ts +13 -0
  244. package/src/ecosystem/rpc.ts +7 -0
  245. package/src/ecosystem/safe-fetch.ts +8 -0
  246. package/src/ecosystem/scenario.ts +32 -0
  247. package/src/ecosystem/scheduler.ts +5 -0
  248. package/src/ecosystem/schema.ts +1 -0
  249. package/src/ecosystem/scope.ts +14 -0
  250. package/src/ecosystem/secret.ts +15 -0
  251. package/src/ecosystem/services/istanbul-coverage.ts +1 -0
  252. package/src/ecosystem/services/local-content-request-handler.ts +16 -0
  253. package/src/ecosystem/services/local-content.ts +1 -0
  254. package/src/ecosystem/services/v8-coverage.ts +1 -0
  255. package/src/ecosystem/services.ts +82 -0
  256. package/src/ecosystem/testing.ts +8 -0
  257. package/src/ecosystem/trigger.ts +7 -0
  258. package/src/ecosystem/types.ts +34 -0
  259. package/src/ecosystem/variable.ts +14 -0
  260. package/src/ecosystem/virtual-user.ts +48 -0
  261. package/src/ecosystem/workflow.ts +68 -0
  262. package/src/index.ts +8 -19
  263. package/src/pikku-state.ts +3 -3
  264. package/src/public-surface.json +173 -68
  265. package/src/public-surface.json.README +20 -2
  266. package/src/public-surface.test.ts +31 -3
  267. package/src/services/{ai-run-state-service.ts → agent-run-state-service.ts} +5 -5
  268. package/src/services/{ai-agent-runner-service.ts → agent-runner-service.ts} +18 -18
  269. package/src/services/{ai-storage-service.ts → agent-storage-service.ts} +7 -7
  270. package/src/services/http-personas-converse.test.ts +3 -3
  271. package/src/services/http-personas.ts +4 -4
  272. package/src/services/{in-memory-ai-run-state-service.ts → in-memory-agent-run-state-service.ts} +7 -7
  273. package/src/services/index.ts +9 -9
  274. package/src/services/meta-service.ts +3 -3
  275. package/src/testing/service-tests/agent-run-service-tests.ts +4 -4
  276. package/src/testing/service-tests/{ai-storage-service-tests.ts → agent-storage-service-tests.ts} +8 -8
  277. package/src/testing/service-tests.ts +10 -8
  278. package/src/types/core.types.ts +12 -12
  279. package/src/types/state.types.ts +6 -9
  280. package/src/wirings/actor-flow/run-conversation.test.ts +2 -2
  281. package/src/wirings/actor-flow/run-conversation.ts +7 -9
  282. package/src/wirings/{ai-agent/ai-agent-agui.test.ts → agent/agent-agui.test.ts} +126 -105
  283. package/src/wirings/{ai-agent/ai-agent-agui.ts → agent/agent-agui.ts} +7 -7
  284. package/src/wirings/{ai-agent/ai-agent-authorization.test.ts → agent/agent-authorization.test.ts} +6 -6
  285. package/src/wirings/{ai-agent/ai-agent-finalize.test.ts → agent/agent-finalize.test.ts} +17 -16
  286. package/src/wirings/{ai-agent/ai-agent-finalize.ts → agent/agent-finalize.ts} +22 -22
  287. package/src/wirings/{ai-agent/ai-agent-helpers.test.ts → agent/agent-helpers.test.ts} +1 -1
  288. package/src/wirings/{ai-agent/ai-agent-helpers.ts → agent/agent-helpers.ts} +1 -1
  289. package/src/wirings/{ai-agent/ai-agent-interrupt.test.ts → agent/agent-interrupt.test.ts} +67 -77
  290. package/src/wirings/{ai-agent/ai-agent-interrupt.ts → agent/agent-interrupt.ts} +5 -5
  291. package/src/wirings/{ai-agent/ai-agent-memory.test.ts → agent/agent-memory.test.ts} +12 -12
  292. package/src/wirings/{ai-agent/ai-agent-memory.ts → agent/agent-memory.ts} +36 -36
  293. package/src/wirings/{ai-agent/ai-agent-model-config.test.ts → agent/agent-model-config.test.ts} +2 -5
  294. package/src/wirings/{ai-agent/ai-agent-model-config.ts → agent/agent-model-config.ts} +1 -1
  295. package/src/wirings/{ai-agent/ai-agent-prepare.test.ts → agent/agent-prepare.test.ts} +18 -18
  296. package/src/wirings/{ai-agent/ai-agent-prepare.ts → agent/agent-prepare.ts} +52 -51
  297. package/src/wirings/{ai-agent/ai-agent-registry.test.ts → agent/agent-registry.test.ts} +49 -43
  298. package/src/wirings/{ai-agent/ai-agent-registry.ts → agent/agent-registry.ts} +14 -14
  299. package/src/wirings/{ai-agent/ai-agent-resume-authorization.test.ts → agent/agent-resume-authorization.test.ts} +18 -18
  300. package/src/wirings/{ai-agent → agent}/agent-rpc.ts +16 -20
  301. package/src/wirings/{ai-agent/ai-agent-runner.test.ts → agent/agent-runner.test.ts} +105 -106
  302. package/src/wirings/{ai-agent/ai-agent-runner.ts → agent/agent-runner.ts} +90 -80
  303. package/src/wirings/{ai-agent/ai-agent-stream-output-hooks.test.ts → agent/agent-stream-output-hooks.test.ts} +25 -25
  304. package/src/wirings/{ai-agent/ai-agent-stream.test.ts → agent/agent-stream.test.ts} +147 -143
  305. package/src/wirings/{ai-agent/ai-agent-stream.ts → agent/agent-stream.ts} +147 -146
  306. package/src/wirings/{ai-agent/ai-agent-thread-ownership.test.ts → agent/agent-thread-ownership.test.ts} +24 -28
  307. package/src/wirings/{ai-agent/ai-agent-turn.test.ts → agent/agent-turn.test.ts} +3 -5
  308. package/src/wirings/{ai-agent/ai-agent-turn.ts → agent/agent-turn.ts} +7 -7
  309. package/src/wirings/{ai-agent/ai-agent.types.ts → agent/agent.types.ts} +51 -48
  310. package/src/wirings/agent/index.ts +56 -0
  311. package/src/wirings/{ai-agent → agent}/voice-input.test.ts +15 -15
  312. package/src/wirings/{ai-agent → agent}/voice-input.ts +11 -11
  313. package/src/wirings/{ai-agent → agent}/voice-output.test.ts +23 -23
  314. package/src/wirings/{ai-agent → agent}/voice-output.ts +11 -11
  315. package/src/wirings/{ai-scorer/ai-scorer-grade.test.ts → agent-scorer/agent-scorer-grade.test.ts} +8 -8
  316. package/src/wirings/{ai-scorer/ai-scorer-grade.ts → agent-scorer/agent-scorer-grade.ts} +9 -9
  317. package/src/wirings/{ai-scorer/ai-scorer-judge.test.ts → agent-scorer/agent-scorer-judge.test.ts} +11 -14
  318. package/src/wirings/{ai-scorer/ai-scorer-judge.ts → agent-scorer/agent-scorer-judge.ts} +11 -11
  319. package/src/wirings/{ai-scorer/ai-scorer-live.test.ts → agent-scorer/agent-scorer-live.test.ts} +11 -11
  320. package/src/wirings/{ai-scorer/ai-scorer-live.ts → agent-scorer/agent-scorer-live.ts} +3 -3
  321. package/src/wirings/{ai-scorer/ai-scorer-registry.ts → agent-scorer/agent-scorer-registry.ts} +11 -8
  322. package/src/wirings/{ai-scorer/ai-scorer-sampling.test.ts → agent-scorer/agent-scorer-sampling.test.ts} +1 -1
  323. package/src/wirings/{ai-scorer/ai-scorer-snapshots.test.ts → agent-scorer/agent-scorer-snapshots.test.ts} +2 -2
  324. package/src/wirings/{ai-scorer/ai-scorer-snapshots.ts → agent-scorer/agent-scorer-snapshots.ts} +1 -1
  325. package/src/wirings/{ai-scorer/ai-scorer-worker.test.ts → agent-scorer/agent-scorer-worker.test.ts} +15 -15
  326. package/src/wirings/{ai-scorer/ai-scorer-worker.ts → agent-scorer/agent-scorer-worker.ts} +9 -7
  327. package/src/wirings/{ai-scorer/ai-scorer.ts → agent-scorer/agent-scorer.ts} +7 -7
  328. package/src/wirings/{ai-scorer/ai-scorer.types.ts → agent-scorer/agent-scorer.types.ts} +6 -6
  329. package/src/wirings/agent-scorer/index.ts +22 -0
  330. package/src/wirings/channel/channel-rpc.types.ts +2 -2
  331. package/src/wirings/rpc/rpc-runner.ts +2 -2
  332. package/src/wirings/rpc/rpc-types.ts +1 -1
  333. package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
  334. package/src/wirings/virtual-user/run-virtual-user.test.ts +2 -2
  335. package/src/wirings/virtual-user/run-virtual-user.ts +3 -3
  336. package/src/wirings/virtual-user/virtual-user-agents.ts +1 -1
  337. package/src/wirings/workflow/run-timeline.ts +1 -1
  338. package/src/wirings-stay-decoupled.test.ts +3 -3
  339. package/tsconfig.tsbuildinfo +1 -1
  340. package/src/wirings/ai-agent/index.ts +0 -65
  341. package/src/wirings/ai-scorer/index.ts +0 -24
  342. /package/src/wirings/{ai-agent/ai-agent-utils.ts → agent/agent-utils.ts} +0 -0
  343. /package/src/wirings/{ai-scorer/ai-scorer-sampling.ts → agent-scorer/agent-scorer-sampling.ts} +0 -0
@@ -2,14 +2,14 @@
2
2
  type: decision
3
3
  title: Agent thread ownership fails closed when there is no principal
4
4
  description: A sessionless caller gets an ephemeral owner and reaches no stored thread, rather than reaching all of them
5
- tags: ai-agent
5
+ tags: agent
6
6
  ---
7
7
 
8
8
  # Agent thread ownership fails closed when there is no principal
9
9
 
10
10
  `canAccessThread` returns `false` and `threadOwnerConstraint` returns `[]` when
11
11
  the session carries neither `userId` nor `orgId`
12
- (`packages/core/src/wirings/ai-agent/ai-agent-prepare.ts`).
12
+ (`packages/core/src/wirings/agent/agent-prepare.ts`).
13
13
  `resolveOwnerResourceId` never accepts the client-supplied `resourceId` as an
14
14
  ownership key; without a principal it mints an ephemeral `anon-<uuid>` owner
15
15
  memoized on the request's params object.
@@ -17,8 +17,8 @@ memoized on the request's params object.
17
17
  Agent wirings default to `auth: false`, so "no session" is the common case
18
18
  rather than an exotic one. Treating it as "no ownership model to enforce" made
19
19
  every ownership check vacuous: a caller named any `resourceId` and reached that
20
- thread, and because `undefined` on `AgentRunService.listThreads` means *no
21
- filter* rather than *no rows*, a sessionless `getAgentThreads` returned every
20
+ thread, and because `undefined` on `AgentRunService.listThreads` means _no
21
+ filter_ rather than _no rows_, a sessionless `getAgentThreads` returned every
22
22
  thread in the deployment. The ephemeral owner is what keeps one-shot
23
23
  conversations working while denying continuity — it is unguessable, so nothing
24
24
  stored can be reached, and it is stable within a request, so a sub-agent
@@ -32,7 +32,7 @@ field, never in its body.
32
32
 
33
33
  **What this rules out:** returning `undefined` from `threadOwnerConstraint` for
34
34
  any caller; deriving `owners` from request input instead of the session; reading
35
- `auth: false` as permission to skip ownership on a *stored* thread; and
35
+ `auth: false` as permission to skip ownership on a _stored_ thread; and
36
36
  persisting the anonymous owner anywhere, which would turn an ephemeral identity
37
37
  into a forgeable one. Cross-request thread continuity without a session is not
38
38
  available by design — wire a session to get it back. See
@@ -2,12 +2,12 @@
2
2
  type: decision
3
3
  title: An agent thread key is always prefixed with the trusted principal
4
4
  description: Ownership keys are composed as principal:resourceId, so a client id can sub-divide its own boundary but never widen it
5
- tags: ai-agent
5
+ tags: agent
6
6
  ---
7
7
 
8
8
  # An agent thread key is always prefixed with the trusted principal
9
9
 
10
- `resolveOwnerResourceId` in `packages/core/src/wirings/ai-agent/ai-agent-prepare.ts`
10
+ `resolveOwnerResourceId` in `packages/core/src/wirings/agent/agent-prepare.ts`
11
11
  composes the ownership key for a thread or run as `principal:resourceId`. The
12
12
  principal is the trusted one — `session.userId` for the default `'user'`
13
13
  `SessionScope`, `session.orgId` for `'org'` — and the client-supplied
@@ -2,12 +2,12 @@
2
2
  type: decision
3
3
  title: Agent tool permission filtering reads the live function config, not the metadata
4
4
  description: The pikkuAuth brand survives only on live permission objects, so a metadata-driven check would silently admit every gated tool
5
- tags: ai-agent
5
+ tags: agent
6
6
  ---
7
7
 
8
8
  # Agent tool permission filtering reads the live function config, not the metadata
9
9
 
10
- `buildToolDefs` in `packages/core/src/wirings/ai-agent/ai-agent-prepare.ts`
10
+ `buildToolDefs` in `packages/core/src/wirings/agent/agent-prepare.ts`
11
11
  decides which tools and sub-agents to expose to the model by calling
12
12
  `checkAuthPermissions` against the permission objects held in the live function
13
13
  (or agent) config in `pikkuState`, using the metadata only to learn that a
@@ -2,7 +2,7 @@
2
2
  type: decision
3
3
  title: An agent approval is claimed before the tool runs
4
4
  description: resolveApproval is a compare-and-swap returning whether this caller won, because the read that precedes it is not a claim and ten concurrent approvals would otherwise mean ten refunds
5
- tags: ai-agent
5
+ tags: agent
6
6
  ---
7
7
 
8
8
  # An agent approval is claimed before the tool runs
@@ -15,7 +15,7 @@ same tool call all observed `suspended`, all snapshotted the same list, and all
15
15
  reached `execute`. `resolveApproval` returned `void`, so a loser could not even
16
16
  tell.
17
17
 
18
- `resolveApproval` is now the claim, and returns whether *this* caller made it.
18
+ `resolveApproval` is now the claim, and returns whether _this_ caller made it.
19
19
  The stores implement it as a compare-and-swap: Kysely updates the run row only
20
20
  while `status = 'suspended'` and `pendingApprovals` still equals the list it
21
21
  read; the tool-call stores move the row off `approvalStatus = 'pending'` and
@@ -23,7 +23,7 @@ count the rows they changed. Both resume paths run the tool only for the ids the
23
23
  claimed, and a caller that claimed nothing gets an error rather than a silent
24
24
  re-run.
25
25
 
26
- The claim is per tool call, not per run, so concurrent approvals of *different*
26
+ The claim is per tool call, not per run, so concurrent approvals of _different_
27
27
  tool calls on one run all proceed — which is the case that made a run-level
28
28
  `claimSuspendedRun` the worse fit.
29
29
 
@@ -2,13 +2,13 @@
2
2
  type: decision
3
3
  title: An empty owners constraint matches nothing
4
4
  description: owners is an authorization boundary, so every storage backend must treat [] as no rows rather than no filter
5
- tags: ai-agent, storage
5
+ tags: agent, storage
6
6
  ---
7
7
 
8
8
  # An empty owners constraint matches nothing
9
9
 
10
10
  Every `AgentRunService.listThreads` implementation returns `[]` immediately when
11
- `owners` is present and empty — `kysely-ai-agent-run-service.ts`,
11
+ `owners` is present and empty — `kysely-agent-run-service.ts`,
12
12
  `redis-agent-run-service.ts`, `mongodb-agent-run-service.ts`. The conformance
13
13
  suite in `packages/core/src/testing/service-tests.ts` pins it, so a new backend
14
14
  inherits the requirement instead of rediscovering it.
@@ -27,4 +27,4 @@ return; the two decisions only hold together.
27
27
  `if (owners)` path; treating `owners: []` as equivalent to `owners: undefined`
28
28
  at any layer; and adding a backend without the conformance suite.
29
29
 
30
- See [[ai-agent-sessionless-deployments-have-no-thread-ownership]].
30
+ See [[agent-sessionless-deployments-have-no-thread-ownership]].
@@ -2,7 +2,7 @@
2
2
  type: decision
3
3
  title: The console addon's privileged functions gate themselves
4
4
  description: Thread listing is owner-scoped unless the caller holds admin, and addon installation requires an admin session, rather than trusting the host to register a global permission
5
- tags: addon, ai-agent, rpc
5
+ tags: addon, agent, rpc
6
6
  ---
7
7
 
8
8
  # The console addon's privileged functions gate themselves
@@ -27,14 +27,18 @@ runner's, which for a `pikkuSessionlessFunc` fires only when the function itself
27
27
  sets `auth: true`.
28
28
 
29
29
  The addon's original authorization story was a single package-scoped
30
- `addGlobalPermission([isAdmin], '@pikku/addon-console')` that the *host*
30
+ `addGlobalPermission([isAdmin], '@pikku/addon-console')` that the _host_
31
31
  registered, which `runPermissions` resolves in the callee's package namespace and
32
32
  applies to every function at once. Nothing generated that call — the scaffold
33
33
  emitted only a comment recommending it, and `resolveGlobalPermissions` returns an
34
34
  empty list when the host registered none, which `runPermissions` treats as
35
35
  allow. An app that followed the scaffold and stopped there had a fully open
36
- console surface. The scaffold now emits `wireAddon({ …, scopes: ['admin'] })`
37
- instead, which the function runner enforces on every function in the package.
36
+ console surface. Every console function now declares its own
37
+ `pikku:console:<area>:<action>` scope instead, which the function runner
38
+ enforces per call. A blanket `wireAddon({ …, scopes: ['admin'] })` stood in for
39
+ that briefly; it is gone, because a single grant covering secrets, source
40
+ editing and the audit trail alike is not something an operator can reason
41
+ about.
38
42
 
39
43
  The two functions whose failure mode is worst still do not depend on any
40
44
  package-wide gate:
@@ -51,16 +55,19 @@ storage backend already treats as no rows.
51
55
  attacker-chosen package name and write a wiring file into the project. They were
52
56
  `pikkuSessionlessFunc` with `auth: false`, which — behind a `no-auth` RPC route
53
57
  and with no host global permission — meant an unauthenticated POST reached
54
- `execFileSync`. They now declare `auth: true` and `scopes: ['admin']`, enforced
55
- by `verifyScopes` in the function runner before the body runs. Both gates are
56
- checked whether or not the host registered a global permission, and whether or
57
- not the addon itself was wired with scopes — an app that hand-wires
58
- `wireAddon({ name: 'console', package: '@pikku/addon-console' })` without them
58
+ `execFileSync`. They now declare `auth: true` and
59
+ `scopes: ['pikku:console:addons:install']`, enforced by `verifyScopes` in the
60
+ function runner before the body runs. Both gates are
61
+ checked whether or not the host registered a global permission — an app that
62
+ hand-wires `wireAddon({ name: 'console', package: '@pikku/addon-console' })`
59
63
  still cannot reach `execFileSync` unauthenticated.
60
64
 
61
- `admin` is spelled as a literal here because it is a scope id in the addon's own
62
- `wireScope` tree, the same tree the `pikku:scopes:*` gates on the scope-admin
63
- functions come from.
65
+ The scopes are spelled as literals here because they are scope ids in the
66
+ addon's own `wireScope` tree the same tree the `pikku:console:scopes:*` gates
67
+ on the scope-admin functions come from. The generated secret and variable
68
+ brokers live in the app's own scaffold rather than the addon, so the addon
69
+ boundary never covered them; they carry `pikku:console:secrets:*` and
70
+ `pikku:console:variables:*` themselves.
64
71
 
65
72
  **What this rules out:** treating the host's `addGlobalPermission` as the only
66
73
  gate in front of an operation that installs code or reads another principal's
@@ -72,5 +79,5 @@ is-this-localhost test.
72
79
 
73
80
  See [[addon-scopes-are-resolved-where-the-function-runs]],
74
81
  [[an-empty-owners-constraint-matches-nothing]],
75
- [[ai-agent-sessionless-deployments-have-no-thread-ownership]] and
82
+ [[agent-sessionless-deployments-have-no-thread-ownership]] and
76
83
  [[global-permissions-and-function-permissions-are-independent-gates]].
@@ -15,7 +15,7 @@ A rule about who may do what, and which way it fails when it is unsure.
15
15
  - [A permission gets a wire it cannot reply on](a-permission-gets-a-wire-it-cannot-reply-on.md) — The permission wire is typed with Out = never so a permission cannot send on the channel; that narrowing is not a subtype, so the call site asserts
16
16
  - [A step runs the function the workflow dispatched it with](a-step-runs-the-function-the-workflow-dispatched-it-with.md) — StepState records the step's function name so the worker can reject a queue message naming a different one, because the step executes under the run owner's identity
17
17
  - [A virtual user is never offered a scenario, platform or addon step](a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md) — Being able to invoke "the webhook arrives" lets the user manufacture the outcome it exists to discover, which invalidates every finding downstream
18
- - [A workflow run is read by its owner, and answered by whoever its gate declares](a-workflow-run-is-read-and-approved-by-its-owner.md) — A run started through a session records that user and only that user may read it; who may answer an approval gate is the gate's own declaration, and a run with no recorded owner has no ownership to enforce
18
+ - [A workflow run is read and approved by its owner](a-workflow-run-is-read-and-approved-by-its-owner.md) — A run started through a session records that user and only that user may read it or answer its approval gates; a run with no recorded owner has no ownership to enforce
19
19
  - [An actor's missing approval decision defaults to denied](actor-flow-missing-approval-decisions-default-to-denied.md) — Every pending tool call gets an explicit decision; an id the persona LLM omitted is denied, so a dropped field can never read as consent
20
20
  - [Actor sign-in is proven by Set-Cookie, not a non-empty jar](actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md) — HttpScenarioActor tracks its own signedIn flag and requires the sign-in response itself to set a cookie, because a populated jar proves nothing
21
21
  - [Actor sign-in only works for actor-flagged users](actor-sign-in-only-works-for-actor-flagged-users.md) — The scenario actor secret mints sessions for user rows flagged actor and nothing else, so holding it never impersonates a real user
@@ -31,7 +31,6 @@ A rule about who may do what, and which way it fails when it is unsure.
31
31
  - [An agent thread key is always prefixed with the trusted principal](ai-agent-thread-ownership-composes-the-session-principal.md) — Ownership keys are composed as principal:resourceId, so a client id can sub-divide its own boundary but never widen it
32
32
  - [Agent tool permission filtering reads the live function config, not the metadata](ai-agent-tool-filtering-reads-the-live-function-config.md) — The pikkuAuth brand survives only on live permission objects, so a metadata-driven check would silently admit every gated tool
33
33
  - [An agent approval is claimed before the tool runs](an-agent-approval-is-claimed-before-the-tool-runs.md) — resolveApproval is a compare-and-swap returning whether this caller won, because the read that precedes it is not a claim and ten concurrent approvals would otherwise mean ten refunds
34
- - [An approval answer outlives the run it answered](an-approval-answer-outlives-the-run-it-answered.md) — Run state holds a decision only while the gate is open, so the settled answer carries decidedBy/decidedAt into the step result and every attempt is written to the audit sink, which has no foreign key to the run
35
34
  - [An empty owners constraint matches nothing](an-empty-owners-constraint-matches-nothing.md) — owners is an authorization boundary, so every storage backend must treat [] as no rows rather than no filter
36
35
  - [An exposed function with no gate is reported at codegen, not at boot](an-exposed-ungated-function-is-a-codegen-warning.md) — The check runs in the inspector where function meta and every wireAddon declaration are both in hand, because neither source alone can tell a gated function from an ungated one
37
36
  - [An upload is counted as it arrives, not buffered and then measured](an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md) — Reading the whole body before checking its size hands an unauthenticated caller a way to spend the server's memory
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/core",
3
- "version": "0.12.83",
3
+ "version": "0.12.84",
4
4
  "description": "The Pikku runtime — functions, wirings, services, middleware and types",
5
5
  "author": "yasser.fadl@gmail.com",
6
6
  "license": "MIT",
@@ -49,8 +49,8 @@
49
49
  "./safe-fetch": "./dist/utils/safe-fetch.js",
50
50
  "./node-host-resolver": "./dist/utils/node-host-resolver.js",
51
51
  "./mcp": "./dist/wirings/mcp/index.js",
52
- "./ai-agent": "./dist/wirings/ai-agent/index.js",
53
- "./ai-scorer": "./dist/wirings/ai-scorer/index.js",
52
+ "./agent": "./dist/wirings/agent/index.js",
53
+ "./agent-scorer": "./dist/wirings/agent-scorer/index.js",
54
54
  "./gateway": "./dist/wirings/gateway/index.js",
55
55
  "./cli": "./dist/wirings/cli/index.js",
56
56
  "./cli/command-parser": "./dist/wirings/cli/command-parser.js",
@@ -74,6 +74,7 @@
74
74
  "./crypto-utils": "./dist/crypto-utils.js",
75
75
  "./hmac": "./dist/utils/hmac.js",
76
76
  "./ecosystem": "./dist/ecosystem.js",
77
+ "./ecosystem/*": "./dist/ecosystem/*.js",
77
78
  "./schema": "./dist/schema.js",
78
79
  "./testing": "./dist/testing/index.js",
79
80
  "./dev": "./dist/dev/hot-reload.js"
@@ -22,7 +22,7 @@
22
22
  *
23
23
  * Run: yarn api-report
24
24
  */
25
- import { readFileSync, writeFileSync } from 'node:fs'
25
+ import { readdirSync, readFileSync, writeFileSync } from 'node:fs'
26
26
  import { resolve, dirname } from 'node:path'
27
27
  import { fileURLToPath } from 'node:url'
28
28
  import ts from 'typescript'
@@ -32,15 +32,36 @@ const pkg = JSON.parse(
32
32
  readFileSync(resolve(packageRoot, 'package.json'), 'utf-8')
33
33
  )
34
34
 
35
- const entryPoints = Object.entries(pkg.exports as Record<string, string>).map(
36
- ([subpath, dist]) => ({
35
+ /**
36
+ * A wildcard subpath stands for as many entry points as there are files behind
37
+ * it, and the report is per entry point. Left as a pattern it resolves to no
38
+ * source file at all, so every sub-barrel it publishes goes unreported.
39
+ */
40
+ const expand = ([subpath, dist]: [string, string]): [string, string][] => {
41
+ if (!subpath.includes('*')) return [[subpath, dist]]
42
+ const [prefix] = dist.split('*') as [string]
43
+ return readdirSync(
44
+ resolve(packageRoot, prefix.replace('./dist/', './src/')),
45
+ {
46
+ recursive: true,
47
+ encoding: 'utf-8',
48
+ }
49
+ )
50
+ .filter((file) => file.endsWith('.ts') && !file.endsWith('.d.ts'))
51
+ .map((file) => file.slice(0, -'.ts'.length))
52
+ .sort()
53
+ .map((area) => [subpath.replace('*', area), dist.replace('*', area)])
54
+ }
55
+
56
+ const entryPoints = Object.entries(pkg.exports as Record<string, string>)
57
+ .flatMap(expand)
58
+ .map(([subpath, dist]) => ({
37
59
  subpath,
38
60
  file: resolve(
39
61
  packageRoot,
40
62
  dist.replace('./dist/', './src/').replace(/\.js$/, '.ts')
41
63
  ),
42
- })
43
- )
64
+ }))
44
65
 
45
66
  const program = ts.createProgram(
46
67
  entryPoints.map((e) => e.file),
@@ -218,7 +239,10 @@ const signature = (exported: ts.Symbol): string => {
218
239
  *
219
240
  * knowledge: decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md
220
241
  */
221
- const ECOSYSTEM_SUBPATHS = new Set(['./ecosystem', './internal'])
242
+ const isEcosystem = (subpath: string) =>
243
+ subpath === './ecosystem' ||
244
+ subpath === './internal' ||
245
+ subpath.startsWith('./ecosystem/')
222
246
 
223
247
  type Exported = { name: string; members: number; signature: string }
224
248
 
@@ -264,7 +288,7 @@ for (const { subpath, file } of entryPoints) {
264
288
  const tierOf = new Map<string, string>()
265
289
  const membersOf = new Map<string, number>()
266
290
  for (const [subpath, exports] of modules) {
267
- const tier = ECOSYSTEM_SUBPATHS.has(subpath) ? 'ecosystem' : 'stable'
291
+ const tier = isEcosystem(subpath) ? 'ecosystem' : 'stable'
268
292
  for (const { name, members } of exports) {
269
293
  if (tier === 'stable' || !tierOf.has(name)) tierOf.set(name, tier)
270
294
  membersOf.set(name, Math.max(membersOf.get(name) ?? 0, members))
@@ -275,7 +299,7 @@ const tally = (tier: string) => {
275
299
  const names = [...tierOf].filter(([, t]) => t === tier).map(([n]) => n)
276
300
  return {
277
301
  entryPoints: [...modules.keys()].filter(
278
- (s) => (ECOSYSTEM_SUBPATHS.has(s) ? 'ecosystem' : 'stable') === tier
302
+ (s) => (isEcosystem(s) ? 'ecosystem' : 'stable') === tier
279
303
  ).length,
280
304
  names: names.length,
281
305
  members: names.reduce((total, n) => total + (membersOf.get(n) ?? 0), 0),
@@ -0,0 +1,68 @@
1
+ import { describe, test } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { readFileSync } from 'node:fs'
4
+ import { fileURLToPath } from 'node:url'
5
+ import { join, dirname } from 'node:path'
6
+
7
+ const packageRoot = join(dirname(fileURLToPath(import.meta.url)), '..')
8
+ const reportPath = join(packageRoot, 'api-report.md')
9
+
10
+ /**
11
+ * `AI` described the model provider, never the agent runtime, so #596 renamed
12
+ * every agent symbol to `Agent`. The names below are the ones that survived,
13
+ * because each really does wrap a provider call.
14
+ *
15
+ * Listing them here is what makes the rule checkable: anything else exported as
16
+ * `AI*` is a symbol that slipped back to the old naming, and this fails rather
17
+ * than letting it reach a consumer.
18
+ */
19
+ const PROVIDER_SYMBOLS = new Set([
20
+ 'AIEmbeddingService',
21
+ 'AIEmbedManyParams',
22
+ 'AIEmbedManyResult',
23
+ 'AIEmbedParams',
24
+ 'AIEmbedResult',
25
+ 'AIGenerateImageParams',
26
+ 'AIGenerateImagePrompt',
27
+ 'AIGenerateImageResult',
28
+ 'AIGenerateSpeechParams',
29
+ 'AIGenerateSpeechResult',
30
+ 'AIProviderAuthError',
31
+ 'AIProviderNotConfiguredError',
32
+ 'AIProviderOptions',
33
+ 'AIRerankParams',
34
+ 'AIRerankResult',
35
+ 'AITranscriptionParams',
36
+ 'AITranscriptionResult',
37
+ ])
38
+
39
+ describe('the agent runtime is not exported under the AI name', () => {
40
+ test('every AI* symbol in the public surface is a provider wrapper', () => {
41
+ const report = readFileSync(reportPath, 'utf-8')
42
+ const found = new Set(report.match(/\bAI[A-Z][A-Za-z]*/g) ?? [])
43
+
44
+ const strays = [...found].filter((name) => !PROVIDER_SYMBOLS.has(name))
45
+
46
+ assert.deepEqual(
47
+ strays,
48
+ [],
49
+ 'these are exported as `AI*` but are not provider wrappers — rename them ' +
50
+ 'to `Agent*`, or add them to PROVIDER_SYMBOLS if they genuinely wrap a ' +
51
+ 'model provider call'
52
+ )
53
+ })
54
+
55
+ test('the agent entry points are the renamed ones', () => {
56
+ const { exports } = JSON.parse(
57
+ readFileSync(join(packageRoot, 'package.json'), 'utf-8')
58
+ )
59
+
60
+ assert.ok(exports['./agent'], 'expected the ./agent entry point')
61
+ assert.ok(
62
+ exports['./agent-scorer'],
63
+ 'expected the ./agent-scorer entry point'
64
+ )
65
+ assert.equal(exports['./ai-agent'], undefined)
66
+ assert.equal(exports['./ai-scorer'], undefined)
67
+ })
68
+ })
@@ -0,0 +1,24 @@
1
+ export { gradeRun } from '../wirings/agent-scorer/agent-scorer-grade.js'
2
+ export { addAgentScorer } from '../wirings/agent-scorer/agent-scorer-registry.js'
3
+ export {
4
+ enableScoreSnapshots,
5
+ getScoreSnapshot,
6
+ } from '../wirings/agent-scorer/agent-scorer-snapshots.js'
7
+ export { wireAgentScorerQueueWorkers } from '../wirings/agent-scorer/agent-scorer-worker.js'
8
+ export {
9
+ pikkuAgentJudge,
10
+ pikkuAgentScorer,
11
+ } from '../wirings/agent-scorer/agent-scorer.js'
12
+ export type { ScorerMeta } from '../wirings/agent-scorer/agent-scorer.types.js'
13
+
14
+ /**
15
+ * Types the exports above mention but do not themselves export. Without
16
+ * them a consumer's declaration emit has no name for the type it infers,
17
+ * and fails with TS2883 rather than reaching for the original entry point.
18
+ */
19
+ export type {
20
+ PikkuAgentScorer,
21
+ ScoreJob,
22
+ ScorerInput,
23
+ ScorerOutput,
24
+ } from '../wirings/agent-scorer/agent-scorer.types.js'
@@ -0,0 +1,42 @@
1
+ export {
2
+ agent,
3
+ agentApprove,
4
+ agentResume,
5
+ agentStream,
6
+ } from '../wirings/agent/agent-helpers.js'
7
+ export { resolveModelAlias } from '../wirings/agent/agent-model-config.js'
8
+ export {
9
+ canAccessThread,
10
+ isOwnedByPrincipal,
11
+ threadOwnerConstraint,
12
+ } from '../wirings/agent/agent-prepare.js'
13
+ export { addAgent } from '../wirings/agent/agent-registry.js'
14
+ export type {
15
+ AgentInput,
16
+ AgentMemoryConfig,
17
+ AgentsMeta,
18
+ AgentStep,
19
+ AgentContentPart,
20
+ AgentRunRow,
21
+ AgentRunService,
22
+ CoreAgent,
23
+ PendingApproval,
24
+ PikkuAgentMiddlewareHooks,
25
+ } from '../wirings/agent/agent.types.js'
26
+ export { voiceInput } from '../wirings/agent/voice-input.js'
27
+ export { voiceOutput } from '../wirings/agent/voice-output.js'
28
+
29
+ /**
30
+ * Types the exports above mention but do not themselves export. Without
31
+ * them a consumer's declaration emit has no name for the type it infers,
32
+ * and fails with TS2883 rather than reaching for the original entry point.
33
+ */
34
+ export type { LogLevel } from '../services/logger.js'
35
+ export type { WebhookServiceConfig } from '../services/webhook-service.js'
36
+ export type {
37
+ CoreSingletonServices,
38
+ PostgresConfig,
39
+ } from '../types/core.types.js'
40
+ export type { SpeakableScripts } from '../wirings/agent/voice-output.js'
41
+ export type { WorkflowServiceConfig } from '../wirings/workflow/workflow.types.js'
42
+ export type { VoiceOutputState } from '../wirings/agent/voice-output.js'
@@ -0,0 +1 @@
1
+ export { PikkuLocalChannelHandler } from '../../wirings/channel/local/local-channel-handler.js'
@@ -0,0 +1,22 @@
1
+ export { addChannelMiddleware } from '../wirings/channel/channel-middleware-runner.js'
2
+ export type { Capabilities } from '../wirings/channel/channel-rpc.types.js'
3
+ export type {
4
+ BinaryData,
5
+ ChannelMessageMeta,
6
+ ChannelMeta,
7
+ ChannelsMeta,
8
+ CoreChannel,
9
+ CorePikkuChannelMiddleware,
10
+ CorePikkuChannelMiddlewareFactory,
11
+ PikkuChannelHandlerFactory,
12
+ } from '../wirings/channel/channel.types.js'
13
+ export { EventHubStore } from '../wirings/channel/eventhub-store.js'
14
+ export { logChannels } from '../wirings/channel/log-channels.js'
15
+ export { PikkuAbstractChannelHandler } from '../wirings/channel/pikku-abstract-channel-handler.js'
16
+
17
+ /**
18
+ * Types the exports above mention but do not themselves export. Without
19
+ * them a consumer's declaration emit has no name for the type it infers,
20
+ * and fails with TS2883 rather than reaching for the original entry point.
21
+ */
22
+ export type { Logger } from '../services/logger.js'
@@ -0,0 +1,25 @@
1
+ export { handleRawCLI } from '../../wirings/cli/channel/cli-raw-channel-runner.js'
2
+ export type { RawCLIFrame } from '../../wirings/cli/channel/cli-raw-channel-runner.js'
3
+ export { executeRawCLIViaChannel } from '../../wirings/cli/channel/cli-raw-client-runner.js'
4
+ export type { CorePikkuCLIClientRender } from '../../wirings/cli/channel/cli-raw-client-runner.js'
5
+
6
+ /**
7
+ * Types the exports above mention but do not themselves export. Without
8
+ * them a consumer's declaration emit has no name for the type it infers,
9
+ * and fails with TS2883 rather than reaching for the original entry point.
10
+ */
11
+ export type { LogLevel } from '../../services/logger.js'
12
+ export type { WebhookServiceConfig } from '../../services/webhook-service.js'
13
+ export type {
14
+ CoreSingletonServices,
15
+ CoreUserSession,
16
+ CreateWireServices,
17
+ PostgresConfig,
18
+ } from '../../types/core.types.js'
19
+ export type {
20
+ ApprovalRequester,
21
+ Capabilities,
22
+ } from '../../wirings/channel/channel-rpc.types.js'
23
+ export type { PikkuChannel } from '../../wirings/channel/channel.types.js'
24
+ export type { RawCLIResult } from '../../wirings/cli/channel/cli-raw-channel-runner.js'
25
+ export type { WorkflowServiceConfig } from '../../wirings/workflow/workflow.types.js'
@@ -0,0 +1,21 @@
1
+ export { CLIError, executeCLI } from '../wirings/cli/cli-runner.js'
2
+ export type {
3
+ CLICommandMeta,
4
+ CLIMeta,
5
+ CLIProgramMeta,
6
+ CoreCLI,
7
+ CoreCLICommandConfig,
8
+ CorePikkuCLIRender,
9
+ } from '../wirings/cli/cli.types.js'
10
+ export { generateCommandHelp } from '../wirings/cli/command-parser.js'
11
+
12
+ /**
13
+ * Types the exports above mention but do not themselves export. Without
14
+ * them a consumer's declaration emit has no name for the type it infers,
15
+ * and fails with TS2883 rather than reaching for the original entry point.
16
+ */
17
+ export type {
18
+ CreateConfig,
19
+ CreateSingletonServices,
20
+ CreateWireServices,
21
+ } from '../types/core.types.js'
@@ -0,0 +1,10 @@
1
+ export type { CredentialDefinitions } from '../wirings/credential/credential.types.js'
2
+ export { validateAndBuildCredentialDefinitionsMeta } from '../wirings/credential/validate-credential-definitions.js'
3
+
4
+ /**
5
+ * Types the exports above mention but do not themselves export. Without
6
+ * them a consumer's declaration emit has no name for the type it infers,
7
+ * and fails with TS2883 rather than reaching for the original entry point.
8
+ */
9
+ export type { SchemaRefLike } from '../types/core.types.js'
10
+ export type { CredentialDefinitionsMeta } from '../wirings/credential/credential.types.js'
@@ -0,0 +1,12 @@
1
+ export {
2
+ reconcileAddonRegistry,
3
+ reloadGeneratedMeta,
4
+ } from '../dev/reload-meta.js'
5
+
6
+ /**
7
+ * Types the exports above mention but do not themselves export. Without
8
+ * them a consumer's declaration emit has no name for the type it infers,
9
+ * and fails with TS2883 rather than reaching for the original entry point.
10
+ */
11
+ export type { ReloadGeneratedMetaOptions } from '../dev/reload-meta.js'
12
+ export type { Logger } from '../services/logger.js'
@@ -0,0 +1,28 @@
1
+ export { getAllFunctionNames } from '../function/function-runner.js'
2
+ export { pikkuAuth } from '../function/functions.types.js'
3
+ export type {
4
+ CorePikkuAuth,
5
+ CorePikkuAuthConfig,
6
+ CorePikkuFunction,
7
+ CorePikkuFunctionConfig,
8
+ CorePikkuFunctionSessionless,
9
+ CorePikkuPermission,
10
+ CorePikkuSessionlessFunctionConfig,
11
+ } from '../function/functions.types.js'
12
+ export type { ListInput, ListOutput } from '../function/list.types.js'
13
+
14
+ /**
15
+ * Types the exports above mention but do not themselves export. Without
16
+ * them a consumer's declaration emit has no name for the type it infers,
17
+ * and fails with TS2883 rather than reaching for the original entry point.
18
+ */
19
+ export type { LogLevel } from '../services/logger.js'
20
+ export type { WebhookServiceConfig } from '../services/webhook-service.js'
21
+ export type {
22
+ CoreSecretlessSingletonServices,
23
+ CoreSingletonServices,
24
+ CoreUserSession,
25
+ PostgresConfig,
26
+ SecretlessServices,
27
+ } from '../types/core.types.js'
28
+ export type { WorkflowServiceConfig } from '../wirings/workflow/workflow.types.js'
@@ -0,0 +1,4 @@
1
+ export type {
2
+ GatewayTransportType,
3
+ GatewaysMeta,
4
+ } from '../wirings/gateway/gateway.types.js'
@@ -0,0 +1 @@
1
+ export { hmacSha256Hex, timingSafeStringEqual } from '../utils/hmac.js'
@@ -0,0 +1,22 @@
1
+ export type {
2
+ AssertHTTPWiringParams,
3
+ CoreHTTPFunctionWiring,
4
+ HTTPMethod,
5
+ HTTPRouteBaseConfig,
6
+ HTTPWiringsMeta,
7
+ PikkuHTTP,
8
+ PikkuHTTPResponse,
9
+ PikkuQuery,
10
+ RunHTTPWiringOptions,
11
+ } from '../wirings/http/http.types.js'
12
+ export { logRoutes } from '../wirings/http/log-http-routes.js'
13
+ export { DEFAULT_MAX_BODY_SIZE } from '../wirings/http/pikku-fetch-http-request.js'
14
+ export { toWebRequest } from '../wirings/http/web-request.js'
15
+
16
+ /**
17
+ * Types the exports above mention but do not themselves export. Without
18
+ * them a consumer's declaration emit has no name for the type it infers,
19
+ * and fails with TS2883 rather than reaching for the original entry point.
20
+ */
21
+ export type { Logger } from '../services/logger.js'
22
+ export type { PikkuHTTPRequest } from '../wirings/http/http.types.js'
@@ -0,0 +1,17 @@
1
+ export { MCPEndpointRegistry } from '../wirings/mcp/mcp-endpoint-registry.js'
2
+ export {
3
+ MCPError,
4
+ getMCPPromptsMeta,
5
+ getMCPResourcesMeta,
6
+ getMCPToolsMeta,
7
+ } from '../wirings/mcp/mcp-runner.js'
8
+ export type {
9
+ AssertMCPResourceURIParams,
10
+ CoreMCPPrompt,
11
+ CoreMCPResource,
12
+ MCPPromptMeta,
13
+ MCPResourceMeta,
14
+ MCPToolMeta,
15
+ MCPToolResponse,
16
+ PikkuMCP,
17
+ } from '../wirings/mcp/mcp.types.js'