@pikku/core 0.12.0 → 0.12.1

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 (262) hide show
  1. package/CHANGELOG.md +24 -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/permissions.d.ts +2 -2
  23. package/dist/pikku-state.d.ts +9 -8
  24. package/dist/pikku-state.js +30 -17
  25. package/dist/schema.d.ts +4 -4
  26. package/dist/schema.js +9 -5
  27. package/dist/services/ai-agent-runner-service.d.ts +22 -3
  28. package/dist/services/ai-run-state-service.d.ts +1 -1
  29. package/dist/services/ai-storage-service.d.ts +1 -1
  30. package/dist/services/content-service.d.ts +6 -0
  31. package/dist/services/gopass-secrets.d.ts +1 -1
  32. package/dist/services/gopass-secrets.js +3 -0
  33. package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
  34. package/dist/services/in-memory-ai-run-state-service.js +44 -0
  35. package/dist/services/in-memory-trigger-service.d.ts +0 -1
  36. package/dist/services/in-memory-trigger-service.js +6 -8
  37. package/dist/services/index.d.ts +3 -2
  38. package/dist/services/index.js +1 -0
  39. package/dist/services/local-content.d.ts +2 -1
  40. package/dist/services/local-content.js +6 -1
  41. package/dist/services/local-secrets.d.ts +2 -2
  42. package/dist/services/local-variables.d.ts +1 -1
  43. package/dist/services/logger-console.d.ts +2 -1
  44. package/dist/services/scheduler-service.d.ts +0 -12
  45. package/dist/services/scheduler-service.js +0 -6
  46. package/dist/services/scoped-secret-service.d.ts +1 -1
  47. package/dist/services/trigger-service.d.ts +0 -7
  48. package/dist/services/user-session-service.d.ts +3 -3
  49. package/dist/services/workflow-service.d.ts +2 -3
  50. package/dist/types/core.types.d.ts +24 -18
  51. package/dist/types/state.types.d.ts +17 -15
  52. package/dist/utils.d.ts +5 -5
  53. package/dist/utils.js +12 -9
  54. package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
  55. package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +146 -0
  56. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
  57. package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
  58. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +4 -5
  59. package/dist/wirings/ai-agent/ai-agent-prepare.js +66 -30
  60. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +1 -1
  61. package/dist/wirings/ai-agent/ai-agent-runner.js +107 -8
  62. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
  63. package/dist/wirings/ai-agent/ai-agent-stream.js +246 -87
  64. package/dist/wirings/ai-agent/ai-agent.types.d.ts +61 -2
  65. package/dist/wirings/ai-agent/index.d.ts +3 -1
  66. package/dist/wirings/ai-agent/index.js +2 -0
  67. package/dist/wirings/channel/channel-common.d.ts +2 -2
  68. package/dist/wirings/channel/channel-handler.d.ts +3 -3
  69. package/dist/wirings/channel/channel-handler.js +4 -4
  70. package/dist/wirings/channel/channel-runner.d.ts +5 -5
  71. package/dist/wirings/channel/channel-runner.js +3 -2
  72. package/dist/wirings/channel/channel-store.d.ts +1 -1
  73. package/dist/wirings/channel/channel.types.d.ts +4 -6
  74. package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
  75. package/dist/wirings/channel/local/local-channel-runner.js +4 -3
  76. package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
  77. package/dist/wirings/channel/log-channels.d.ts +1 -1
  78. package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +1 -1
  79. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +4 -4
  80. package/dist/wirings/channel/serverless/serverless-channel-runner.js +25 -19
  81. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
  82. package/dist/wirings/cli/cli-runner.d.ts +2 -2
  83. package/dist/wirings/cli/cli.types.d.ts +3 -3
  84. package/dist/wirings/cli/command-parser.d.ts +1 -1
  85. package/dist/wirings/http/http-runner.d.ts +9 -9
  86. package/dist/wirings/http/http-runner.js +33 -14
  87. package/dist/wirings/http/http.types.d.ts +2 -6
  88. package/dist/wirings/http/log-http-routes.d.ts +1 -1
  89. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
  90. package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
  91. package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
  92. package/dist/wirings/http/routers/http-router.d.ts +1 -1
  93. package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
  94. package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
  95. package/dist/wirings/mcp/mcp-runner.d.ts +0 -3
  96. package/dist/wirings/mcp/mcp-runner.js +4 -2
  97. package/dist/wirings/mcp/mcp.types.d.ts +2 -2
  98. package/dist/wirings/oauth2/oauth2-client.d.ts +3 -3
  99. package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +1 -1
  100. package/dist/wirings/queue/index.d.ts +1 -1
  101. package/dist/wirings/queue/index.js +1 -1
  102. package/dist/wirings/queue/queue-runner.d.ts +1 -12
  103. package/dist/wirings/queue/queue-runner.js +4 -12
  104. package/dist/wirings/queue/queue.types.d.ts +3 -9
  105. package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
  106. package/dist/wirings/queue/register-queue-helper.js +1 -1
  107. package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
  108. package/dist/wirings/rpc/index.d.ts +2 -0
  109. package/dist/wirings/rpc/index.js +1 -0
  110. package/dist/wirings/rpc/rpc-runner.d.ts +36 -14
  111. package/dist/wirings/rpc/rpc-runner.js +56 -28
  112. package/dist/wirings/rpc/rpc-types.d.ts +14 -2
  113. package/dist/wirings/rpc/wire-addon.d.ts +10 -0
  114. package/dist/wirings/rpc/wire-addon.js +9 -0
  115. package/dist/wirings/scheduler/index.d.ts +1 -1
  116. package/dist/wirings/scheduler/index.js +1 -1
  117. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
  118. package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -10
  119. package/dist/wirings/scheduler/scheduler-runner.js +4 -25
  120. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
  121. package/dist/wirings/trigger/pikku-trigger-service.d.ts +2 -6
  122. package/dist/wirings/trigger/pikku-trigger-service.js +11 -16
  123. package/dist/wirings/trigger/trigger-runner.d.ts +1 -5
  124. package/dist/wirings/trigger/trigger-runner.js +4 -3
  125. package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -6
  126. package/dist/wirings/workflow/pikku-workflow-service.js +20 -29
  127. package/dist/wirings/workflow/workflow.types.d.ts +2 -2
  128. package/package.json +2 -1
  129. package/src/crypto-utils.test.ts +116 -0
  130. package/src/errors/error.test.ts +143 -2
  131. package/src/errors/errors.ts +10 -0
  132. package/src/errors/index.ts +1 -0
  133. package/src/function/function-runner.test.ts +2 -2
  134. package/src/function/function-runner.ts +72 -49
  135. package/src/function/functions.types.ts +1 -0
  136. package/src/handle-error.test.ts +361 -0
  137. package/src/handle-error.ts +4 -4
  138. package/src/index.ts +3 -10
  139. package/src/internal.ts +6 -0
  140. package/src/middleware/auth-apikey.test.ts +1 -1
  141. package/src/middleware/auth-bearer.test.ts +1 -1
  142. package/src/middleware/auth-bearer.ts +2 -5
  143. package/src/middleware/auth-cookie.test.ts +1 -1
  144. package/src/middleware/auth-cookie.ts +3 -5
  145. package/src/middleware/cors.test.ts +424 -0
  146. package/src/middleware/cors.ts +14 -6
  147. package/src/middleware/remote-auth.test.ts +488 -0
  148. package/src/middleware-runner.test.ts +1 -1
  149. package/src/middleware-runner.ts +1 -1
  150. package/src/permissions.test.ts +2 -2
  151. package/src/permissions.ts +2 -2
  152. package/src/pikku-state.test.ts +224 -0
  153. package/src/pikku-state.ts +40 -28
  154. package/src/schema.test.ts +198 -6
  155. package/src/schema.ts +11 -7
  156. package/src/services/ai-agent-runner-service.ts +15 -3
  157. package/src/services/ai-run-state-service.ts +1 -1
  158. package/src/services/ai-storage-service.ts +1 -1
  159. package/src/services/content-service.ts +7 -0
  160. package/src/services/gopass-secrets.ts +4 -1
  161. package/src/services/in-memory-ai-run-state-service.ts +73 -0
  162. package/src/services/in-memory-trigger-service.ts +6 -10
  163. package/src/services/in-memory-workflow-service.test.ts +351 -0
  164. package/src/services/index.ts +2 -1
  165. package/src/services/local-content.ts +9 -3
  166. package/src/services/local-secrets.test.ts +80 -0
  167. package/src/services/local-secrets.ts +2 -2
  168. package/src/services/local-variables.test.ts +61 -0
  169. package/src/services/local-variables.ts +1 -1
  170. package/src/services/logger-console.test.ts +118 -0
  171. package/src/services/logger-console.ts +2 -1
  172. package/src/services/scheduler-service.ts +0 -18
  173. package/src/services/scoped-secret-service.test.ts +74 -0
  174. package/src/services/scoped-secret-service.ts +1 -1
  175. package/src/services/trigger-service.ts +0 -21
  176. package/src/services/typed-secret-service.test.ts +93 -0
  177. package/src/services/typed-variables-service.test.ts +73 -0
  178. package/src/services/user-session-service.test.ts +113 -0
  179. package/src/services/user-session-service.ts +3 -3
  180. package/src/services/workflow-service.ts +2 -12
  181. package/src/time-utils.test.ts +1 -1
  182. package/src/types/core.types.ts +25 -19
  183. package/src/types/state.types.ts +24 -15
  184. package/src/utils.test.ts +350 -0
  185. package/src/utils.ts +14 -13
  186. package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
  187. package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +214 -0
  188. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
  189. package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
  190. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
  191. package/src/wirings/ai-agent/ai-agent-prepare.ts +79 -45
  192. package/src/wirings/ai-agent/ai-agent-registry.ts +1 -1
  193. package/src/wirings/ai-agent/ai-agent-runner.test.ts +245 -3
  194. package/src/wirings/ai-agent/ai-agent-runner.ts +121 -7
  195. package/src/wirings/ai-agent/ai-agent-stream.test.ts +430 -24
  196. package/src/wirings/ai-agent/ai-agent-stream.ts +377 -102
  197. package/src/wirings/ai-agent/ai-agent.types.ts +57 -2
  198. package/src/wirings/ai-agent/index.ts +11 -0
  199. package/src/wirings/channel/channel-common.ts +2 -2
  200. package/src/wirings/channel/channel-handler.ts +13 -9
  201. package/src/wirings/channel/channel-runner.ts +6 -6
  202. package/src/wirings/channel/channel-store.ts +1 -1
  203. package/src/wirings/channel/channel.types.ts +4 -8
  204. package/src/wirings/channel/local/local-channel-runner.test.ts +19 -12
  205. package/src/wirings/channel/local/local-channel-runner.ts +18 -13
  206. package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
  207. package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
  208. package/src/wirings/channel/log-channels.ts +1 -1
  209. package/src/wirings/channel/pikku-abstract-channel-handler.ts +1 -1
  210. package/src/wirings/channel/serverless/serverless-channel-runner.ts +37 -32
  211. package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
  212. package/src/wirings/cli/cli-runner.test.ts +1 -1
  213. package/src/wirings/cli/cli-runner.ts +11 -4
  214. package/src/wirings/cli/cli.types.ts +3 -3
  215. package/src/wirings/cli/command-parser.test.ts +1 -1
  216. package/src/wirings/cli/command-parser.ts +1 -1
  217. package/src/wirings/http/http-routes.test.ts +1 -1
  218. package/src/wirings/http/http-runner.test.ts +9 -17
  219. package/src/wirings/http/http-runner.ts +43 -27
  220. package/src/wirings/http/http.types.ts +1 -14
  221. package/src/wirings/http/log-http-routes.ts +1 -1
  222. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  223. package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
  224. package/src/wirings/http/routers/http-router.ts +1 -1
  225. package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
  226. package/src/wirings/http/routers/path-to-regex.ts +4 -3
  227. package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
  228. package/src/wirings/mcp/mcp-runner.ts +9 -15
  229. package/src/wirings/mcp/mcp.types.ts +2 -2
  230. package/src/wirings/oauth2/oauth2-client.ts +3 -3
  231. package/src/wirings/oauth2/wire-oauth2-credential.ts +1 -1
  232. package/src/wirings/queue/index.ts +0 -1
  233. package/src/wirings/queue/queue-runner.test.ts +52 -25
  234. package/src/wirings/queue/queue-runner.ts +8 -30
  235. package/src/wirings/queue/queue.types.ts +3 -13
  236. package/src/wirings/queue/register-queue-helper.ts +3 -5
  237. package/src/wirings/queue/validate-worker-config.test.ts +108 -0
  238. package/src/wirings/queue/validate-worker-config.ts +4 -1
  239. package/src/wirings/rpc/index.ts +2 -0
  240. package/src/wirings/rpc/rpc-runner.ts +92 -49
  241. package/src/wirings/rpc/rpc-types.ts +17 -2
  242. package/src/wirings/rpc/wire-addon.ts +20 -0
  243. package/src/wirings/scheduler/index.ts +0 -1
  244. package/src/wirings/scheduler/log-schedulers.ts +1 -1
  245. package/src/wirings/scheduler/scheduler-runner.test.ts +49 -60
  246. package/src/wirings/scheduler/scheduler-runner.ts +9 -56
  247. package/src/wirings/scheduler/scheduler.types.ts +2 -2
  248. package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
  249. package/src/wirings/trigger/pikku-trigger-service.ts +17 -39
  250. package/src/wirings/trigger/trigger-runner.test.ts +79 -0
  251. package/src/wirings/trigger/trigger-runner.ts +8 -11
  252. package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
  253. package/src/wirings/workflow/graph/graph-runner.test.ts +14 -22
  254. package/src/wirings/workflow/graph/template.test.ts +49 -0
  255. package/src/wirings/workflow/pikku-workflow-service.test.ts +15 -27
  256. package/src/wirings/workflow/pikku-workflow-service.ts +29 -45
  257. package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
  258. package/src/wirings/workflow/workflow.types.ts +2 -2
  259. package/tsconfig.tsbuildinfo +1 -1
  260. package/dist/wirings/workflow/workflow-utils.d.ts +0 -1
  261. package/dist/wirings/workflow/workflow-utils.js +0 -1
  262. package/src/wirings/workflow/workflow-utils.ts +0 -0
@@ -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.
@@ -4,11 +4,10 @@ import {
4
4
  wireScheduler,
5
5
  runScheduledTask,
6
6
  getScheduledTasks,
7
- createSchedulerRuntimeHandlers,
8
7
  } from './scheduler-runner.js'
9
8
  import { resetPikkuState, pikkuState } from '../../pikku-state.js'
10
- import { CoreScheduledTask } from './scheduler.types.js'
11
- import { CoreUserSession } from '../../types/core.types.js'
9
+ import type { CoreScheduledTask } from './scheduler.types.js'
10
+ import type { CoreUserSession } from '../../types/core.types.js'
12
11
 
13
12
  beforeEach(() => {
14
13
  resetPikkuState()
@@ -168,9 +167,11 @@ describe('runScheduledTask', () => {
168
167
  wireScheduler(mockTask)
169
168
 
170
169
  const mockLogger = createMockLogger()
170
+ pikkuState(null, 'package', 'singletonServices', {
171
+ logger: mockLogger,
172
+ } as any)
171
173
  await runScheduledTask({
172
174
  name: 'simple-task',
173
- singletonServices: { logger: mockLogger } as any,
174
175
  })
175
176
 
176
177
  assert.equal(taskExecuted, true)
@@ -208,12 +209,14 @@ describe('runScheduledTask', () => {
208
209
  wireScheduler(mockTask)
209
210
 
210
211
  const mockLogger = createMockLogger()
212
+ pikkuState(null, 'package', 'singletonServices', {
213
+ logger: mockLogger,
214
+ } as any)
211
215
  const session: CoreUserSession = { userId: 'user123' }
212
216
 
213
217
  await runScheduledTask({
214
218
  name: 'task-with-session',
215
219
  session,
216
- singletonServices: { logger: mockLogger } as any,
217
220
  })
218
221
 
219
222
  assert.deepEqual(receivedSession, session)
@@ -221,12 +224,14 @@ describe('runScheduledTask', () => {
221
224
 
222
225
  test('should throw ScheduledTaskNotFoundError when task not found', async () => {
223
226
  const mockLogger = createMockLogger()
227
+ pikkuState(null, 'package', 'singletonServices', {
228
+ logger: mockLogger,
229
+ } as any)
224
230
 
225
231
  await assert.rejects(
226
232
  async () => {
227
233
  await runScheduledTask({
228
234
  name: 'non-existent-task',
229
- singletonServices: { logger: mockLogger } as any,
230
235
  })
231
236
  },
232
237
  (error: any) => {
@@ -250,12 +255,14 @@ describe('runScheduledTask', () => {
250
255
  pikkuState(null, 'scheduler', 'tasks').set('task-without-meta', mockTask)
251
256
 
252
257
  const mockLogger = createMockLogger()
258
+ pikkuState(null, 'package', 'singletonServices', {
259
+ logger: mockLogger,
260
+ } as any)
253
261
 
254
262
  await assert.rejects(
255
263
  async () => {
256
264
  await runScheduledTask({
257
265
  name: 'task-without-meta',
258
- singletonServices: { logger: mockLogger } as any,
259
266
  })
260
267
  },
261
268
  (error: any) => {
@@ -290,12 +297,14 @@ describe('runScheduledTask', () => {
290
297
  wireScheduler(mockTask)
291
298
 
292
299
  const mockLogger = createMockLogger()
300
+ pikkuState(null, 'package', 'singletonServices', {
301
+ logger: mockLogger,
302
+ } as any)
293
303
 
294
304
  await assert.rejects(
295
305
  async () => {
296
306
  await runScheduledTask({
297
307
  name: 'skipped-task',
298
- singletonServices: { logger: mockLogger } as any,
299
308
  })
300
309
  },
301
310
  (error: any) => {
@@ -333,12 +342,14 @@ describe('runScheduledTask', () => {
333
342
  wireScheduler(mockTask)
334
343
 
335
344
  const mockLogger = createMockLogger()
345
+ pikkuState(null, 'package', 'singletonServices', {
346
+ logger: mockLogger,
347
+ } as any)
336
348
 
337
349
  await assert.rejects(
338
350
  async () => {
339
351
  await runScheduledTask({
340
352
  name: 'skipped-task-no-reason',
341
- singletonServices: { logger: mockLogger } as any,
342
353
  })
343
354
  },
344
355
  (error: any) => {
@@ -379,10 +390,12 @@ describe('runScheduledTask', () => {
379
390
  wireScheduler(mockTask)
380
391
 
381
392
  const mockLogger = createMockLogger()
393
+ pikkuState(null, 'package', 'singletonServices', {
394
+ logger: mockLogger,
395
+ } as any)
382
396
 
383
397
  await runScheduledTask({
384
398
  name: 'wire-task',
385
- singletonServices: { logger: mockLogger } as any,
386
399
  })
387
400
 
388
401
  assert.equal(capturedWire.scheduledTask.name, 'wire-task')
@@ -417,14 +430,18 @@ describe('runScheduledTask', () => {
417
430
  wireScheduler(mockTask)
418
431
 
419
432
  const mockLogger = createMockLogger()
420
-
421
- await runScheduledTask({
422
- name: 'session-services-task',
423
- singletonServices: { logger: mockLogger } as any,
433
+ pikkuState(null, 'package', 'singletonServices', {
434
+ logger: mockLogger,
435
+ } as any)
436
+ pikkuState(null, 'package', 'factories', {
424
437
  createWireServices: async () => {
425
438
  createWireServicesCalled = true
426
439
  return mockWireService as any
427
440
  },
441
+ } as any)
442
+
443
+ await runScheduledTask({
444
+ name: 'session-services-task',
428
445
  })
429
446
 
430
447
  assert.equal(createWireServicesCalled, true)
@@ -462,11 +479,15 @@ describe('runScheduledTask', () => {
462
479
  wireScheduler(mockTask)
463
480
 
464
481
  const mockLogger = createMockLogger()
482
+ pikkuState(null, 'package', 'singletonServices', {
483
+ logger: mockLogger,
484
+ } as any)
485
+ pikkuState(null, 'package', 'factories', {
486
+ createWireServices: async () => mockWireService as any,
487
+ } as any)
465
488
 
466
489
  await runScheduledTask({
467
490
  name: 'cleanup-task',
468
- singletonServices: { logger: mockLogger } as any,
469
- createWireServices: async () => mockWireService as any,
470
491
  })
471
492
 
472
493
  assert.equal(closeCalled, true)
@@ -506,12 +527,16 @@ describe('runScheduledTask', () => {
506
527
  wireScheduler(mockTask)
507
528
 
508
529
  const mockLogger = createMockLogger()
530
+ pikkuState(null, 'package', 'singletonServices', {
531
+ logger: mockLogger,
532
+ } as any)
533
+ pikkuState(null, 'package', 'factories', {
534
+ createWireServices: async () => mockWireService as any,
535
+ } as any)
509
536
 
510
537
  await assert.rejects(async () => {
511
538
  await runScheduledTask({
512
539
  name: 'error-cleanup-task',
513
- singletonServices: { logger: mockLogger } as any,
514
- createWireServices: async () => mockWireService as any,
515
540
  })
516
541
  })
517
542
 
@@ -543,11 +568,13 @@ describe('runScheduledTask', () => {
543
568
  wireScheduler(mockTask)
544
569
 
545
570
  const mockLogger = createMockLogger()
571
+ pikkuState(null, 'package', 'singletonServices', {
572
+ logger: mockLogger,
573
+ } as any)
546
574
 
547
575
  await assert.rejects(async () => {
548
576
  await runScheduledTask({
549
577
  name: 'error-task',
550
- singletonServices: { logger: mockLogger } as any,
551
578
  })
552
579
  })
553
580
 
@@ -590,10 +617,12 @@ describe('runScheduledTask', () => {
590
617
  wireScheduler(mockTask)
591
618
 
592
619
  const mockLogger = createMockLogger()
620
+ pikkuState(null, 'package', 'singletonServices', {
621
+ logger: mockLogger,
622
+ } as any)
593
623
 
594
624
  await runScheduledTask({
595
625
  name: 'middleware-task',
596
- singletonServices: { logger: mockLogger } as any,
597
626
  })
598
627
 
599
628
  assert.deepEqual(executionOrder, ['middleware', 'task'])
@@ -629,43 +658,3 @@ describe('getScheduledTasks', () => {
629
658
  assert.equal(tasks.size, 0)
630
659
  })
631
660
  })
632
-
633
- describe('createSchedulerRuntimeHandlers', () => {
634
- test('invokes RPC with optional session and runs scheduled task callback', async () => {
635
- const calls: Array<{ type: string; value: any }> = []
636
- const logger = createMockLogger()
637
- const singletonServices = { logger } as any
638
-
639
- const handlers = createSchedulerRuntimeHandlers({
640
- singletonServices,
641
- })
642
-
643
- const originalGetContextRPCService = (await import('../rpc/rpc-runner.js'))
644
- .rpcService.getContextRPCService
645
- ;(await import('../rpc/rpc-runner.js')).rpcService.getContextRPCService = ((
646
- _services: any,
647
- wire: any
648
- ) => {
649
- calls.push({ type: 'wire', value: wire })
650
- return {
651
- invoke: async (rpcName: string, data: any) => {
652
- calls.push({ type: 'invoke', value: { rpcName, data } })
653
- },
654
- } as any
655
- }) as any
656
-
657
- try {
658
- await handlers.invokeRPC('testRpc', { value: 1 }, { userId: 'u1' } as any)
659
- } finally {
660
- ;(await import('../rpc/rpc-runner.js')).rpcService.getContextRPCService =
661
- originalGetContextRPCService
662
- }
663
-
664
- assert.equal(calls[0]?.type, 'wire')
665
- assert.deepEqual(calls[0]?.value, { session: { userId: 'u1' } })
666
- assert.deepEqual(calls[1]?.value, {
667
- rpcName: 'testRpc',
668
- data: { value: 1 },
669
- })
670
- })
671
- })
@@ -1,36 +1,25 @@
1
- import {
2
- PikkuWire,
3
- type CoreServices,
4
- type CoreSingletonServices,
5
- type CoreUserSession,
6
- type CreateWireServices,
7
- } from '../../types/core.types.js'
1
+ import type { PikkuWire, CoreUserSession } from '../../types/core.types.js'
8
2
  import type { CoreScheduledTask } from './scheduler.types.js'
9
3
  import { getErrorResponse, PikkuError } from '../../errors/error-handler.js'
10
4
  import { PikkuMissingMetaError } from '../../errors/errors.js'
11
- import { closeWireServices } from '../../utils.js'
12
- import { pikkuState } from '../../pikku-state.js'
5
+ import {
6
+ getSingletonServices,
7
+ getCreateWireServices,
8
+ pikkuState,
9
+ } from '../../pikku-state.js'
13
10
  import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
14
11
  import {
15
12
  PikkuSessionService,
16
13
  createMiddlewareSessionWireProps,
17
14
  } from '../../services/user-session-service.js'
18
- import {
15
+ import type {
19
16
  CorePikkuFunctionConfig,
20
17
  CorePikkuFunctionSessionless,
21
18
  } from '../../function/functions.types.js'
22
- import { rpcService } from '../rpc/rpc-runner.js'
23
- import { SchedulerRuntimeHandlers } from '../../services/scheduler-service.js'
24
19
 
25
20
  export type RunScheduledTasksParams = {
26
21
  name: string
27
22
  session?: CoreUserSession
28
- singletonServices: CoreSingletonServices
29
- createWireServices?: CreateWireServices<
30
- CoreSingletonServices,
31
- CoreServices<CoreSingletonServices>,
32
- CoreUserSession
33
- >
34
23
  }
35
24
 
36
25
  export const wireScheduler = <
@@ -80,10 +69,9 @@ class ScheduledTaskSkippedError extends PikkuError {
80
69
  export async function runScheduledTask({
81
70
  name,
82
71
  session,
83
- singletonServices,
84
- createWireServices,
85
72
  }: RunScheduledTasksParams): Promise<void> {
86
- let wireServices: any
73
+ const singletonServices = getSingletonServices()
74
+ const createWireServices = getCreateWireServices()
87
75
  const task = pikkuState(null, 'scheduler', 'tasks').get(name)
88
76
  const meta = pikkuState(null, 'scheduler', 'meta')[name]
89
77
 
@@ -136,44 +124,9 @@ export async function runScheduledTask({
136
124
  singletonServices.logger.error(e)
137
125
  }
138
126
  throw e
139
- } finally {
140
- if (wireServices) {
141
- await closeWireServices(singletonServices.logger, wireServices)
142
- }
143
127
  }
144
128
  }
145
129
 
146
130
  export const getScheduledTasks = () => {
147
131
  return pikkuState(null, 'scheduler', 'tasks')
148
132
  }
149
-
150
- export const createSchedulerRuntimeHandlers = ({
151
- singletonServices,
152
- createWireServices,
153
- }: {
154
- singletonServices: CoreSingletonServices
155
- createWireServices?: CreateWireServices<
156
- CoreSingletonServices,
157
- CoreServices<CoreSingletonServices>,
158
- CoreUserSession
159
- >
160
- }): SchedulerRuntimeHandlers => {
161
- return {
162
- logger: singletonServices.logger,
163
- invokeRPC: async (
164
- rpcName: string,
165
- data?: any,
166
- session?: CoreUserSession
167
- ) => {
168
- const wire = session ? ({ session } as PikkuWire) : ({} as PikkuWire)
169
- const rpc = rpcService.getContextRPCService(singletonServices, wire)
170
- await rpc.invoke(rpcName, data)
171
- },
172
- runScheduledTask: async (name: string) =>
173
- runScheduledTask({
174
- name,
175
- singletonServices,
176
- createWireServices,
177
- }),
178
- }
179
- }
@@ -1,9 +1,9 @@
1
- import {
1
+ import type {
2
2
  CoreUserSession,
3
3
  CorePikkuMiddleware,
4
4
  CommonWireMeta,
5
5
  } from '../../types/core.types.js'
6
- import {
6
+ import type {
7
7
  CorePikkuFunctionConfig,
8
8
  CorePikkuFunctionSessionless,
9
9
  } from '../../function/functions.types.js'