@pikku/core 0.12.80 → 0.12.83

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 (237) hide show
  1. package/CHANGELOG.md +345 -0
  2. package/dist/errors/index.d.ts +1 -1
  3. package/dist/errors/index.js +1 -1
  4. package/dist/function/function-runner.js +2 -5
  5. package/dist/function/index.d.ts +1 -1
  6. package/dist/index.d.ts +11 -11
  7. package/dist/index.js +3 -3
  8. package/dist/pikku-state.js +4 -0
  9. package/dist/services/ai-agent-runner-service.d.ts +7 -0
  10. package/dist/services/ai-run-state-service.d.ts +10 -0
  11. package/dist/services/in-memory-ai-run-state-service.d.ts +5 -1
  12. package/dist/services/in-memory-ai-run-state-service.js +9 -0
  13. package/dist/services/index.d.ts +15 -16
  14. package/dist/services/index.js +5 -5
  15. package/dist/services/meta-service.d.ts +2 -1
  16. package/dist/services/scoped-credential-service.d.ts +21 -0
  17. package/dist/services/scoped-credential-service.js +53 -0
  18. package/dist/testing/service-tests/ai-storage-service-tests.js +76 -0
  19. package/dist/types/core.types.d.ts +2 -3
  20. package/dist/types/state.types.d.ts +19 -1
  21. package/dist/wirings/actor-flow/index.d.ts +1 -1
  22. package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +58 -0
  23. package/dist/wirings/ai-agent/ai-agent-finalize.js +138 -0
  24. package/dist/wirings/ai-agent/ai-agent-interrupt.js +1 -0
  25. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +2 -8
  26. package/dist/wirings/ai-agent/ai-agent-memory.js +34 -17
  27. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +7 -0
  28. package/dist/wirings/ai-agent/ai-agent-model-config.js +44 -1
  29. package/dist/wirings/ai-agent/ai-agent-prepare.js +4 -0
  30. package/dist/wirings/ai-agent/ai-agent-runner.js +61 -40
  31. package/dist/wirings/ai-agent/ai-agent-stream.js +89 -36
  32. package/dist/wirings/ai-agent/ai-agent-turn.d.ts +1 -0
  33. package/dist/wirings/ai-agent/ai-agent-turn.js +1 -0
  34. package/dist/wirings/ai-agent/ai-agent.types.d.ts +46 -1
  35. package/dist/wirings/ai-agent/index.d.ts +8 -7
  36. package/dist/wirings/ai-agent/index.js +5 -4
  37. package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +26 -0
  38. package/dist/wirings/ai-scorer/ai-scorer-grade.js +33 -0
  39. package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +17 -0
  40. package/dist/wirings/ai-scorer/ai-scorer-judge.js +92 -0
  41. package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +15 -0
  42. package/dist/wirings/ai-scorer/ai-scorer-live.js +38 -0
  43. package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +18 -0
  44. package/dist/wirings/ai-scorer/ai-scorer-registry.js +46 -0
  45. package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +8 -0
  46. package/dist/wirings/ai-scorer/ai-scorer-sampling.js +31 -0
  47. package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +10 -0
  48. package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +40 -0
  49. package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +15 -0
  50. package/dist/wirings/ai-scorer/ai-scorer-worker.js +58 -0
  51. package/dist/wirings/ai-scorer/ai-scorer.d.ts +39 -0
  52. package/dist/wirings/ai-scorer/ai-scorer.js +40 -0
  53. package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +90 -0
  54. package/dist/wirings/ai-scorer/ai-scorer.types.js +4 -0
  55. package/dist/wirings/ai-scorer/index.d.ts +6 -0
  56. package/dist/wirings/ai-scorer/index.js +5 -0
  57. package/dist/wirings/channel/index.d.ts +5 -6
  58. package/dist/wirings/channel/index.js +3 -4
  59. package/dist/wirings/channel/local/local-channel-runner.js +8 -1
  60. package/dist/wirings/cli/channel/cli-raw-channel-runner.js +9 -1
  61. package/dist/wirings/cli/channel/index.d.ts +1 -2
  62. package/dist/wirings/cli/channel/index.js +0 -1
  63. package/dist/wirings/cli/cli-runner.js +13 -1
  64. package/dist/wirings/credential/index.d.ts +1 -1
  65. package/dist/wirings/gateway/index.d.ts +1 -1
  66. package/dist/wirings/http/http-runner.js +8 -2
  67. package/dist/wirings/http/index.d.ts +1 -2
  68. package/dist/wirings/mcp/index.d.ts +1 -1
  69. package/dist/wirings/mcp/mcp-runner.d.ts +15 -0
  70. package/dist/wirings/mcp/mcp-runner.js +18 -5
  71. package/dist/wirings/persona/index.d.ts +3 -4
  72. package/dist/wirings/persona/index.js +2 -3
  73. package/dist/wirings/queue/index.d.ts +1 -3
  74. package/dist/wirings/queue/index.js +1 -3
  75. package/dist/wirings/rpc/addon-runner.d.ts +8 -0
  76. package/dist/wirings/rpc/addon-runner.js +31 -3
  77. package/dist/wirings/rpc/rpc-runner.js +4 -0
  78. package/dist/wirings/rpc/rpc-types.d.ts +8 -0
  79. package/dist/wirings/rpc/wire-addon.d.ts +25 -0
  80. package/dist/wirings/rpc/wire-addon.js +8 -0
  81. package/dist/wirings/scheduler/index.d.ts +1 -1
  82. package/dist/wirings/trigger/index.d.ts +1 -1
  83. package/dist/wirings/virtual-user/index.d.ts +5 -6
  84. package/dist/wirings/virtual-user/index.js +2 -4
  85. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +85 -15
  86. package/dist/wirings/workflow/feature.d.ts +2 -1
  87. package/dist/wirings/workflow/index.d.ts +5 -16
  88. package/dist/wirings/workflow/index.js +1 -9
  89. package/dist/wirings/workflow/pikku-scenario-service.d.ts +17 -7
  90. package/dist/wirings/workflow/pikku-scenario-service.js +48 -13
  91. package/dist/wirings/workflow/pikku-workflow-service.js +17 -3
  92. package/dist/wirings/workflow/scenario-step.types.d.ts +8 -0
  93. package/dist/wirings/workflow/scenario.types.d.ts +37 -0
  94. package/dist/wirings/workflow/workflow-approval-audit.d.ts +16 -0
  95. package/dist/wirings/workflow/workflow-approval-audit.js +40 -0
  96. package/dist/wirings/workflow/workflow-approval-policy.d.ts +20 -0
  97. package/dist/wirings/workflow/workflow-approval-policy.js +48 -0
  98. package/dist/wirings/workflow/workflow-approval.d.ts +29 -1
  99. package/dist/wirings/workflow/workflow-approval.js +65 -2
  100. package/dist/wirings/workflow/workflow-run-ownership.d.ts +2 -1
  101. package/dist/wirings/workflow/workflow-run-ownership.js +2 -1
  102. package/dist/wirings/workflow/workflow.types.d.ts +2 -37
  103. package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +32 -0
  104. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +39 -0
  105. package/knowledge/decisions/internals/index.md +30 -3
  106. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +115 -0
  107. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +37 -0
  108. package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +30 -14
  109. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +59 -0
  110. package/knowledge/decisions/security/index.md +3 -1
  111. package/knowledge/questions/index.md +1 -1
  112. package/package.json +3 -2
  113. package/scripts/generate-api-report.mts +143 -18
  114. package/src/api-report.test.ts +2 -2
  115. package/src/errors/index.ts +1 -1
  116. package/src/function/function-runner.test.ts +52 -0
  117. package/src/function/function-runner.ts +5 -9
  118. package/src/function/index.ts +0 -2
  119. package/src/index.ts +0 -35
  120. package/src/pikku-state.ts +5 -0
  121. package/src/public-surface.json +81 -118
  122. package/src/services/ai-agent-runner-service.ts +12 -1
  123. package/src/services/ai-run-state-service.ts +11 -0
  124. package/src/services/in-memory-ai-run-state-service.ts +13 -0
  125. package/src/services/index.ts +7 -58
  126. package/src/services/meta-service.ts +2 -4
  127. package/src/services/scoped-credential-service.test.ts +86 -0
  128. package/src/services/scoped-credential-service.ts +63 -0
  129. package/src/testing/service-tests/ai-storage-service-tests.ts +93 -0
  130. package/src/types/core.types.ts +4 -7
  131. package/src/types/state.types.ts +21 -1
  132. package/src/wirings/actor-flow/index.ts +0 -3
  133. package/src/wirings/ai-agent/ai-agent-finalize.test.ts +186 -0
  134. package/src/wirings/ai-agent/ai-agent-finalize.ts +197 -0
  135. package/src/wirings/ai-agent/ai-agent-interrupt.ts +1 -0
  136. package/src/wirings/ai-agent/ai-agent-memory.ts +54 -38
  137. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +72 -3
  138. package/src/wirings/ai-agent/ai-agent-model-config.ts +49 -1
  139. package/src/wirings/ai-agent/ai-agent-prepare.ts +4 -0
  140. package/src/wirings/ai-agent/ai-agent-runner.ts +71 -40
  141. package/src/wirings/ai-agent/ai-agent-stream-output-hooks.test.ts +353 -0
  142. package/src/wirings/ai-agent/ai-agent-stream.ts +116 -54
  143. package/src/wirings/ai-agent/ai-agent-turn.test.ts +67 -0
  144. package/src/wirings/ai-agent/ai-agent-turn.ts +1 -0
  145. package/src/wirings/ai-agent/ai-agent.types.ts +64 -4
  146. package/src/wirings/ai-agent/index.ts +2 -16
  147. package/src/wirings/ai-scorer/ai-scorer-grade.test.ts +106 -0
  148. package/src/wirings/ai-scorer/ai-scorer-grade.ts +55 -0
  149. package/src/wirings/ai-scorer/ai-scorer-judge.test.ts +143 -0
  150. package/src/wirings/ai-scorer/ai-scorer-judge.ts +120 -0
  151. package/src/wirings/ai-scorer/ai-scorer-live.test.ts +174 -0
  152. package/src/wirings/ai-scorer/ai-scorer-live.ts +56 -0
  153. package/src/wirings/ai-scorer/ai-scorer-registry.ts +63 -0
  154. package/src/wirings/ai-scorer/ai-scorer-sampling.test.ts +34 -0
  155. package/src/wirings/ai-scorer/ai-scorer-sampling.ts +36 -0
  156. package/src/wirings/ai-scorer/ai-scorer-snapshots.test.ts +49 -0
  157. package/src/wirings/ai-scorer/ai-scorer-snapshots.ts +46 -0
  158. package/src/wirings/ai-scorer/ai-scorer-worker.test.ts +122 -0
  159. package/src/wirings/ai-scorer/ai-scorer-worker.ts +69 -0
  160. package/src/wirings/ai-scorer/ai-scorer.ts +76 -0
  161. package/src/wirings/ai-scorer/ai-scorer.types.ts +107 -0
  162. package/src/wirings/ai-scorer/index.ts +24 -0
  163. package/src/wirings/channel/index.ts +1 -20
  164. package/src/wirings/channel/local/local-channel-runner.test.ts +68 -0
  165. package/src/wirings/channel/local/local-channel-runner.ts +8 -1
  166. package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +23 -0
  167. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +12 -1
  168. package/src/wirings/cli/channel/index.ts +0 -7
  169. package/src/wirings/cli/cli-runner.test.ts +68 -0
  170. package/src/wirings/cli/cli-runner.ts +18 -1
  171. package/src/wirings/credential/index.ts +0 -1
  172. package/src/wirings/gateway/index.ts +0 -3
  173. package/src/wirings/http/http-runner.test.ts +66 -0
  174. package/src/wirings/http/http-runner.ts +10 -2
  175. package/src/wirings/http/index.ts +1 -1
  176. package/src/wirings/mcp/index.ts +0 -1
  177. package/src/wirings/mcp/mcp-runner.test.ts +181 -0
  178. package/src/wirings/mcp/mcp-runner.ts +35 -5
  179. package/src/wirings/persona/index.ts +0 -8
  180. package/src/wirings/queue/index.ts +0 -14
  181. package/src/wirings/rpc/addon-runner.ts +62 -3
  182. package/src/wirings/rpc/addon-secrets.test.ts +391 -0
  183. package/src/wirings/rpc/rpc-runner.test.ts +2 -0
  184. package/src/wirings/rpc/rpc-runner.ts +4 -0
  185. package/src/wirings/rpc/rpc-types.ts +8 -0
  186. package/src/wirings/rpc/wire-addon.ts +33 -0
  187. package/src/wirings/scheduler/index.ts +0 -1
  188. package/src/wirings/trigger/index.ts +0 -1
  189. package/src/wirings/virtual-user/index.ts +0 -16
  190. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +96 -16
  191. package/src/wirings/workflow/feature.ts +2 -5
  192. package/src/wirings/workflow/graph/graph-runner.test.ts +72 -0
  193. package/src/wirings/workflow/index.ts +2 -68
  194. package/src/wirings/workflow/pikku-scenario-service.ts +81 -16
  195. package/src/wirings/workflow/pikku-workflow-service.test.ts +13 -12
  196. package/src/wirings/workflow/pikku-workflow-service.ts +28 -4
  197. package/src/wirings/workflow/scenario-expectations.test.ts +75 -0
  198. package/src/wirings/workflow/scenario-hooks.test.ts +3 -2
  199. package/src/wirings/workflow/scenario-step.types.ts +8 -0
  200. package/src/wirings/workflow/scenario.types.ts +63 -0
  201. package/src/wirings/workflow/workflow-approval-audit.ts +47 -0
  202. package/src/wirings/workflow/workflow-approval-policy.test.ts +524 -0
  203. package/src/wirings/workflow/workflow-approval-policy.ts +68 -0
  204. package/src/wirings/workflow/workflow-approval.ts +113 -9
  205. package/src/wirings/workflow/workflow-run-authority.test.ts +12 -15
  206. package/src/wirings/workflow/workflow-run-ownership.ts +2 -1
  207. package/src/wirings/workflow/workflow.types.ts +1 -63
  208. package/src/wirings-stay-decoupled.test.ts +6 -2
  209. package/tsconfig.tsbuildinfo +1 -1
  210. package/dist/internal.d.ts +0 -3
  211. package/dist/internal.js +0 -2
  212. package/dist/middleware/timeout.d.ts +0 -9
  213. package/dist/middleware/timeout.js +0 -15
  214. package/dist/pikku-response.d.ts +0 -6
  215. package/dist/pikku-response.js +0 -6
  216. package/dist/services/gopass-secrets.d.ts +0 -15
  217. package/dist/services/gopass-secrets.js +0 -76
  218. package/dist/services/http-scenario-actors.d.ts +0 -75
  219. package/dist/services/http-scenario-actors.js +0 -195
  220. package/dist/services/http-user-flow-actors.d.ts +0 -67
  221. package/dist/services/http-user-flow-actors.js +0 -193
  222. package/dist/services/scenario-actors-service.d.ts +0 -127
  223. package/dist/services/scenario-actors-service.js +0 -40
  224. package/dist/services/user-flow-actors-service.d.ts +0 -39
  225. package/dist/wirings/credential/wire-credential.d.ts +0 -48
  226. package/dist/wirings/credential/wire-credential.js +0 -47
  227. package/dist/wirings/oauth2/oauth2-client.d.ts +0 -47
  228. package/dist/wirings/oauth2/oauth2-client.js +0 -263
  229. package/dist/wirings/oauth2/oauth2-routes.d.ts +0 -35
  230. package/dist/wirings/oauth2/oauth2-routes.js +0 -146
  231. package/dist/wirings/scope/wire-scope.d.ts +0 -33
  232. package/dist/wirings/scope/wire-scope.js +0 -32
  233. package/dist/wirings/workflow/dsl/index.d.ts +0 -5
  234. package/dist/wirings/workflow/dsl/index.js +0 -4
  235. package/dist/wirings/workflow/graph/index.d.ts +0 -5
  236. package/dist/wirings/workflow/graph/index.js +0 -4
  237. /package/dist/{services/user-flow-actors-service.js → wirings/workflow/scenario.types.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,348 @@
1
+ ## 0.12.83
2
+
3
+ ### Patch Changes
4
+
5
+ - 02c4fe5: fix(core,inspector): let a host grant an addon secrets it could not declare
6
+
7
+ Scoping an addon's `SecretService` to its `declaredSecrets` left generic addons
8
+ with nothing readable: `declaredSecrets` is derived from the addon package's own
9
+ source, but the secrets an addon like `@pikku/addon-graph` reads are named by the
10
+ consuming app's workflow nodes at runtime. Every authenticated `graph:httpRequest`
11
+ threw.
12
+
13
+ `wireAddon` now takes `secretGrants: string[]` and `credentialGrants: string[]`,
14
+ completing the grant family alongside `secretOverrides` (grant + rename) and
15
+ `globalSecrets` (grant everything, with a reason). Grants name the secret as the
16
+ addon reads it, since the scope check runs before the override map renames it —
17
+ which is also why an override's key grants and its value does not.
18
+
19
+ A grant naming a secret the project does not declare is an `INVALID_VALUE`
20
+ critical at codegen, resolved through the override map before lookup.
21
+
22
+ - 438b776: Move the scenario and feature surface off `@pikku/core/workflow` and onto
23
+ `@pikku/core/scenario`. Scenarios extend workflows, so the production workflow
24
+ wiring no longer names a scenario module in its import graph. Feature and
25
+ scenario types are declared in their own `scenario.types.ts` rather than in
26
+ `workflow.types.ts`. Import `requireActor`, `requireScenarioEnv`, `pollUntil`,
27
+ `createCookieJar`, `addFeature`, `ScenarioHttpResponse` and the rest from
28
+ `@pikku/core/scenario`; `HttpPersonasConfig` now comes from
29
+ `@pikku/core/persona` rather than `@pikku/core/services`.
30
+ - 438b776: Remove the `@pikku/core/internal` entry point. It aliased the same file as
31
+ `@pikku/core/ecosystem`, so the two published an identical set of names under
32
+ two specifiers. Import from `@pikku/core/ecosystem`.
33
+
34
+ ## 0.12.82
35
+
36
+ ### Patch Changes
37
+
38
+ - 063f43a: api-report.md reports public signatures, one member per line
39
+
40
+ The report was built from `declaration.getText()`, so a class arrived as its own
41
+ source — private fields and method bodies included — flattened onto a single
42
+ line. `PikkuWorkflowService` was 40,603 characters of one line.
43
+
44
+ That made the file unmergeable. One line is one conflict hunk, so two branches
45
+ touching different methods of the same class conflicted on a line neither had
46
+ meaningfully changed, and the repo paid for it every rebase.
47
+
48
+ Now each member is its own line and stops at its signature, with private members
49
+ dropped and inferred return types filled in from the checker. The file is a
50
+ quarter smaller, and every declaration in it parses as TypeScript — 42 of its 50
51
+ code fences previously did not, because collapsing a multi-line object type threw
52
+ away the newline that was serving as the member separator.
53
+
54
+ Also adds the report to `.prettierignore`: prettier pads the summary tables to
55
+ their widest cell, so one changed count rewrote all fifty rows, and it reflowed a
56
+ file that `api-report.test.ts` compares byte-for-byte.
57
+
58
+ - ce66bf8: A channel message handler that returns nothing no longer tries to send it.
59
+
60
+ `local-channel-runner` sent the message handler's result unconditionally, so a
61
+ handler with nothing to say produced `send requires a non-empty message` on every
62
+ inbound message. The connect path directly above it has always guarded this; the
63
+ message path did not.
64
+
65
+ Gateway websockets hit it every time — `wireGateway` generates a message handler
66
+ that returns `undefined` by design — which showed up as a chat gateway accepting
67
+ a connection and then erroring on each message rather than delivering it.
68
+
69
+ Found while testing a webchat gateway in a template. Note that fixing this is
70
+ necessary but not sufficient for that case: codegen does not emit the channel a
71
+ websocket gateway registers, so route resolution finds no handler and falls back
72
+ to the empty inline `onMessage` the gateway wires as a placeholder. That gap is
73
+ still open.
74
+
75
+ - d0307a8: Stop the runner overwriting a status the route set
76
+
77
+ A function that calls `response.redirect()` has nothing left to return, so it
78
+ returns `undefined` — and the HTTP runner read that as "no content" and
79
+ overwrote the 3xx with a 204. The `Location` header survived, but a browser
80
+ does not follow `Location` on a 204, so the redirect silently became a dead
81
+ end: the user sits on the page that sent them, waiting for a hop that never
82
+ comes. This is the whole OAuth/app-install callback shape, where the redirect
83
+ back to the app is the last step of the flow.
84
+
85
+ The same clobber applied to a body: a route that set `201` and returned a
86
+ value was answered `200`.
87
+
88
+ The runner's 204 and 200 are now defaults rather than overrides — they apply
89
+ only when the route left the status alone.
90
+
91
+ - ce66bf8: MCP calls now carry the caller's HTTP request, so an MCP tool can require a session.
92
+
93
+ Every auth middleware opens with `if (!http?.request) return`. The MCP runner
94
+ never put an `http` on the wire, so all of them bailed on their first line and
95
+ an MCP call reached the function with no session — no cookie, no bearer token,
96
+ no API key, whatever the app had registered. A tool fronting a session-requiring
97
+ `pikkuFunc` could therefore only ever answer `Authentication required`, and a
98
+ tool fronting a sessionless one was callable by anyone who could reach the mount.
99
+
100
+ Almost nothing was missing. Global middleware already ran for MCP wirings, and
101
+ the runner already built a `PikkuSessionService` and the middleware session wire
102
+ props. Only the request was being dropped — twice: `RunMCPEndpointParams` had
103
+ nowhere to put one, and `createFetchHandler` received the caller's `Request` and
104
+ discarded it.
105
+
106
+ `RunMCPEndpointParams` gains an optional `http`, which the runner places on the
107
+ wire, and the fetch handler wraps the incoming `Request` in a
108
+ `PikkuFetchHTTPRequest` and threads it through tools, resources and prompts. The
109
+ request is cloned before wrapping, because the MCP transport reads the body and
110
+ both would otherwise compete for one single-use stream; only headers and cookies
111
+ are wanted, since a tool's input arrives in the JSON-RPC params.
112
+
113
+ Transports with no request to offer — stdio, and the long-lived stdio/SSE server
114
+ paths — pass nothing and stay anonymous. That is a property of those transports
115
+ rather than a default chosen here, and it is now visible in the type.
116
+
117
+ The generated auth middleware moves from `addHTTPMiddleware('*')` to
118
+ `addGlobalMiddleware`. Carrying the request is necessary but not sufficient:
119
+ session middleware registered as HTTP middleware runs for HTTP wirings only, so
120
+ an MCP call still met no middleware and still had no session. Both entries —
121
+ the Better Auth session and the console bearer token — resolve a session from
122
+ whatever request the call arrived on, which is not an HTTP routing concern.
123
+ Wirings with no request are unaffected, since each middleware returns
124
+ immediately without one.
125
+
126
+ That move also retires a hazard the old shape carried: the two entries had to
127
+ share a single `addHTTPMiddleware('*')` call because the inspector keys
128
+ route-middleware groups by pattern, so a second `'*'` registration from another
129
+ file would silently displace the first. Global middleware is an append-only
130
+ list.
131
+
132
+ **Regenerate the auth scaffold after upgrading** — an app still carrying the
133
+ `addHTTPMiddleware('*')` form keeps anonymous MCP calls.
134
+
135
+ Two consequences worth planning for:
136
+ - **A tool fronting a session-requiring function starts working.** It previously
137
+ could not run at all.
138
+ - **A tool fronting a sessionless function is unchanged and still anonymous.**
139
+ Scopes and permissions now apply to MCP calls exactly as they do elsewhere, so
140
+ audit any tool that mutates state and give it the scope its HTTP sibling has.
141
+
142
+ `PikkuHTTP` is now exported from `@pikku/core/http`; it is part of this contract
143
+ and was previously only reachable as a type on other exported shapes.
144
+
145
+ - 3ad2131: Name models by what they are for, and switch them all in one place
146
+
147
+ A `models` table in pikku.config.json maps an alias to a provider-qualified
148
+ model, so a declaration can say `model: 'cheap'` and the project repoints every
149
+ use of that tier at once instead of editing each agent. A model containing `/`
150
+ is still concrete and used exactly as written, which is how an agent that needs
151
+ one specific model pins it — aliases are opt-in.
152
+
153
+ The table is baked into codegen rather than read at runtime, so it applies to
154
+ deployed units and not just local runs, and `pikku dev`/`pikku serve` take
155
+ `--model cheap:openai/gpt-5-nano` to repoint a tier for one run without editing
156
+ the config.
157
+
158
+ Because the inspector already holds every agent's model literal, a bare name
159
+ with no matching alias now fails the build (PKU146) naming the aliases that do
160
+ exist, rather than reaching a provider as an unknown model.
161
+
162
+ Aliases resolve for every modality, not just agents: image, speech,
163
+ transcription, embedding and reranking all reach a provider through the same
164
+ point in the Vercel runner.
165
+
166
+ - b930dca: Remove the `secretBroker` escape hatch and scope addon secrets and credentials
167
+
168
+ `secretBroker` let three named console functions receive the real `SecretService`,
169
+ against the rule that a function never sees one. It is gone: the inspector allowlist,
170
+ the `FunctionRuntimeMeta` flag, the runner branches, and the `WiredSecretBrokerServices`
171
+ type. Console secret administration moved into the console addon, where a
172
+ `SecretAdminService` holds the `SecretService` and the functions hold none.
173
+
174
+ Addons are now scoped rather than trusted. The CLI emits each package's declared secret
175
+ keys, and the host wraps the `SecretService` in a `ScopedSecretService` and the
176
+ `CredentialService` in a new `ScopedCredentialService` before the addon's service factory
177
+ runs — so an addon reads only what it declared, cannot write secrets, and cannot enumerate
178
+ the app's users. `wireAddon({ globalSecrets, globalCredentials })` waives this, taking the
179
+ reason as its value; only the consuming app can grant it, and the deploy manifest reports
180
+ every grant under `unscopedSecretAddons` / `unscopedCredentialAddons`.
181
+
182
+ - b95e77d: fix(core): persist working memory on streamed agent runs
183
+
184
+ Working memory was never persisted when an agent streamed. The working memory
185
+ middleware strips the `<working_memory>` block from the outgoing deltas, and the
186
+ channel that accumulates the reply sits downstream of that strip — so the text
187
+ later handed to `modifyOutput`, the only place that calls `saveWorkingMemory`,
188
+ had already had the block removed. It now persists from the stream hook, at the
189
+ step's `usage` (or `done`) event, where the raw text is still reachable.
190
+
191
+ With that dependency gone, `modifyOutput` no longer runs at all on a streamed
192
+ run: nothing on that path could act on what it returned, since the text has
193
+ already reached the client and each step is flushed to storage as it goes. A
194
+ middleware that rewrites in `modifyOutput` without a `modifyOutputStream` — a
195
+ redaction hook, typically — was silently ineffective while streaming, and is now
196
+ warned about once per agent.
197
+
198
+ - fd9d834: Stop publishing internals that only their own package or file used. The declarations stay; only the entrypoint re-export is removed, so nothing that imported a name from where it is declared is affected.
199
+ - 8978fbd: feat(workflow): let an approval gate declare who may answer it
200
+
201
+ `workflow.approval()` gains `approvers` (`'any' | 'owner' | 'not-initiator'`)
202
+ and `approverScope`, so a gate can require four-eyes sign-off, restrict itself
203
+ to the run's initiator, or require the decider to hold a named scope.
204
+
205
+ Both are enforced when the workflow replays the gate — the same place, and for
206
+ the same reason, the decision payload is validated: the policy is a value on
207
+ the workflow, and a decision can be recorded before the run has ever reached
208
+ the gate. A decision that fails the policy is discarded and the gate stays
209
+ closed. Where the run has already published its policy, the check also runs at
210
+ submission time so the caller gets a 403 rather than silence.
211
+
212
+ An answer is now recorded where it can be answered for later. The settled
213
+ decision carries `decidedBy` and `decidedAt` in its `ApprovalOutcome`, so who
214
+ signed reaches `workflowStep.result` and `workflowStepHistory` rather than
215
+ living only in mutable run state. Every answer — accepted, refused at the door,
216
+ or cleared on replay — is also written to the audit sink as
217
+ `workflow.approval.decided`, which outlives the run: `deleteRun` cascades to
218
+ steps and history, and a refused attempt never reaches a step at all. Projects
219
+ with no audit service wired are unaffected.
220
+
221
+ **This loosens the default.** `approveStep` previously refused anyone but the
222
+ run's initiator, unconditionally. A gate that declares no `approvers` now
223
+ accepts a decision from anyone the approve entrypoint admits — restore the old
224
+ behaviour per-gate with `approvers: 'owner'`, or gate the approve route with
225
+ `auth`/`permissions`. Ownership still governs _reads_ of a run unchanged.
226
+
227
+ ## 0.12.81
228
+
229
+ ### Patch Changes
230
+
231
+ - e110c55: Give a finished agent run one finalization seam, and make a failed tool call
232
+ distinguishable from a tool that returned text saying "Error:".
233
+ - Tool results carry `error` as its own field, from the runner through the
234
+ stream event and the run's step record into persisted messages.
235
+ - `modifyOutput` receives the run's tool calls and may return a rewritten list,
236
+ which is redistributed back onto the steps it came from.
237
+ - Streamed runs accumulate their tool calls across steps, and every completion
238
+ path — streamed, non-streamed, and resumed after a tool approval — now
239
+ finalizes through `finalizeAgentRun`. A tool that fails after being approved
240
+ leaves a record on the run instead of vanishing.
241
+
242
+ - e110c55: Add `scenario.expectScore` — grade a finished agent run with a declared scorer and assert on it.
243
+
244
+ An agent's answer cannot be matched against a fixed string, so a scenario grades
245
+ it instead. `expectScore(step, runId, scorer, { atLeast, atMost, reference })`
246
+ runs one declared scorer against the run the scenario just triggered and fails
247
+ with the reason the judge gave. The default bound is `atLeast: 0.5`, so an
248
+ unqualified assertion still fails a run graded zero.
249
+
250
+ Grading goes over the new `pikkuScenarioGradeRun` instrumentation RPC, which the
251
+ dev server registers alongside the coverage and stub RPCs — so it exists only in
252
+ processes that should have it, and never in a deployed bundle. It grades from
253
+ the snapshot the runtime already took when the run finished, which is what makes
254
+ a scenario's grade the same measurement production's sampler makes rather than
255
+ an approximation of it: a run's prompt, answer and tool calls are spread across
256
+ a thread's messages, where the boundary of one run is not recoverable.
257
+
258
+ Two things differ deliberately from live scoring. The sample rate is ignored — a
259
+ scorer grading 1% of traffic still grades every scenario run — and the grade is
260
+ returned rather than recorded, so a test's score never lands among the
261
+ production figures. `reference` supplies the answer key a `requiresReference`
262
+ judge grades against, which is the only way such a judge is reachable at all.
263
+
264
+ - e110c55: Add runtime scoring for AI agents: `pikkuAIScorer` for heuristic grades and
265
+ `pikkuAIJudge` for LLM-judged ones, graded off the request path on two queue
266
+ lanes so a slow judge cannot starve the cheap checks. Grades are sampled
267
+ deterministically per `(run, scorer)` and persisted to `ai_run_score`.
268
+ - acc8077: Enforce a CLI command's declared `auth`/`permissions`, and mask CLI channel
269
+ errors in production.
270
+
271
+ A command's declared `auth`/`permissions` were accepted by the types but dropped
272
+ in `registerCLICommands`: when the command wrapped a function-config object,
273
+ `unwrapFunc` kept only the inner func's fields, so a command-level access-control
274
+ declaration was a silent no-op. They are now merged into the config passed to
275
+ `addFunction` — command-level winning, falling back to the handler's — so the
276
+ function runner enforces them.
277
+
278
+ The CLI raw channel runner returned the raw exception message to the remote
279
+ client. It can carry internals (a stack, a DB error, a path), so it is now logged
280
+ server-side and replaced with a generic `Command failed` in production; dev keeps
281
+ the message inline.
282
+
283
+ CWE-862 / CWE-209.
284
+
285
+ - 905f737: Restrict a graph workflow's `startNode` to its declared entry nodes.
286
+
287
+ The scaffolded public route `POST /workflow/:name/graph/:nodeId` passes `:nodeId`
288
+ straight through as `startNode`, and `validateGraphReferences` only checked that
289
+ the node exists. A caller could name any dependency-free node — one whose input
290
+ reads only `trigger` — and fire its RPC directly with chosen data, skipping every
291
+ upstream eligibility, validation or approval node. These node RPCs are internal,
292
+ so the public `/rpc` endpoint refuses them; this route was the only outside path
293
+ to them.
294
+
295
+ `startWorkflow` — the boundary the public route and triggers enter through — now
296
+ rejects a `startNode` that is not in the graph's `entryNodeIds`. Internal
297
+ resume/replay drives `runWorkflowGraph` directly and keeps full node targeting,
298
+ so the check sits at the trust boundary rather than in the low-level runner.
299
+
300
+ CWE-20 / CWE-863.
301
+
302
+ - 3cc6428: Run a templated MCP resource's middleware for concrete request URIs.
303
+
304
+ `runMCPResource` resolves a templated resource's `pikkuFuncId` via the template
305
+ key, but `runMCPPikkuFunc` then re-looked-up the resource meta by the concrete
306
+ request URI (`resource://users/123`), which no meta is stored under — so meta was
307
+ `undefined` and the resource's merged middleware, including any tag-derived auth
308
+ gate, was silently dropped. A templated MCP resource was reachable with its gate
309
+ skipped.
310
+
311
+ The meta key — the template for a templated match, the URI otherwise — is now
312
+ carried through to the meta lookup, so the declared middleware runs.
313
+
314
+ CWE-863 / CWE-306.
315
+
316
+ - c524adf: fix(cli,core): make scenario captures reachable, filed per scenario, and findable
317
+
318
+ `--screenshots` and `--video` were read by `scenario run` but never declared as
319
+ options, so both flags were rejected as unknown and silently ignored — capture
320
+ could not be switched on from the command line at all.
321
+
322
+ A provider's `beginScenario` was never called, so every capture in a run was
323
+ filed under one shared label instead of the scenario that produced it. It is now
324
+ part of `ScenarioBrowserProvider` and called after the per-scenario reset, once
325
+ the previous scenario's context is closed and its video finalised.
326
+
327
+ The run also never said where it wrote anything. It now reports `Captures → …`
328
+ after the browser closes, which is the point at which a video exists.
329
+
330
+ - e110c55: fix(core): persist working memory on streamed agent runs
331
+
332
+ Working memory was never persisted when an agent streamed. The working memory
333
+ middleware strips the `<working_memory>` block from the outgoing deltas, and the
334
+ channel that accumulates the reply sits downstream of that strip — so the text
335
+ later handed to `modifyOutput`, the only place that calls `saveWorkingMemory`,
336
+ had already had the block removed. It now persists from the stream hook, at the
337
+ step's `usage` (or `done`) event, where the raw text is still reachable.
338
+
339
+ With that dependency gone, `modifyOutput` no longer runs at all on a streamed
340
+ run: nothing on that path could act on what it returned, since the text has
341
+ already reached the client and each step is flushed to storage as it goes. A
342
+ middleware that rewrites in `modifyOutput` without a `modifyOutputStream` — a
343
+ redaction hook, typically — was silently ineffective while streaming, and is now
344
+ warned about once per agent.
345
+
1
346
  ## 0.12.80
2
347
 
3
348
  ### Patch Changes
@@ -1,2 +1,2 @@
1
1
  export * from './errors.js';
2
- export { PikkuError, addError, addErrors } from './error-handler.js';
2
+ export { PikkuError, addError } from './error-handler.js';
@@ -1,2 +1,2 @@
1
1
  export * from './errors.js';
2
- export { PikkuError, addError, addErrors } from './error-handler.js';
2
+ export { PikkuError, addError } from './error-handler.js';
@@ -84,7 +84,6 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
84
84
  throw new Error(`Function meta not found: ${funcName}`);
85
85
  }
86
86
  const resolvedFunctionId = funcMeta.pikkuFuncId ?? funcName;
87
- const keepsSecrets = funcMeta.secretBroker === true;
88
87
  const resolvedSingletonServices = packageName
89
88
  ? await getOrCreatePackageSingletonServices(packageName, singletonServices, addonInstance)
90
89
  : singletonServices;
@@ -201,9 +200,7 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
201
200
  }
202
201
  await runPermissions({
203
202
  funcPermissions: funcConfig.permissions,
204
- services: keepsSecrets
205
- ? resolvedSingletonServices
206
- : withoutSecrets(resolvedSingletonServices, 'a permission'),
203
+ services: withoutSecrets(resolvedSingletonServices, 'a permission'),
207
204
  // knowledge: decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md
208
205
  wire: invocationWire,
209
206
  data: actualData,
@@ -237,7 +234,7 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
237
234
  configurable: true,
238
235
  enumerable: true,
239
236
  });
240
- return await funcConfig.func(keepsSecrets ? services : withoutSecrets(services, 'a pikku function'), actualData, invocationWire);
237
+ return await funcConfig.func(withoutSecrets(services, 'a pikku function'), actualData, invocationWire);
241
238
  }
242
239
  finally {
243
240
  // Flush the runner-installed audit buffer before wire services close.
@@ -1,4 +1,4 @@
1
1
  export { addFunction, getAllFunctionNames } from './function-runner.js';
2
2
  export { pikkuAuth, pikkuPermission, pikkuPermissionFactory, pikkuApprovalDescription, } from './functions.types.js';
3
3
  export type { CorePikkuFunction, CorePikkuFunctionSessionless, CorePikkuFunctionConfig, CorePikkuSessionlessFunctionConfig, CorePikkuAuth, CorePikkuAuthConfig, CorePikkuPermission, } from './functions.types.js';
4
- export type { ListInput, ListOutput, Filter, LeafFilter, LeafValue, } from './list.types.js';
4
+ export type { ListInput, ListOutput, Filter, } from './list.types.js';
package/dist/index.d.ts CHANGED
@@ -1,18 +1,18 @@
1
1
  /**
2
2
  * @module @pikku/core
3
3
  */
4
- export type { AuthInstance, CommonWireMeta, CoreConfig, CorePikkuMiddleware, CorePikkuMiddlewareConfig, CorePikkuMiddlewareFactory, CorePikkuMiddlewareGroup, CoreServices, CoreSecretlessSingletonServices, CoreSingletonServices, CoreUserSession, SecretlessServices, CreateConfig, ServerLifecycle, FunctionMeta, FunctionRuntimeMeta, FunctionServicesMeta, FunctionWiresMeta, FunctionsMeta, FunctionsRuntimeMeta, JSONPrimitive, JSONValue, MakeRequired, MiddlewareMetadata, MiddlewarePriority, PermissionMetadata, PickOptional, PickRequired, PikkuAIMiddlewareHooks, PikkuWire, PikkuRawWire, PikkuWiringTypes, PostgresConfig, RequireAtLeastOne, SecurityAuditIssue, SecurityAuditReport, SecurityAuditSummary, SecurityAuditUpdate, SecuritySeverity, SecurityUpdateLevel, SerializedError, WireServices, } from './types/core.types.js';
4
+ export type { AuthInstance, CommonWireMeta, CoreConfig, CorePikkuMiddleware, CorePikkuMiddlewareConfig, CorePikkuMiddlewareFactory, CorePikkuMiddlewareGroup, CoreServices, CoreSecretlessSingletonServices, CoreSingletonServices, CoreUserSession, SecretlessServices, CreateConfig, ServerLifecycle, FunctionMeta, FunctionServicesMeta, FunctionWiresMeta, FunctionsMeta, FunctionsRuntimeMeta, JSONValue, MakeRequired, MiddlewareMetadata, MiddlewarePriority, PermissionMetadata, PickOptional, PickRequired, PikkuAIMiddlewareHooks, PikkuWire, PikkuRawWire, PikkuWiringTypes, PostgresConfig, RequireAtLeastOne, SecurityAuditIssue, SecurityAuditReport, SecurityAuditSummary, SecurityAuditUpdate, SecuritySeverity, SecurityUpdateLevel, SerializedError, } from './types/core.types.js';
5
5
  export { pikkuAIMiddleware, pikkuChannelMiddleware, pikkuChannelMiddlewareFactory, pikkuMiddleware, pikkuMiddlewareFactory, } from './types/core.types.js';
6
- export type { CorePikkuAuth, CorePikkuAuthConfig, CorePikkuFunction, CorePikkuFunctionConfig, CorePikkuFunctionHook, CorePikkuPermission, CorePikkuPermissionConfig, CorePikkuPermissionFactory, CorePikkuApprovalDescription, CorePermissionGroup, } from './function/functions.types.js';
6
+ export type { CorePikkuAuth, CorePikkuAuthConfig, CorePikkuFunction, CorePikkuFunctionConfig, CorePikkuPermission, CorePikkuPermissionConfig, CorePikkuPermissionFactory, CorePikkuApprovalDescription, CorePermissionGroup, } from './function/functions.types.js';
7
7
  export { pikkuAuth, pikkuPermission, pikkuPermissionFactory, pikkuApprovalDescription, } from './function/functions.types.js';
8
8
  export { getAllFunctionNames } from './function/index.js';
9
- export type { ListInput, ListOutput, Filter, LeafFilter, LeafValue, } from './function/list.types.js';
9
+ export type { ListInput, ListOutput, Filter, } from './function/list.types.js';
10
10
  export { pikkuCLIRender } from './wirings/cli/cli-runner.js';
11
11
  export { PikkuRequest } from './pikku-request.js';
12
12
  export { getRelativeTimeOffsetFromNow, parseDurationString, } from './time-utils.js';
13
13
  export type { RelativeTimeInput } from './time-utils.js';
14
14
  export { formatVersionedId, isVersionedId, parseVersionedId, } from './version.js';
15
- export { AbandonedError, beginChanges, getAbortScope, runInAbortScope, type AbortScope, } from './function/abort-scope.js';
15
+ export { AbandonedError, type AbortScope, } from './function/abort-scope.js';
16
16
  export { fetch } from './wirings/http/http-runner.js';
17
17
  export type { MCPToolResponse, MCPResourceResponse, MCPPromptResponse, } from './wirings/mcp/mcp.types.js';
18
18
  export { AIProviderAuthError, AIProviderNotConfiguredError, BadGatewayError, BadRequestError, ConflictError, ExpectationFailedError, ForbiddenError, GatewayTimeoutError, GoneError, HTTPVersionNotSupportedError, InternalServerError, InvalidMiddlewareWireError, InvalidOriginError, InvalidSessionError, LengthRequiredError, LocalEnvironmentOnlyError, LockedError, MaxComputeTimeReachedError, MethodNotAllowedError, MissingCredentialError, MissingSchemaError, MissingScopeError, MissingServiceError, MissingSessionError, NotAcceptableError, NotFoundError, NotImplementedError, PayloadTooLargeError, PaymentRequiredError, PikkuMissingMetaError, PreconditionFailedError, ProxyAuthenticationRequiredError, RangeNotSatisfiableError, ReadonlySessionError, RequestTimeoutError, ServiceUnavailableError, TooManyRequestsError, URITooLongError, UnauthorizedError, UnprocessableContentError, UnsupportedMediaTypeError, } from './errors/errors.js';
@@ -20,7 +20,7 @@ export { PikkuError, isExpectedError } from './errors/error-handler.js';
20
20
  export type { EventHubService } from './wirings/channel/eventhub-service.js';
21
21
  export type { QueueService } from './wirings/queue/queue.types.js';
22
22
  export type { JWTService } from './services/jwt-service.js';
23
- export type { EmailService, EmailTemplateReference, SendEmailInput, SendEmailResult, SendHTMLEmailInput, SendTemplateEmailInput, SendTextEmailInput, } from './services/email-service.js';
23
+ export type { EmailService, SendEmailInput, SendEmailResult, SendHTMLEmailInput, SendTemplateEmailInput, SendTextEmailInput, } from './services/email-service.js';
24
24
  export type { SecretService } from './services/secret-service.js';
25
25
  export { SecretAccessDeniedError, withoutSecrets, } from './services/secretless.js';
26
26
  export { SecretHostNotAllowedError, assertSecretAllowedForHost, } from './services/secret-host-binding.js';
@@ -32,13 +32,13 @@ export type { GatewayService } from './services/gateway-service.js';
32
32
  export type { TriggerService } from './services/trigger-service.js';
33
33
  export type { SchemaService } from './services/schema-service.js';
34
34
  export type { SessionService } from './services/user-session-service.js';
35
- export { NoopAuditService, createInvocationAudit, resolveAuditConfig, resolveAuditUserIdentityFromWire, } from './services/audit-service.js';
36
- export type { AuditConfig, AuditDurability, AuditEvent, AuditEventBatch, AuditFacets, AuditLog, AuditLogWriteInput, AuditOutcome, AuditQuery, AuditQueryResult, AuditService, AuditSource, AuditUserIdentity, ResolvedAuditConfig, } from './services/audit-service.js';
37
- export type { AIAgentRunnerService, AIEmbedManyParams, AIEmbedManyResult, AIEmbedParams, AIEmbedResult, AIGenerateImageParams, AIGenerateImagePrompt, AIGenerateImageResult, AIGenerateSpeechParams, AIGenerateSpeechResult, AIProviderOptions, AIRerankParams, AIRerankResult, AITranscriptionParams, AITranscriptionResult, } from './services/ai-agent-runner-service.js';
35
+ export { NoopAuditService, createInvocationAudit, } from './services/audit-service.js';
36
+ export type { AuditConfig, AuditDurability, AuditEvent, AuditEventBatch, AuditFacets, AuditLog, AuditQuery, AuditQueryResult, AuditService, AuditUserIdentity, ResolvedAuditConfig, } from './services/audit-service.js';
37
+ export type { AIAgentRunnerService, } from './services/ai-agent-runner-service.js';
38
38
  export type { AIEmbeddingService } from './services/ai-embedding-service.js';
39
39
  export type { AIRunStateService } from './services/ai-run-state-service.js';
40
40
  export type { AIStorageService } from './services/ai-storage-service.js';
41
- export type { EmailsMeta, EmailTemplateMeta, EmailTemplateLocaleMeta, EmailTemplateAssets, MetaService, } from './services/meta-service.js';
41
+ export type { EmailsMeta, EmailTemplateMeta, MetaService, } from './services/meta-service.js';
42
42
  export type { HTTPMethod } from './wirings/http/http.types.js';
43
43
  export type { GraphNodeConfig } from './wirings/workflow/graph/workflow-graph.types.js';
44
44
  export { createGraph } from './wirings/workflow/graph/graph-node.js';
@@ -54,7 +54,7 @@ export { isSerializable, stopSingletonServices, pikkuServerLifecycle, } from './
54
54
  export { clearPikkuRuntimeState } from './test-utils.js';
55
55
  export { type ScheduledTaskInfo, type ScheduledTaskSummary, } from './services/scheduler-service.js';
56
56
  export { SchedulerService } from './services/scheduler-service.js';
57
- export type { Private, Pii, Secret, Classification, AnonymizeStrategy, ColumnClassification, ClassificationManifest, ColumnForm, WrappedValue, SealedValue, HashedValue, } from './data-classification.js';
58
- export { hashToken, unsafeAsWrapped, unsafeAsSealed, unsafeAsHashed, } from './column-form.js';
57
+ export type { Private, Pii, Secret, Classification, AnonymizeStrategy, ClassificationManifest, ColumnForm, WrappedValue, SealedValue, HashedValue, } from './data-classification.js';
58
+ export { hashToken, } from './column-form.js';
59
59
  export type { SecretValue, Safe } from './secret-value.js';
60
60
  export { createSecretValue, isSecretValue, SecretCoercionError, REDACTED, } from './secret-value.js';
package/dist/index.js CHANGED
@@ -5,13 +5,13 @@ export { pikkuCLIRender } from './wirings/cli/cli-runner.js';
5
5
  export { PikkuRequest } from './pikku-request.js';
6
6
  export { getRelativeTimeOffsetFromNow, parseDurationString, } from './time-utils.js';
7
7
  export { formatVersionedId, isVersionedId, parseVersionedId, } from './version.js';
8
- export { AbandonedError, beginChanges, getAbortScope, runInAbortScope, } from './function/abort-scope.js';
8
+ export { AbandonedError, } from './function/abort-scope.js';
9
9
  export { fetch } from './wirings/http/http-runner.js';
10
10
  export { AIProviderAuthError, AIProviderNotConfiguredError, BadGatewayError, BadRequestError, ConflictError, ExpectationFailedError, ForbiddenError, GatewayTimeoutError, GoneError, HTTPVersionNotSupportedError, InternalServerError, InvalidMiddlewareWireError, InvalidOriginError, InvalidSessionError, LengthRequiredError, LocalEnvironmentOnlyError, LockedError, MaxComputeTimeReachedError, MethodNotAllowedError, MissingCredentialError, MissingSchemaError, MissingScopeError, MissingServiceError, MissingSessionError, NotAcceptableError, NotFoundError, NotImplementedError, PayloadTooLargeError, PaymentRequiredError, PikkuMissingMetaError, PreconditionFailedError, ProxyAuthenticationRequiredError, RangeNotSatisfiableError, ReadonlySessionError, RequestTimeoutError, ServiceUnavailableError, TooManyRequestsError, URITooLongError, UnauthorizedError, UnprocessableContentError, UnsupportedMediaTypeError, } from './errors/errors.js';
11
11
  export { PikkuError, isExpectedError } from './errors/error-handler.js';
12
12
  export { SecretAccessDeniedError, withoutSecrets, } from './services/secretless.js';
13
13
  export { SecretHostNotAllowedError, assertSecretAllowedForHost, } from './services/secret-host-binding.js';
14
- export { NoopAuditService, createInvocationAudit, resolveAuditConfig, resolveAuditUserIdentityFromWire, } from './services/audit-service.js';
14
+ export { NoopAuditService, createInvocationAudit, } from './services/audit-service.js';
15
15
  export { createGraph } from './wirings/workflow/graph/graph-node.js';
16
16
  export { wireAddon } from './wirings/rpc/wire-addon.js';
17
17
  export { wireRemoteAddon } from './wirings/rpc/wire-remote-addon.js';
@@ -21,5 +21,5 @@ export { hasScopes, verifyScopes } from './scopes.js';
21
21
  export { isSerializable, stopSingletonServices, pikkuServerLifecycle, } from './utils.js';
22
22
  export { clearPikkuRuntimeState } from './test-utils.js';
23
23
  export { SchedulerService } from './services/scheduler-service.js';
24
- export { hashToken, unsafeAsWrapped, unsafeAsSealed, unsafeAsHashed, } from './column-form.js';
24
+ export { hashToken, } from './column-form.js';
25
25
  export { createSecretValue, isSecretValue, SecretCoercionError, REDACTED, } from './secret-value.js';
@@ -84,6 +84,9 @@ const createEmptyPackageState = () => ({
84
84
  agent: {
85
85
  agents: new Map(),
86
86
  agentsMeta: {},
87
+ scorers: new Map(),
88
+ scorersMeta: {},
89
+ modelAliases: {},
87
90
  },
88
91
  gateway: {
89
92
  gateways: new Map(),
@@ -117,6 +120,7 @@ const createEmptyPackageState = () => ({
117
120
  authFactory: null,
118
121
  credentialsMeta: null,
119
122
  requiredParentServices: null,
123
+ declaredSecrets: null,
120
124
  },
121
125
  });
122
126
  export const initializePikkuState = (packageName) => {
@@ -54,6 +54,13 @@ export type AIAgentStepResult = {
54
54
  toolCallId: string;
55
55
  toolName: string;
56
56
  result: unknown;
57
+ /**
58
+ * Set when the tool threw rather than returned. Carried as its own field
59
+ * because `result` is a rendered string by the time anything downstream
60
+ * reads it, and "did this tool fail" is not answerable by looking for an
61
+ * `Error:` prefix in text a tool could legitimately have returned.
62
+ */
63
+ error?: string;
57
64
  }[];
58
65
  usage: {
59
66
  inputTokens: number;
@@ -1,5 +1,7 @@
1
1
  import type { AgentRunState, PendingApproval } from '../wirings/ai-agent/ai-agent.types.js';
2
+ import type { AIRunScore } from '../wirings/ai-scorer/ai-scorer.types.js';
2
3
  export type CreateRunInput = Omit<AgentRunState, 'runId'>;
4
+ export type SaveScoreInput = Omit<AIRunScore, 'createdAt'>;
3
5
  export interface AIRunStateService {
4
6
  createRun(run: CreateRunInput): Promise<string>;
5
7
  updateRun(runId: string, updates: Partial<AgentRunState>): Promise<void>;
@@ -16,4 +18,12 @@ export interface AIRunStateService {
16
18
  run: AgentRunState;
17
19
  approval: PendingApproval;
18
20
  } | null>;
21
+ /**
22
+ * Record one scorer's grade of a finished run. A run accumulates one row per
23
+ * scorer, and a scorer may grade the same run more than once — a retried job
24
+ * appends rather than replaces, so a re-grade never silently overwrites the
25
+ * grade that was acted on.
26
+ */
27
+ saveScore(score: SaveScoreInput): Promise<void>;
28
+ getScores(runId: string): Promise<AIRunScore[]>;
19
29
  }
@@ -1,7 +1,9 @@
1
- import type { AIRunStateService, CreateRunInput } from './ai-run-state-service.js';
1
+ import type { AIRunStateService, CreateRunInput, SaveScoreInput } from './ai-run-state-service.js';
2
2
  import type { AgentRunState, PendingApproval } from '../wirings/ai-agent/ai-agent.types.js';
3
+ import type { AIRunScore } from '../wirings/ai-scorer/ai-scorer.types.js';
3
4
  export declare class InMemoryAIRunStateService implements AIRunStateService {
4
5
  private runs;
6
+ private scores;
5
7
  private counter;
6
8
  createRun(run: CreateRunInput): Promise<string>;
7
9
  updateRun(runId: string, updates: Partial<AgentRunState>): Promise<void>;
@@ -12,4 +14,6 @@ export declare class InMemoryAIRunStateService implements AIRunStateService {
12
14
  run: AgentRunState;
13
15
  approval: PendingApproval;
14
16
  } | null>;
17
+ saveScore(score: SaveScoreInput): Promise<void>;
18
+ getScores(runId: string): Promise<AIRunScore[]>;
15
19
  }
@@ -1,5 +1,6 @@
1
1
  export class InMemoryAIRunStateService {
2
2
  runs = new Map();
3
+ scores = new Map();
3
4
  counter = 0;
4
5
  async createRun(run) {
5
6
  const runId = `run-${++this.counter}-${Date.now()}`;
@@ -42,4 +43,12 @@ export class InMemoryAIRunStateService {
42
43
  }
43
44
  return null;
44
45
  }
46
+ async saveScore(score) {
47
+ const existing = this.scores.get(score.runId) ?? [];
48
+ existing.push({ ...score, createdAt: new Date() });
49
+ this.scores.set(score.runId, existing);
50
+ }
51
+ async getScores(runId) {
52
+ return [...(this.scores.get(runId) ?? [])];
53
+ }
45
54
  }