@pikku/core 0.12.79 → 0.12.82

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 (479) hide show
  1. package/CHANGELOG.md +473 -0
  2. package/dist/dev/hot-reload.js +1 -6
  3. package/dist/ecosystem.d.ts +27 -0
  4. package/dist/ecosystem.js +26 -0
  5. package/dist/errors/error-handler.js +4 -2
  6. package/dist/errors/index.d.ts +1 -1
  7. package/dist/errors/index.js +1 -1
  8. package/dist/function/function-runner.js +22 -47
  9. package/dist/function/functions.types.d.ts +9 -5
  10. package/dist/function/index.d.ts +1 -1
  11. package/dist/index.d.ts +14 -19
  12. package/dist/index.js +6 -11
  13. package/dist/middleware/auth-cookie.d.ts +0 -4
  14. package/dist/middleware/auth-cookie.js +38 -2
  15. package/dist/middleware/cors.js +1 -0
  16. package/dist/middleware/index.d.ts +1 -1
  17. package/dist/middleware/index.js +1 -1
  18. package/dist/middleware/remote-auth.js +14 -3
  19. package/dist/permissions.d.ts +8 -10
  20. package/dist/permissions.js +0 -11
  21. package/dist/pikku-state.js +16 -5
  22. package/dist/schema.js +35 -1
  23. package/dist/services/ai-agent-runner-service.d.ts +7 -0
  24. package/dist/services/ai-run-state-service.d.ts +17 -1
  25. package/dist/services/in-memory-ai-run-state-service.d.ts +6 -2
  26. package/dist/services/in-memory-ai-run-state-service.js +11 -1
  27. package/dist/services/in-memory-workflow-service.js +2 -0
  28. package/dist/services/index.d.ts +15 -15
  29. package/dist/services/index.js +5 -5
  30. package/dist/services/local-content-request-handler.d.ts +21 -0
  31. package/dist/services/local-content-request-handler.js +72 -53
  32. package/dist/services/local-content.d.ts +6 -0
  33. package/dist/services/local-content.js +14 -1
  34. package/dist/services/scoped-credential-service.d.ts +21 -0
  35. package/dist/services/scoped-credential-service.js +53 -0
  36. package/dist/services/workflow-service.d.ts +4 -2
  37. package/dist/testing/service-tests/agent-run-service-tests.d.ts +10 -0
  38. package/dist/testing/service-tests/agent-run-service-tests.js +72 -0
  39. package/dist/testing/service-tests/ai-storage-service-tests.d.ts +3 -0
  40. package/dist/testing/service-tests/ai-storage-service-tests.js +302 -0
  41. package/dist/testing/service-tests/channel-store-tests.d.ts +3 -0
  42. package/dist/testing/service-tests/channel-store-tests.js +72 -0
  43. package/dist/testing/service-tests/credential-service-tests.d.ts +3 -0
  44. package/dist/testing/service-tests/credential-service-tests.js +109 -0
  45. package/dist/testing/service-tests/deployment-service-tests.d.ts +3 -0
  46. package/dist/testing/service-tests/deployment-service-tests.js +21 -0
  47. package/dist/testing/service-tests/event-hub-store-tests.d.ts +3 -0
  48. package/dist/testing/service-tests/event-hub-store-tests.js +34 -0
  49. package/dist/testing/service-tests/secret-service-tests.d.ts +3 -0
  50. package/dist/testing/service-tests/secret-service-tests.js +80 -0
  51. package/dist/testing/service-tests/session-store-tests.d.ts +3 -0
  52. package/dist/testing/service-tests/session-store-tests.js +43 -0
  53. package/dist/testing/service-tests/workflow-run-service-tests.d.ts +3 -0
  54. package/dist/testing/service-tests/workflow-run-service-tests.js +42 -0
  55. package/dist/testing/service-tests/workflow-service-tests.d.ts +3 -0
  56. package/dist/testing/service-tests/workflow-service-tests.js +150 -0
  57. package/dist/testing/service-tests.d.ts +6 -0
  58. package/dist/testing/service-tests.js +26 -791
  59. package/dist/types/core.types.d.ts +11 -3
  60. package/dist/types/state.types.d.ts +14 -1
  61. package/dist/wirings/actor-flow/index.d.ts +1 -1
  62. package/dist/wirings/actor-flow/run-conversation.js +1 -6
  63. package/dist/wirings/ai-agent/agent-rpc.d.ts +15 -0
  64. package/dist/wirings/ai-agent/agent-rpc.js +53 -0
  65. package/dist/wirings/ai-agent/ai-agent-agui.js +1 -5
  66. package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +58 -0
  67. package/dist/wirings/ai-agent/ai-agent-finalize.js +138 -0
  68. package/dist/wirings/ai-agent/ai-agent-interrupt.js +1 -0
  69. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +2 -8
  70. package/dist/wirings/ai-agent/ai-agent-memory.js +37 -18
  71. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +7 -0
  72. package/dist/wirings/ai-agent/ai-agent-model-config.js +44 -1
  73. package/dist/wirings/ai-agent/ai-agent-prepare.js +5 -9
  74. package/dist/wirings/ai-agent/ai-agent-runner.js +89 -147
  75. package/dist/wirings/ai-agent/ai-agent-stream.js +109 -97
  76. package/dist/wirings/ai-agent/ai-agent-turn.d.ts +57 -0
  77. package/dist/wirings/ai-agent/ai-agent-turn.js +82 -0
  78. package/dist/wirings/ai-agent/ai-agent.types.d.ts +47 -2
  79. package/dist/wirings/ai-agent/index.d.ts +8 -7
  80. package/dist/wirings/ai-agent/index.js +5 -4
  81. package/dist/wirings/ai-agent/voice-input.js +1 -6
  82. package/dist/wirings/ai-agent/voice-output.js +2 -12
  83. package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +26 -0
  84. package/dist/wirings/ai-scorer/ai-scorer-grade.js +33 -0
  85. package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +17 -0
  86. package/dist/wirings/ai-scorer/ai-scorer-judge.js +92 -0
  87. package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +15 -0
  88. package/dist/wirings/ai-scorer/ai-scorer-live.js +38 -0
  89. package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +18 -0
  90. package/dist/wirings/ai-scorer/ai-scorer-registry.js +46 -0
  91. package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +8 -0
  92. package/dist/wirings/ai-scorer/ai-scorer-sampling.js +31 -0
  93. package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +10 -0
  94. package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +40 -0
  95. package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +15 -0
  96. package/dist/wirings/ai-scorer/ai-scorer-worker.js +58 -0
  97. package/dist/wirings/ai-scorer/ai-scorer.d.ts +39 -0
  98. package/dist/wirings/ai-scorer/ai-scorer.js +40 -0
  99. package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +90 -0
  100. package/dist/wirings/ai-scorer/ai-scorer.types.js +4 -0
  101. package/dist/wirings/ai-scorer/index.d.ts +6 -0
  102. package/dist/wirings/ai-scorer/index.js +5 -0
  103. package/dist/wirings/channel/channel-common.js +1 -0
  104. package/dist/wirings/channel/channel-handler.js +3 -5
  105. package/dist/wirings/channel/channel-rpc-service.d.ts +0 -6
  106. package/dist/wirings/channel/channel-rpc-service.js +0 -8
  107. package/dist/wirings/channel/channel-rpc.types.d.ts +6 -0
  108. package/dist/wirings/channel/channel-rpc.types.js +8 -0
  109. package/dist/wirings/channel/channel-runner.d.ts +1 -3
  110. package/dist/wirings/channel/channel-runner.js +16 -8
  111. package/dist/wirings/channel/channel.types.d.ts +2 -0
  112. package/dist/wirings/channel/index.d.ts +5 -6
  113. package/dist/wirings/channel/index.js +3 -4
  114. package/dist/wirings/channel/local/local-channel-runner.js +8 -1
  115. package/dist/wirings/channel/pikku-abstract-channel-handler.js +1 -0
  116. package/dist/wirings/channel/serverless/serverless-channel-runner.js +3 -0
  117. package/dist/wirings/cli/channel/cli-channel-runner.js +2 -0
  118. package/dist/wirings/cli/channel/cli-raw-channel-runner.js +9 -1
  119. package/dist/wirings/cli/channel/index.d.ts +1 -2
  120. package/dist/wirings/cli/channel/index.js +0 -1
  121. package/dist/wirings/cli/cli-runner.js +17 -3
  122. package/dist/wirings/cli/cli.types.d.ts +0 -8
  123. package/dist/wirings/cli/command-parser.js +13 -0
  124. package/dist/wirings/credential/index.d.ts +1 -1
  125. package/dist/wirings/gateway/gateway-runner.js +9 -2
  126. package/dist/wirings/gateway/index.d.ts +1 -1
  127. package/dist/wirings/http/http-routes.js +2 -0
  128. package/dist/wirings/http/http-runner.d.ts +0 -10
  129. package/dist/wirings/http/http-runner.js +14 -15
  130. package/dist/wirings/http/http.types.d.ts +0 -10
  131. package/dist/wirings/http/index.d.ts +2 -3
  132. package/dist/wirings/http/index.js +1 -1
  133. package/dist/wirings/mcp/index.d.ts +1 -1
  134. package/dist/wirings/mcp/mcp-runner.d.ts +15 -7
  135. package/dist/wirings/mcp/mcp-runner.js +18 -11
  136. package/dist/wirings/persona/index.d.ts +3 -4
  137. package/dist/wirings/persona/index.js +2 -3
  138. package/dist/wirings/queue/index.d.ts +1 -3
  139. package/dist/wirings/queue/index.js +1 -3
  140. package/dist/wirings/rpc/addon-runner.d.ts +4 -0
  141. package/dist/wirings/rpc/addon-runner.js +19 -3
  142. package/dist/wirings/rpc/rpc-runner.d.ts +8 -51
  143. package/dist/wirings/rpc/rpc-runner.js +55 -86
  144. package/dist/wirings/rpc/rpc-types.d.ts +7 -0
  145. package/dist/wirings/rpc/wire-addon.d.ts +13 -0
  146. package/dist/wirings/rpc/wire-addon.js +4 -0
  147. package/dist/wirings/scheduler/index.d.ts +1 -1
  148. package/dist/wirings/secret/validate-secret-definitions.js +2 -2
  149. package/dist/wirings/trigger/index.d.ts +1 -1
  150. package/dist/wirings/trigger/pikku-trigger-service.d.ts +0 -4
  151. package/dist/wirings/trigger/trigger-runner.js +1 -0
  152. package/dist/wirings/virtual-user/index.d.ts +5 -6
  153. package/dist/wirings/virtual-user/index.js +2 -4
  154. package/dist/wirings/virtual-user/run-virtual-user.js +11 -11
  155. package/dist/wirings/virtual-user/virtual-user-derive.js +4 -25
  156. package/dist/wirings/virtual-user/virtual-user-dispositions.js +1 -4
  157. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +100 -3
  158. package/dist/wirings/workflow/feature.js +7 -4
  159. package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -2
  160. package/dist/wirings/workflow/graph/graph-runner.js +8 -7
  161. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -4
  162. package/dist/wirings/workflow/index.d.ts +12 -7
  163. package/dist/wirings/workflow/index.js +7 -3
  164. package/dist/wirings/workflow/pikku-scenario-service.d.ts +17 -3
  165. package/dist/wirings/workflow/pikku-scenario-service.js +64 -10
  166. package/dist/wirings/workflow/pikku-workflow-service.d.ts +28 -147
  167. package/dist/wirings/workflow/pikku-workflow-service.js +85 -493
  168. package/dist/wirings/workflow/scenario-step.types.d.ts +8 -0
  169. package/dist/wirings/workflow/workflow-approval-audit.d.ts +16 -0
  170. package/dist/wirings/workflow/workflow-approval-audit.js +40 -0
  171. package/dist/wirings/workflow/workflow-approval-policy.d.ts +20 -0
  172. package/dist/wirings/workflow/workflow-approval-policy.js +48 -0
  173. package/dist/wirings/workflow/workflow-approval.d.ts +67 -0
  174. package/dist/wirings/workflow/workflow-approval.js +177 -0
  175. package/dist/wirings/workflow/workflow-constants.d.ts +26 -0
  176. package/dist/wirings/workflow/workflow-constants.js +35 -0
  177. package/dist/wirings/workflow/workflow-errors.d.ts +58 -0
  178. package/dist/wirings/workflow/workflow-errors.js +112 -0
  179. package/dist/wirings/workflow/workflow-meta-resolver.d.ts +11 -0
  180. package/dist/wirings/workflow/workflow-meta-resolver.js +31 -0
  181. package/dist/wirings/workflow/workflow-queue-routing.d.ts +8 -0
  182. package/dist/wirings/workflow/workflow-queue-routing.js +38 -0
  183. package/dist/wirings/workflow/workflow-queue-wiring.d.ts +20 -0
  184. package/dist/wirings/workflow/workflow-queue-wiring.js +79 -0
  185. package/dist/wirings/workflow/workflow-recovery.d.ts +68 -0
  186. package/dist/wirings/workflow/workflow-recovery.js +101 -0
  187. package/dist/wirings/workflow/workflow-run-engine.types.d.ts +54 -0
  188. package/dist/wirings/workflow/workflow-run-ownership.d.ts +17 -0
  189. package/dist/wirings/workflow/workflow-run-ownership.js +30 -0
  190. package/dist/wirings/workflow/workflow-suspend.d.ts +12 -0
  191. package/dist/wirings/workflow/workflow-suspend.js +33 -0
  192. package/dist/wirings/workflow/workflow.types.d.ts +8 -1
  193. package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-airunstate-too.md +22 -0
  194. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +20 -0
  195. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +21 -0
  196. package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +21 -0
  197. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +46 -0
  198. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +45 -0
  199. package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +32 -0
  200. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +21 -0
  201. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +22 -0
  202. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +39 -0
  203. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +23 -0
  204. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +25 -0
  205. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +22 -0
  206. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +20 -0
  207. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +22 -0
  208. package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +66 -0
  209. package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +33 -0
  210. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +43 -0
  211. package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +26 -0
  212. package/knowledge/decisions/internals/index.md +42 -3
  213. package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +21 -0
  214. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +24 -0
  215. package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +34 -0
  216. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +24 -0
  217. package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +22 -0
  218. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +26 -0
  219. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +43 -0
  220. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +58 -0
  221. package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +40 -0
  222. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +40 -0
  223. package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +28 -0
  224. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +25 -0
  225. package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +21 -0
  226. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +22 -0
  227. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +25 -0
  228. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +115 -0
  229. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +21 -0
  230. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +24 -0
  231. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +35 -0
  232. package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +4 -2
  233. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +37 -0
  234. package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +33 -0
  235. package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +33 -0
  236. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +37 -0
  237. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +28 -0
  238. package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +50 -0
  239. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +33 -0
  240. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +59 -0
  241. package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +24 -0
  242. package/knowledge/decisions/security/index.md +9 -0
  243. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +35 -0
  244. package/knowledge/questions/index.md +2 -1
  245. package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +44 -0
  246. package/package.json +15 -3
  247. package/scripts/generate-api-report.d.mts +1 -0
  248. package/scripts/generate-api-report.mjs +89 -0
  249. package/scripts/generate-api-report.mts +343 -0
  250. package/src/api-report.test.ts +69 -0
  251. package/src/column-form.ts +1 -4
  252. package/src/crypto-utils.test.ts +15 -2
  253. package/src/dev/hot-reload.ts +2 -7
  254. package/src/ecosystem.ts +40 -0
  255. package/src/errors/error-handler.ts +5 -3
  256. package/src/errors/error.test.ts +4 -1
  257. package/src/errors/index.ts +1 -1
  258. package/src/function/function-runner.test.ts +53 -1
  259. package/src/function/function-runner.ts +33 -48
  260. package/src/function/functions.types.ts +15 -9
  261. package/src/function/index.ts +0 -2
  262. package/src/handle-error.ts +1 -1
  263. package/src/index.ts +3 -57
  264. package/src/middleware/auth-cookie.test.ts +50 -0
  265. package/src/middleware/auth-cookie.ts +38 -2
  266. package/src/middleware/cors.ts +2 -1
  267. package/src/middleware/index.ts +1 -1
  268. package/src/middleware/remote-auth.test.ts +43 -0
  269. package/src/middleware/remote-auth.ts +17 -3
  270. package/src/middleware-runner.ts +4 -2
  271. package/src/no-any-casts.test.ts +57 -0
  272. package/src/permissions.test.ts +3 -1
  273. package/src/permissions.ts +22 -24
  274. package/src/pikku-state.ts +22 -6
  275. package/src/public-surface.json +554 -0
  276. package/src/public-surface.json.README +25 -0
  277. package/src/public-surface.test.ts +105 -0
  278. package/src/removed-legacy-exports.test.ts +62 -0
  279. package/src/schema.test.ts +78 -0
  280. package/src/schema.ts +36 -1
  281. package/src/services/ai-agent-runner-service.ts +12 -1
  282. package/src/services/ai-run-state-service.ts +18 -1
  283. package/src/services/audit-service.ts +2 -2
  284. package/src/services/in-memory-ai-run-state-service.ts +16 -2
  285. package/src/services/in-memory-workflow-service.ts +2 -0
  286. package/src/services/index.ts +4 -47
  287. package/src/services/local-content-request-handler.test.ts +43 -5
  288. package/src/services/local-content-request-handler.ts +103 -74
  289. package/src/services/local-content.ts +15 -1
  290. package/src/services/local-email-service.ts +5 -1
  291. package/src/services/scoped-credential-service.test.ts +86 -0
  292. package/src/services/scoped-credential-service.ts +63 -0
  293. package/src/services/system-role-guard.test.ts +4 -1
  294. package/src/services/workflow-service.ts +9 -2
  295. package/src/side-effects-are-declared.test.ts +84 -0
  296. package/src/source-files-stay-composable.test.ts +41 -0
  297. package/src/testing/service-tests/agent-run-service-tests.ts +98 -0
  298. package/src/testing/service-tests/ai-storage-service-tests.ts +379 -0
  299. package/src/testing/service-tests/channel-store-tests.ts +98 -0
  300. package/src/testing/service-tests/credential-service-tests.ts +143 -0
  301. package/src/testing/service-tests/deployment-service-tests.ts +33 -0
  302. package/src/testing/service-tests/event-hub-store-tests.ts +48 -0
  303. package/src/testing/service-tests/secret-service-tests.ts +105 -0
  304. package/src/testing/service-tests/session-store-tests.ts +62 -0
  305. package/src/testing/service-tests/workflow-run-service-tests.ts +59 -0
  306. package/src/testing/service-tests/workflow-service-tests.ts +308 -0
  307. package/src/testing/service-tests.ts +31 -1111
  308. package/src/types/core.types.ts +14 -3
  309. package/src/types/state.types.ts +17 -1
  310. package/src/wirings/actor-flow/index.ts +0 -3
  311. package/src/wirings/actor-flow/run-conversation.ts +1 -6
  312. package/src/wirings/ai-agent/agent-rpc.ts +120 -0
  313. package/src/wirings/ai-agent/ai-agent-agui.ts +1 -5
  314. package/src/wirings/ai-agent/ai-agent-finalize.test.ts +186 -0
  315. package/src/wirings/ai-agent/ai-agent-finalize.ts +197 -0
  316. package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +2 -1
  317. package/src/wirings/ai-agent/ai-agent-interrupt.ts +1 -0
  318. package/src/wirings/ai-agent/ai-agent-memory.ts +62 -39
  319. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +72 -3
  320. package/src/wirings/ai-agent/ai-agent-model-config.ts +49 -1
  321. package/src/wirings/ai-agent/ai-agent-prepare.ts +12 -12
  322. package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +1 -0
  323. package/src/wirings/ai-agent/ai-agent-runner.test.ts +82 -2
  324. package/src/wirings/ai-agent/ai-agent-runner.ts +120 -160
  325. package/src/wirings/ai-agent/ai-agent-stream-output-hooks.test.ts +353 -0
  326. package/src/wirings/ai-agent/ai-agent-stream.test.ts +2 -0
  327. package/src/wirings/ai-agent/ai-agent-stream.ts +152 -117
  328. package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +1 -1
  329. package/src/wirings/ai-agent/ai-agent-turn.test.ts +67 -0
  330. package/src/wirings/ai-agent/ai-agent-turn.ts +122 -0
  331. package/src/wirings/ai-agent/ai-agent.types.ts +65 -5
  332. package/src/wirings/ai-agent/index.ts +2 -16
  333. package/src/wirings/ai-agent/voice-input.ts +1 -6
  334. package/src/wirings/ai-agent/voice-output.ts +2 -12
  335. package/src/wirings/ai-scorer/ai-scorer-grade.test.ts +106 -0
  336. package/src/wirings/ai-scorer/ai-scorer-grade.ts +55 -0
  337. package/src/wirings/ai-scorer/ai-scorer-judge.test.ts +143 -0
  338. package/src/wirings/ai-scorer/ai-scorer-judge.ts +120 -0
  339. package/src/wirings/ai-scorer/ai-scorer-live.test.ts +174 -0
  340. package/src/wirings/ai-scorer/ai-scorer-live.ts +56 -0
  341. package/src/wirings/ai-scorer/ai-scorer-registry.ts +63 -0
  342. package/src/wirings/ai-scorer/ai-scorer-sampling.test.ts +34 -0
  343. package/src/wirings/ai-scorer/ai-scorer-sampling.ts +36 -0
  344. package/src/wirings/ai-scorer/ai-scorer-snapshots.test.ts +49 -0
  345. package/src/wirings/ai-scorer/ai-scorer-snapshots.ts +46 -0
  346. package/src/wirings/ai-scorer/ai-scorer-worker.test.ts +122 -0
  347. package/src/wirings/ai-scorer/ai-scorer-worker.ts +69 -0
  348. package/src/wirings/ai-scorer/ai-scorer.ts +76 -0
  349. package/src/wirings/ai-scorer/ai-scorer.types.ts +107 -0
  350. package/src/wirings/ai-scorer/index.ts +24 -0
  351. package/src/wirings/channel/channel-common.ts +5 -2
  352. package/src/wirings/channel/channel-handler-shapes.test.ts +72 -0
  353. package/src/wirings/channel/channel-handler.ts +7 -7
  354. package/src/wirings/channel/channel-rpc-service.ts +0 -14
  355. package/src/wirings/channel/channel-rpc.test.ts +25 -4
  356. package/src/wirings/channel/channel-rpc.types.ts +14 -0
  357. package/src/wirings/channel/channel-runner.ts +33 -20
  358. package/src/wirings/channel/channel.types.ts +2 -0
  359. package/src/wirings/channel/index.ts +1 -20
  360. package/src/wirings/channel/local/local-channel-runner.test.ts +68 -0
  361. package/src/wirings/channel/local/local-channel-runner.ts +9 -2
  362. package/src/wirings/channel/pikku-abstract-channel-handler.ts +2 -1
  363. package/src/wirings/channel/serverless/serverless-channel-runner.ts +6 -3
  364. package/src/wirings/cli/channel/cli-channel-runner.ts +3 -1
  365. package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +23 -0
  366. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +12 -1
  367. package/src/wirings/cli/channel/cli-raw-client-runner.ts +4 -1
  368. package/src/wirings/cli/channel/index.ts +0 -7
  369. package/src/wirings/cli/cli-runner.test.ts +68 -0
  370. package/src/wirings/cli/cli-runner.ts +25 -5
  371. package/src/wirings/cli/cli.types.ts +0 -39
  372. package/src/wirings/cli/command-parser.test.ts +19 -0
  373. package/src/wirings/cli/command-parser.ts +17 -1
  374. package/src/wirings/credential/index.ts +0 -1
  375. package/src/wirings/gateway/gateway-channel-meta.test.ts +44 -0
  376. package/src/wirings/gateway/gateway-runner.ts +27 -19
  377. package/src/wirings/gateway/index.ts +0 -3
  378. package/src/wirings/http/http-routes.ts +4 -1
  379. package/src/wirings/http/http-runner.test.ts +66 -0
  380. package/src/wirings/http/http-runner.ts +21 -28
  381. package/src/wirings/http/http.types.ts +0 -15
  382. package/src/wirings/http/index.ts +2 -8
  383. package/src/wirings/http/pikku-fetch-http-request.ts +2 -2
  384. package/src/wirings/http/web-request.ts +1 -1
  385. package/src/wirings/mcp/index.ts +0 -1
  386. package/src/wirings/mcp/mcp-runner.test.ts +181 -0
  387. package/src/wirings/mcp/mcp-runner.ts +37 -21
  388. package/src/wirings/persona/index.ts +0 -8
  389. package/src/wirings/persona/persona-environments.test.ts +14 -3
  390. package/src/wirings/persona/persona.test.ts +13 -3
  391. package/src/wirings/persona/validate-personas.ts +5 -1
  392. package/src/wirings/queue/index.ts +0 -14
  393. package/src/wirings/queue/queue-runner.ts +1 -1
  394. package/src/wirings/rpc/addon-auth-tags.test.ts +1 -5
  395. package/src/wirings/rpc/addon-runner.ts +34 -3
  396. package/src/wirings/rpc/addon-secrets.test.ts +261 -0
  397. package/src/wirings/rpc/rpc-runner.test.ts +2 -0
  398. package/src/wirings/rpc/rpc-runner.ts +60 -136
  399. package/src/wirings/rpc/rpc-types.ts +11 -0
  400. package/src/wirings/rpc/wire-addon.ts +20 -1
  401. package/src/wirings/scheduler/index.ts +0 -1
  402. package/src/wirings/secret/validate-secret-definitions.test.ts +22 -0
  403. package/src/wirings/secret/validate-secret-definitions.ts +2 -2
  404. package/src/wirings/trigger/index.ts +0 -1
  405. package/src/wirings/trigger/pikku-trigger-service.ts +0 -5
  406. package/src/wirings/trigger/trigger-runner.ts +7 -5
  407. package/src/wirings/virtual-user/index.ts +0 -16
  408. package/src/wirings/virtual-user/run-virtual-user.test.ts +18 -9
  409. package/src/wirings/virtual-user/run-virtual-user.ts +28 -15
  410. package/src/wirings/virtual-user/virtual-user-agents.test.ts +4 -1
  411. package/src/wirings/virtual-user/virtual-user-derive.ts +4 -25
  412. package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +7 -2
  413. package/src/wirings/virtual-user/virtual-user-dispositions.ts +1 -4
  414. package/src/wirings/virtual-user/virtual-user-intents.test.ts +13 -3
  415. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +117 -4
  416. package/src/wirings/workflow/feature.ts +7 -4
  417. package/src/wirings/workflow/graph/graph-node.ts +1 -1
  418. package/src/wirings/workflow/graph/graph-runner.test.ts +76 -2
  419. package/src/wirings/workflow/graph/graph-runner.ts +13 -16
  420. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -5
  421. package/src/wirings/workflow/index.ts +14 -24
  422. package/src/wirings/workflow/pikku-scenario-service.ts +101 -27
  423. package/src/wirings/workflow/pikku-workflow-service.test.ts +15 -14
  424. package/src/wirings/workflow/pikku-workflow-service.ts +214 -743
  425. package/src/wirings/workflow/scenario-expectations.test.ts +75 -0
  426. package/src/wirings/workflow/scenario-hooks.test.ts +52 -0
  427. package/src/wirings/workflow/scenario-step.types.ts +8 -0
  428. package/src/wirings/workflow/workflow-approval-audit.ts +47 -0
  429. package/src/wirings/workflow/workflow-approval-policy.test.ts +524 -0
  430. package/src/wirings/workflow/workflow-approval-policy.ts +68 -0
  431. package/src/wirings/workflow/workflow-approval.ts +289 -0
  432. package/src/wirings/workflow/workflow-child-run-session.test.ts +89 -0
  433. package/src/wirings/workflow/workflow-constants.ts +47 -0
  434. package/src/wirings/workflow/workflow-dispatch-durability.test.ts +1 -1
  435. package/src/wirings/workflow/workflow-errors.ts +128 -0
  436. package/src/wirings/workflow/workflow-inline-authority.test.ts +12 -6
  437. package/src/wirings/workflow/workflow-meta-resolver.ts +45 -0
  438. package/src/wirings/workflow/workflow-missing-meta.test.ts +92 -0
  439. package/src/wirings/workflow/workflow-queue-routing.ts +85 -0
  440. package/src/wirings/workflow/workflow-queue-wiring.ts +149 -0
  441. package/src/wirings/workflow/workflow-recovery.ts +162 -0
  442. package/src/wirings/workflow/workflow-retry-policy.test.ts +1 -1
  443. package/src/wirings/workflow/workflow-run-authority.test.ts +212 -0
  444. package/src/wirings/workflow/workflow-run-engine.types.ts +91 -0
  445. package/src/wirings/workflow/workflow-run-ownership.ts +37 -0
  446. package/src/wirings/workflow/workflow-suspend.ts +61 -0
  447. package/src/wirings/workflow/workflow.types.ts +7 -9
  448. package/src/wirings-stay-decoupled.test.ts +127 -0
  449. package/tsconfig.json +1 -1
  450. package/tsconfig.tsbuildinfo +1 -1
  451. package/dist/internal.d.ts +0 -3
  452. package/dist/internal.js +0 -2
  453. package/dist/middleware/timeout.d.ts +0 -9
  454. package/dist/middleware/timeout.js +0 -15
  455. package/dist/pikku-response.d.ts +0 -6
  456. package/dist/pikku-response.js +0 -6
  457. package/dist/services/gopass-secrets.d.ts +0 -15
  458. package/dist/services/gopass-secrets.js +0 -76
  459. package/dist/services/http-scenario-actors.d.ts +0 -75
  460. package/dist/services/http-scenario-actors.js +0 -195
  461. package/dist/services/http-user-flow-actors.d.ts +0 -67
  462. package/dist/services/http-user-flow-actors.js +0 -193
  463. package/dist/services/scenario-actors-service.d.ts +0 -127
  464. package/dist/services/scenario-actors-service.js +0 -40
  465. package/dist/services/user-flow-actors-service.d.ts +0 -39
  466. package/dist/wirings/credential/wire-credential.d.ts +0 -48
  467. package/dist/wirings/credential/wire-credential.js +0 -47
  468. package/dist/wirings/oauth2/oauth2-client.d.ts +0 -47
  469. package/dist/wirings/oauth2/oauth2-client.js +0 -263
  470. package/dist/wirings/oauth2/oauth2-routes.d.ts +0 -35
  471. package/dist/wirings/oauth2/oauth2-routes.js +0 -146
  472. package/dist/wirings/scope/wire-scope.d.ts +0 -33
  473. package/dist/wirings/scope/wire-scope.js +0 -32
  474. package/dist/wirings/workflow/dsl/index.d.ts +0 -5
  475. package/dist/wirings/workflow/dsl/index.js +0 -4
  476. package/dist/wirings/workflow/graph/index.d.ts +0 -5
  477. package/dist/wirings/workflow/graph/index.js +0 -4
  478. package/src/internal.ts +0 -10
  479. /package/dist/{services/user-flow-actors-service.js → wirings/workflow/workflow-run-engine.types.js} +0 -0
@@ -13,6 +13,14 @@ import { PikkuError, addError } from '../../errors/error-handler.js'
13
13
  import type { PikkuRPC, ResolvedFunction } from './rpc-types.js'
14
14
  import { parseVersionedId } from '../../version.js'
15
15
  import { resolveRemoteAddonToken } from './remote-addon-auth.js'
16
+ import { createAgentRPC } from '../ai-agent/agent-rpc.js'
17
+
18
+ /**
19
+ * The session for a wire: read through `getSession` when a runner attached one,
20
+ * otherwise whatever was placed on the wire directly.
21
+ */
22
+ const resolveWireSession = async (wire: PikkuRawWire) =>
23
+ typeof wire.getSession === 'function' ? await wire.getSession() : wire.session
16
24
 
17
25
  export class RPCNotFoundError extends PikkuError {
18
26
  public readonly rpcName: string
@@ -55,16 +63,6 @@ addError(RemoteAddonRequestError, {
55
63
  status: 502,
56
64
  message: 'Remote addon request failed.',
57
65
  })
58
- import type { AIAgentInput } from '../ai-agent/ai-agent.types.js'
59
- import type { AIStreamChannel } from '../ai-agent/ai-agent.types.js'
60
- import type { StreamAIAgentOptions } from '../ai-agent/ai-agent-prepare.js'
61
- import { runAIAgent, resumeAIAgentSync } from '../ai-agent/ai-agent-runner.js'
62
- import {
63
- streamAIAgent,
64
- resumeAIAgent,
65
- interruptAIAgent,
66
- } from '../ai-agent/ai-agent-stream.js'
67
- import { wrapChannelWithAGUI } from '../ai-agent/ai-agent-agui.js'
68
66
 
69
67
  export const resolveNamespace = (
70
68
  namespacedFunction: string
@@ -209,10 +207,7 @@ export class ContextAwareRPCService {
209
207
  } catch (e) {
210
208
  if (e instanceof RPCNotFoundError) {
211
209
  if (this.services.deploymentService) {
212
- const session =
213
- this.wire.getSession && typeof this.wire.getSession === 'function'
214
- ? await this.wire.getSession()
215
- : (this.wire as any).session
210
+ const session = await resolveWireSession(this.wire)
216
211
  return this.services.deploymentService.invoke(
217
212
  funcName,
218
213
  data,
@@ -289,6 +284,8 @@ export class ContextAwareRPCService {
289
284
  secretOverrides: resolved.addonConfig?.secretOverrides,
290
285
  variableOverrides: resolved.addonConfig?.variableOverrides,
291
286
  credentialOverrides: resolved.addonConfig?.credentialOverrides,
287
+ globalSecrets: resolved.addonConfig?.globalSecrets,
288
+ globalCredentials: resolved.addonConfig?.globalCredentials,
292
289
  },
293
290
  }
294
291
  }
@@ -405,10 +402,7 @@ export class ContextAwareRPCService {
405
402
  resolved = resolvePikkuFunction(rpcName, this.packageName)
406
403
  } catch (e) {
407
404
  if (e instanceof RPCNotFoundError && this.services.deploymentService) {
408
- const session =
409
- this.wire.getSession && typeof this.wire.getSession === 'function'
410
- ? await this.wire.getSession()
411
- : (this.wire as any).session
405
+ const session = await resolveWireSession(this.wire)
412
406
  return this.services.deploymentService.invoke(
413
407
  rpcName,
414
408
  data,
@@ -462,108 +456,15 @@ export class ContextAwareRPCService {
462
456
  )
463
457
  }
464
458
 
465
- public get agent() {
466
- return {
467
- run: async (agentName: string, input: AIAgentInput) => {
468
- const result = await runAIAgent(agentName, input, {
469
- sessionService: this.options.sessionService,
470
- getCredential: this.wire.getCredential?.bind(this.wire),
471
- })
472
- return {
473
- runId: result.runId,
474
- result: result.object ?? result.text,
475
- usage: result.usage,
476
- ...(result.status === 'suspended' && {
477
- status: 'suspended' as const,
478
- pendingApprovals: result.pendingApprovals,
479
- }),
480
- }
481
- },
482
- stream: async (
483
- agentName: string,
484
- input: {
485
- message: string
486
- threadId: string
487
- resourceId: string
488
- model?: string
489
- temperature?: number
490
- },
491
- options?: StreamAIAgentOptions
492
- ) => {
493
- const channel = this.wire.channel as unknown as AIStreamChannel
494
- if (!channel) throw new Error('No channel available for streaming')
495
- let currentRunId: string | undefined
496
- await streamAIAgent(
497
- agentName,
498
- input,
499
- wrapChannelWithAGUI(channel, {
500
- threadId: input.threadId,
501
- getRunId: () => currentRunId,
502
- }),
503
- {
504
- sessionService: this.options.sessionService,
505
- getCredential: this.wire.getCredential?.bind(this.wire),
506
- },
507
- undefined,
508
- {
509
- ...options,
510
- onRunCreated: (runId) => {
511
- currentRunId = runId
512
- options?.onRunCreated?.(runId)
513
- },
514
- }
515
- )
516
- },
517
- resume: async (
518
- runId: string,
519
- input: { toolCallId: string; approved: boolean },
520
- options?: StreamAIAgentOptions
521
- ) => {
522
- const channel = this.wire.channel as unknown as AIStreamChannel
523
- if (!channel) throw new Error('No channel available for streaming')
524
- await resumeAIAgent(
525
- { runId, ...input },
526
- wrapChannelWithAGUI(channel, { runId }),
527
- {
528
- sessionService: this.options.sessionService,
529
- getCredential: this.wire.getCredential?.bind(this.wire),
530
- },
531
- options
532
- )
533
- },
534
- interrupt: async (
535
- runId: string,
536
- reason?: 'speech' | 'user' | 'timeout'
537
- ) => {
538
- return interruptAIAgent(
539
- { runId, ...(reason ? { reason } : {}) },
540
- { sessionService: this.options.sessionService }
541
- )
542
- },
543
- approve: async (
544
- runId: string,
545
- approvals: { toolCallId: string; approved: boolean }[],
546
- expectedAgentName?: string
547
- ) => {
548
- const result = await resumeAIAgentSync(
549
- runId,
550
- approvals,
551
- {
552
- sessionService: this.options.sessionService,
553
- },
554
- expectedAgentName
555
- )
556
- return {
557
- runId: result.runId,
558
- result: result.object ?? result.text,
559
- usage: result.usage,
560
- ...(result.status === 'suspended' && {
561
- status: 'suspended' as const,
562
- pendingApprovals: result.pendingApprovals,
563
- }),
564
- }
565
- },
566
- }
459
+ /**
460
+ * The agent facade, built on access.
461
+ *
462
+ * The implementation lives in `ai-agent/agent-rpc.ts` so the agent surface is
463
+ * one file rather than a wing of this one; a getter rather than a field so a
464
+ * request that never touches an agent never builds it.
465
+ */
466
+ public get agent(): PikkuRPC['agent'] {
467
+ return createAgentRPC(this.wire, this.options)
567
468
  }
568
469
 
569
470
  public async remote<In = any, Out = any>(
@@ -577,10 +478,7 @@ export class ContextAwareRPCService {
577
478
  )
578
479
  }
579
480
 
580
- const session =
581
- this.wire.getSession && typeof this.wire.getSession === 'function'
582
- ? await this.wire.getSession()
583
- : (this.wire as any).session
481
+ const session = await resolveWireSession(this.wire)
584
482
 
585
483
  return this.services.deploymentService.invoke(
586
484
  funcName,
@@ -619,18 +517,44 @@ export class PikkuRPCService<
619
517
  options,
620
518
  packageName
621
519
  )
622
- return {
623
- depth,
624
- global: false,
625
- invoke: serviceRPC.rpc.bind(serviceRPC),
626
- remote: serviceRPC.remote.bind(serviceRPC),
627
- exposed: serviceRPC.rpcExposed.bind(serviceRPC),
628
- startWorkflow: serviceRPC.startWorkflow.bind(serviceRPC),
629
- get agent() {
630
- return serviceRPC.agent
631
- },
632
- rpcWithWire: serviceRPC.rpcWithWire.bind(serviceRPC),
633
- } as any
520
+ // `TypedRPC` is named by the caller from its generated RPC map. Nothing
521
+ // concrete can satisfy a type the caller has not chosen yet.
522
+ return new ContextRPCView(serviceRPC, depth) as TypedRPC
523
+ }
524
+ }
525
+
526
+ /**
527
+ * The per-invocation `wire.rpc`.
528
+ *
529
+ * A class rather than an object literal because `agent` has to stay lazy — most
530
+ * requests never touch it — and an accessor declared on an object literal is
531
+ * defined per instance, which drops the literal off V8's fast construction
532
+ * path. Measured at ~1.15µs per request as a literal against ~0.47µs here, on
533
+ * the hot path every request takes.
534
+ *
535
+ * knowledge: decisions/internals/the-per-invocation-rpc-view-is-a-class.md
536
+ */
537
+ class ContextRPCView {
538
+ public readonly global = false
539
+ public readonly invoke: ContextAwareRPCService['rpc']
540
+ public readonly remote: ContextAwareRPCService['remote']
541
+ public readonly exposed: ContextAwareRPCService['rpcExposed']
542
+ public readonly startWorkflow: ContextAwareRPCService['startWorkflow']
543
+ public readonly rpcWithWire: ContextAwareRPCService['rpcWithWire']
544
+
545
+ constructor(
546
+ private readonly serviceRPC: ContextAwareRPCService,
547
+ public readonly depth: number
548
+ ) {
549
+ this.invoke = serviceRPC.rpc.bind(serviceRPC)
550
+ this.remote = serviceRPC.remote.bind(serviceRPC)
551
+ this.exposed = serviceRPC.rpcExposed.bind(serviceRPC)
552
+ this.startWorkflow = serviceRPC.startWorkflow.bind(serviceRPC)
553
+ this.rpcWithWire = serviceRPC.rpcWithWire.bind(serviceRPC)
554
+ }
555
+
556
+ get agent() {
557
+ return this.serviceRPC.agent
634
558
  }
635
559
  }
636
560
 
@@ -1,3 +1,4 @@
1
+ import type { PikkuRawWire } from '../../types/core.types.js'
1
2
  import type { AgentInterruptResult } from '../ai-agent/ai-agent-interrupt.js'
2
3
 
3
4
  export type PikkuRPC<
@@ -12,6 +13,12 @@ export type PikkuRPC<
12
13
  invoke: Invoke
13
14
  remote: Remote
14
15
  exposed: (name: string, data: any) => Promise<any>
16
+ /** Invoke an RPC with explicit wire fields merged over the caller's. */
17
+ rpcWithWire: <In = any, Out = any>(
18
+ rpcName: string,
19
+ data: In,
20
+ wire: PikkuRawWire
21
+ ) => Promise<Out>
15
22
  startWorkflow: startWorkflow
16
23
  agent: {
17
24
  run: AgentRun
@@ -60,6 +67,10 @@ export interface ResolvedFunction {
60
67
  secretOverrides?: Record<string, string>
61
68
  variableOverrides?: Record<string, string>
62
69
  credentialOverrides?: Record<string, string>
70
+ /** Set by the consuming app: hand this instance the unscoped `SecretService` */
71
+ globalSecrets?: string
72
+ /** Set by the consuming app: hand this instance the unscoped `CredentialService` */
73
+ globalCredentials?: string
63
74
  /** Set by `wireRemoteAddon`: dispatch this namespace's RPCs over HTTP */
64
75
  remote?: boolean
65
76
  serverUrl?: string | ((services: any) => string | Promise<string>)
@@ -14,6 +14,19 @@ export type WireAddonConfig = {
14
14
  secretOverrides?: Record<string, string>
15
15
  variableOverrides?: Record<string, string>
16
16
  credentialOverrides?: Record<string, string>
17
+ /**
18
+ * Hands this instance the whole `SecretService` instead of one scoped to the
19
+ * secrets it declared. The value is the reason, recorded in the deploy
20
+ * manifest — an addon that names secrets at runtime cannot be scoped, and
21
+ * only the consuming app, never the addon, can grant it.
22
+ */
23
+ globalSecrets?: string
24
+ /**
25
+ * Hands this instance the whole `CredentialService` instead of one narrowed
26
+ * to the credentials it declared. The value is the reason, recorded in the
27
+ * deploy manifest, and only the consuming app can grant it.
28
+ */
29
+ globalCredentials?: string
17
30
  }
18
31
 
19
32
  export const wireAddon = (config: WireAddonConfig): void => {
@@ -32,6 +45,10 @@ export const wireAddon = (config: WireAddonConfig): void => {
32
45
  ...(config.credentialOverrides
33
46
  ? { credentialOverrides: config.credentialOverrides }
34
47
  : {}),
48
+ ...(config.globalSecrets ? { globalSecrets: config.globalSecrets } : {}),
49
+ ...(config.globalCredentials
50
+ ? { globalCredentials: config.globalCredentials }
51
+ : {}),
35
52
  })
36
53
  }
37
54
 
@@ -61,7 +78,9 @@ const governingAddonConfigs = (
61
78
  }
62
79
  }
63
80
 
64
- return [...addons.values()].filter((config) => config?.package === packageName)
81
+ return [...addons.values()].filter(
82
+ (config) => config?.package === packageName
83
+ )
65
84
  }
66
85
 
67
86
  const unionOf = (
@@ -7,5 +7,4 @@ export { logSchedulers } from './log-schedulers.js'
7
7
  export type {
8
8
  CoreScheduledTask,
9
9
  ScheduledTasksMeta,
10
- PikkuScheduledTask,
11
10
  } from './scheduler.types.js'
@@ -22,6 +22,28 @@ describe('validateAndBuildSecretDefinitionsMeta', () => {
22
22
  assert.strictEqual(result['stripe'].displayName, 'Stripe')
23
23
  })
24
24
 
25
+ test('carries allowedHosts into the meta so the egress binding is enforced', () => {
26
+ const definitions = [
27
+ {
28
+ name: 'notion',
29
+ displayName: 'Notion',
30
+ secretId: 'NOTION_KEY',
31
+ allowedHosts: ['api.notion.com', '*.notion.com'],
32
+ sourceFile: 'a.ts',
33
+ },
34
+ ]
35
+ const result = validateAndBuildSecretDefinitionsMeta(
36
+ definitions as any,
37
+ new Map()
38
+ )
39
+ // assertSecretAllowedForHost reads allowedHosts off this meta; if it is
40
+ // dropped here the host binding silently permits every host.
41
+ assert.deepStrictEqual(result['notion']!.allowedHosts, [
42
+ 'api.notion.com',
43
+ '*.notion.com',
44
+ ])
45
+ })
46
+
25
47
  test('should allow duplicate secretId with same schema', () => {
26
48
  const schemaLookup = new Map([
27
49
  ['schema1', { variableName: 'Schema', sourceFile: 'types.ts' }],
@@ -56,8 +56,8 @@ export function validateAndBuildSecretDefinitionsMeta(
56
56
  schema: def.schema,
57
57
  oauth2: def.oauth2,
58
58
  rotationPeriod: def.rotationPeriod,
59
- docsUrl: def.docsUrl,
60
59
  allowedHosts: def.allowedHosts,
60
+ docsUrl: def.docsUrl,
61
61
  sourceFile: def.sourceFile,
62
62
  }
63
63
  }
@@ -75,8 +75,8 @@ export function validateAndBuildSecretDefinitionsMeta(
75
75
  schema: def.schema,
76
76
  oauth2: def.oauth2,
77
77
  rotationPeriod: def.rotationPeriod,
78
- docsUrl: def.docsUrl,
79
78
  allowedHosts: def.allowedHosts,
79
+ docsUrl: def.docsUrl,
80
80
  sourceFile: def.sourceFile,
81
81
  }
82
82
  }
@@ -6,5 +6,4 @@ export type {
6
6
  CorePikkuTriggerFunction,
7
7
  CorePikkuTriggerFunctionConfig,
8
8
  CoreTrigger,
9
- PikkuTrigger,
10
9
  } from './trigger.types.js'
@@ -14,11 +14,6 @@ export type TriggerTarget = {
14
14
  startNode?: string
15
15
  }
16
16
 
17
- export type TriggerSourceInfo = {
18
- name: string
19
- input: unknown
20
- }
21
-
22
17
  export abstract class PikkuTriggerService implements TriggerService {
23
18
  protected activeTriggers = new Map<string, TriggerInstance>()
24
19
 
@@ -10,6 +10,7 @@ import {
10
10
  getCreateWireServices,
11
11
  } from '../../pikku-state.js'
12
12
  import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
13
+ import type { CorePikkuFunctionConfig } from '../../function/functions.types.js'
13
14
  import { PikkuMissingMetaError } from '../../errors/errors.js'
14
15
 
15
16
  export const wireTrigger = (trigger: CoreTrigger) => {
@@ -22,10 +23,10 @@ export const wireTrigger = (trigger: CoreTrigger) => {
22
23
  return
23
24
  }
24
25
 
25
- addFunction(triggerMeta.pikkuFuncId, trigger.func as any)
26
+ addFunction(triggerMeta.pikkuFuncId, trigger.func)
26
27
 
27
28
  const triggers = pikkuState(null, 'trigger', 'triggers')
28
- triggers.set(trigger.name, trigger as any)
29
+ triggers.set(trigger.name, trigger)
29
30
  }
30
31
 
31
32
  // knowledge: decisions/internals/trigger-declaration-is-split-from-trigger-source.md
@@ -45,11 +46,12 @@ export const wireTriggerSource = <TInput = unknown, TOutput = unknown>(
45
46
  if (triggerSources.has(source.name)) {
46
47
  throw new Error(`Trigger source already exists: ${source.name}`)
47
48
  }
48
- triggerSources.set(source.name, source as any)
49
+ // knowledge: decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md
50
+ triggerSources.set(source.name, source as CoreTriggerSource)
49
51
 
50
52
  addFunction(
51
53
  triggerSourceMeta.pikkuFuncId,
52
- source.func as any,
54
+ source.func as CorePikkuFunctionConfig<any, any>,
53
55
  triggerSourceMeta.packageName
54
56
  )
55
57
  }
@@ -94,7 +96,7 @@ export async function setupTrigger<TInput = unknown, TOutput = unknown>({
94
96
  singletonServices,
95
97
  createWireServices,
96
98
  auth: false,
97
- data: () => input as any,
99
+ data: () => input,
98
100
  wire,
99
101
  packageName: sourceMeta.packageName || null,
100
102
  })
@@ -18,25 +18,16 @@
18
18
  */
19
19
  export type {
20
20
  ApiCatalogueEntry,
21
- IntentRecord,
22
21
  IntentSource,
23
- IntentStatus,
24
- StepRecord,
25
- VirtualUserAction,
26
- VirtualUserBudget,
27
22
  VirtualUserDisposition,
28
23
  VirtualUserFinding,
29
- VirtualUserFindingKind,
30
24
  VirtualUserRunResult,
31
- VirtualUserTally,
32
25
  VirtualUserTarget,
33
26
  } from './virtual-user.types.js'
34
27
  export { PRODUCTION_DISPOSITION } from './virtual-user.types.js'
35
28
  export {
36
29
  runVirtualUser,
37
- rememberIds,
38
30
  type RunVirtualUserParams,
39
- type VirtualUserCallContext,
40
31
  } from './run-virtual-user.js'
41
32
  export {
42
33
  personaScopes,
@@ -57,26 +48,19 @@ export {
57
48
  } from './virtual-user-dispositions.js'
58
49
  export {
59
50
  catalogueClassification,
60
- catalogueIndex,
61
51
  catalogueLookup,
62
- describeEntry,
63
52
  isReadOnly,
64
53
  reachableCatalogue,
65
- renderCatalogue,
66
54
  unreachableCatalogue,
67
55
  } from './virtual-user-catalogue.js'
68
56
  export {
69
- reachableAgents,
70
57
  type AgentReachability,
71
58
  type ReachableAgent,
72
59
  } from './virtual-user-agents.js'
73
60
  export {
74
61
  IntentStack,
75
62
  intentsForPersona,
76
- type IntentMove,
77
- type ScheduledTick,
78
63
  } from './virtual-user-intents.js'
79
- export { createRng, type VirtualUserRng } from './virtual-user-rng.js'
80
64
  export {
81
65
  deriveCatalogue,
82
66
  deriveIntents,
@@ -41,7 +41,11 @@ const CATALOGUE: ApiCatalogueEntry[] = [
41
41
  ]
42
42
 
43
43
  const INTENTS: IntentSource[] = [
44
- { id: 'onboard', title: 'set up your first project', steps: ['sign in', 'make a project'] },
44
+ {
45
+ id: 'onboard',
46
+ title: 'set up your first project',
47
+ steps: ['sign in', 'make a project'],
48
+ },
45
49
  ]
46
50
 
47
51
  const PERSONA = {
@@ -84,10 +88,7 @@ const scripted = (
84
88
  return { llm, turns: () => turn }
85
89
  }
86
90
 
87
- const respond = <T>(
88
- status: number,
89
- body: T
90
- ): ScenarioHttpResponse<T> => ({
91
+ const respond = <T>(status: number, body: T): ScenarioHttpResponse<T> => ({
91
92
  status,
92
93
  ok: status >= 200 && status < 300,
93
94
  body,
@@ -126,7 +127,12 @@ describe('running a virtual user', () => {
126
127
  { kind: 'complete', summary: 'done' },
127
128
  ])
128
129
 
129
- const result = await runVirtualUser({ ...base, target, llm, budget: { steps: 3 } })
130
+ const result = await runVirtualUser({
131
+ ...base,
132
+ target,
133
+ llm,
134
+ budget: { steps: 3 },
135
+ })
130
136
 
131
137
  // The first attempt cost a step and bought the schema; only the second
132
138
  // reached the server.
@@ -355,7 +361,9 @@ describe('what a virtual user reports', () => {
355
361
  })
356
362
 
357
363
  test('an app-specific oracle can add what the engine cannot know', async () => {
358
- const target = recordingTarget(() => respond(200, { orgId: 'someone-else' }))
364
+ const target = recordingTarget(() =>
365
+ respond(200, { orgId: 'someone-else' })
366
+ )
359
367
  const { llm } = scripted(walkTo('listProjects'))
360
368
 
361
369
  const result = await runVirtualUser({
@@ -595,8 +603,9 @@ describe('goals and persona', () => {
595
603
  test('goals in the user’s own words become intents alongside the derived ones', async () => {
596
604
  const seen: string[] = []
597
605
  const target = recordingTarget(() => respond(200, {}))
598
- const { llm } = scripted([{ kind: 'complete' }, { kind: 'complete' }], (_i, m) =>
599
- seen.push(...m)
606
+ const { llm } = scripted(
607
+ [{ kind: 'complete' }, { kind: 'complete' }],
608
+ (_i, m) => seen.push(...m)
600
609
  )
601
610
 
602
611
  const result = await runVirtualUser({
@@ -143,8 +143,12 @@ const msg = (role: AIMessage['role'], content: string): AIMessage => ({
143
143
  })
144
144
 
145
145
  /** Read a structured result, falling back to parsing JSON out of the text. */
146
- const readObject = <T>(result: { object?: unknown; text?: string }): T | null => {
147
- if (result.object && typeof result.object === 'object') return result.object as T
146
+ const readObject = <T>(result: {
147
+ object?: unknown
148
+ text?: string
149
+ }): T | null => {
150
+ if (result.object && typeof result.object === 'object')
151
+ return result.object as T
148
152
  if (result.text) {
149
153
  try {
150
154
  return JSON.parse(result.text) as T
@@ -201,7 +205,11 @@ export const rememberIds = (
201
205
  return into
202
206
  }
203
207
  for (const [key, value] of Object.entries(body)) {
204
- if (typeof value === 'string' && MEMORABLE.test(key) && value.length < 200) {
208
+ if (
209
+ typeof value === 'string' &&
210
+ MEMORABLE.test(key) &&
211
+ value.length < 200
212
+ ) {
205
213
  into[key] = value
206
214
  } else if (typeof value === 'object') {
207
215
  rememberIds(value, into, depth + 1)
@@ -237,7 +245,10 @@ const personaInstructions = (
237
245
  '',
238
246
  agents.length
239
247
  ? `Assistants you can talk to:\n${agents
240
- .map((agent) => `- ${agent.name}${agent.description ? `: ${agent.description}` : ''}`)
248
+ .map(
249
+ (agent) =>
250
+ `- ${agent.name}${agent.description ? `: ${agent.description}` : ''}`
251
+ )
241
252
  .join('\n')}`
242
253
  : '',
243
254
  fixtures.length ? `Files you have: ${fixtures.join(', ')}` : '',
@@ -351,7 +362,10 @@ export const runVirtualUser = async (
351
362
  stoppedBy = 'budget-duration'
352
363
  break
353
364
  }
354
- if (budget?.mutations !== undefined && tally.mutations >= budget.mutations) {
365
+ if (
366
+ budget?.mutations !== undefined &&
367
+ tally.mutations >= budget.mutations
368
+ ) {
355
369
  stoppedBy = 'budget-mutations'
356
370
  break
357
371
  }
@@ -402,10 +416,7 @@ export const runVirtualUser = async (
402
416
  )
403
417
  )
404
418
  }
405
- // Whether this user trusts its notes this turn or goes and looks again.
406
- // `stale` almost always trusts them, a newcomer has none to trust, and an
407
- // auditor checks nearly everything — which is the whole difference between
408
- // those runs, expressed as one roll rather than as prose.
419
+ // knowledge: decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md
409
420
  if (Object.keys(memory).length && !rng.chance(profile.reReadRate)) {
410
421
  messages.push(
411
422
  msg(
@@ -448,7 +459,9 @@ export const runVirtualUser = async (
448
459
 
449
460
  if (!raw || typeof raw.kind !== 'string') {
450
461
  steps.push(record)
451
- messages.push(msg('user', 'That was not a valid action. Choose one action.'))
462
+ messages.push(
463
+ msg('user', 'That was not a valid action. Choose one action.')
464
+ )
452
465
  continue
453
466
  }
454
467
 
@@ -550,10 +563,7 @@ export const runVirtualUser = async (
550
563
  continue
551
564
  }
552
565
 
553
- // What may be called is decided once, when the catalogue is narrowed: a
554
- // read-only disposition is never offered a mutation and an approval-gated
555
- // endpoint is never offered at all, so `index` is the gate and there is no
556
- // second one here to drift out of step with it.
566
+ // knowledge: decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md
557
567
  const mutating = !isReadOnly(entry)
558
568
 
559
569
  const args = readArgs((action as { args?: unknown }).args)
@@ -566,7 +576,10 @@ export const runVirtualUser = async (
566
576
  try {
567
577
  response = await target.call(entry.name, args)
568
578
  } catch (error) {
569
- record.findingKinds = [...(record.findingKinds ?? []), 'transport-error']
579
+ record.findingKinds = [
580
+ ...(record.findingKinds ?? []),
581
+ 'transport-error',
582
+ ]
570
583
  addFinding({
571
584
  kind: 'transport-error',
572
585
  detail: `${entry.name} threw: ${(error as Error).message}`,
@@ -45,7 +45,10 @@ describe('reachableAgents', () => {
45
45
 
46
46
  test('carries the description through, which is what the model chooses on', () => {
47
47
  const [router] = reachableAgents(AGENTS, ['content:write'])
48
- assert.equal(router!.description, 'Routes requests to the right domain agent')
48
+ assert.equal(
49
+ router!.description,
50
+ 'Routes requests to the right domain agent'
51
+ )
49
52
  })
50
53
 
51
54
  test('omits description rather than passing undefined', () => {