@memberjunction/server 6.2.0-edge.4 → 6.2.0-edge.6

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 (560) hide show
  1. package/README.md +47 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/SessionJanitor.d.ts +91 -30
  4. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  5. package/dist/agentSessions/SessionJanitor.js +311 -81
  6. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  7. package/dist/agentSessions/SessionManager.d.ts +17 -3
  8. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  9. package/dist/agentSessions/SessionManager.js +44 -10
  10. package/dist/agentSessions/SessionManager.js.map +1 -1
  11. package/dist/apiRoot.d.ts +32 -0
  12. package/dist/apiRoot.d.ts.map +1 -0
  13. package/dist/apiRoot.js +67 -0
  14. package/dist/apiRoot.js.map +1 -0
  15. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
  16. package/dist/auth/AuthProviderCatalogRouter.js +27 -0
  17. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
  18. package/dist/auth/LoginScreenEngine.d.ts +22 -0
  19. package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
  20. package/dist/auth/LoginScreenEngine.js +57 -0
  21. package/dist/auth/LoginScreenEngine.js.map +1 -0
  22. package/dist/auth/index.d.ts +1 -0
  23. package/dist/auth/index.d.ts.map +1 -1
  24. package/dist/auth/index.js +52 -10
  25. package/dist/auth/index.js.map +1 -1
  26. package/dist/auth/initializeProviders.d.ts +10 -0
  27. package/dist/auth/initializeProviders.d.ts.map +1 -1
  28. package/dist/auth/initializeProviders.js +37 -1
  29. package/dist/auth/initializeProviders.js.map +1 -1
  30. package/dist/auth/localDevAuth.d.ts +79 -0
  31. package/dist/auth/localDevAuth.d.ts.map +1 -0
  32. package/dist/auth/localDevAuth.js +439 -0
  33. package/dist/auth/localDevAuth.js.map +1 -0
  34. package/dist/auth/magicLink/MagicLinkKeys.d.ts +2 -2
  35. package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
  36. package/dist/auth/magicLink/MagicLinkKeys.js +1 -1
  37. package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
  38. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  39. package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
  40. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  41. package/dist/auth/magicLink/types.d.ts +12 -0
  42. package/dist/auth/magicLink/types.d.ts.map +1 -1
  43. package/dist/auth/sessionUserClone.d.ts +1 -1
  44. package/dist/auth/sessionUserClone.d.ts.map +1 -1
  45. package/dist/auth/sessionUserClone.js +3 -2
  46. package/dist/auth/sessionUserClone.js.map +1 -1
  47. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
  48. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
  49. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
  50. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
  51. package/dist/broadcast/index.d.ts +6 -0
  52. package/dist/broadcast/index.d.ts.map +1 -0
  53. package/dist/broadcast/index.js +6 -0
  54. package/dist/broadcast/index.js.map +1 -0
  55. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
  56. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
  57. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
  58. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
  59. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
  60. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
  61. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
  62. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
  63. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
  64. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
  65. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
  66. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
  67. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
  68. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
  69. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
  70. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
  71. package/dist/cache.d.ts +3 -2
  72. package/dist/cache.d.ts.map +1 -1
  73. package/dist/cache.js.map +1 -1
  74. package/dist/config.d.ts +632 -22
  75. package/dist/config.d.ts.map +1 -1
  76. package/dist/config.js +104 -4
  77. package/dist/config.js.map +1 -1
  78. package/dist/context.d.ts +3 -1
  79. package/dist/context.d.ts.map +1 -1
  80. package/dist/context.js +29 -8
  81. package/dist/context.js.map +1 -1
  82. package/dist/coreRoutes.d.ts +29 -0
  83. package/dist/coreRoutes.d.ts.map +1 -0
  84. package/dist/coreRoutes.js +156 -0
  85. package/dist/coreRoutes.js.map +1 -0
  86. package/dist/generated/graphql-schemas/__mj.d.ts +1016 -29
  87. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  88. package/dist/generated/graphql-schemas/__mj.js +5125 -434
  89. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  90. package/dist/generic/CacheInvalidationResolver.d.ts +85 -30
  91. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  92. package/dist/generic/CacheInvalidationResolver.js +175 -60
  93. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  94. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
  95. package/dist/generic/OrphanedConversationDetailReconciler.js +2 -0
  96. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  97. package/dist/generic/PubSubManager.d.ts +10 -0
  98. package/dist/generic/PubSubManager.d.ts.map +1 -1
  99. package/dist/generic/PubSubManager.js +44 -1
  100. package/dist/generic/PubSubManager.js.map +1 -1
  101. package/dist/generic/PushStatusResolver.d.ts +39 -6
  102. package/dist/generic/PushStatusResolver.d.ts.map +1 -1
  103. package/dist/generic/PushStatusResolver.js +94 -12
  104. package/dist/generic/PushStatusResolver.js.map +1 -1
  105. package/dist/generic/ResolverBase.d.ts +168 -69
  106. package/dist/generic/ResolverBase.d.ts.map +1 -1
  107. package/dist/generic/ResolverBase.js +464 -405
  108. package/dist/generic/ResolverBase.js.map +1 -1
  109. package/dist/generic/RunViewResolver.d.ts +11 -3
  110. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  111. package/dist/generic/RunViewResolver.js +91 -13
  112. package/dist/generic/RunViewResolver.js.map +1 -1
  113. package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
  114. package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
  115. package/dist/generic/actionOutputFieldSecurity.js +47 -0
  116. package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
  117. package/dist/generic/fieldSecurityTransport.d.ts +30 -0
  118. package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
  119. package/dist/generic/fieldSecurityTransport.js +30 -0
  120. package/dist/generic/fieldSecurityTransport.js.map +1 -0
  121. package/dist/globalCors.d.ts +33 -0
  122. package/dist/globalCors.d.ts.map +1 -0
  123. package/dist/globalCors.js +58 -0
  124. package/dist/globalCors.js.map +1 -0
  125. package/dist/index.d.ts +14 -0
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +230 -222
  128. package/dist/index.js.map +1 -1
  129. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  130. package/dist/integration/CustomColumnPromoter.js +6 -1
  131. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  132. package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
  133. package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
  134. package/dist/logging/variablesLoggingMiddleware.js +50 -1
  135. package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
  136. package/dist/multiTenancy/index.d.ts.map +1 -1
  137. package/dist/multiTenancy/index.js +22 -2
  138. package/dist/multiTenancy/index.js.map +1 -1
  139. package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -1
  140. package/dist/realtimeSessions/RealtimeSessionVerificationService.js +2 -1
  141. package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -1
  142. package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -1
  143. package/dist/realtimeSessions/RealtimeVerifyRouter.js +2 -1
  144. package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -1
  145. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
  146. package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
  147. package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
  148. package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
  149. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
  150. package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
  151. package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
  152. package/dist/realtimeSessions/index.d.ts +2 -0
  153. package/dist/realtimeSessions/index.d.ts.map +1 -1
  154. package/dist/realtimeSessions/index.js +2 -0
  155. package/dist/realtimeSessions/index.js.map +1 -1
  156. package/dist/realtimeSessions/ownedRealtimeSession.d.ts +32 -0
  157. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
  158. package/dist/realtimeSessions/ownedRealtimeSession.js +56 -0
  159. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
  160. package/dist/realtimeSessions/sessionAccess.d.ts +91 -8
  161. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
  162. package/dist/realtimeSessions/sessionAccess.js +127 -20
  163. package/dist/realtimeSessions/sessionAccess.js.map +1 -1
  164. package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
  165. package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
  166. package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
  167. package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
  168. package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
  169. package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
  170. package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
  171. package/dist/realtimeSessions/verificationWorkflow.js +1 -1
  172. package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
  173. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
  174. package/dist/realtimeWidget/WidgetRouter.js +19 -3
  175. package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
  176. package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
  177. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
  178. package/dist/realtimeWidget/WidgetSessionService.js +201 -19
  179. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  180. package/dist/realtimeWidget/host-identity.d.ts +1 -1
  181. package/dist/realtimeWidget/host-identity.js +1 -1
  182. package/dist/realtimeWidget/widgetCore.d.ts +20 -1
  183. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  184. package/dist/realtimeWidget/widgetCore.js +17 -1
  185. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  186. package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
  187. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  188. package/dist/realtimeWidget/widgetGuestElevation.js +2 -1
  189. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  190. package/dist/resolvers/ActionResolver.d.ts +19 -1
  191. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  192. package/dist/resolvers/ActionResolver.js +63 -12
  193. package/dist/resolvers/ActionResolver.js.map +1 -1
  194. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  195. package/dist/resolvers/AdhocQueryResolver.js +1 -0
  196. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  197. package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
  198. package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
  199. package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
  200. package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
  201. package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
  202. package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
  203. package/dist/resolvers/AgentSessionResolver.js +40 -17
  204. package/dist/resolvers/AgentSessionResolver.js.map +1 -1
  205. package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
  206. package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
  207. package/dist/resolvers/ArtifactFileResolver.js +9 -7
  208. package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
  209. package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
  210. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  211. package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
  212. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  213. package/dist/resolvers/DatasetResolver.d.ts +24 -3
  214. package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
  215. package/dist/resolvers/DatasetResolver.js +57 -8
  216. package/dist/resolvers/DatasetResolver.js.map +1 -1
  217. package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
  218. package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
  219. package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
  220. package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
  221. package/dist/resolvers/EntityRecordNameResolver.d.ts +2 -1
  222. package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
  223. package/dist/resolvers/EntityRecordNameResolver.js +3 -2
  224. package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
  225. package/dist/resolvers/FetchEntityVectorsResolver.d.ts +46 -3
  226. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  227. package/dist/resolvers/FetchEntityVectorsResolver.js +211 -50
  228. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  229. package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
  230. package/dist/resolvers/FileCategoryResolver.js +1 -0
  231. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  232. package/dist/resolvers/FileResolver.d.ts +87 -11
  233. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  234. package/dist/resolvers/FileResolver.js +292 -105
  235. package/dist/resolvers/FileResolver.js.map +1 -1
  236. package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
  237. package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
  238. package/dist/resolvers/GetDataContextDataResolver.js +117 -38
  239. package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
  240. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  241. package/dist/resolvers/GetDataResolver.js +6 -3
  242. package/dist/resolvers/GetDataResolver.js.map +1 -1
  243. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  244. package/dist/resolvers/IntegrationDiscoveryResolver.js +49 -9
  245. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  246. package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
  247. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  248. package/dist/resolvers/MergeRecordsResolver.js +31 -3
  249. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  250. package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
  251. package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
  252. package/dist/resolvers/PipelineProgressResolver.js +5 -3
  253. package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
  254. package/dist/resolvers/QueryResolver.d.ts +2 -0
  255. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  256. package/dist/resolvers/QueryResolver.js +33 -6
  257. package/dist/resolvers/QueryResolver.js.map +1 -1
  258. package/dist/resolvers/QuerySystemUserResolver.d.ts +2 -0
  259. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  260. package/dist/resolvers/QuerySystemUserResolver.js +15 -6
  261. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  262. package/dist/resolvers/RSUResolver.d.ts.map +1 -1
  263. package/dist/resolvers/RSUResolver.js +12 -0
  264. package/dist/resolvers/RSUResolver.js.map +1 -1
  265. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +18 -10
  266. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  267. package/dist/resolvers/RealtimeClientSessionResolver.js +92 -54
  268. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  269. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  270. package/dist/resolvers/RemoteBrowserActionResolver.js +11 -9
  271. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  272. package/dist/resolvers/RunAIAgentResolver.d.ts +56 -8
  273. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  274. package/dist/resolvers/RunAIAgentResolver.js +241 -67
  275. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  276. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  277. package/dist/resolvers/RunTemplateResolver.js +4 -4
  278. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  279. package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
  280. package/dist/resolvers/RunTestResolver.js +3 -1
  281. package/dist/resolvers/RunTestResolver.js.map +1 -1
  282. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts +12 -1
  283. package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
  284. package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
  285. package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
  286. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  287. package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
  288. package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
  289. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  290. package/dist/resolvers/SyncDataResolver.js +4 -0
  291. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  292. package/dist/resolvers/TaskGraphFrameResolver.d.ts +2 -1
  293. package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
  294. package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
  295. package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
  296. package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
  297. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  298. package/dist/resolvers/TestQuerySQLResolver.js +66 -13
  299. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  300. package/dist/resolvers/TransactionGroupResolver.d.ts +34 -2
  301. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  302. package/dist/resolvers/TransactionGroupResolver.js +150 -27
  303. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  304. package/dist/resolvers/UserViewResolver.d.ts +1 -1
  305. package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
  306. package/dist/resolvers/UserViewResolver.js +2 -1
  307. package/dist/resolvers/UserViewResolver.js.map +1 -1
  308. package/dist/resolvers/agent-run-data-guard.d.ts +31 -0
  309. package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
  310. package/dist/resolvers/agent-run-data-guard.js +72 -0
  311. package/dist/resolvers/agent-run-data-guard.js.map +1 -0
  312. package/dist/rest/EntityCRUDHandler.d.ts +6 -0
  313. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  314. package/dist/rest/EntityCRUDHandler.js +19 -5
  315. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  316. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  317. package/dist/rest/RESTEndpointHandler.js +8 -5
  318. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  319. package/dist/rest/RealtimeRecordingHandler.d.ts +49 -0
  320. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
  321. package/dist/rest/RealtimeRecordingHandler.js +383 -0
  322. package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
  323. package/dist/rest/ViewOperationsHandler.d.ts +9 -1
  324. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  325. package/dist/rest/ViewOperationsHandler.js +43 -17
  326. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  327. package/dist/rest/setupRESTEndpoints.d.ts +6 -0
  328. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  329. package/dist/rest/setupRESTEndpoints.js +6 -0
  330. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  331. package/dist/serverExtensionReservedRoots.d.ts +12 -10
  332. package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
  333. package/dist/serverExtensionReservedRoots.js +14 -17
  334. package/dist/serverExtensionReservedRoots.js.map +1 -1
  335. package/dist/serverRoleConfigUnits.d.ts +29 -0
  336. package/dist/serverRoleConfigUnits.d.ts.map +1 -0
  337. package/dist/serverRoleConfigUnits.js +33 -0
  338. package/dist/serverRoleConfigUnits.js.map +1 -0
  339. package/dist/services/MJStorageBlobStore.d.ts +8 -1
  340. package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
  341. package/dist/services/MJStorageBlobStore.js +25 -19
  342. package/dist/services/MJStorageBlobStore.js.map +1 -1
  343. package/dist/services/StartTaskGraphDispatcher.js +2 -2
  344. package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
  345. package/dist/services/TaskGraphActionRunner.d.ts +5 -3
  346. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  347. package/dist/services/TaskGraphActionRunner.js +27 -5
  348. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  349. package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
  350. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  351. package/dist/services/TaskGraphAgentRunner.js +157 -9
  352. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  353. package/dist/services/TaskGraphContinuationDeliverer.d.ts +59 -2
  354. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  355. package/dist/services/TaskGraphContinuationDeliverer.js +626 -16
  356. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  357. package/dist/sharedCache.d.ts.map +1 -1
  358. package/dist/sharedCache.js +3 -0
  359. package/dist/sharedCache.js.map +1 -1
  360. package/dist/types.d.ts +23 -1
  361. package/dist/types.d.ts.map +1 -1
  362. package/dist/types.js.map +1 -1
  363. package/package.json +99 -98
  364. package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
  365. package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
  366. package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
  367. package/src/__tests__/AgentSessionResolver.ownership.test.ts +137 -0
  368. package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
  369. package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
  370. package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
  371. package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
  372. package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
  373. package/src/__tests__/FetchEntityVectorsResolver.test.ts +369 -18
  374. package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
  375. package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
  376. package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
  377. package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
  378. package/src/__tests__/LoginScreenEngine.test.ts +86 -0
  379. package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
  380. package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
  381. package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
  382. package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
  383. package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
  384. package/src/__tests__/RealtimeClientSessionResolver.test.ts +324 -46
  385. package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
  386. package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +98 -0
  387. package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
  388. package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
  389. package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
  390. package/src/__tests__/ResolverBase.clientOldValues.test.ts +243 -7
  391. package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
  392. package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +176 -0
  393. package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
  394. package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +23 -1
  395. package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
  396. package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
  397. package/src/__tests__/RunAIAgentResolver.branch.test.ts +69 -13
  398. package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
  399. package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
  400. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +20 -28
  401. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +264 -0
  402. package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
  403. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +4 -1
  404. package/src/__tests__/RunTemplateResolver.test.ts +35 -2
  405. package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
  406. package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
  407. package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
  408. package/src/__tests__/SessionJanitor.test.ts +365 -10
  409. package/src/__tests__/SessionManager.test.ts +122 -0
  410. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
  411. package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
  412. package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +468 -23
  413. package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
  414. package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
  415. package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
  416. package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
  417. package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
  418. package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
  419. package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
  420. package/src/__tests__/ViewOperationsHandler.test.ts +7 -2
  421. package/src/__tests__/WidgetSessionService.test.ts +583 -4
  422. package/src/__tests__/agent-run-data-guard.test.ts +130 -0
  423. package/src/__tests__/apiRootBoot.test.ts +202 -0
  424. package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
  425. package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
  426. package/src/__tests__/cacheInvalidationRecordData.test.ts +109 -0
  427. package/src/__tests__/conversationRunEvents.test.ts +56 -14
  428. package/src/__tests__/fieldSecurityFixtures.ts +91 -0
  429. package/src/__tests__/globalCors.test.ts +217 -0
  430. package/src/__tests__/localDevAuth.test.ts +196 -0
  431. package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
  432. package/src/__tests__/multiTenancy.security.test.ts +51 -0
  433. package/src/__tests__/multiTenancy.test.ts +1 -1
  434. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
  435. package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
  436. package/src/__tests__/pushStatusResolver.filter.test.ts +64 -1
  437. package/src/__tests__/realtimeRecordingHandler.test.ts +669 -0
  438. package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
  439. package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
  440. package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
  441. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +146 -7
  442. package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
  443. package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
  444. package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
  445. package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
  446. package/src/__tests__/resolverBase.fls.test.ts +146 -97
  447. package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
  448. package/src/__tests__/runParamsTimeZone.test.ts +179 -0
  449. package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
  450. package/src/__tests__/runViewProperties.test.ts +114 -0
  451. package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
  452. package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
  453. package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
  454. package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -98
  455. package/src/__tests__/sessionUserClone.test.ts +5 -1
  456. package/src/__tests__/sharedCache.test.ts +5 -3
  457. package/src/__tests__/startupSweepOrder.test.ts +40 -0
  458. package/src/__tests__/unifiedAuth.test.ts +28 -0
  459. package/src/__tests__/widgetGuestElevation.test.ts +2 -0
  460. package/src/agentSessions/SessionJanitor.ts +369 -93
  461. package/src/agentSessions/SessionManager.ts +45 -10
  462. package/src/apiRoot.ts +78 -0
  463. package/src/auth/AuthProviderCatalogRouter.ts +29 -0
  464. package/src/auth/LoginScreenEngine.ts +50 -0
  465. package/src/auth/index.ts +57 -12
  466. package/src/auth/initializeProviders.ts +43 -1
  467. package/src/auth/localDevAuth.ts +528 -0
  468. package/src/auth/magicLink/MagicLinkKeys.ts +2 -2
  469. package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
  470. package/src/auth/magicLink/types.ts +10 -0
  471. package/src/auth/sessionUserClone.ts +3 -2
  472. package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
  473. package/src/broadcast/index.ts +5 -0
  474. package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
  475. package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
  476. package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
  477. package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
  478. package/src/cache.ts +2 -1
  479. package/src/config.ts +115 -5
  480. package/src/context.ts +32 -8
  481. package/src/coreRoutes.ts +181 -0
  482. package/src/generated/graphql-schemas/__mj.ts +3684 -284
  483. package/src/generic/CacheInvalidationResolver.ts +172 -60
  484. package/src/generic/OrphanedConversationDetailReconciler.ts +4 -2
  485. package/src/generic/PubSubManager.ts +54 -1
  486. package/src/generic/PushStatusResolver.ts +109 -12
  487. package/src/generic/ResolverBase.ts +540 -431
  488. package/src/generic/RunViewResolver.ts +97 -15
  489. package/src/generic/actionOutputFieldSecurity.ts +75 -0
  490. package/src/generic/fieldSecurityTransport.ts +62 -0
  491. package/src/globalCors.ts +71 -0
  492. package/src/index.ts +239 -238
  493. package/src/integration/CustomColumnPromoter.ts +6 -1
  494. package/src/logging/variablesLoggingMiddleware.ts +59 -3
  495. package/src/multiTenancy/index.ts +24 -2
  496. package/src/realtimeSessions/README.md +7 -3
  497. package/src/realtimeSessions/RealtimeSessionVerificationService.ts +2 -1
  498. package/src/realtimeSessions/RealtimeVerifyRouter.ts +2 -1
  499. package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
  500. package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
  501. package/src/realtimeSessions/index.ts +2 -0
  502. package/src/realtimeSessions/ownedRealtimeSession.ts +69 -0
  503. package/src/realtimeSessions/sessionAccess.ts +183 -23
  504. package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
  505. package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
  506. package/src/realtimeSessions/verificationWorkflow.ts +3 -1
  507. package/src/realtimeWidget/WidgetRouter.ts +22 -4
  508. package/src/realtimeWidget/WidgetSessionService.ts +252 -17
  509. package/src/realtimeWidget/host-identity.ts +1 -1
  510. package/src/realtimeWidget/widgetCore.ts +30 -1
  511. package/src/realtimeWidget/widgetGuestElevation.ts +2 -1
  512. package/src/resolvers/ActionResolver.ts +78 -15
  513. package/src/resolvers/AdhocQueryResolver.ts +1 -0
  514. package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
  515. package/src/resolvers/AgentSessionResolver.ts +46 -18
  516. package/src/resolvers/ArtifactFileResolver.ts +9 -8
  517. package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
  518. package/src/resolvers/DatasetResolver.ts +70 -10
  519. package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
  520. package/src/resolvers/EntityRecordNameResolver.ts +3 -2
  521. package/src/resolvers/FetchEntityVectorsResolver.ts +248 -55
  522. package/src/resolvers/FileCategoryResolver.ts +1 -0
  523. package/src/resolvers/FileResolver.ts +334 -109
  524. package/src/resolvers/GetDataContextDataResolver.ts +139 -41
  525. package/src/resolvers/GetDataResolver.ts +6 -3
  526. package/src/resolvers/IntegrationDiscoveryResolver.ts +53 -9
  527. package/src/resolvers/MergeRecordsResolver.ts +23 -2
  528. package/src/resolvers/PipelineProgressResolver.ts +12 -3
  529. package/src/resolvers/QueryResolver.ts +31 -6
  530. package/src/resolvers/QuerySystemUserResolver.ts +15 -6
  531. package/src/resolvers/RSUResolver.ts +12 -0
  532. package/src/resolvers/RealtimeClientSessionResolver.ts +114 -66
  533. package/src/resolvers/RemoteBrowserActionResolver.ts +15 -10
  534. package/src/resolvers/RunAIAgentResolver.ts +296 -85
  535. package/src/resolvers/RunTemplateResolver.ts +6 -4
  536. package/src/resolvers/RunTestResolver.ts +3 -1
  537. package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
  538. package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
  539. package/src/resolvers/SyncDataResolver.ts +4 -0
  540. package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
  541. package/src/resolvers/TestQuerySQLResolver.ts +69 -13
  542. package/src/resolvers/TransactionGroupResolver.ts +185 -30
  543. package/src/resolvers/UserViewResolver.ts +2 -1
  544. package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
  545. package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
  546. package/src/resolvers/agent-run-data-guard.ts +89 -0
  547. package/src/rest/EntityCRUDHandler.ts +22 -5
  548. package/src/rest/RESTEndpointHandler.ts +8 -5
  549. package/src/rest/RealtimeRecordingHandler.ts +467 -0
  550. package/src/rest/ViewOperationsHandler.ts +52 -18
  551. package/src/rest/setupRESTEndpoints.ts +6 -0
  552. package/src/serverExtensionReservedRoots.ts +14 -17
  553. package/src/serverRoleConfigUnits.ts +48 -0
  554. package/src/services/MJStorageBlobStore.ts +31 -30
  555. package/src/services/StartTaskGraphDispatcher.ts +2 -2
  556. package/src/services/TaskGraphActionRunner.ts +25 -5
  557. package/src/services/TaskGraphAgentRunner.ts +188 -11
  558. package/src/services/TaskGraphContinuationDeliverer.ts +738 -16
  559. package/src/sharedCache.ts +3 -0
  560. package/src/types.ts +23 -1
@@ -0,0 +1,209 @@
1
+ /**
2
+ * @fileoverview A fire-and-forget run always ends with one completion on the caller's socket.
3
+ *
4
+ * The widget and Explorer return as soon as the mutation acks, then wait for a `complete` status message. When the
5
+ * run fails (the agent cannot be validated, the run throws, or the agent's reply row cannot be saved), that message
6
+ * must still arrive, exactly once, with the reason, addressed to the owner the caller's socket is authenticated as.
7
+ * For a widget guest that is the guest, not the system user its run is elevated to. Without it the client waits for
8
+ * its idle timeout and then reconciles the run as a success.
9
+ *
10
+ * The liveness pulse of the same run is addressed to the same owner.
11
+ */
12
+ import 'reflect-metadata'; // must precede any type-graphql decorator evaluation
13
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
14
+ import type { PubSubEngine } from 'type-graphql';
15
+
16
+ vi.mock('type-graphql', () => {
17
+ const decoratorFactory = (..._args: unknown[]) => (..._decorated: unknown[]) => undefined;
18
+ const exportNames = [
19
+ 'Resolver', 'Query', 'Mutation', 'Subscription', 'Arg', 'Args', 'ArgsType', 'Ctx', 'Root',
20
+ 'Info', 'Field', 'FieldResolver', 'ObjectType', 'InputType', 'InterfaceType', 'Authorized',
21
+ 'UseMiddleware', 'Extensions', 'Directive', 'ID', 'Int', 'Float', 'GraphQLISODateTime',
22
+ 'GraphQLTimestamp', 'registerEnumType', 'createMethodDecorator', 'createParamDecorator',
23
+ 'buildSchema', 'buildSchemaSync', 'PubSub',
24
+ ];
25
+ return Object.fromEntries(exportNames.map((name) => [name, decoratorFactory]));
26
+ });
27
+
28
+ const hoisted = vi.hoisted(() => ({
29
+ runAgentInConversation: vi.fn(),
30
+ agents: new Map<string, { ID: string; Name: string; Status: string }>(),
31
+ }));
32
+
33
+ vi.mock('@memberjunction/aiengine', () => ({
34
+ AIEngine: {
35
+ Instance: {
36
+ Config: async () => undefined,
37
+ GetAgentByID: (id: string) => hoisted.agents.get(id),
38
+ CanUserRunAgent: async () => true,
39
+ },
40
+ },
41
+ GetAttachmentService: () => ({}),
42
+ }));
43
+
44
+ vi.mock('@memberjunction/ai-agents', () => ({
45
+ AgentRunner: class {
46
+ RunAgentInConversation(...args: unknown[]) {
47
+ return hoisted.runAgentInConversation(...args);
48
+ }
49
+ },
50
+ ArtifactToolManager: class {},
51
+ }));
52
+
53
+ import { UserInfo } from '@memberjunction/core';
54
+ import { RunAIAgentResolver } from '../resolvers/RunAIAgentResolver.js';
55
+ import { StatusUpdateOwnerID } from '../generic/PushStatusResolver.js';
56
+ import { DEFAULT_PULSE_INTERVAL_MS, HEARTBEAT_MESSAGE_TYPE } from '../generic/FireAndForgetHeartbeat.js';
57
+ import type { AppContext, UserPayload } from '../types.js';
58
+
59
+ const ANONYMOUS_USER_ID = 'AAAAAAAA-0000-4000-8000-0000000000A0';
60
+ const SYSTEM_USER_ID = 'BBBBBBBB-0000-4000-8000-0000000000B0';
61
+ const SESSION = 'session-1';
62
+
63
+ /** A public-widget guest: the shared Anonymous user, told apart by its scope identity. */
64
+ function widgetGuest(): UserInfo {
65
+ const guest = new UserInfo(null, { ID: ANONYMOUS_USER_ID, Email: 'anonymous@magic-link.local' });
66
+ guest.IsMagicLinkAnonymous = true;
67
+ guest.AnonymousVisitorID = 'sid-guest-1';
68
+ return guest;
69
+ }
70
+
71
+ /** The payload a widget guest's run executes under: elevated to the system user, standing in for the guest. */
72
+ function elevatedGuestPayload(): UserPayload {
73
+ return {
74
+ sessionId: SESSION,
75
+ email: 'system@example.com',
76
+ userRecord: new UserInfo(null, { ID: SYSTEM_USER_ID, Email: 'system@example.com' }),
77
+ ElevatedFrom: widgetGuest(),
78
+ };
79
+ }
80
+
81
+ interface PublishedEnvelope {
82
+ sessionId: string;
83
+ ownerUserId: string;
84
+ message: { resolver: string; type: string; data: Record<string, unknown> };
85
+ }
86
+
87
+ function makePubSub(): { pubSub: PubSubEngine; published: () => PublishedEnvelope[] } {
88
+ const publish = vi.fn().mockResolvedValue(undefined);
89
+ const pubSub: PubSubEngine = { publish, subscribe: vi.fn(), unsubscribe: vi.fn(), asyncIterator: vi.fn() };
90
+ const published = (): PublishedEnvelope[] =>
91
+ publish.mock.calls.map((call) => {
92
+ const payload = call[1] as { sessionId: string; ownerUserId: string; message: string };
93
+ return { sessionId: payload.sessionId, ownerUserId: payload.ownerUserId, message: JSON.parse(payload.message) };
94
+ });
95
+ return { pubSub, published };
96
+ }
97
+
98
+ function completions(envelopes: PublishedEnvelope[]): PublishedEnvelope[] {
99
+ return envelopes.filter((e) => e.message.type === 'StreamingContent' && e.message.data.type === 'complete');
100
+ }
101
+
102
+ /** Starts the public RunAIAgent mutation in fire-and-forget mode for `agentId`, answering into `reply-1`. */
103
+ async function startFireAndForget(pubSub: PubSubEngine, userPayload: UserPayload, agentId = 'agent-1') {
104
+ const ctx = { userPayload, providers: [], dataSource: {} } as AppContext;
105
+ return new RunAIAgentResolver().RunAIAgent(
106
+ agentId, ctx, '[{"role":"user","content":"hi"}]', SESSION, pubSub,
107
+ undefined, undefined, undefined, undefined, undefined, undefined,
108
+ 'reply-1', // conversationDetailId
109
+ undefined, undefined, undefined, undefined,
110
+ true, // fireAndForget
111
+ );
112
+ }
113
+
114
+ /** Lets the background run settle, then gives any late (double) publish a chance to land. */
115
+ async function settle(published: () => PublishedEnvelope[]): Promise<void> {
116
+ await vi.waitFor(() => expect(completions(published()).length).toBeGreaterThan(0), { timeout: 1000 });
117
+ await new Promise((resolve) => setTimeout(resolve, 20));
118
+ }
119
+
120
+ beforeEach(() => {
121
+ hoisted.agents.clear();
122
+ hoisted.agents.set('agent-1', { ID: 'agent-1', Name: 'Research', Status: 'Active' });
123
+ hoisted.runAgentInConversation.mockReset();
124
+ vi.spyOn(console, 'log').mockImplementation(() => undefined);
125
+ vi.spyOn(console, 'error').mockImplementation(() => undefined);
126
+ });
127
+
128
+ afterEach(() => {
129
+ vi.useRealTimers();
130
+ vi.restoreAllMocks();
131
+ });
132
+
133
+ describe('RunAIAgent fire-and-forget — the failure completion', () => {
134
+ it("publishes one failed completion with the reason when the agent's reply cannot be saved, to the guest's socket", async () => {
135
+ const reason = "The agent's reply could not be saved: Message exceeds the maximum length";
136
+ hoisted.runAgentInConversation.mockRejectedValue(new Error(reason));
137
+ const { pubSub, published } = makePubSub();
138
+ const userPayload = elevatedGuestPayload();
139
+
140
+ const ack = await startFireAndForget(pubSub, userPayload);
141
+ expect(ack.success).toBe(true); // the ack only says the run started
142
+
143
+ await settle(published);
144
+ const done = completions(published());
145
+ expect(done).toHaveLength(1);
146
+ expect(done[0].message.data).toMatchObject({
147
+ type: 'complete',
148
+ success: false,
149
+ errorMessage: reason,
150
+ conversationDetailId: 'reply-1',
151
+ });
152
+ expect(done[0].sessionId).toBe(SESSION);
153
+ // The guest's owner key, never the system user the run was elevated to.
154
+ expect(done[0].ownerUserId).toBe(StatusUpdateOwnerID(userPayload));
155
+ expect(done[0].ownerUserId).toBe(`${ANONYMOUS_USER_ID.toLowerCase()}|sid-guest-1`);
156
+ });
157
+
158
+ it('publishes one failed completion when the run fails before the agent starts (agent not runnable)', async () => {
159
+ const { pubSub, published } = makePubSub();
160
+
161
+ await startFireAndForget(pubSub, elevatedGuestPayload(), 'missing-agent');
162
+
163
+ await settle(published);
164
+ const done = completions(published());
165
+ expect(done).toHaveLength(1);
166
+ expect(done[0].message.data).toMatchObject({
167
+ success: false,
168
+ errorMessage: 'AI Agent with ID missing-agent not found',
169
+ conversationDetailId: 'reply-1',
170
+ });
171
+ expect(hoisted.runAgentInConversation).not.toHaveBeenCalled();
172
+ });
173
+
174
+ it('publishes only the run\'s own completion when the run returns a failed result (no second completion)', async () => {
175
+ const run = { ID: 'run-1', ConversationDetailID: 'reply-1', ErrorMessage: 'model refused', Steps: [] };
176
+ hoisted.runAgentInConversation.mockResolvedValue({
177
+ agentResult: { success: false, agentRun: run },
178
+ agentResponseDetailId: 'reply-1',
179
+ conversationId: 'conv-1',
180
+ });
181
+ const { pubSub, published } = makePubSub();
182
+
183
+ await startFireAndForget(pubSub, elevatedGuestPayload());
184
+
185
+ await settle(published);
186
+ const done = completions(published());
187
+ expect(done).toHaveLength(1);
188
+ expect(done[0].message.data).toMatchObject({ agentRunId: 'run-1', success: false, errorMessage: 'model refused' });
189
+ });
190
+ });
191
+
192
+ describe("RunAIAgent fire-and-forget — the liveness pulse", () => {
193
+ it("addresses heartbeats to the guest's owner key, not to the elevated system user", async () => {
194
+ vi.useFakeTimers();
195
+ hoisted.runAgentInConversation.mockReturnValue(new Promise(() => undefined)); // the run is still going
196
+ const { pubSub, published } = makePubSub();
197
+ const userPayload = elevatedGuestPayload();
198
+
199
+ await startFireAndForget(pubSub, userPayload);
200
+ await vi.advanceTimersByTimeAsync(DEFAULT_PULSE_INTERVAL_MS);
201
+
202
+ const heartbeats = published().filter((e) => e.message.type === HEARTBEAT_MESSAGE_TYPE);
203
+ expect(heartbeats.length).toBeGreaterThan(0);
204
+ for (const heartbeat of heartbeats) {
205
+ expect(heartbeat.ownerUserId).toBe(StatusUpdateOwnerID(userPayload));
206
+ expect(heartbeat.ownerUserId).not.toBe(SYSTEM_USER_ID);
207
+ }
208
+ });
209
+ });
@@ -28,6 +28,7 @@ vi.mock('type-graphql', () => {
28
28
 
29
29
  const hoisted = vi.hoisted(() => ({
30
30
  runAgentInConversation: vi.fn(),
31
+ reply: { ID: 'reply-1', ConversationID: 'conv-1', __mj_CreatedAt: new Date('2026-10-12T10:00:00.000Z') },
31
32
  }));
32
33
 
33
34
  vi.mock('@memberjunction/ai-agents', () => ({
@@ -35,6 +36,9 @@ vi.mock('@memberjunction/ai-agents', () => ({
35
36
  RunAgentInConversation(...args: unknown[]) {
36
37
  return hoisted.runAgentInConversation(...args);
37
38
  }
39
+ async CreateAgentReplyDetail() {
40
+ return hoisted.reply;
41
+ }
38
42
  },
39
43
  ArtifactToolManager: class {},
40
44
  }));
@@ -94,7 +98,7 @@ async function runMutation(
94
98
  options: { agentHistoryFrom?: string; fireAndForget?: boolean }
95
99
  ) {
96
100
  return resolver.RunAIAgentFromConversationDetail(
97
- 'detail-1', 'agent-1', makeContext(), 'session-1', pubSub,
101
+ 'user-msg-1', 'agent-1', makeContext(), 'session-1', pubSub,
98
102
  undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined,
99
103
  undefined, undefined, options.fireAndForget, undefined, undefined,
100
104
  options.agentHistoryFrom
@@ -108,6 +112,8 @@ afterEach(() => {
108
112
  describe('RunAIAgentFromConversationDetail — agentHistoryFrom', () => {
109
113
  let resolver: RunAIAgentResolver;
110
114
  let seams: ResolverSeams;
115
+ /** The floor's position in executeAIAgent / executeAgentInBackground: fourth from last, before TrustReservedRunData, the branch, and the reply detail. */
116
+ const FLOOR_ARG = -4;
111
117
 
112
118
  beforeEach(() => {
113
119
  ({ resolver, seams } = makeResolver());
@@ -122,9 +128,9 @@ describe('RunAIAgentFromConversationDetail — agentHistoryFrom', () => {
122
128
  expect(result.success).toBe(true);
123
129
  const loaderArgs = seams.loadConversationHistoryWithAttachments.mock.calls[0];
124
130
  expect(loaderArgs[0]).toBe('conv-1');
125
- expect(loaderArgs[4]).toEqual(['detail-1']);
131
+ expect(loaderArgs[4]).toBeUndefined(); // the reply row is created after the history loads, so nothing to exclude
126
132
  expect((loaderArgs[5] as Date).toISOString()).toBe(FLOOR_ISO);
127
- const runFloor = seams.executeAIAgent.mock.calls[0].at(-2) as Date;
133
+ const runFloor = seams.executeAIAgent.mock.calls[0].at(FLOOR_ARG) as Date;
128
134
  expect(runFloor.toISOString()).toBe(FLOOR_ISO);
129
135
  });
130
136
 
@@ -133,7 +139,7 @@ describe('RunAIAgentFromConversationDetail — agentHistoryFrom', () => {
133
139
 
134
140
  expect(result.success).toBe(true);
135
141
  expect(seams.executeAIAgent).not.toHaveBeenCalled();
136
- const runFloor = seams.executeAgentInBackground.mock.calls[0].at(-2) as Date;
142
+ const runFloor = seams.executeAgentInBackground.mock.calls[0].at(FLOOR_ARG) as Date;
137
143
  expect(runFloor.toISOString()).toBe(FLOOR_ISO);
138
144
  });
139
145
 
@@ -141,7 +147,7 @@ describe('RunAIAgentFromConversationDetail — agentHistoryFrom', () => {
141
147
  await runMutation(resolver, {});
142
148
 
143
149
  expect(seams.loadConversationHistoryWithAttachments.mock.calls[0][5]).toBeUndefined();
144
- expect(seams.executeAIAgent.mock.calls[0].at(-2)).toBeUndefined();
150
+ expect(seams.executeAIAgent.mock.calls[0].at(FLOOR_ARG)).toBeUndefined();
145
151
  });
146
152
 
147
153
  it('fails the request on an unreadable floor, before loading or running anything', async () => {
@@ -288,10 +294,13 @@ describe('executeAIAgent — status publishing', () => {
288
294
  expect(completion.success).toBe(true);
289
295
  });
290
296
 
291
- it('publishes a failure completion when a fire-and-forget run rejects', async () => {
297
+ it('logs a fire-and-forget run that rejects, and publishes no second completion', async () => {
298
+ // executeAIAgent resolves on every failure and publishes the failure completion itself
299
+ // (RunAIAgentResolver.fireAndForgetCompletion.test.ts). A rejection breaks that contract; the background
300
+ // runner only logs it, with the agent and session, instead of leaving an unhandled rejection.
292
301
  const { resolver, seams } = makeResolver();
293
302
  seams.executeAIAgent = vi.fn().mockRejectedValue(new Error('background blew up'));
294
- vi.spyOn(console, 'error').mockImplementation(() => undefined);
303
+ const errors = vi.spyOn(console, 'error').mockImplementation(() => undefined);
295
304
  vi.spyOn(console, 'log').mockImplementation(() => undefined);
296
305
  const publish = vi.fn().mockResolvedValue(undefined);
297
306
  const localPubSub = { publish } as unknown as PubSubEngine;
@@ -304,28 +313,11 @@ describe('executeAIAgent — status publishing', () => {
304
313
  {}, {}, 'agent-1', userPayload, '[]', 'session-1', localPubSub,
305
314
  undefined, undefined, undefined, undefined, undefined, 'detail-1',
306
315
  );
307
- await vi.waitFor(() => expect(publish).toHaveBeenCalled());
316
+ await vi.waitFor(() =>
317
+ expect(errors.mock.calls.some((call) => String(call[0]).includes('agent-1') && String(call[0]).includes('session-1'))).toBe(true),
318
+ );
308
319
 
309
- const sent = envelopes(publish);
310
- expect(sent).toHaveLength(1);
311
- expect(sent[0].type).toBe('StreamingContent');
312
- expect(sent[0].resolver).toBe('RunAIAgentResolver');
313
- const completion = sent[0].data as {
314
- type: string;
315
- agentRunId: string;
316
- conversationDetailId: string;
317
- success: boolean;
318
- errorMessage: string;
319
- result: string;
320
- };
321
- expect(completion).toMatchObject({
322
- type: 'complete',
323
- agentRunId: 'unknown',
324
- conversationDetailId: 'detail-1',
325
- success: false,
326
- errorMessage: 'background blew up',
327
- result: JSON.stringify({ success: false, errorMessage: 'background blew up' }),
328
- });
320
+ expect(publish).not.toHaveBeenCalled();
329
321
  });
330
322
 
331
323
  it('saves a Running run reported by progress as Failed when the agent throws', async () => {
@@ -0,0 +1,264 @@
1
+ /**
2
+ * @fileoverview Every agent-run entry of `RunAIAgentResolver` tells the run whether it may read the reserved scope
3
+ * and agent-type keys from a client's `data` (`ExecuteAgentParams.TrustReservedRunData`, A12.15).
4
+ *
5
+ * The decision is pinned by `agent-run-data-guard.test.ts`, and what an untrusted run loses by the ai-core-plus and
6
+ * ai-agents suites (`BaseAgent.Execute` drops the keys). These tests pin the call sites: the synchronous and
7
+ * fire-and-forget paths of `RunAIAgent` and `RunAIAgentFromConversationDetail`, the widget-guest path (judged on
8
+ * the guest's own payload, not the system principal it is elevated to), the trusted callers, and an API key with and
9
+ * without the `agent:trusted` scope — each through the real `executeAIAgent`, up to the params handed to
10
+ * `AgentRunner`. The resolver forwards `data` as sent.
11
+ */
12
+ import 'reflect-metadata'; // must precede any type-graphql decorator evaluation
13
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
14
+ import type { PubSubEngine } from 'type-graphql';
15
+
16
+ // type-graphql's real decorators need emitDecoratorMetadata, which vitest's esbuild transform
17
+ // does not emit; the schema is irrelevant here, so every decorator is a no-op.
18
+ vi.mock('type-graphql', () => {
19
+ const decoratorFactory = (..._args: unknown[]) => (..._decorated: unknown[]) => undefined;
20
+ const exportNames = [
21
+ 'Resolver', 'Query', 'Mutation', 'Subscription', 'Arg', 'Args', 'ArgsType', 'Ctx', 'Root',
22
+ 'Info', 'Field', 'FieldResolver', 'ObjectType', 'InputType', 'InterfaceType', 'Authorized',
23
+ 'UseMiddleware', 'Extensions', 'Directive', 'ID', 'Int', 'Float', 'GraphQLISODateTime',
24
+ 'GraphQLTimestamp', 'registerEnumType', 'createMethodDecorator', 'createParamDecorator',
25
+ 'buildSchema', 'buildSchemaSync', 'PubSub',
26
+ ];
27
+ return Object.fromEntries(exportNames.map((name) => [name, decoratorFactory]));
28
+ });
29
+
30
+ const hoisted = vi.hoisted(() => ({
31
+ runAgentInConversation: vi.fn(),
32
+ resolveWidgetGuestRunContext: vi.fn(),
33
+ authorize: vi.fn(),
34
+ }));
35
+
36
+ // Only the key engine is stubbed: Authorize allows `agent:trusted` for the key whose hash is 'hash-trusted'.
37
+ vi.mock('@memberjunction/api-keys', async (importOriginal) => ({
38
+ ...(await importOriginal<typeof import('@memberjunction/api-keys')>()),
39
+ GetAPIKeyEngine: () => ({ Authorize: hoisted.authorize }),
40
+ }));
41
+
42
+ vi.mock('@memberjunction/ai-agents', () => ({
43
+ AgentRunner: class {
44
+ async CreateAgentReplyDetail() {
45
+ return { ID: 'reply-1', __mj_CreatedAt: new Date() };
46
+ }
47
+ RunAgentInConversation(...args: unknown[]) {
48
+ return hoisted.runAgentInConversation(...args);
49
+ }
50
+ },
51
+ ArtifactToolManager: class {},
52
+ }));
53
+
54
+ // Only the widget lookup is stubbed; ElevateUserPayload is the real one, so the widget-guest test runs
55
+ // against the elevated system-user payload the resolver really builds.
56
+ vi.mock('../realtimeWidget/widgetGuestElevation.js', async (importOriginal) => ({
57
+ ...(await importOriginal<typeof import('../realtimeWidget/widgetGuestElevation.js')>()),
58
+ ResolveWidgetGuestRunContext: hoisted.resolveWidgetGuestRunContext,
59
+ }));
60
+
61
+ import { UserCache } from '@memberjunction/generic-database-provider';
62
+ import type { UserInfo } from '@memberjunction/core';
63
+ import { RunAIAgentResolver } from '../resolvers/RunAIAgentResolver.js';
64
+ import type { AppContext, UserPayload } from '../types.js';
65
+
66
+ const SCOPE_RECORD_ID = 'B1A2C3D4-0000-4000-8000-00000000A115';
67
+ const ORDINARY = { conversationId: 'conv-1', latestMessageId: 'detail-1', invocationReason: 'user-message' };
68
+ const CLIENT_DATA = JSON.stringify({
69
+ ...ORDINARY,
70
+ PrimaryScopeRecordID: SCOPE_RECORD_ID,
71
+ PrimaryScopeEntityName: 'MJ: Companies',
72
+ SecondaryScopes: { TeamID: 'team-other' },
73
+ __agentTypePromptParams: { enableTaskGraphs: true },
74
+ });
75
+
76
+ const USER = { ID: 'user-1', Email: 'browser.user@example.com' };
77
+ const SYSTEM_USER = { ID: 'system-user', Email: 'system@example.com' };
78
+ // A widget guest always carries its per-visitor scope id (mj_sid) as its MagicLinkScope.ResourceID, and its
79
+ // conversation is stamped with the same value as ExternalID: that stamp is what tells one guest from another
80
+ // under the shared Anonymous user (MJ#6032), so the fake conversation below carries it.
81
+ const GUEST = { ID: 'guest-1', Email: 'anonymous@magic-link.local', IsMagicLinkAnonymous: true, AnonymousVisitorID: 'sid-1', MagicLinkScope: { ResourceID: 'sid-1' } };
82
+
83
+ type Fn = ReturnType<typeof vi.fn>;
84
+
85
+ /** The private members this test reaches, through an explicit shape (no `any`). */
86
+ interface ResolverSeams {
87
+ CheckAPIKeyScopeAuthorization: Fn;
88
+ GetUserFromPayload: Fn;
89
+ loadConversationHistoryWithAttachments: Fn;
90
+ validateAgent: Fn;
91
+ persistInFlightAgentFailure: Fn;
92
+ }
93
+
94
+ const pubSub = { publish: vi.fn().mockResolvedValue(undefined) } as unknown as PubSubEngine;
95
+
96
+ function makeResolver(): { resolver: RunAIAgentResolver; seams: ResolverSeams } {
97
+ const resolver = new RunAIAgentResolver();
98
+ const seams = resolver as unknown as ResolverSeams;
99
+ seams.CheckAPIKeyScopeAuthorization = vi.fn().mockResolvedValue(undefined);
100
+ seams.GetUserFromPayload = vi.fn((payload: UserPayload) => payload.userRecord);
101
+ seams.loadConversationHistoryWithAttachments = vi.fn().mockResolvedValue([{ role: 'user', content: 'hi' }]);
102
+ seams.validateAgent = vi.fn().mockResolvedValue({ ID: 'agent-1', Name: 'Test Agent' });
103
+ seams.persistInFlightAgentFailure = vi.fn().mockResolvedValue(undefined);
104
+ return { resolver, seams };
105
+ }
106
+
107
+ function makeContext(userPayload: Partial<UserPayload>): AppContext {
108
+ const provider = {
109
+ GetEntityObject: vi.fn().mockResolvedValue({ ConversationID: 'conv-1', UserID: GUEST.ID, ExternalID: 'sid-1', Load: vi.fn().mockResolvedValue(true) }),
110
+ };
111
+ return {
112
+ userPayload: { sessionId: 'session-1', email: USER.Email, userRecord: USER, ...userPayload } as UserPayload,
113
+ providers: [{ type: 'Read-Write', provider }],
114
+ dataSource: {},
115
+ } as unknown as AppContext;
116
+ }
117
+
118
+ /** The params the n-th run was handed by the real executeAIAgent (what AgentRunner.RunAgentInConversation received). */
119
+ interface HandedParams {
120
+ data: Record<string, unknown>;
121
+ TrustReservedRunData?: boolean;
122
+ contextUser: { ID: string };
123
+ }
124
+
125
+ /** Waits for the n-th run to start (the fire-and-forget path starts it after the resolver has returned). */
126
+ async function handedParams(n = 0): Promise<HandedParams> {
127
+ await vi.waitFor(() => expect(hoisted.runAgentInConversation.mock.calls.length).toBeGreaterThan(n));
128
+ return hoisted.runAgentInConversation.mock.calls[n][0] as HandedParams;
129
+ }
130
+
131
+ function runAIAgent(resolver: RunAIAgentResolver, ctx: AppContext, fireAndForget?: boolean) {
132
+ return resolver.RunAIAgent(
133
+ 'agent-1', ctx, '[{"role":"user","content":"hi"}]', 'session-1', pubSub, CLIENT_DATA,
134
+ undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined,
135
+ fireAndForget
136
+ );
137
+ }
138
+
139
+ function runFromDetail(resolver: RunAIAgentResolver, ctx: AppContext, fireAndForget?: boolean) {
140
+ return resolver.RunAIAgentFromConversationDetail(
141
+ 'detail-1', 'agent-1', ctx, 'session-1', pubSub, undefined, CLIENT_DATA,
142
+ undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, fireAndForget
143
+ );
144
+ }
145
+
146
+ beforeEach(() => {
147
+ hoisted.resolveWidgetGuestRunContext.mockReset().mockResolvedValue(null);
148
+ // Stop right after the run's params are captured — the rest of the run is out of scope.
149
+ hoisted.runAgentInConversation.mockReset().mockRejectedValue(new Error('stop here'));
150
+ hoisted.authorize.mockReset().mockImplementation(async (apiKeyHash: string, _app: string, scopePath: string) =>
151
+ apiKeyHash === 'hash-trusted' && scopePath === 'agent:trusted'
152
+ ? { Allowed: true, MatchedKeyRule: { ScopePath: scopePath }, EvaluatedRules: [] }
153
+ : { Allowed: false, Reason: 'No matching key scope rules', EvaluatedRules: [] });
154
+ vi.spyOn(UserCache.Instance, 'GetSystemUser').mockReturnValue(SYSTEM_USER as UserInfo);
155
+ vi.spyOn(console, 'log').mockImplementation(() => undefined);
156
+ vi.spyOn(console, 'error').mockImplementation(() => undefined);
157
+ });
158
+
159
+ afterEach(() => {
160
+ vi.restoreAllMocks();
161
+ });
162
+
163
+ describe('RunAIAgent — reserved run-data keys', () => {
164
+ it('marks the run untrusted for an interactive user and forwards data as sent', async () => {
165
+ const { resolver } = makeResolver();
166
+
167
+ await runAIAgent(resolver, makeContext({}));
168
+
169
+ const params = await handedParams();
170
+ expect(params.TrustReservedRunData).toBe(false);
171
+ expect(params.data).toEqual(JSON.parse(CLIENT_DATA));
172
+ });
173
+
174
+ it('marks it untrusted on the fire-and-forget path too', async () => {
175
+ const { resolver } = makeResolver();
176
+
177
+ await runAIAgent(resolver, makeContext({}), true);
178
+
179
+ expect((await handedParams()).TrustReservedRunData).toBe(false);
180
+ });
181
+
182
+ it('marks it trusted for an API key holding agent:trusted, on both paths', async () => {
183
+ const { resolver } = makeResolver();
184
+ const ctx = makeContext({ apiKeyId: 'key-1', apiKeyHash: 'hash-trusted' });
185
+
186
+ await runAIAgent(resolver, ctx);
187
+ await runAIAgent(resolver, ctx, true);
188
+
189
+ expect((await handedParams(0)).TrustReservedRunData).toBe(true);
190
+ expect((await handedParams(1)).TrustReservedRunData).toBe(true);
191
+ });
192
+
193
+ it('marks it untrusted for an API key without agent:trusted, on both paths', async () => {
194
+ const { resolver } = makeResolver();
195
+ const ctx = makeContext({ apiKeyId: 'key-2', apiKeyHash: 'hash-plain' });
196
+
197
+ await runAIAgent(resolver, ctx);
198
+ await runAIAgent(resolver, ctx, true);
199
+
200
+ expect((await handedParams(0)).TrustReservedRunData).toBe(false);
201
+ expect((await handedParams(1)).TrustReservedRunData).toBe(false);
202
+ });
203
+ });
204
+
205
+ describe('RunAIAgentFromConversationDetail — reserved run-data keys', () => {
206
+ it('marks the run untrusted for an interactive user on both paths', async () => {
207
+ const { resolver } = makeResolver();
208
+
209
+ await runFromDetail(resolver, makeContext({}));
210
+ await runFromDetail(resolver, makeContext({}), true);
211
+
212
+ expect((await handedParams(0)).TrustReservedRunData).toBe(false);
213
+ expect((await handedParams(1)).TrustReservedRunData).toBe(false);
214
+ });
215
+
216
+ it('marks a widget-guest run untrusted although it executes as the system user', async () => {
217
+ const { resolver } = makeResolver();
218
+ hoisted.resolveWidgetGuestRunContext.mockResolvedValue({
219
+ ElevatedUser: SYSTEM_USER,
220
+ Widget: {},
221
+ PinnedAgentId: 'pinned-agent',
222
+ });
223
+
224
+ await runFromDetail(resolver, makeContext({ email: GUEST.Email, userRecord: GUEST }));
225
+
226
+ const params = await handedParams();
227
+ expect(params.contextUser.ID).toBe(SYSTEM_USER.ID); // the premise: the run is elevated
228
+ expect(params.TrustReservedRunData).toBe(false);
229
+ });
230
+
231
+ it('marks it trusted for the system user, on both paths', async () => {
232
+ const { resolver } = makeResolver();
233
+ const ctx = makeContext({ isSystemUser: true, email: SYSTEM_USER.Email, userRecord: SYSTEM_USER });
234
+
235
+ await runFromDetail(resolver, ctx);
236
+ await runFromDetail(resolver, ctx, true);
237
+
238
+ expect((await handedParams(0)).TrustReservedRunData).toBe(true);
239
+ expect((await handedParams(1)).TrustReservedRunData).toBe(true);
240
+ });
241
+
242
+ it('marks it trusted for an API key holding agent:trusted, and untrusted for one without', async () => {
243
+ const { resolver } = makeResolver();
244
+
245
+ await runFromDetail(resolver, makeContext({ apiKeyId: 'key-1', apiKeyHash: 'hash-trusted' }));
246
+ await runFromDetail(resolver, makeContext({ apiKeyId: 'key-2', apiKeyHash: 'hash-plain' }));
247
+
248
+ expect((await handedParams(0)).TrustReservedRunData).toBe(true);
249
+ expect((await handedParams(1)).TrustReservedRunData).toBe(false);
250
+ });
251
+ });
252
+
253
+ describe('RunAIAgentSystemUser — reserved run-data keys', () => {
254
+ it('marks the run trusted for the system user it admits, and forwards data as sent', async () => {
255
+ const { resolver } = makeResolver();
256
+ const ctx = makeContext({ isSystemUser: true, email: SYSTEM_USER.Email, userRecord: SYSTEM_USER });
257
+
258
+ await resolver.RunAIAgentSystemUser('agent-1', ctx, '[]', 'session-1', pubSub, CLIENT_DATA);
259
+
260
+ const params = await handedParams();
261
+ expect(params.TrustReservedRunData).toBe(true);
262
+ expect(params.data).toEqual(JSON.parse(CLIENT_DATA));
263
+ });
264
+ });