@pikku/core 0.12.82 → 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 (364) hide show
  1. package/CHANGELOG.md +101 -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 +9 -10
  104. package/dist/services/index.js +3 -3
  105. package/dist/services/meta-service.d.ts +5 -4
  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 +12 -11
  113. package/dist/types/core.types.js +1 -1
  114. package/dist/types/state.types.d.ts +11 -6
  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/ai-agent-prepare.js +2 -0
  171. package/dist/wirings/ai-agent/voice-output.d.ts +1 -2
  172. package/dist/wirings/channel/channel-rpc.types.d.ts +2 -2
  173. package/dist/wirings/rpc/addon-runner.d.ts +4 -0
  174. package/dist/wirings/rpc/addon-runner.js +14 -2
  175. package/dist/wirings/rpc/rpc-runner.d.ts +1 -1
  176. package/dist/wirings/rpc/rpc-runner.js +4 -2
  177. package/dist/wirings/rpc/rpc-types.d.ts +5 -1
  178. package/dist/wirings/rpc/wire-addon.d.ts +12 -0
  179. package/dist/wirings/rpc/wire-addon.js +4 -0
  180. package/dist/wirings/virtual-user/prepare-virtual-user-run.js +1 -1
  181. package/dist/wirings/virtual-user/virtual-user-agents.d.ts +1 -1
  182. package/dist/wirings/workflow/feature.d.ts +2 -1
  183. package/dist/wirings/workflow/index.d.ts +3 -14
  184. package/dist/wirings/workflow/index.js +0 -8
  185. package/dist/wirings/workflow/pikku-scenario-service.d.ts +10 -0
  186. package/dist/wirings/workflow/pikku-scenario-service.js +9 -0
  187. package/dist/wirings/workflow/run-timeline.d.ts +1 -2
  188. package/dist/wirings/workflow/scenario.types.d.ts +37 -0
  189. package/dist/wirings/workflow/scenario.types.js +1 -0
  190. package/dist/wirings/workflow/workflow.types.d.ts +2 -37
  191. 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
  192. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +1 -1
  193. package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +1 -1
  194. 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
  195. 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
  196. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +1 -1
  197. package/knowledge/decisions/internals/{ai-agent-credential-suspensions-hide-the-tool-result.md → agent-credential-suspensions-hide-the-tool-result.md} +2 -2
  198. package/knowledge/decisions/internals/{ai-agent-delegate-and-supervise-hide-different-text.md → agent-delegate-and-supervise-hide-different-text.md} +4 -4
  199. package/knowledge/decisions/internals/{ai-agent-llm-tool-arguments-have-nulls-stripped.md → agent-llm-tool-arguments-have-nulls-stripped.md} +3 -3
  200. 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
  201. package/knowledge/decisions/internals/{ai-agent-onerror-hooks-cannot-change-the-failure.md → agent-onerror-hooks-cannot-change-the-failure.md} +6 -6
  202. package/knowledge/decisions/internals/{ai-agent-runner-methods-must-keep-their-receiver.md → agent-runner-methods-must-keep-their-receiver.md} +4 -4
  203. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +1 -1
  204. package/knowledge/decisions/internals/{ai-agent-stream-persistence-is-best-effort.md → agent-stream-persistence-is-best-effort.md} +4 -4
  205. 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
  206. package/knowledge/decisions/internals/{ai-agent-tool-execute-failures-are-logged-unconditionally.md → agent-tool-execute-failures-are-logged-unconditionally.md} +3 -3
  207. 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
  208. 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
  209. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +2 -2
  210. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +3 -3
  211. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +2 -2
  212. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +1 -1
  213. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +1 -1
  214. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +1 -1
  215. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +1 -1
  216. package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +1 -1
  217. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +5 -5
  218. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +2 -2
  219. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +2 -2
  220. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +1 -1
  221. package/knowledge/decisions/security/{ai-agent-approval-forwarding-requires-a-symbol-brand.md → agent-approval-forwarding-requires-a-symbol-brand.md} +3 -3
  222. package/knowledge/decisions/security/{ai-agent-credential-requests-are-symbol-branded.md → agent-credential-requests-are-symbol-branded.md} +4 -4
  223. 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
  224. package/knowledge/decisions/security/{ai-agent-ownership-failures-never-echo-the-resource.md → agent-ownership-failures-never-echo-the-resource.md} +2 -2
  225. package/knowledge/decisions/security/{ai-agent-resume-re-runs-the-authorization-gate.md → agent-resume-re-runs-the-authorization-gate.md} +4 -4
  226. package/knowledge/decisions/security/{ai-agent-sessionless-deployments-have-no-thread-ownership.md → agent-sessionless-deployments-have-no-thread-ownership.md} +5 -5
  227. package/knowledge/decisions/security/{ai-agent-thread-ownership-composes-the-session-principal.md → agent-thread-ownership-composes-the-session-principal.md} +2 -2
  228. 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
  229. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +3 -3
  230. package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +3 -3
  231. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +20 -13
  232. package/knowledge/decisions/security/index.md +1 -2
  233. package/package.json +4 -4
  234. package/scripts/generate-api-report.mts +32 -8
  235. package/src/agent-naming.test.ts +68 -0
  236. package/src/ecosystem/agent-scorer.ts +24 -0
  237. package/src/ecosystem/agent.ts +42 -0
  238. package/src/ecosystem/channel/local.ts +1 -0
  239. package/src/ecosystem/channel.ts +22 -0
  240. package/src/ecosystem/cli/channel.ts +25 -0
  241. package/src/ecosystem/cli.ts +21 -0
  242. package/src/ecosystem/credential.ts +10 -0
  243. package/src/ecosystem/dev.ts +12 -0
  244. package/src/ecosystem/function.ts +28 -0
  245. package/src/ecosystem/gateway.ts +4 -0
  246. package/src/ecosystem/hmac.ts +1 -0
  247. package/src/ecosystem/http.ts +22 -0
  248. package/src/ecosystem/mcp.ts +17 -0
  249. package/src/ecosystem/middleware.ts +27 -0
  250. package/src/ecosystem/node-host-resolver.ts +1 -0
  251. package/src/ecosystem/node.ts +5 -0
  252. package/src/ecosystem/oauth2.ts +4 -0
  253. package/src/ecosystem/persona.ts +30 -0
  254. package/src/ecosystem/queue.ts +23 -0
  255. package/src/ecosystem/remote.ts +9 -0
  256. package/src/ecosystem/role.ts +13 -0
  257. package/src/ecosystem/rpc.ts +7 -0
  258. package/src/ecosystem/safe-fetch.ts +8 -0
  259. package/src/ecosystem/scenario.ts +32 -0
  260. package/src/ecosystem/scheduler.ts +5 -0
  261. package/src/ecosystem/schema.ts +1 -0
  262. package/src/ecosystem/scope.ts +14 -0
  263. package/src/ecosystem/secret.ts +15 -0
  264. package/src/ecosystem/services/istanbul-coverage.ts +1 -0
  265. package/src/ecosystem/services/local-content-request-handler.ts +16 -0
  266. package/src/ecosystem/services/local-content.ts +1 -0
  267. package/src/ecosystem/services/v8-coverage.ts +1 -0
  268. package/src/ecosystem/services.ts +82 -0
  269. package/src/ecosystem/testing.ts +8 -0
  270. package/src/ecosystem/trigger.ts +7 -0
  271. package/src/ecosystem/types.ts +34 -0
  272. package/src/ecosystem/variable.ts +14 -0
  273. package/src/ecosystem/virtual-user.ts +48 -0
  274. package/src/ecosystem/workflow.ts +68 -0
  275. package/src/index.ts +8 -19
  276. package/src/pikku-state.ts +3 -3
  277. package/src/public-surface.json +183 -91
  278. package/src/public-surface.json.README +20 -2
  279. package/src/public-surface.test.ts +31 -3
  280. package/src/services/{ai-run-state-service.ts → agent-run-state-service.ts} +5 -5
  281. package/src/services/{ai-agent-runner-service.ts → agent-runner-service.ts} +18 -18
  282. package/src/services/{ai-storage-service.ts → agent-storage-service.ts} +7 -7
  283. package/src/services/http-personas-converse.test.ts +3 -3
  284. package/src/services/http-personas.ts +4 -4
  285. package/src/services/{in-memory-ai-run-state-service.ts → in-memory-agent-run-state-service.ts} +7 -7
  286. package/src/services/index.ts +13 -24
  287. package/src/services/meta-service.ts +5 -7
  288. package/src/testing/service-tests/agent-run-service-tests.ts +4 -4
  289. package/src/testing/service-tests/{ai-storage-service-tests.ts → agent-storage-service-tests.ts} +8 -8
  290. package/src/testing/service-tests.ts +10 -8
  291. package/src/types/core.types.ts +13 -13
  292. package/src/types/state.types.ts +11 -10
  293. package/src/wirings/actor-flow/run-conversation.test.ts +2 -2
  294. package/src/wirings/actor-flow/run-conversation.ts +7 -9
  295. package/src/wirings/{ai-agent/ai-agent-agui.test.ts → agent/agent-agui.test.ts} +126 -105
  296. package/src/wirings/{ai-agent/ai-agent-agui.ts → agent/agent-agui.ts} +7 -7
  297. package/src/wirings/{ai-agent/ai-agent-authorization.test.ts → agent/agent-authorization.test.ts} +6 -6
  298. package/src/wirings/{ai-agent/ai-agent-finalize.test.ts → agent/agent-finalize.test.ts} +17 -16
  299. package/src/wirings/{ai-agent/ai-agent-finalize.ts → agent/agent-finalize.ts} +22 -22
  300. package/src/wirings/{ai-agent/ai-agent-helpers.test.ts → agent/agent-helpers.test.ts} +1 -1
  301. package/src/wirings/{ai-agent/ai-agent-helpers.ts → agent/agent-helpers.ts} +1 -1
  302. package/src/wirings/{ai-agent/ai-agent-interrupt.test.ts → agent/agent-interrupt.test.ts} +67 -77
  303. package/src/wirings/{ai-agent/ai-agent-interrupt.ts → agent/agent-interrupt.ts} +5 -5
  304. package/src/wirings/{ai-agent/ai-agent-memory.test.ts → agent/agent-memory.test.ts} +12 -12
  305. package/src/wirings/{ai-agent/ai-agent-memory.ts → agent/agent-memory.ts} +36 -36
  306. package/src/wirings/{ai-agent/ai-agent-model-config.test.ts → agent/agent-model-config.test.ts} +2 -5
  307. package/src/wirings/{ai-agent/ai-agent-model-config.ts → agent/agent-model-config.ts} +1 -1
  308. package/src/wirings/{ai-agent/ai-agent-prepare.test.ts → agent/agent-prepare.test.ts} +18 -18
  309. package/src/wirings/{ai-agent/ai-agent-prepare.ts → agent/agent-prepare.ts} +54 -51
  310. package/src/wirings/{ai-agent/ai-agent-registry.test.ts → agent/agent-registry.test.ts} +49 -43
  311. package/src/wirings/{ai-agent/ai-agent-registry.ts → agent/agent-registry.ts} +14 -14
  312. package/src/wirings/{ai-agent/ai-agent-resume-authorization.test.ts → agent/agent-resume-authorization.test.ts} +18 -18
  313. package/src/wirings/{ai-agent → agent}/agent-rpc.ts +16 -20
  314. package/src/wirings/{ai-agent/ai-agent-runner.test.ts → agent/agent-runner.test.ts} +105 -106
  315. package/src/wirings/{ai-agent/ai-agent-runner.ts → agent/agent-runner.ts} +90 -80
  316. package/src/wirings/{ai-agent/ai-agent-stream-output-hooks.test.ts → agent/agent-stream-output-hooks.test.ts} +25 -25
  317. package/src/wirings/{ai-agent/ai-agent-stream.test.ts → agent/agent-stream.test.ts} +147 -143
  318. package/src/wirings/{ai-agent/ai-agent-stream.ts → agent/agent-stream.ts} +147 -146
  319. package/src/wirings/{ai-agent/ai-agent-thread-ownership.test.ts → agent/agent-thread-ownership.test.ts} +24 -28
  320. package/src/wirings/{ai-agent/ai-agent-turn.test.ts → agent/agent-turn.test.ts} +3 -5
  321. package/src/wirings/{ai-agent/ai-agent-turn.ts → agent/agent-turn.ts} +7 -7
  322. package/src/wirings/{ai-agent/ai-agent.types.ts → agent/agent.types.ts} +51 -48
  323. package/src/wirings/agent/index.ts +56 -0
  324. package/src/wirings/{ai-agent → agent}/voice-input.test.ts +15 -15
  325. package/src/wirings/{ai-agent → agent}/voice-input.ts +11 -11
  326. package/src/wirings/{ai-agent → agent}/voice-output.test.ts +23 -23
  327. package/src/wirings/{ai-agent → agent}/voice-output.ts +11 -11
  328. package/src/wirings/{ai-scorer/ai-scorer-grade.test.ts → agent-scorer/agent-scorer-grade.test.ts} +8 -8
  329. package/src/wirings/{ai-scorer/ai-scorer-grade.ts → agent-scorer/agent-scorer-grade.ts} +9 -9
  330. package/src/wirings/{ai-scorer/ai-scorer-judge.test.ts → agent-scorer/agent-scorer-judge.test.ts} +11 -14
  331. package/src/wirings/{ai-scorer/ai-scorer-judge.ts → agent-scorer/agent-scorer-judge.ts} +11 -11
  332. package/src/wirings/{ai-scorer/ai-scorer-live.test.ts → agent-scorer/agent-scorer-live.test.ts} +11 -11
  333. package/src/wirings/{ai-scorer/ai-scorer-live.ts → agent-scorer/agent-scorer-live.ts} +3 -3
  334. package/src/wirings/{ai-scorer/ai-scorer-registry.ts → agent-scorer/agent-scorer-registry.ts} +11 -8
  335. package/src/wirings/{ai-scorer/ai-scorer-sampling.test.ts → agent-scorer/agent-scorer-sampling.test.ts} +1 -1
  336. package/src/wirings/{ai-scorer/ai-scorer-snapshots.test.ts → agent-scorer/agent-scorer-snapshots.test.ts} +2 -2
  337. package/src/wirings/{ai-scorer/ai-scorer-snapshots.ts → agent-scorer/agent-scorer-snapshots.ts} +1 -1
  338. package/src/wirings/{ai-scorer/ai-scorer-worker.test.ts → agent-scorer/agent-scorer-worker.test.ts} +15 -15
  339. package/src/wirings/{ai-scorer/ai-scorer-worker.ts → agent-scorer/agent-scorer-worker.ts} +9 -7
  340. package/src/wirings/{ai-scorer/ai-scorer.ts → agent-scorer/agent-scorer.ts} +7 -7
  341. package/src/wirings/{ai-scorer/ai-scorer.types.ts → agent-scorer/agent-scorer.types.ts} +6 -6
  342. package/src/wirings/agent-scorer/index.ts +22 -0
  343. package/src/wirings/channel/channel-rpc.types.ts +2 -2
  344. package/src/wirings/rpc/addon-runner.ts +31 -3
  345. package/src/wirings/rpc/addon-secrets.test.ts +130 -0
  346. package/src/wirings/rpc/rpc-runner.ts +4 -2
  347. package/src/wirings/rpc/rpc-types.ts +5 -1
  348. package/src/wirings/rpc/wire-addon.ts +16 -0
  349. package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
  350. package/src/wirings/virtual-user/run-virtual-user.test.ts +2 -2
  351. package/src/wirings/virtual-user/run-virtual-user.ts +3 -3
  352. package/src/wirings/virtual-user/virtual-user-agents.ts +1 -1
  353. package/src/wirings/workflow/feature.ts +2 -5
  354. package/src/wirings/workflow/index.ts +1 -49
  355. package/src/wirings/workflow/pikku-scenario-service.ts +21 -1
  356. package/src/wirings/workflow/run-timeline.ts +1 -1
  357. package/src/wirings/workflow/scenario.types.ts +63 -0
  358. package/src/wirings/workflow/workflow.types.ts +1 -54
  359. package/src/wirings-stay-decoupled.test.ts +3 -3
  360. package/tsconfig.tsbuildinfo +1 -1
  361. package/src/wirings/ai-agent/index.ts +0 -65
  362. package/src/wirings/ai-scorer/index.ts +0 -24
  363. /package/src/wirings/{ai-agent/ai-agent-utils.ts → agent/agent-utils.ts} +0 -0
  364. /package/src/wirings/{ai-scorer/ai-scorer-sampling.ts → agent-scorer/agent-scorer-sampling.ts} +0 -0
@@ -5,12 +5,13 @@ import type { CoreChannel, ChannelsMeta } from '../wirings/channel/channel.types
5
5
  import type { CLIMeta, CLIProgramState } from '../wirings/cli/cli.types.js';
6
6
  import type { HTTPMethod, CoreHTTPFunctionWiring, HTTPWiringsMeta } from '../wirings/http/http.types.js';
7
7
  import type { CoreMCPResource, MCPResourceMeta, MCPToolMeta, CoreMCPPrompt, MCPPromptMeta } from '../wirings/mcp/mcp.types.js';
8
- import type { CoreAIAgent, AIAgentMeta } from '../wirings/ai-agent/ai-agent.types.js';
9
- import type { PikkuAIScorer, ScorerMeta } from '../wirings/ai-scorer/ai-scorer.types.js';
8
+ import type { CoreAgent, AgentsMeta } from '../wirings/agent/agent.types.js';
9
+ import type { PikkuAgentScorer, ScorerMeta } from '../wirings/agent-scorer/agent-scorer.types.js';
10
10
  import type { CoreGateway, GatewaysMeta } from '../wirings/gateway/gateway.types.js';
11
11
  import type { CoreQueueWorker, QueueWorkersMeta } from '../wirings/queue/queue.types.js';
12
12
  import type { CoreScheduledTask, ScheduledTasksMeta } from '../wirings/scheduler/scheduler.types.js';
13
- import type { CoreWorkflow, CoreFeature, WorkflowsRuntimeMeta } from '../wirings/workflow/workflow.types.js';
13
+ import type { CoreWorkflow, WorkflowsRuntimeMeta } from '../wirings/workflow/workflow.types.js';
14
+ import type { CoreFeature } from '../wirings/workflow/scenario.types.js';
14
15
  import type { CoreTrigger, CoreTriggerSource, TriggerMeta, TriggerSourceMeta } from '../wirings/trigger/trigger.types.js';
15
16
  import type { FunctionsMeta, CorePikkuMiddleware, CorePikkuMiddlewareGroup, CreateConfig, CreateSingletonServices, CreateWireServices, CoreConfig, CoreSingletonServices, CoreServices, CoreUserSession } from './core.types.js';
16
17
  import type { CorePikkuChannelMiddleware } from '../wirings/channel/channel.types.js';
@@ -41,6 +42,10 @@ export interface PikkuPackageState {
41
42
  variableOverrides?: Record<string, string>;
42
43
  /** Per-instance name-aliases: logical name the addon reads -> actual project credential name */
43
44
  credentialOverrides?: Record<string, string>;
45
+ /** Secrets the host lends this instance, named as the addon reads them */
46
+ secretGrants?: string[];
47
+ /** Credentials the host lends this instance, named as the addon reads them */
48
+ credentialGrants?: string[];
44
49
  /** Why this instance gets the whole `SecretService` rather than one scoped to its declared secrets */
45
50
  globalSecrets?: string;
46
51
  /** Why this instance gets the whole `CredentialService` rather than one scoped to its declared credentials */
@@ -100,9 +105,9 @@ export interface PikkuPackageState {
100
105
  promptsMeta: MCPPromptMeta;
101
106
  };
102
107
  agent: {
103
- agents: Map<string, CoreAIAgent>;
104
- agentsMeta: AIAgentMeta;
105
- scorers: Map<string, PikkuAIScorer>;
108
+ agents: Map<string, CoreAgent>;
109
+ agentsMeta: AgentsMeta;
110
+ scorers: Map<string, PikkuAgentScorer>;
106
111
  scorersMeta: ScorerMeta;
107
112
  /** Alias -> `provider/model`, from the `models` table in pikku.config.json. */
108
113
  modelAliases: Record<string, string>;
@@ -1,8 +1,8 @@
1
1
  import type { ActorFlowApprovalPolicy, ActorFlowVerdict, TargetAgentDriver } from './actor-flow.types.js';
2
2
  import type { ResolvedPersona } from '../../services/personas-service.js';
3
- import type { AIAgentRunnerParams, AIAgentStepResult } from '../../services/ai-agent-runner-service.js';
3
+ import type { AgentRunnerParams, AgentStepResult } from '../../services/agent-runner-service.js';
4
4
  /** The LLM call the actor uses for its own turns/decisions/evaluation. */
5
- export type ActorLLM = (params: AIAgentRunnerParams) => Promise<AIAgentStepResult>;
5
+ export type ActorLLM = (params: AgentRunnerParams) => Promise<AgentStepResult>;
6
6
  export interface RunConversationParams {
7
7
  /** The person being played — name, job title, personality. */
8
8
  persona: ResolvedPersona;
@@ -0,0 +1,79 @@
1
+ import type { AgentStreamChannel } from './agent.types.js';
2
+ type AGUIEvent = {
3
+ type: 'TEXT_MESSAGE_START';
4
+ messageId: string;
5
+ } | {
6
+ type: 'TEXT_MESSAGE_CONTENT';
7
+ messageId: string;
8
+ delta: string;
9
+ } | {
10
+ type: 'TEXT_MESSAGE_END';
11
+ messageId: string;
12
+ } | {
13
+ type: 'TOOL_CALL_START';
14
+ toolCallId: string;
15
+ toolCallName: string;
16
+ } | {
17
+ type: 'TOOL_CALL_ARGS';
18
+ toolCallId: string;
19
+ delta: string;
20
+ } | {
21
+ type: 'TOOL_CALL_END';
22
+ toolCallId: string;
23
+ toolCallName: string;
24
+ } | {
25
+ type: 'TOOL_CALL_RESULT';
26
+ messageId: string;
27
+ toolCallId: string;
28
+ role: 'tool';
29
+ content: string;
30
+ } | {
31
+ type: 'THINKING_START';
32
+ } | {
33
+ type: 'THINKING_TEXT_MESSAGE_START';
34
+ messageId: string;
35
+ } | {
36
+ type: 'THINKING_TEXT_MESSAGE_CONTENT';
37
+ messageId: string;
38
+ delta: string;
39
+ } | {
40
+ type: 'THINKING_TEXT_MESSAGE_END';
41
+ messageId: string;
42
+ } | {
43
+ type: 'THINKING_END';
44
+ } | {
45
+ type: 'RUN_STARTED';
46
+ threadId: string;
47
+ runId: string;
48
+ } | {
49
+ type: 'RUN_FINISHED';
50
+ threadId: string;
51
+ runId: string;
52
+ model?: string;
53
+ usage?: {
54
+ promptTokens: number;
55
+ completionTokens: number;
56
+ totalTokens: number;
57
+ };
58
+ } | {
59
+ type: 'RUN_ERROR';
60
+ message: string;
61
+ code?: string;
62
+ } | {
63
+ type: 'STEP_STARTED';
64
+ stepName: string;
65
+ } | {
66
+ type: 'STEP_FINISHED';
67
+ stepName: string;
68
+ } | {
69
+ type: 'CUSTOM';
70
+ name: string;
71
+ value: unknown;
72
+ };
73
+ export type { AGUIEvent };
74
+ export type AGUIChannelOptions = {
75
+ threadId?: string;
76
+ runId?: string;
77
+ getRunId?: () => string | undefined;
78
+ };
79
+ export declare function wrapChannelWithAGUI(inner: AgentStreamChannel, options?: AGUIChannelOptions): AgentStreamChannel;
@@ -0,0 +1,327 @@
1
+ import { randomUUID } from './agent-utils.js';
2
+ function resultToString(result) {
3
+ if (typeof result === 'string')
4
+ return result;
5
+ try {
6
+ return JSON.stringify(result, (_key, val) => typeof val === 'bigint' ? val.toString() : val);
7
+ }
8
+ catch {
9
+ return String(result);
10
+ }
11
+ }
12
+ export function wrapChannelWithAGUI(inner, options) {
13
+ const threadId = options?.threadId ?? randomUUID();
14
+ let runId = options?.runId ?? null;
15
+ function resolveRunId() {
16
+ if (!runId) {
17
+ runId = options?.getRunId?.() ?? randomUUID();
18
+ }
19
+ return runId;
20
+ }
21
+ let textMessageId = null;
22
+ let thinkingMessageId = null;
23
+ let openStepName = null;
24
+ let stepSeq = 0;
25
+ let runStartedSent = false;
26
+ let terminal = false;
27
+ let sawUsage = false;
28
+ let usageModel;
29
+ const usageTotals = { input: 0, output: 0 };
30
+ function send(event) {
31
+ if (!runStartedSent) {
32
+ runStartedSent = true;
33
+ inner.send({
34
+ type: 'RUN_STARTED',
35
+ threadId,
36
+ runId: resolveRunId(),
37
+ });
38
+ }
39
+ inner.send(event);
40
+ }
41
+ function endTextMessage() {
42
+ if (textMessageId) {
43
+ send({ type: 'TEXT_MESSAGE_END', messageId: textMessageId });
44
+ textMessageId = null;
45
+ }
46
+ }
47
+ function endThinkingMessage() {
48
+ if (thinkingMessageId) {
49
+ send({ type: 'THINKING_TEXT_MESSAGE_END', messageId: thinkingMessageId });
50
+ send({ type: 'THINKING_END' });
51
+ thinkingMessageId = null;
52
+ }
53
+ }
54
+ function endStep() {
55
+ if (openStepName) {
56
+ send({ type: 'STEP_FINISHED', stepName: openStepName });
57
+ openStepName = null;
58
+ }
59
+ }
60
+ function ensureTextMessage() {
61
+ if (!textMessageId) {
62
+ textMessageId = randomUUID();
63
+ send({ type: 'TEXT_MESSAGE_START', messageId: textMessageId });
64
+ }
65
+ return textMessageId;
66
+ }
67
+ function ensureThinkingMessage() {
68
+ if (!thinkingMessageId) {
69
+ thinkingMessageId = randomUUID();
70
+ send({ type: 'THINKING_START' });
71
+ send({
72
+ type: 'THINKING_TEXT_MESSAGE_START',
73
+ messageId: thinkingMessageId,
74
+ });
75
+ }
76
+ return thinkingMessageId;
77
+ }
78
+ function finishRun() {
79
+ endTextMessage();
80
+ endThinkingMessage();
81
+ endStep();
82
+ send({
83
+ type: 'RUN_FINISHED',
84
+ threadId,
85
+ runId: resolveRunId(),
86
+ ...(usageModel ? { model: usageModel } : {}),
87
+ ...(sawUsage
88
+ ? {
89
+ usage: {
90
+ promptTokens: usageTotals.input,
91
+ completionTokens: usageTotals.output,
92
+ totalTokens: usageTotals.input + usageTotals.output,
93
+ },
94
+ }
95
+ : {}),
96
+ });
97
+ terminal = true;
98
+ }
99
+ return {
100
+ channelId: inner.channelId,
101
+ openingData: inner.openingData,
102
+ get state() {
103
+ return inner.state;
104
+ },
105
+ setState: (s) => inner.setState(s),
106
+ getState: () => inner.getState(),
107
+ clearState: () => inner.clearState(),
108
+ // Delegated: the wrapper is a view over the same connection, so a peer
109
+ // reachable from the channel underneath is reachable from here too.
110
+ remote: (funcName, data) => inner.remote(funcName, data),
111
+ sendBinary: (data) => inner.sendBinary(data),
112
+ close: () => inner.close(),
113
+ send: (event) => {
114
+ if (terminal)
115
+ return;
116
+ switch (event.type) {
117
+ case 'text-delta': {
118
+ endThinkingMessage();
119
+ const id = ensureTextMessage();
120
+ send({
121
+ type: 'TEXT_MESSAGE_CONTENT',
122
+ messageId: id,
123
+ delta: event.text,
124
+ });
125
+ break;
126
+ }
127
+ case 'reasoning-delta': {
128
+ endTextMessage();
129
+ const id = ensureThinkingMessage();
130
+ send({
131
+ type: 'THINKING_TEXT_MESSAGE_CONTENT',
132
+ messageId: id,
133
+ delta: event.text,
134
+ });
135
+ break;
136
+ }
137
+ case 'tool-call': {
138
+ endTextMessage();
139
+ endThinkingMessage();
140
+ send({
141
+ type: 'TOOL_CALL_START',
142
+ toolCallId: event.toolCallId,
143
+ toolCallName: event.toolName,
144
+ });
145
+ send({
146
+ type: 'TOOL_CALL_ARGS',
147
+ toolCallId: event.toolCallId,
148
+ delta: resultToString(event.args) || '{}',
149
+ });
150
+ send({
151
+ type: 'TOOL_CALL_END',
152
+ toolCallId: event.toolCallId,
153
+ toolCallName: event.toolName,
154
+ });
155
+ break;
156
+ }
157
+ case 'tool-result': {
158
+ send({
159
+ type: 'TOOL_CALL_RESULT',
160
+ messageId: randomUUID(),
161
+ toolCallId: event.toolCallId,
162
+ role: 'tool',
163
+ content: resultToString(event.result),
164
+ });
165
+ break;
166
+ }
167
+ case 'usage': {
168
+ endTextMessage();
169
+ endThinkingMessage();
170
+ sawUsage = true;
171
+ usageTotals.input += event.tokens.input;
172
+ usageTotals.output += event.tokens.output;
173
+ if (event.model)
174
+ usageModel = event.model;
175
+ break;
176
+ }
177
+ case 'error': {
178
+ endTextMessage();
179
+ endThinkingMessage();
180
+ endStep();
181
+ send({ type: 'RUN_ERROR', message: event.message });
182
+ terminal = true;
183
+ break;
184
+ }
185
+ case 'done': {
186
+ finishRun();
187
+ break;
188
+ }
189
+ case 'step-start': {
190
+ endTextMessage();
191
+ endThinkingMessage();
192
+ endStep();
193
+ stepSeq += 1;
194
+ openStepName = `${event.agent ?? 'step'}#${stepSeq}`;
195
+ send({ type: 'STEP_STARTED', stepName: openStepName });
196
+ break;
197
+ }
198
+ case 'approval-request': {
199
+ endTextMessage();
200
+ endThinkingMessage();
201
+ send({
202
+ type: 'CUSTOM',
203
+ name: 'pikku:approval-request',
204
+ value: {
205
+ toolCallId: event.toolCallId,
206
+ toolName: event.toolName,
207
+ args: event.args,
208
+ reason: event.reason,
209
+ runId: event.runId,
210
+ agent: event.agent,
211
+ session: event.session,
212
+ },
213
+ });
214
+ break;
215
+ }
216
+ case 'credential-request': {
217
+ endTextMessage();
218
+ endThinkingMessage();
219
+ send({
220
+ type: 'CUSTOM',
221
+ name: 'pikku:credential-request',
222
+ value: {
223
+ toolCallId: event.toolCallId,
224
+ toolName: event.toolName,
225
+ args: event.args,
226
+ credentialName: event.credentialName,
227
+ credentialType: event.credentialType,
228
+ connectUrl: event.connectUrl,
229
+ runId: event.runId,
230
+ agent: event.agent,
231
+ session: event.session,
232
+ },
233
+ });
234
+ break;
235
+ }
236
+ case 'generative-ui': {
237
+ send({
238
+ type: 'CUSTOM',
239
+ name: 'pikku:generative-ui',
240
+ value: { spec: event.spec },
241
+ });
242
+ break;
243
+ }
244
+ case 'data': {
245
+ send({
246
+ type: 'CUSTOM',
247
+ name: 'pikku:data',
248
+ value: { name: event.name, data: event.data },
249
+ });
250
+ break;
251
+ }
252
+ case 'agent-call': {
253
+ send({
254
+ type: 'CUSTOM',
255
+ name: 'pikku:agent-call',
256
+ value: {
257
+ agentName: event.agentName,
258
+ session: event.session,
259
+ input: event.input,
260
+ },
261
+ });
262
+ break;
263
+ }
264
+ case 'agent-result': {
265
+ send({
266
+ type: 'CUSTOM',
267
+ name: 'pikku:agent-result',
268
+ value: {
269
+ agentName: event.agentName,
270
+ session: event.session,
271
+ result: event.result,
272
+ },
273
+ });
274
+ break;
275
+ }
276
+ case 'suspended': {
277
+ send({
278
+ type: 'CUSTOM',
279
+ name: 'pikku:suspended',
280
+ value: { reason: event.reason, missingRpcs: event.missingRpcs },
281
+ });
282
+ break;
283
+ }
284
+ case 'interrupted': {
285
+ endTextMessage();
286
+ endThinkingMessage();
287
+ endStep();
288
+ send({
289
+ type: 'CUSTOM',
290
+ name: 'pikku:interrupted',
291
+ value: {
292
+ runId: event.runId,
293
+ text: event.text,
294
+ reason: event.reason,
295
+ },
296
+ });
297
+ break;
298
+ }
299
+ // knowledge: decisions/internals/agent-speech-travels-as-a-custom-agui-event.md
300
+ case 'audio-delta': {
301
+ send({
302
+ type: 'CUSTOM',
303
+ name: 'pikku:audio-delta',
304
+ value: {
305
+ data: event.data,
306
+ format: event.format,
307
+ ...(event.text === undefined ? {} : { text: event.text }),
308
+ },
309
+ });
310
+ break;
311
+ }
312
+ case 'audio-done': {
313
+ send({ type: 'CUSTOM', name: 'pikku:audio-done', value: {} });
314
+ break;
315
+ }
316
+ case 'transcript': {
317
+ send({
318
+ type: 'CUSTOM',
319
+ name: 'pikku:transcript',
320
+ value: { text: event.text },
321
+ });
322
+ break;
323
+ }
324
+ }
325
+ },
326
+ };
327
+ }
@@ -0,0 +1,58 @@
1
+ import type { AgentStep, AgentMessage, PikkuAgentMiddlewareHooks } from './agent.types.js';
2
+ import type { AgentRunStateService } from '../../services/agent-run-state-service.js';
3
+ export type RunUsage = {
4
+ inputTokens: number;
5
+ outputTokens: number;
6
+ model?: string;
7
+ };
8
+ /**
9
+ * Everything a finished run produced, after all middleware has had its say.
10
+ *
11
+ * One snapshot feeds persistence and anything that grades the run, so that what
12
+ * a scorer is shown is exactly what was stored — including the redactions.
13
+ */
14
+ export type FinalizedRun = {
15
+ runId: string;
16
+ agentName: string;
17
+ threadId: string;
18
+ resourceId?: string;
19
+ /** The prompt the run answered — what a scorer grades the answer against. */
20
+ input: string;
21
+ text: string;
22
+ steps: AgentStep[];
23
+ usage: RunUsage;
24
+ };
25
+ /**
26
+ * The prompt a run answered: the most recent user turn, which is what the model
27
+ * was last asked. On a resumed run the earlier turns are context, not the ask.
28
+ */
29
+ export declare const lastUserMessageText: (messages: AgentMessage[]) => string;
30
+ /**
31
+ * Run the `modifyOutput` chain over a finished non-streaming run.
32
+ *
33
+ * Reverse order, matching the input chain: the middleware registered first
34
+ * wraps the others, so it sees the output last.
35
+ */
36
+ export declare const applyOutputMiddleware: (agentMiddlewares: PikkuAgentMiddlewareHooks[], singletonServices: any, input: {
37
+ text: string;
38
+ messages: AgentMessage[];
39
+ steps: AgentStep[];
40
+ usage: {
41
+ inputTokens: number;
42
+ outputTokens: number;
43
+ };
44
+ }) => Promise<{
45
+ text: string;
46
+ messages: AgentMessage[];
47
+ steps: AgentStep[];
48
+ }>;
49
+ /**
50
+ * The one place a run ends successfully.
51
+ *
52
+ * Every path that completes a run — streamed, non-streamed, and resumed after a
53
+ * tool approval — goes through here, so that anything terminal is reachable
54
+ * from all of them and cannot be reordered by a middleware author. Nothing here
55
+ * may rewrite the run: by this point the output middleware has resolved and, on
56
+ * the streaming path, the client already has the reply.
57
+ */
58
+ export declare const finalizeAgentRun: (agentRunState: AgentRunStateService, run: FinalizedRun) => Promise<void>;
@@ -0,0 +1,138 @@
1
+ import { pikkuState } from '../../pikku-state.js';
2
+ import { scoreFinishedRun } from '../agent-scorer/agent-scorer-live.js';
3
+ import { recordScoreSnapshot } from '../agent-scorer/agent-scorer-snapshots.js';
4
+ /**
5
+ * The prompt a run answered: the most recent user turn, which is what the model
6
+ * was last asked. On a resumed run the earlier turns are context, not the ask.
7
+ */
8
+ export const lastUserMessageText = (messages) => {
9
+ for (let i = messages.length - 1; i >= 0; i--) {
10
+ const message = messages[i];
11
+ if (message?.role !== 'user')
12
+ continue;
13
+ if (typeof message.content === 'string')
14
+ return message.content;
15
+ if (Array.isArray(message.content)) {
16
+ return message.content
17
+ .filter((part) => part.type === 'text')
18
+ .map((part) => part.text)
19
+ .join('\n');
20
+ }
21
+ }
22
+ return '';
23
+ };
24
+ const flattenToolCalls = (steps) => steps.flatMap((step) => step.toolCalls ?? []);
25
+ /**
26
+ * Push a rewritten flat tool-call list back onto the steps it came from,
27
+ * preserving the step boundaries. A hook that adds or drops calls would make
28
+ * the boundaries meaningless, so a length change collapses them into the last
29
+ * step rather than silently mis-attributing calls to the wrong step.
30
+ */
31
+ const distributeToolCalls = (steps, toolCalls) => {
32
+ if (toolCalls.length !== flattenToolCalls(steps).length) {
33
+ return steps.map((step, index) => ({
34
+ ...step,
35
+ toolCalls: index === steps.length - 1 ? toolCalls : [],
36
+ }));
37
+ }
38
+ let cursor = 0;
39
+ return steps.map((step) => {
40
+ if (!step.toolCalls)
41
+ return step;
42
+ const next = toolCalls.slice(cursor, cursor + step.toolCalls.length);
43
+ cursor += step.toolCalls.length;
44
+ return { ...step, toolCalls: next };
45
+ });
46
+ };
47
+ /**
48
+ * Run the `modifyOutput` chain over a finished non-streaming run.
49
+ *
50
+ * Reverse order, matching the input chain: the middleware registered first
51
+ * wraps the others, so it sees the output last.
52
+ */
53
+ export const applyOutputMiddleware = async (agentMiddlewares, singletonServices, input) => {
54
+ let text = input.text;
55
+ let messages = input.messages;
56
+ let steps = input.steps;
57
+ let toolCalls = flattenToolCalls(steps);
58
+ for (let i = agentMiddlewares.length - 1; i >= 0; i--) {
59
+ const mw = agentMiddlewares[i];
60
+ if (!mw.modifyOutput)
61
+ continue;
62
+ const result = await mw.modifyOutput(singletonServices, {
63
+ text,
64
+ messages,
65
+ usage: {
66
+ inputTokens: input.usage.inputTokens,
67
+ outputTokens: input.usage.outputTokens,
68
+ },
69
+ toolCalls,
70
+ });
71
+ text = result.text;
72
+ messages = result.messages;
73
+ if (result.toolCalls) {
74
+ toolCalls = result.toolCalls;
75
+ steps = distributeToolCalls(steps, toolCalls);
76
+ }
77
+ }
78
+ return { text, messages, steps };
79
+ };
80
+ /**
81
+ * The one place a run ends successfully.
82
+ *
83
+ * Every path that completes a run — streamed, non-streamed, and resumed after a
84
+ * tool approval — goes through here, so that anything terminal is reachable
85
+ * from all of them and cannot be reordered by a middleware author. Nothing here
86
+ * may rewrite the run: by this point the output middleware has resolved and, on
87
+ * the streaming path, the client already has the reply.
88
+ */
89
+ export const finalizeAgentRun = async (agentRunState, run) => {
90
+ await agentRunState.updateRun(run.runId, {
91
+ status: 'completed',
92
+ ...(run.usage.model
93
+ ? {
94
+ usage: {
95
+ inputTokens: run.usage.inputTokens,
96
+ outputTokens: run.usage.outputTokens,
97
+ model: run.usage.model,
98
+ },
99
+ }
100
+ : {}),
101
+ });
102
+ // Read rather than `getSingletonServices()`: a process that never registered
103
+ // them grades nothing, which is not an error at the point a run has already
104
+ // succeeded.
105
+ const services = pikkuState(null, 'package', 'singletonServices');
106
+ if (!services)
107
+ return;
108
+ const snapshot = {
109
+ runId: run.runId,
110
+ agentName: run.agentName,
111
+ threadId: run.threadId,
112
+ ...(run.resourceId !== undefined ? { resourceId: run.resourceId } : {}),
113
+ input: run.input,
114
+ output: run.text,
115
+ toolCalls: run.steps.flatMap((step) => (step.toolCalls ?? []).map((call) => ({
116
+ name: call.name,
117
+ args: call.args,
118
+ result: call.result,
119
+ ...(call.error !== undefined ? { error: call.error } : {}),
120
+ }))),
121
+ usage: {
122
+ inputTokens: run.usage.inputTokens,
123
+ outputTokens: run.usage.outputTokens,
124
+ ...(run.usage.model !== undefined ? { model: run.usage.model } : {}),
125
+ },
126
+ };
127
+ // The same object a scenario grades, so an asserted score and a sampled one
128
+ // are the same measurement. A no-op unless a dev server turned retention on.
129
+ recordScoreSnapshot(snapshot);
130
+ // Best-effort and last: the client already has its answer, so a grading
131
+ // failure must not surface as a failed run.
132
+ try {
133
+ await scoreFinishedRun(snapshot, services);
134
+ }
135
+ catch (error) {
136
+ services.logger?.error(`[pikku] Live scoring failed for run ${run.runId}`, error);
137
+ }
138
+ };
@@ -0,0 +1,35 @@
1
+ import type { AgentInterruptResult } from './agent-interrupt.js';
2
+ export declare function agent<TAgentMap extends Record<string, {
3
+ output: any;
4
+ }>>(agentName: string & keyof TAgentMap): {
5
+ func: (services: any, data: any, wire: any) => Promise<any>;
6
+ };
7
+ export declare function agentStream<TAgentMap extends Record<string, {
8
+ output: any;
9
+ }>>(agentName?: string & keyof TAgentMap): {
10
+ func: (services: any, data: any, wire: any) => Promise<void>;
11
+ };
12
+ export declare function agentResume(): {
13
+ func: (services: any, data: {
14
+ runId: string;
15
+ toolCallId: string;
16
+ approved: boolean;
17
+ }, wire: any) => Promise<void>;
18
+ };
19
+ export declare function agentInterrupt(): {
20
+ func: (services: any, data: {
21
+ runId: string;
22
+ reason?: 'speech' | 'user' | 'timeout';
23
+ }, wire: any) => Promise<AgentInterruptResult>;
24
+ };
25
+ export declare function agentApprove<TAgentMap extends Record<string, {
26
+ output: any;
27
+ }>>(_agentName: string & keyof TAgentMap): {
28
+ func: (services: any, data: {
29
+ runId: string;
30
+ approvals: {
31
+ toolCallId: string;
32
+ approved: boolean;
33
+ }[];
34
+ }, wire: any) => Promise<any>;
35
+ };