@pikku/core 0.12.0 → 0.12.2

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 (290) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/errors/errors.d.ts +6 -0
  3. package/dist/errors/errors.js +10 -0
  4. package/dist/errors/index.d.ts +1 -0
  5. package/dist/errors/index.js +1 -0
  6. package/dist/function/function-runner.d.ts +3 -3
  7. package/dist/function/function-runner.js +66 -44
  8. package/dist/function/functions.types.d.ts +1 -0
  9. package/dist/handle-error.d.ts +2 -2
  10. package/dist/handle-error.js +2 -2
  11. package/dist/index.d.ts +5 -3
  12. package/dist/index.js +2 -1
  13. package/dist/internal.d.ts +3 -0
  14. package/dist/internal.js +2 -0
  15. package/dist/middleware/auth-bearer.d.ts +1 -1
  16. package/dist/middleware/auth-bearer.js +1 -1
  17. package/dist/middleware/auth-cookie.d.ts +2 -2
  18. package/dist/middleware/auth-cookie.js +1 -1
  19. package/dist/middleware/cors.d.ts +2 -2
  20. package/dist/middleware/cors.js +45 -37
  21. package/dist/middleware-runner.d.ts +1 -1
  22. package/dist/middleware-runner.js +1 -0
  23. package/dist/permissions.d.ts +2 -2
  24. package/dist/permissions.js +1 -0
  25. package/dist/pikku-state.d.ts +9 -8
  26. package/dist/pikku-state.js +34 -17
  27. package/dist/schema.d.ts +4 -4
  28. package/dist/schema.js +9 -5
  29. package/dist/services/ai-agent-runner-service.d.ts +22 -3
  30. package/dist/services/ai-run-state-service.d.ts +1 -1
  31. package/dist/services/ai-storage-service.d.ts +1 -1
  32. package/dist/services/content-service.d.ts +6 -0
  33. package/dist/services/gateway-service.d.ts +19 -0
  34. package/dist/services/gopass-secrets.d.ts +1 -1
  35. package/dist/services/gopass-secrets.js +3 -0
  36. package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
  37. package/dist/services/in-memory-ai-run-state-service.js +44 -0
  38. package/dist/services/in-memory-trigger-service.d.ts +0 -1
  39. package/dist/services/in-memory-trigger-service.js +6 -8
  40. package/dist/services/index.d.ts +5 -2
  41. package/dist/services/index.js +2 -0
  42. package/dist/services/local-content.d.ts +2 -1
  43. package/dist/services/local-content.js +6 -1
  44. package/dist/services/local-gateway-service.d.ts +22 -0
  45. package/dist/services/local-gateway-service.js +51 -0
  46. package/dist/services/local-secrets.d.ts +2 -2
  47. package/dist/services/local-variables.d.ts +1 -1
  48. package/dist/services/logger-console.d.ts +2 -1
  49. package/dist/services/scheduler-service.d.ts +0 -12
  50. package/dist/services/scheduler-service.js +0 -6
  51. package/dist/services/scoped-secret-service.d.ts +1 -1
  52. package/dist/services/trigger-service.d.ts +0 -7
  53. package/dist/services/user-session-service.d.ts +3 -3
  54. package/dist/services/workflow-service.d.ts +2 -3
  55. package/dist/types/core.types.d.ts +27 -19
  56. package/dist/types/state.types.d.ts +22 -15
  57. package/dist/utils.d.ts +5 -5
  58. package/dist/utils.js +12 -9
  59. package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
  60. package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +168 -0
  61. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
  62. package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
  63. package/dist/wirings/ai-agent/ai-agent-memory.js +13 -2
  64. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +4 -5
  65. package/dist/wirings/ai-agent/ai-agent-prepare.js +80 -31
  66. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +1 -1
  67. package/dist/wirings/ai-agent/ai-agent-runner.js +107 -8
  68. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
  69. package/dist/wirings/ai-agent/ai-agent-stream.js +263 -89
  70. package/dist/wirings/ai-agent/ai-agent.types.d.ts +96 -4
  71. package/dist/wirings/ai-agent/index.d.ts +3 -1
  72. package/dist/wirings/ai-agent/index.js +2 -0
  73. package/dist/wirings/channel/channel-common.d.ts +2 -2
  74. package/dist/wirings/channel/channel-handler.d.ts +7 -4
  75. package/dist/wirings/channel/channel-handler.js +15 -5
  76. package/dist/wirings/channel/channel-middleware-runner.js +1 -0
  77. package/dist/wirings/channel/channel-runner.d.ts +5 -5
  78. package/dist/wirings/channel/channel-runner.js +3 -2
  79. package/dist/wirings/channel/channel-store.d.ts +1 -1
  80. package/dist/wirings/channel/channel.types.d.ts +10 -6
  81. package/dist/wirings/channel/index.d.ts +1 -1
  82. package/dist/wirings/channel/local/local-channel-handler.d.ts +7 -0
  83. package/dist/wirings/channel/local/local-channel-handler.js +17 -0
  84. package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
  85. package/dist/wirings/channel/local/local-channel-runner.js +18 -4
  86. package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
  87. package/dist/wirings/channel/log-channels.d.ts +1 -1
  88. package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +2 -1
  89. package/dist/wirings/channel/pikku-abstract-channel-handler.js +1 -0
  90. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +4 -4
  91. package/dist/wirings/channel/serverless/serverless-channel-runner.js +26 -20
  92. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
  93. package/dist/wirings/cli/cli-runner.d.ts +2 -2
  94. package/dist/wirings/cli/cli-runner.js +3 -0
  95. package/dist/wirings/cli/cli.types.d.ts +3 -3
  96. package/dist/wirings/cli/command-parser.d.ts +1 -1
  97. package/dist/wirings/gateway/gateway-runner.d.ts +24 -0
  98. package/dist/wirings/gateway/gateway-runner.js +325 -0
  99. package/dist/wirings/gateway/gateway.types.d.ts +127 -0
  100. package/dist/wirings/gateway/index.d.ts +2 -0
  101. package/dist/wirings/gateway/index.js +1 -0
  102. package/dist/wirings/http/http-runner.d.ts +9 -9
  103. package/dist/wirings/http/http-runner.js +36 -14
  104. package/dist/wirings/http/http.types.d.ts +2 -6
  105. package/dist/wirings/http/log-http-routes.d.ts +1 -1
  106. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
  107. package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
  108. package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
  109. package/dist/wirings/http/routers/http-router.d.ts +1 -1
  110. package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
  111. package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
  112. package/dist/wirings/mcp/mcp-runner.d.ts +0 -3
  113. package/dist/wirings/mcp/mcp-runner.js +4 -2
  114. package/dist/wirings/mcp/mcp.types.d.ts +2 -2
  115. package/dist/wirings/oauth2/oauth2-client.d.ts +3 -3
  116. package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +1 -1
  117. package/dist/wirings/queue/index.d.ts +1 -1
  118. package/dist/wirings/queue/index.js +1 -1
  119. package/dist/wirings/queue/queue-runner.d.ts +1 -12
  120. package/dist/wirings/queue/queue-runner.js +4 -12
  121. package/dist/wirings/queue/queue.types.d.ts +3 -9
  122. package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
  123. package/dist/wirings/queue/register-queue-helper.js +1 -1
  124. package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
  125. package/dist/wirings/rpc/index.d.ts +2 -0
  126. package/dist/wirings/rpc/index.js +1 -0
  127. package/dist/wirings/rpc/rpc-runner.d.ts +36 -14
  128. package/dist/wirings/rpc/rpc-runner.js +56 -28
  129. package/dist/wirings/rpc/rpc-types.d.ts +14 -2
  130. package/dist/wirings/rpc/wire-addon.d.ts +10 -0
  131. package/dist/wirings/rpc/wire-addon.js +9 -0
  132. package/dist/wirings/scheduler/index.d.ts +1 -1
  133. package/dist/wirings/scheduler/index.js +1 -1
  134. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
  135. package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -10
  136. package/dist/wirings/scheduler/scheduler-runner.js +4 -25
  137. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
  138. package/dist/wirings/trigger/pikku-trigger-service.d.ts +2 -6
  139. package/dist/wirings/trigger/pikku-trigger-service.js +11 -16
  140. package/dist/wirings/trigger/trigger-runner.d.ts +1 -5
  141. package/dist/wirings/trigger/trigger-runner.js +4 -3
  142. package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -6
  143. package/dist/wirings/workflow/pikku-workflow-service.js +20 -29
  144. package/dist/wirings/workflow/workflow.types.d.ts +2 -2
  145. package/package.json +4 -2
  146. package/src/crypto-utils.test.ts +116 -0
  147. package/src/errors/error.test.ts +143 -2
  148. package/src/errors/errors.ts +10 -0
  149. package/src/errors/index.ts +1 -0
  150. package/src/function/function-runner.test.ts +2 -2
  151. package/src/function/function-runner.ts +72 -49
  152. package/src/function/functions.types.ts +1 -0
  153. package/src/handle-error.test.ts +361 -0
  154. package/src/handle-error.ts +4 -4
  155. package/src/index.ts +3 -10
  156. package/src/internal.ts +6 -0
  157. package/src/middleware/auth-apikey.test.ts +1 -1
  158. package/src/middleware/auth-bearer.test.ts +1 -1
  159. package/src/middleware/auth-bearer.ts +2 -5
  160. package/src/middleware/auth-cookie.test.ts +1 -1
  161. package/src/middleware/auth-cookie.ts +3 -5
  162. package/src/middleware/cors.test.ts +424 -0
  163. package/src/middleware/cors.ts +14 -6
  164. package/src/middleware/remote-auth.test.ts +488 -0
  165. package/src/middleware-runner.test.ts +1 -1
  166. package/src/middleware-runner.ts +2 -1
  167. package/src/permissions.test.ts +2 -2
  168. package/src/permissions.ts +3 -2
  169. package/src/pikku-state.test.ts +224 -0
  170. package/src/pikku-state.ts +45 -28
  171. package/src/schema.test.ts +198 -6
  172. package/src/schema.ts +11 -7
  173. package/src/services/ai-agent-runner-service.ts +15 -3
  174. package/src/services/ai-run-state-service.ts +1 -1
  175. package/src/services/ai-storage-service.ts +1 -1
  176. package/src/services/content-service.ts +7 -0
  177. package/src/services/gateway-service.ts +20 -0
  178. package/src/services/gopass-secrets.ts +4 -1
  179. package/src/services/in-memory-ai-run-state-service.ts +73 -0
  180. package/src/services/in-memory-trigger-service.ts +6 -10
  181. package/src/services/in-memory-workflow-service.test.ts +351 -0
  182. package/src/services/index.ts +4 -1
  183. package/src/services/local-content.ts +9 -3
  184. package/src/services/local-gateway-service.ts +62 -0
  185. package/src/services/local-secrets.test.ts +80 -0
  186. package/src/services/local-secrets.ts +2 -2
  187. package/src/services/local-variables.test.ts +61 -0
  188. package/src/services/local-variables.ts +1 -1
  189. package/src/services/logger-console.test.ts +118 -0
  190. package/src/services/logger-console.ts +2 -1
  191. package/src/services/scheduler-service.ts +0 -18
  192. package/src/services/scoped-secret-service.test.ts +74 -0
  193. package/src/services/scoped-secret-service.ts +1 -1
  194. package/src/services/trigger-service.ts +0 -21
  195. package/src/services/typed-secret-service.test.ts +93 -0
  196. package/src/services/typed-variables-service.test.ts +73 -0
  197. package/src/services/user-session-service.test.ts +113 -0
  198. package/src/services/user-session-service.ts +3 -3
  199. package/src/services/workflow-service.ts +2 -12
  200. package/src/time-utils.test.ts +1 -1
  201. package/src/types/core.types.ts +28 -19
  202. package/src/types/state.types.ts +32 -15
  203. package/src/utils.test.ts +350 -0
  204. package/src/utils.ts +14 -13
  205. package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
  206. package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +238 -0
  207. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
  208. package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
  209. package/src/wirings/ai-agent/ai-agent-memory.ts +10 -1
  210. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
  211. package/src/wirings/ai-agent/ai-agent-prepare.ts +98 -46
  212. package/src/wirings/ai-agent/ai-agent-registry.ts +1 -1
  213. package/src/wirings/ai-agent/ai-agent-runner.test.ts +245 -3
  214. package/src/wirings/ai-agent/ai-agent-runner.ts +121 -7
  215. package/src/wirings/ai-agent/ai-agent-stream.test.ts +430 -24
  216. package/src/wirings/ai-agent/ai-agent-stream.ts +390 -104
  217. package/src/wirings/ai-agent/ai-agent.types.ts +91 -4
  218. package/src/wirings/ai-agent/index.ts +13 -0
  219. package/src/wirings/channel/channel-common.ts +2 -2
  220. package/src/wirings/channel/channel-handler.ts +43 -11
  221. package/src/wirings/channel/channel-middleware-runner.ts +1 -0
  222. package/src/wirings/channel/channel-runner.ts +6 -6
  223. package/src/wirings/channel/channel-store.ts +1 -1
  224. package/src/wirings/channel/channel.types.ts +15 -8
  225. package/src/wirings/channel/index.ts +1 -0
  226. package/src/wirings/channel/local/local-channel-handler.ts +26 -0
  227. package/src/wirings/channel/local/local-channel-runner.test.ts +19 -12
  228. package/src/wirings/channel/local/local-channel-runner.ts +33 -14
  229. package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
  230. package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
  231. package/src/wirings/channel/log-channels.ts +1 -1
  232. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +2 -0
  233. package/src/wirings/channel/pikku-abstract-channel-handler.ts +8 -1
  234. package/src/wirings/channel/serverless/serverless-channel-runner.ts +38 -33
  235. package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
  236. package/src/wirings/cli/cli-runner.test.ts +1 -1
  237. package/src/wirings/cli/cli-runner.ts +14 -4
  238. package/src/wirings/cli/cli.types.ts +3 -3
  239. package/src/wirings/cli/command-parser.test.ts +1 -1
  240. package/src/wirings/cli/command-parser.ts +1 -1
  241. package/src/wirings/gateway/gateway-runner.test.ts +474 -0
  242. package/src/wirings/gateway/gateway-runner.ts +411 -0
  243. package/src/wirings/gateway/gateway.types.ts +149 -0
  244. package/src/wirings/gateway/index.ts +13 -0
  245. package/src/wirings/http/http-routes.test.ts +1 -1
  246. package/src/wirings/http/http-runner.test.ts +9 -17
  247. package/src/wirings/http/http-runner.ts +46 -27
  248. package/src/wirings/http/http.types.ts +1 -14
  249. package/src/wirings/http/log-http-routes.ts +1 -1
  250. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  251. package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
  252. package/src/wirings/http/routers/http-router.ts +1 -1
  253. package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
  254. package/src/wirings/http/routers/path-to-regex.ts +4 -3
  255. package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
  256. package/src/wirings/mcp/mcp-runner.ts +9 -15
  257. package/src/wirings/mcp/mcp.types.ts +2 -2
  258. package/src/wirings/oauth2/oauth2-client.ts +3 -3
  259. package/src/wirings/oauth2/wire-oauth2-credential.ts +1 -1
  260. package/src/wirings/queue/index.ts +0 -1
  261. package/src/wirings/queue/queue-runner.test.ts +52 -25
  262. package/src/wirings/queue/queue-runner.ts +8 -30
  263. package/src/wirings/queue/queue.types.ts +3 -13
  264. package/src/wirings/queue/register-queue-helper.ts +3 -5
  265. package/src/wirings/queue/validate-worker-config.test.ts +108 -0
  266. package/src/wirings/queue/validate-worker-config.ts +4 -1
  267. package/src/wirings/rpc/index.ts +2 -0
  268. package/src/wirings/rpc/rpc-runner.ts +92 -49
  269. package/src/wirings/rpc/rpc-types.ts +17 -2
  270. package/src/wirings/rpc/wire-addon.ts +20 -0
  271. package/src/wirings/scheduler/index.ts +0 -1
  272. package/src/wirings/scheduler/log-schedulers.ts +1 -1
  273. package/src/wirings/scheduler/scheduler-runner.test.ts +49 -60
  274. package/src/wirings/scheduler/scheduler-runner.ts +9 -56
  275. package/src/wirings/scheduler/scheduler.types.ts +2 -2
  276. package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
  277. package/src/wirings/trigger/pikku-trigger-service.ts +17 -39
  278. package/src/wirings/trigger/trigger-runner.test.ts +79 -0
  279. package/src/wirings/trigger/trigger-runner.ts +8 -11
  280. package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
  281. package/src/wirings/workflow/graph/graph-runner.test.ts +14 -22
  282. package/src/wirings/workflow/graph/template.test.ts +49 -0
  283. package/src/wirings/workflow/pikku-workflow-service.test.ts +15 -27
  284. package/src/wirings/workflow/pikku-workflow-service.ts +29 -45
  285. package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
  286. package/src/wirings/workflow/workflow.types.ts +2 -2
  287. package/tsconfig.tsbuildinfo +1 -1
  288. package/src/wirings/workflow/workflow-utils.ts +0 -0
  289. /package/dist/{wirings/workflow/workflow-utils.d.ts → services/gateway-service.js} +0 -0
  290. /package/dist/wirings/{workflow/workflow-utils.js → gateway/gateway.types.js} +0 -0
@@ -1,4 +1,4 @@
1
- import type { CoreServices, PikkuWire } from '../../types/core.types.js'
1
+ import type { PikkuWire } from '../../types/core.types.js'
2
2
  import type { CoreQueueWorker, QueueJob, PikkuQueue } from './queue.types.js'
3
3
  import type {
4
4
  CorePikkuFunctionConfig,
@@ -6,9 +6,12 @@ import type {
6
6
  } from '../../function/functions.types.js'
7
7
  import { getErrorResponse, PikkuError } from '../../errors/error-handler.js'
8
8
  import { PikkuMissingMetaError } from '../../errors/errors.js'
9
- import { pikkuState } from '../../pikku-state.js'
9
+ import {
10
+ getSingletonServices,
11
+ getCreateWireServices,
12
+ pikkuState,
13
+ } from '../../pikku-state.js'
10
14
  import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
11
- import { CreateWireServices } from '../../types/core.types.js'
12
15
 
13
16
  /**
14
17
  * Error class for queue processor not found
@@ -100,16 +103,14 @@ export async function removeQueueWorker(name: string): Promise<void> {
100
103
  * Process a single queue job - this function is called by queue consumers
101
104
  */
102
105
  export async function runQueueJob({
103
- singletonServices,
104
- createWireServices,
105
106
  job,
106
107
  updateProgress,
107
108
  }: {
108
- singletonServices: CoreServices
109
- createWireServices?: CreateWireServices
110
109
  job: QueueJob
111
110
  updateProgress?: (progress: number | string | object) => Promise<void>
112
111
  }): Promise<void> {
112
+ const singletonServices = getSingletonServices()
113
+ const createWireServices = getCreateWireServices()
113
114
  const logger = singletonServices.logger
114
115
 
115
116
  const meta = pikkuState(null, 'queue', 'meta')
@@ -189,26 +190,3 @@ export async function runQueueJob({
189
190
  throw error
190
191
  }
191
192
  }
192
-
193
- export const createQueueJobRunner = ({
194
- singletonServices,
195
- createWireServices,
196
- }: {
197
- singletonServices: CoreServices
198
- createWireServices?: CreateWireServices
199
- }) => {
200
- return async ({
201
- job,
202
- updateProgress,
203
- }: {
204
- job: QueueJob
205
- updateProgress?: (progress: number | string | object) => Promise<void>
206
- }) => {
207
- await runQueueJob({
208
- singletonServices,
209
- createWireServices,
210
- job,
211
- updateProgress,
212
- })
213
- }
214
- }
@@ -1,7 +1,6 @@
1
- import { CommonWireMeta } from '../../types/core.types.js'
2
- import { CorePikkuFunctionConfig } from '../../function/functions.types.js'
3
- import { QueueConfigMapping } from './validate-worker-config.js'
4
- import { Logger } from '../../services/logger.js'
1
+ import type { CommonWireMeta } from '../../types/core.types.js'
2
+ import type { CorePikkuFunctionConfig } from '../../function/functions.types.js'
3
+ import type { QueueConfigMapping } from './validate-worker-config.js'
5
4
 
6
5
  /**
7
6
  * Configuration for queue workers - how jobs are processed
@@ -139,15 +138,6 @@ export interface QueueWorkers {
139
138
  /** Configuration mapping for validation */
140
139
  configMappings: QueueConfigMapping
141
140
 
142
- /** Set runtime queue job runner callback and logger */
143
- setJobRunner(
144
- runJob: (params: {
145
- job: QueueJob
146
- updateProgress?: (progress: number | string | object) => Promise<void>
147
- }) => Promise<void>,
148
- logger: Logger
149
- ): void
150
-
151
141
  /** Scan state and register all compatible processors */
152
142
  registerQueues(): Promise<Record<string, ConfigValidationResult[]>>
153
143
  }
@@ -1,10 +1,8 @@
1
1
  import type { ConfigValidationResult, CoreQueueWorker } from './queue.types.js'
2
2
  import { getQueueWorkers } from './queue-runner.js'
3
- import {
4
- QueueConfigMapping,
5
- validateWorkerConfig,
6
- } from './validate-worker-config.js'
7
- import { Logger } from '../../services/logger.js'
3
+ import type { QueueConfigMapping } from './validate-worker-config.js'
4
+ import { validateWorkerConfig } from './validate-worker-config.js'
5
+ import type { Logger } from '../../services/logger.js'
8
6
 
9
7
  /**
10
8
  * Queue processor registration callback
@@ -0,0 +1,108 @@
1
+ import { describe, test } from 'node:test'
2
+ import assert from 'node:assert'
3
+ import { validateWorkerConfig } from './validate-worker-config.js'
4
+ import type { QueueConfigMapping } from './validate-worker-config.js'
5
+
6
+ const createTestMapping = (): QueueConfigMapping => ({
7
+ supported: {
8
+ concurrency: {
9
+ queueProperty: 'concurrency',
10
+ description: 'Number of concurrent workers',
11
+ },
12
+ maxRetries: {
13
+ queueProperty: 'maxRetries',
14
+ description: 'Maximum retry attempts',
15
+ },
16
+ },
17
+ unsupported: {
18
+ rateLimitMax: {
19
+ reason: 'Not supported',
20
+ explanation: 'This queue does not support rate limiting',
21
+ },
22
+ },
23
+ fallbacks: {
24
+ retryDelay: {
25
+ reason: 'Partial support',
26
+ explanation: 'Uses fixed delay instead of exponential',
27
+ fallbackValue: '1000ms fixed',
28
+ },
29
+ },
30
+ })
31
+
32
+ describe('validateWorkerConfig', () => {
33
+ test('should return empty results for empty config', () => {
34
+ const mapping = createTestMapping()
35
+ const result = validateWorkerConfig(mapping, {})
36
+ assert.deepStrictEqual(result.applied, {})
37
+ assert.deepStrictEqual(result.ignored, {})
38
+ assert.deepStrictEqual(result.warnings, [])
39
+ assert.deepStrictEqual(result.fallbacks, {})
40
+ })
41
+
42
+ test('should return empty results for undefined config', () => {
43
+ const mapping = createTestMapping()
44
+ const result = validateWorkerConfig(mapping)
45
+ assert.deepStrictEqual(result.applied, {})
46
+ assert.deepStrictEqual(result.ignored, {})
47
+ })
48
+
49
+ test('should apply supported configurations', () => {
50
+ const mapping = createTestMapping()
51
+ const result = validateWorkerConfig(mapping, { concurrency: 5 } as any)
52
+ assert.deepStrictEqual(result.applied, { concurrency: 5 })
53
+ assert.deepStrictEqual(result.ignored, {})
54
+ assert.strictEqual(result.warnings.length, 0)
55
+ })
56
+
57
+ test('should ignore unsupported configurations with warning', () => {
58
+ const mapping = createTestMapping()
59
+ const result = validateWorkerConfig(mapping, { rateLimitMax: 100 } as any)
60
+ assert.deepStrictEqual(result.ignored, { rateLimitMax: 100 })
61
+ assert.strictEqual(result.warnings.length, 1)
62
+ assert.ok(result.warnings[0].includes('Not supported'))
63
+ })
64
+
65
+ test('should handle fallback configurations', () => {
66
+ const mapping = createTestMapping()
67
+ const result = validateWorkerConfig(mapping, { retryDelay: 2000 } as any)
68
+ assert.deepStrictEqual(result.applied, { retryDelay: 2000 })
69
+ assert.deepStrictEqual(result.fallbacks, { retryDelay: '1000ms fixed' })
70
+ assert.strictEqual(result.warnings.length, 1)
71
+ assert.ok(result.warnings[0].includes('Partial support'))
72
+ })
73
+
74
+ test('should warn about unknown configurations', () => {
75
+ const mapping = createTestMapping()
76
+ const result = validateWorkerConfig(mapping, {
77
+ unknownOption: 'val',
78
+ } as any)
79
+ assert.deepStrictEqual(result.ignored, { unknownOption: 'val' })
80
+ assert.strictEqual(result.warnings.length, 1)
81
+ assert.ok(result.warnings[0].includes('Unknown configuration'))
82
+ })
83
+
84
+ test('should skip undefined values', () => {
85
+ const mapping = createTestMapping()
86
+ const result = validateWorkerConfig(mapping, {
87
+ concurrency: undefined,
88
+ } as any)
89
+ assert.deepStrictEqual(result.applied, {})
90
+ })
91
+
92
+ test('should handle mixed supported and unsupported configs', () => {
93
+ const mapping = createTestMapping()
94
+ const result = validateWorkerConfig(mapping, {
95
+ concurrency: 3,
96
+ maxRetries: 5,
97
+ rateLimitMax: 100,
98
+ retryDelay: 1000,
99
+ } as any)
100
+ assert.deepStrictEqual(result.applied, {
101
+ concurrency: 3,
102
+ maxRetries: 5,
103
+ retryDelay: 1000,
104
+ })
105
+ assert.deepStrictEqual(result.ignored, { rateLimitMax: 100 })
106
+ assert.strictEqual(result.warnings.length, 2)
107
+ })
108
+ })
@@ -1,4 +1,7 @@
1
- import { PikkuWorkerConfig, ConfigValidationResult } from './queue.types.js'
1
+ import type {
2
+ PikkuWorkerConfig,
3
+ ConfigValidationResult,
4
+ } from './queue.types.js'
2
5
 
3
6
  /**
4
7
  * Configuration mapping structure for queue implementations
@@ -1,2 +1,4 @@
1
1
  export { PikkuRPCService, rpcService, RPCNotFoundError } from './rpc-runner.js'
2
2
  export type { PikkuRPC, RPCMeta } from './rpc-types.js'
3
+ export { wireAddon } from './wire-addon.js'
4
+ export type { WireAddonConfig } from './wire-addon.js'
@@ -1,15 +1,11 @@
1
- import {
2
- CoreServices,
3
- CoreSingletonServices,
4
- PikkuWire,
5
- } from '../../types/core.types.js'
1
+ import type { CoreServices, PikkuWire } from '../../types/core.types.js'
6
2
  import type { SessionService } from '../../services/user-session-service.js'
7
3
  import type { CoreUserSession } from '../../types/core.types.js'
8
4
  import { runPikkuFunc } from '../../function/function-runner.js'
9
5
  import { pikkuState } from '../../pikku-state.js'
10
6
  import { ForbiddenError } from '../../errors/errors.js'
11
7
  import { PikkuError } from '../../errors/error-handler.js'
12
- import { PikkuRPC, ResolvedFunction } from './rpc-types.js'
8
+ import type { PikkuRPC, ResolvedFunction } from './rpc-types.js'
13
9
  import { parseVersionedId } from '../../version.js'
14
10
  import { encryptJSON } from '../../crypto-utils.js'
15
11
 
@@ -21,7 +17,11 @@ export class RPCNotFoundError extends PikkuError {
21
17
  }
22
18
  }
23
19
  import type { AIAgentInput } from '../ai-agent/ai-agent.types.js'
20
+ import type { AIStreamChannel } from '../ai-agent/ai-agent.types.js'
21
+ import type { StreamAIAgentOptions } from '../ai-agent/ai-agent-prepare.js'
24
22
  import { runAIAgent } from '../ai-agent/ai-agent-runner.js'
23
+ import { streamAIAgent, resumeAIAgent } from '../ai-agent/ai-agent-stream.js'
24
+ import { approveAIAgent } from '../ai-agent/ai-agent-registry.js'
25
25
 
26
26
  /**
27
27
  * Resolve a namespaced function reference to package and function names
@@ -38,13 +38,14 @@ const resolveNamespace = (
38
38
  const namespace = namespacedFunction.substring(0, colonIndex)
39
39
  const functionName = namespacedFunction.substring(colonIndex + 1)
40
40
 
41
- const externalPackages = pikkuState(null, 'rpc', 'externalPackages')
42
- const pkgConfig = externalPackages.get(namespace)
41
+ const addons = pikkuState(null, 'rpc', 'addons')
42
+ const pkgConfig = addons.get(namespace)
43
43
  if (!pkgConfig) {
44
44
  return null
45
45
  }
46
46
 
47
47
  return {
48
+ namespace,
48
49
  package: pkgConfig.package,
49
50
  function: functionName,
50
51
  }
@@ -115,11 +116,7 @@ export class ContextAwareRPCService {
115
116
 
116
117
  // Check if it's a namespaced function call (e.g., 'stripe:createCharge')
117
118
  if (funcName.includes(':')) {
118
- return this.invokeExternalPackageFunction<In, Out>(
119
- funcName,
120
- data,
121
- updatedWire
122
- )
119
+ return this.invokeAddonFunction<In, Out>(funcName, data, updatedWire)
123
120
  }
124
121
 
125
122
  // Main package function
@@ -137,12 +134,12 @@ export class ContextAwareRPCService {
137
134
  }
138
135
 
139
136
  /**
140
- * Invoke a function from an external package
141
- * External packages register their functions in pikkuState under their package name.
137
+ * Invoke a function from an addon package
138
+ * Addon packages register their functions in pikkuState under their package name.
142
139
  * The function is executed using the parent services (shared singleton services).
143
140
  * @private
144
141
  */
145
- private async invokeExternalPackageFunction<In = any, Out = any>(
142
+ private async invokeAddonFunction<In = any, Out = any>(
146
143
  namespacedFunction: string,
147
144
  data: In,
148
145
  wire: PikkuWire
@@ -152,36 +149,38 @@ export class ContextAwareRPCService {
152
149
  if (!resolved) {
153
150
  throw new Error(
154
151
  `Unknown namespace in function reference: ${namespacedFunction}. ` +
155
- `Make sure the package is registered in externalPackages config.`
152
+ `Make sure the package is registered in addons config.`
156
153
  )
157
154
  }
158
155
 
159
- // Get the function meta from the external package
160
- // External packages use function meta, not RPC meta
161
- const externalFunctionMeta = pikkuState(
162
- resolved.package,
163
- 'function',
164
- 'meta'
165
- )
166
- const funcMeta = externalFunctionMeta[resolved.function]
156
+ // Get the function meta from the addon package
157
+ // Addon packages use function meta, not RPC meta
158
+ const addonFunctionMeta = pikkuState(resolved.package, 'function', 'meta')
159
+ const funcMeta = addonFunctionMeta[resolved.function]
167
160
  if (!funcMeta) {
168
161
  throw new Error(
169
162
  `Function '${resolved.function}' not found in package '${resolved.package}'. ` +
170
- `Available functions: ${Object.keys(externalFunctionMeta).join(', ') || '(none)'}`
163
+ `Available functions: ${Object.keys(addonFunctionMeta).join(', ') || '(none)'}`
171
164
  )
172
165
  }
173
166
  const funcName = funcMeta.pikkuFuncId || resolved.function
174
167
 
175
- // Execute the function using runPikkuFunc with the external package's state
176
- // We use the parent services (this.services) since external packages share services
168
+ const addonConfig = pikkuState(null, 'rpc', 'addons').get(
169
+ resolved.namespace
170
+ )
171
+ const auth = addonConfig?.auth ?? this.options.requiresAuth
172
+ const tags = [...(addonConfig?.tags ?? []), ...(funcMeta.tags ?? [])]
173
+
174
+ // Execute the function using runPikkuFunc with the addon package's state
175
+ // We use the parent services (this.services) since addon packages share services
177
176
  // Pass the function's tags so tag-based middleware/permissions are applied
178
177
  return runPikkuFunc<In, Out>('rpc', namespacedFunction, funcName, {
179
- auth: this.options.requiresAuth,
178
+ auth,
180
179
  singletonServices: this.services,
181
180
  data: () => data,
182
181
  wire,
183
182
  packageName: resolved.package,
184
- tags: funcMeta.tags,
183
+ tags,
185
184
  })
186
185
  }
187
186
 
@@ -241,22 +240,64 @@ export class ContextAwareRPCService {
241
240
  )
242
241
  }
243
242
 
244
- public async agent(
245
- agentName: string,
246
- input: AIAgentInput
247
- ): Promise<{
248
- runId: string
249
- result: unknown
250
- usage: { inputTokens: number; outputTokens: number }
251
- }> {
252
- const result = await runAIAgent(agentName, input, {
253
- singletonServices: this.services as CoreSingletonServices,
254
- sessionService: this.options.sessionService,
255
- })
243
+ public get agent() {
256
244
  return {
257
- runId: result.runId,
258
- result: result.object ?? result.text,
259
- usage: result.usage,
245
+ run: async (agentName: string, input: AIAgentInput) => {
246
+ const result = await runAIAgent(agentName, input, {
247
+ sessionService: this.options.sessionService,
248
+ })
249
+ return {
250
+ runId: result.runId,
251
+ result: result.object ?? result.text,
252
+ usage: result.usage,
253
+ }
254
+ },
255
+ stream: async (
256
+ agentName: string,
257
+ input:
258
+ | { message: string; threadId: string; resourceId: string }
259
+ | Record<string, unknown>,
260
+ options?: StreamAIAgentOptions
261
+ ) => {
262
+ const channel = this.wire.channel as unknown as AIStreamChannel
263
+ if (!channel) throw new Error('No channel available for streaming')
264
+ await streamAIAgent(
265
+ agentName,
266
+ input,
267
+ channel,
268
+ { sessionService: this.options.sessionService },
269
+ undefined,
270
+ options
271
+ )
272
+ },
273
+ resume: async (
274
+ runId: string,
275
+ input: { toolCallId: string; approved: boolean },
276
+ options?: StreamAIAgentOptions
277
+ ) => {
278
+ const channel = this.wire.channel as unknown as AIStreamChannel
279
+ if (!channel) throw new Error('No channel available for streaming')
280
+ await resumeAIAgent(
281
+ { runId, ...input },
282
+ channel,
283
+ { sessionService: this.options.sessionService },
284
+ options
285
+ )
286
+ },
287
+ approve: async (
288
+ runId: string,
289
+ approvals: { toolCallId: string; approved: boolean }[],
290
+ expectedAgentName?: string
291
+ ) => {
292
+ if (!this.services.aiRunState)
293
+ throw new Error('AIRunStateService not available')
294
+ return approveAIAgent(
295
+ this.services.aiRunState,
296
+ runId,
297
+ approvals,
298
+ expectedAgentName
299
+ )
300
+ },
260
301
  }
261
302
  }
262
303
 
@@ -272,8 +313,8 @@ export class ContextAwareRPCService {
272
313
  const colonIndex = funcName.indexOf(':')
273
314
  if (colonIndex !== -1) {
274
315
  const namespace = funcName.substring(0, colonIndex)
275
- const externalPackages = pikkuState(null, 'rpc', 'externalPackages')
276
- const pkgConfig = externalPackages.get(namespace)
316
+ const addons = pikkuState(null, 'rpc', 'addons')
317
+ const pkgConfig = addons.get(namespace)
277
318
  endpoint = pkgConfig?.rpcEndpoint
278
319
  }
279
320
 
@@ -288,7 +329,7 @@ export class ContextAwareRPCService {
288
329
  if (!endpoint) {
289
330
  throw new Error(
290
331
  `No endpoint configured for remote RPC: ${funcName}. ` +
291
- `Configure rpcEndpoint in externalPackages config or set up a DeploymentService.`
332
+ `Configure rpcEndpoint in addons config or set up a DeploymentService.`
292
333
  )
293
334
  }
294
335
 
@@ -386,7 +427,9 @@ export class PikkuRPCService<
386
427
  remote: serviceRPC.remote.bind(serviceRPC),
387
428
  exposed: serviceRPC.rpcExposed.bind(serviceRPC),
388
429
  startWorkflow: serviceRPC.startWorkflow.bind(serviceRPC),
389
- agent: serviceRPC.agent.bind(serviceRPC),
430
+ get agent() {
431
+ return serviceRPC.agent
432
+ },
390
433
  rpcWithWire: serviceRPC.rpcWithWire.bind(serviceRPC),
391
434
  } as any
392
435
  }
@@ -2,7 +2,8 @@ export type PikkuRPC<
2
2
  Invoke extends Function = any,
3
3
  Remote extends Function = any,
4
4
  startWorkflow extends Function = any,
5
- Agent extends Function = any,
5
+ AgentRun extends Function = any,
6
+ AgentStream extends Function = any,
6
7
  > = {
7
8
  depth: number
8
9
  global: boolean
@@ -10,7 +11,20 @@ export type PikkuRPC<
10
11
  remote: Remote
11
12
  exposed: (name: string, data: any) => Promise<any>
12
13
  startWorkflow: startWorkflow
13
- agent: Agent
14
+ agent: {
15
+ run: AgentRun
16
+ stream: AgentStream
17
+ resume: (
18
+ runId: string,
19
+ input: { toolCallId: string; approved: boolean },
20
+ options?: any
21
+ ) => Promise<void>
22
+ approve: (
23
+ runId: string,
24
+ approvals: { toolCallId: string; approved: boolean }[],
25
+ expectedAgentName?: string
26
+ ) => Promise<any>
27
+ }
14
28
  }
15
29
 
16
30
  export type RPCMeta = {
@@ -31,6 +45,7 @@ export interface RPCHandler<Input, Output> {
31
45
  * Resolved function reference from namespace
32
46
  */
33
47
  export interface ResolvedFunction {
48
+ namespace: string
34
49
  package: string
35
50
  function: string
36
51
  }
@@ -0,0 +1,20 @@
1
+ import { pikkuState } from '../../pikku-state.js'
2
+
3
+ export type WireAddonConfig = {
4
+ name: string
5
+ package: string
6
+ rpcEndpoint?: string
7
+ auth?: boolean
8
+ tags?: string[]
9
+ secretOverrides?: Record<string, string>
10
+ variableOverrides?: Record<string, string>
11
+ }
12
+
13
+ export const wireAddon = (config: WireAddonConfig): void => {
14
+ pikkuState(null, 'rpc', 'addons').set(config.name, {
15
+ package: config.package,
16
+ rpcEndpoint: config.rpcEndpoint,
17
+ auth: config.auth,
18
+ tags: config.tags,
19
+ })
20
+ }
@@ -1,6 +1,5 @@
1
1
  export {
2
2
  runScheduledTask,
3
- createSchedulerRuntimeHandlers,
4
3
  wireScheduler,
5
4
  getScheduledTasks,
6
5
  } from './scheduler-runner.js'
@@ -1,5 +1,5 @@
1
1
  import { pikkuState } from '../../pikku-state.js'
2
- import { Logger } from '../../services/index.js'
2
+ import type { Logger } from '../../services/index.js'
3
3
 
4
4
  /**
5
5
  * Logs all the loaded scheduled tasks.