@memberjunction/server 6.2.0-edge.5 → 6.2.0-edge.7

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 (664) hide show
  1. package/README.md +96 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/agentSessions/BridgeHostInstance.d.ts +8 -3
  4. package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -1
  5. package/dist/agentSessions/BridgeHostInstance.js +14 -4
  6. package/dist/agentSessions/BridgeHostInstance.js.map +1 -1
  7. package/dist/agentSessions/HandoffOfferExpiry.d.ts +10 -0
  8. package/dist/agentSessions/HandoffOfferExpiry.d.ts.map +1 -0
  9. package/dist/agentSessions/HandoffOfferExpiry.js +18 -0
  10. package/dist/agentSessions/HandoffOfferExpiry.js.map +1 -0
  11. package/dist/agentSessions/ReturningVisitorRecap.js +1 -0
  12. package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
  13. package/dist/agentSessions/SessionJanitor.d.ts +34 -11
  14. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  15. package/dist/agentSessions/SessionJanitor.js +88 -44
  16. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  17. package/dist/agentSessions/SessionManager.d.ts +29 -9
  18. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  19. package/dist/agentSessions/SessionManager.js +62 -16
  20. package/dist/agentSessions/SessionManager.js.map +1 -1
  21. package/dist/agentSessions/conversationBrowsers.d.ts +61 -0
  22. package/dist/agentSessions/conversationBrowsers.d.ts.map +1 -0
  23. package/dist/agentSessions/conversationBrowsers.js +118 -0
  24. package/dist/agentSessions/conversationBrowsers.js.map +1 -0
  25. package/dist/agentSessions/sessionDeadline.d.ts +43 -0
  26. package/dist/agentSessions/sessionDeadline.d.ts.map +1 -0
  27. package/dist/agentSessions/sessionDeadline.js +68 -0
  28. package/dist/agentSessions/sessionDeadline.js.map +1 -0
  29. package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
  30. package/dist/auth/APIKeyScopeAuth.js +5 -4
  31. package/dist/auth/APIKeyScopeAuth.js.map +1 -1
  32. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
  33. package/dist/auth/AuthProviderCatalogRouter.js +2 -0
  34. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
  35. package/dist/auth/index.d.ts.map +1 -1
  36. package/dist/auth/index.js +51 -10
  37. package/dist/auth/index.js.map +1 -1
  38. package/dist/auth/initializeProviders.d.ts +10 -0
  39. package/dist/auth/initializeProviders.d.ts.map +1 -1
  40. package/dist/auth/initializeProviders.js +37 -1
  41. package/dist/auth/initializeProviders.js.map +1 -1
  42. package/dist/auth/localDevAuth.d.ts +79 -0
  43. package/dist/auth/localDevAuth.d.ts.map +1 -0
  44. package/dist/auth/localDevAuth.js +439 -0
  45. package/dist/auth/localDevAuth.js.map +1 -0
  46. package/dist/auth/loginEmailResolution.d.ts +41 -0
  47. package/dist/auth/loginEmailResolution.d.ts.map +1 -0
  48. package/dist/auth/loginEmailResolution.js +47 -0
  49. package/dist/auth/loginEmailResolution.js.map +1 -0
  50. package/dist/auth/magicLink/MagicLinkKeys.d.ts +51 -3
  51. package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
  52. package/dist/auth/magicLink/MagicLinkKeys.js +130 -13
  53. package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
  54. package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
  55. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  56. package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
  57. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  58. package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
  59. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  60. package/dist/auth/magicLink/MagicLinkService.js +221 -9
  61. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  62. package/dist/auth/magicLink/index.d.ts +1 -1
  63. package/dist/auth/magicLink/index.d.ts.map +1 -1
  64. package/dist/auth/magicLink/index.js +1 -1
  65. package/dist/auth/magicLink/index.js.map +1 -1
  66. package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
  67. package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
  68. package/dist/auth/magicLink/redeemLanding.js +7 -4
  69. package/dist/auth/magicLink/redeemLanding.js.map +1 -1
  70. package/dist/auth/magicLink/types.d.ts +39 -3
  71. package/dist/auth/magicLink/types.d.ts.map +1 -1
  72. package/dist/auth/magicLink/types.js +0 -4
  73. package/dist/auth/magicLink/types.js.map +1 -1
  74. package/dist/auth/newUsers.d.ts.map +1 -1
  75. package/dist/auth/newUsers.js +1 -0
  76. package/dist/auth/newUsers.js.map +1 -1
  77. package/dist/auth/sessionUserClone.d.ts +1 -1
  78. package/dist/auth/sessionUserClone.d.ts.map +1 -1
  79. package/dist/auth/sessionUserClone.js +3 -2
  80. package/dist/auth/sessionUserClone.js.map +1 -1
  81. package/dist/backgroundSweepConfigUnits.d.ts +231 -0
  82. package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
  83. package/dist/backgroundSweepConfigUnits.js +180 -0
  84. package/dist/backgroundSweepConfigUnits.js.map +1 -0
  85. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
  86. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
  87. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
  88. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
  89. package/dist/broadcast/index.d.ts +6 -0
  90. package/dist/broadcast/index.d.ts.map +1 -0
  91. package/dist/broadcast/index.js +6 -0
  92. package/dist/broadcast/index.js.map +1 -0
  93. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
  94. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
  95. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
  96. package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
  97. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
  98. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
  99. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
  100. package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
  101. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
  102. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
  103. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
  104. package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
  105. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
  106. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
  107. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
  108. package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
  109. package/dist/cache.d.ts +3 -2
  110. package/dist/cache.d.ts.map +1 -1
  111. package/dist/cache.js.map +1 -1
  112. package/dist/config.d.ts +1402 -8
  113. package/dist/config.d.ts.map +1 -1
  114. package/dist/config.js +120 -0
  115. package/dist/config.js.map +1 -1
  116. package/dist/context.d.ts +5 -1
  117. package/dist/context.d.ts.map +1 -1
  118. package/dist/context.js +64 -12
  119. package/dist/context.js.map +1 -1
  120. package/dist/coreRoutes.d.ts +3 -1
  121. package/dist/coreRoutes.d.ts.map +1 -1
  122. package/dist/coreRoutes.js +20 -4
  123. package/dist/coreRoutes.js.map +1 -1
  124. package/dist/generated/graphql-schemas/__mj.d.ts +863 -14
  125. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  126. package/dist/generated/graphql-schemas/__mj.js +4167 -62
  127. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  128. package/dist/generic/CacheInvalidationResolver.d.ts +50 -30
  129. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  130. package/dist/generic/CacheInvalidationResolver.js +154 -79
  131. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  132. package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
  133. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
  134. package/dist/generic/OrphanedConversationDetailReconciler.js +29 -1
  135. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  136. package/dist/generic/PubSubManager.d.ts +10 -0
  137. package/dist/generic/PubSubManager.d.ts.map +1 -1
  138. package/dist/generic/PubSubManager.js +44 -1
  139. package/dist/generic/PubSubManager.js.map +1 -1
  140. package/dist/generic/PushStatusResolver.d.ts +39 -6
  141. package/dist/generic/PushStatusResolver.d.ts.map +1 -1
  142. package/dist/generic/PushStatusResolver.js +93 -11
  143. package/dist/generic/PushStatusResolver.js.map +1 -1
  144. package/dist/generic/ResolverBase.d.ts +114 -29
  145. package/dist/generic/ResolverBase.d.ts.map +1 -1
  146. package/dist/generic/ResolverBase.js +509 -220
  147. package/dist/generic/ResolverBase.js.map +1 -1
  148. package/dist/generic/RunViewResolver.d.ts +15 -3
  149. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  150. package/dist/generic/RunViewResolver.js +126 -20
  151. package/dist/generic/RunViewResolver.js.map +1 -1
  152. package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
  153. package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
  154. package/dist/generic/actionOutputFieldSecurity.js +47 -0
  155. package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
  156. package/dist/generic/fieldSecurityTransport.d.ts +30 -0
  157. package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
  158. package/dist/generic/fieldSecurityTransport.js +30 -0
  159. package/dist/generic/fieldSecurityTransport.js.map +1 -0
  160. package/dist/index.d.ts +4 -0
  161. package/dist/index.d.ts.map +1 -1
  162. package/dist/index.js +262 -84
  163. package/dist/index.js.map +1 -1
  164. package/dist/integration/ConnectionPause.d.ts +121 -0
  165. package/dist/integration/ConnectionPause.d.ts.map +1 -0
  166. package/dist/integration/ConnectionPause.js +183 -0
  167. package/dist/integration/ConnectionPause.js.map +1 -0
  168. package/dist/integration/CustomColumnPromoter.d.ts +72 -6
  169. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  170. package/dist/integration/CustomColumnPromoter.js +93 -47
  171. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  172. package/dist/integration/EntityMapLifecycle.d.ts +78 -4
  173. package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
  174. package/dist/integration/EntityMapLifecycle.js +199 -5
  175. package/dist/integration/EntityMapLifecycle.js.map +1 -1
  176. package/dist/integration/InactiveRowWarnings.d.ts +31 -0
  177. package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
  178. package/dist/integration/InactiveRowWarnings.js +29 -0
  179. package/dist/integration/InactiveRowWarnings.js.map +1 -1
  180. package/dist/integration/ObjectNamesByID.d.ts +28 -0
  181. package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
  182. package/dist/integration/ObjectNamesByID.js +87 -0
  183. package/dist/integration/ObjectNamesByID.js.map +1 -0
  184. package/dist/integration/PostRestartIntrospect.d.ts +26 -0
  185. package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
  186. package/dist/integration/PostRestartIntrospect.js +27 -0
  187. package/dist/integration/PostRestartIntrospect.js.map +1 -0
  188. package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
  189. package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
  190. package/dist/integration/RSUPostRestartProgress.js +323 -0
  191. package/dist/integration/RSUPostRestartProgress.js.map +1 -0
  192. package/dist/integration/RSUProgressBridge.d.ts +41 -2
  193. package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
  194. package/dist/integration/RSUProgressBridge.js +84 -1
  195. package/dist/integration/RSUProgressBridge.js.map +1 -1
  196. package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
  197. package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
  198. package/dist/integration/RunArtifactAuthorization.js +45 -0
  199. package/dist/integration/RunArtifactAuthorization.js.map +1 -0
  200. package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
  201. package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
  202. package/dist/integration/SchemaRefreshLaunch.js +3 -2
  203. package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
  204. package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
  205. package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
  206. package/dist/integration/ScopedFieldsForBuild.js +91 -0
  207. package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
  208. package/dist/integration/TargetConfigGuard.d.ts +40 -0
  209. package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
  210. package/dist/integration/TargetConfigGuard.js +40 -0
  211. package/dist/integration/TargetConfigGuard.js.map +1 -0
  212. package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
  213. package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
  214. package/dist/logging/variablesLoggingMiddleware.js +50 -1
  215. package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
  216. package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
  217. package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
  218. package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
  219. package/dist/realtimeSessions/ownedRealtimeSession.d.ts +8 -6
  220. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
  221. package/dist/realtimeSessions/ownedRealtimeSession.js +14 -6
  222. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
  223. package/dist/realtimeSessions/sessionAccess.d.ts +103 -11
  224. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
  225. package/dist/realtimeSessions/sessionAccess.js +147 -22
  226. package/dist/realtimeSessions/sessionAccess.js.map +1 -1
  227. package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
  228. package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
  229. package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
  230. package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
  231. package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
  232. package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
  233. package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
  234. package/dist/realtimeSessions/verificationWorkflow.js +1 -1
  235. package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
  236. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
  237. package/dist/realtimeWidget/WidgetRouter.js +19 -3
  238. package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
  239. package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
  240. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
  241. package/dist/realtimeWidget/WidgetSessionService.js +203 -19
  242. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  243. package/dist/realtimeWidget/host-identity.d.ts +1 -1
  244. package/dist/realtimeWidget/host-identity.js +1 -1
  245. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
  246. package/dist/realtimeWidget/visitorIdentity.js +1 -0
  247. package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
  248. package/dist/realtimeWidget/widgetCore.d.ts +20 -1
  249. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  250. package/dist/realtimeWidget/widgetCore.js +21 -8
  251. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  252. package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
  253. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  254. package/dist/realtimeWidget/widgetGuestElevation.js +3 -1
  255. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  256. package/dist/requestOrigin.d.ts +22 -0
  257. package/dist/requestOrigin.d.ts.map +1 -0
  258. package/dist/requestOrigin.js +60 -0
  259. package/dist/requestOrigin.js.map +1 -0
  260. package/dist/resolvers/ActionResolver.d.ts +19 -1
  261. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  262. package/dist/resolvers/ActionResolver.js +63 -12
  263. package/dist/resolvers/ActionResolver.js.map +1 -1
  264. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  265. package/dist/resolvers/AdhocQueryResolver.js +1 -0
  266. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  267. package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
  268. package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
  269. package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
  270. package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
  271. package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
  272. package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
  273. package/dist/resolvers/AgentSessionResolver.js +44 -17
  274. package/dist/resolvers/AgentSessionResolver.js.map +1 -1
  275. package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
  276. package/dist/resolvers/AutotagPipelineResolver.js +2 -1
  277. package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
  278. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  279. package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
  280. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  281. package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
  282. package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
  283. package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
  284. package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
  285. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +6 -0
  286. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
  287. package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
  288. package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
  289. package/dist/resolvers/FetchEntityVectorsResolver.d.ts +28 -0
  290. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  291. package/dist/resolvers/FetchEntityVectorsResolver.js +117 -21
  292. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  293. package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
  294. package/dist/resolvers/FileCategoryResolver.js +1 -0
  295. package/dist/resolvers/FileCategoryResolver.js.map +1 -1
  296. package/dist/resolvers/FileResolver.d.ts +5 -0
  297. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  298. package/dist/resolvers/FileResolver.js +13 -4
  299. package/dist/resolvers/FileResolver.js.map +1 -1
  300. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  301. package/dist/resolvers/GetDataResolver.js +34 -13
  302. package/dist/resolvers/GetDataResolver.js.map +1 -1
  303. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
  304. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  305. package/dist/resolvers/IntegrationDiscoveryResolver.js +2713 -1290
  306. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  307. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  308. package/dist/resolvers/MCPResolver.js +13 -2
  309. package/dist/resolvers/MCPResolver.js.map +1 -1
  310. package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
  311. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  312. package/dist/resolvers/MergeRecordsResolver.js +31 -3
  313. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  314. package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
  315. package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
  316. package/dist/resolvers/PipelineProgressResolver.js +5 -3
  317. package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
  318. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  319. package/dist/resolvers/QueryResolver.js +20 -6
  320. package/dist/resolvers/QueryResolver.js.map +1 -1
  321. package/dist/resolvers/QuerySystemUserResolver.d.ts +38 -0
  322. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  323. package/dist/resolvers/QuerySystemUserResolver.js +184 -88
  324. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  325. package/dist/resolvers/RSUResolver.d.ts.map +1 -1
  326. package/dist/resolvers/RSUResolver.js +12 -0
  327. package/dist/resolvers/RSUResolver.js.map +1 -1
  328. package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
  329. package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
  330. package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
  331. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +22 -2
  332. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  333. package/dist/resolvers/RealtimeClientSessionResolver.js +118 -33
  334. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  335. package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
  336. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  337. package/dist/resolvers/RemoteBrowserActionResolver.js +224 -39
  338. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  339. package/dist/resolvers/RunAIAgentResolver.d.ts +80 -16
  340. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  341. package/dist/resolvers/RunAIAgentResolver.js +388 -125
  342. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  343. package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
  344. package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
  345. package/dist/resolvers/RunAIPromptResolver.js +19 -18
  346. package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
  347. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  348. package/dist/resolvers/RunTemplateResolver.js +7 -5
  349. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  350. package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
  351. package/dist/resolvers/RunTestResolver.js +3 -1
  352. package/dist/resolvers/RunTestResolver.js.map +1 -1
  353. package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
  354. package/dist/resolvers/SyncDataResolver.js +4 -0
  355. package/dist/resolvers/SyncDataResolver.js.map +1 -1
  356. package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
  357. package/dist/resolvers/TestQuerySQLResolver.js +1 -0
  358. package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
  359. package/dist/resolvers/TransactionGroupResolver.d.ts +17 -2
  360. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  361. package/dist/resolvers/TransactionGroupResolver.js +60 -15
  362. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  363. package/dist/resolvers/UserViewResolver.d.ts +1 -1
  364. package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
  365. package/dist/resolvers/UserViewResolver.js +2 -1
  366. package/dist/resolvers/UserViewResolver.js.map +1 -1
  367. package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
  368. package/dist/resolvers/meetingRecordingRegistration.js +2 -0
  369. package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
  370. package/dist/rest/EntityCRUDHandler.d.ts +6 -0
  371. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  372. package/dist/rest/EntityCRUDHandler.js +19 -5
  373. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  374. package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
  375. package/dist/rest/MediaAccessKeys.js +6 -2
  376. package/dist/rest/MediaAccessKeys.js.map +1 -1
  377. package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
  378. package/dist/rest/OAuthCallbackHandler.js +11 -5
  379. package/dist/rest/OAuthCallbackHandler.js.map +1 -1
  380. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  381. package/dist/rest/RESTEndpointHandler.js +8 -5
  382. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  383. package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
  384. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
  385. package/dist/rest/RealtimeRecordingHandler.js +6 -8
  386. package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
  387. package/dist/rest/ViewOperationsHandler.d.ts +6 -0
  388. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  389. package/dist/rest/ViewOperationsHandler.js +24 -6
  390. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  391. package/dist/rest/setupRESTEndpoints.d.ts +3 -1
  392. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  393. package/dist/rest/setupRESTEndpoints.js +11 -2
  394. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  395. package/dist/serverRoleConfigUnits.d.ts +29 -0
  396. package/dist/serverRoleConfigUnits.d.ts.map +1 -0
  397. package/dist/serverRoleConfigUnits.js +33 -0
  398. package/dist/serverRoleConfigUnits.js.map +1 -0
  399. package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
  400. package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
  401. package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
  402. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  403. package/dist/services/TaskGraphActionRunner.js +2 -26
  404. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  405. package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
  406. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  407. package/dist/services/TaskGraphAgentRunner.js +38 -0
  408. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  409. package/dist/services/TaskGraphContinuationDeliverer.d.ts +5 -0
  410. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  411. package/dist/services/TaskGraphContinuationDeliverer.js +43 -15
  412. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  413. package/dist/services/WorkQueueHostService.d.ts +2 -1
  414. package/dist/services/WorkQueueHostService.d.ts.map +1 -1
  415. package/dist/services/WorkQueueHostService.js +19 -4
  416. package/dist/services/WorkQueueHostService.js.map +1 -1
  417. package/dist/services/workQueueConfig.d.ts +2 -2
  418. package/dist/services/workQueueConfig.js +5 -5
  419. package/dist/services/workQueueConfig.js.map +1 -1
  420. package/dist/sharedCache.js +1 -1
  421. package/dist/sharedCache.js.map +1 -1
  422. package/dist/types.d.ts +40 -1
  423. package/dist/types.d.ts.map +1 -1
  424. package/dist/types.js.map +1 -1
  425. package/package.json +98 -98
  426. package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
  427. package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
  428. package/src/__tests__/ActiveOperations.test.ts +68 -0
  429. package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
  430. package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
  431. package/src/__tests__/AgentSessionResolver.ownership.test.ts +150 -0
  432. package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
  433. package/src/__tests__/BatchApplyParity.test.ts +109 -0
  434. package/src/__tests__/BridgeHostInstance.test.ts +42 -0
  435. package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
  436. package/src/__tests__/ConnectionPause.test.ts +192 -0
  437. package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
  438. package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
  439. package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
  440. package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
  441. package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
  442. package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
  443. package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
  444. package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
  445. package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
  446. package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
  447. package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
  448. package/src/__tests__/FetchEntityVectorsResolver.test.ts +206 -3
  449. package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
  450. package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
  451. package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
  452. package/src/__tests__/MagicLinkKeys.test.ts +102 -0
  453. package/src/__tests__/MediaAccessKeys.test.ts +57 -10
  454. package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
  455. package/src/__tests__/ObjectNamesByID.test.ts +176 -0
  456. package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
  457. package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
  458. package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
  459. package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
  460. package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
  461. package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
  462. package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
  463. package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
  464. package/src/__tests__/RSUProgressBridge.test.ts +188 -5
  465. package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
  466. package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
  467. package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
  468. package/src/__tests__/RealtimeClientSessionResolver.test.ts +346 -46
  469. package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
  470. package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
  471. package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
  472. package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +100 -0
  473. package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
  474. package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
  475. package/src/__tests__/ResolverBase.clientOldValues.test.ts +344 -14
  476. package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
  477. package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
  478. package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +227 -0
  479. package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +83 -1
  480. package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
  481. package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
  482. package/src/__tests__/RunAIAgentResolver.branch.test.ts +72 -13
  483. package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
  484. package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
  485. package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
  486. package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
  487. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +19 -27
  488. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +10 -2
  489. package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
  490. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +91 -13
  491. package/src/__tests__/RunTemplateResolver.test.ts +35 -2
  492. package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
  493. package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
  494. package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
  495. package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
  496. package/src/__tests__/SessionJanitor.test.ts +195 -4
  497. package/src/__tests__/SessionManager.test.ts +164 -0
  498. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
  499. package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
  500. package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +114 -3
  501. package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
  502. package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
  503. package/src/__tests__/ViewOperationsHandler.test.ts +9 -7
  504. package/src/__tests__/WidgetSessionService.test.ts +583 -4
  505. package/src/__tests__/WorkQueueHostService.test.ts +25 -7
  506. package/src/__tests__/apiRootBoot.test.ts +1 -1
  507. package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
  508. package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
  509. package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
  510. package/src/__tests__/cacheInvalidationRecordData.test.ts +45 -0
  511. package/src/__tests__/contextRequestOrigin.test.ts +105 -0
  512. package/src/__tests__/conversationBrowsers.test.ts +62 -0
  513. package/src/__tests__/fieldSecurityFixtures.ts +91 -0
  514. package/src/__tests__/globalCors.test.ts +3 -3
  515. package/src/__tests__/localDevAuth.test.ts +196 -0
  516. package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
  517. package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
  518. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
  519. package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
  520. package/src/__tests__/pushStatusResolver.filter.test.ts +57 -1
  521. package/src/__tests__/realtimeRecordingHandler.test.ts +24 -2
  522. package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
  523. package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
  524. package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
  525. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +224 -7
  526. package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
  527. package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
  528. package/src/__tests__/requestOrigin.test.ts +104 -0
  529. package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
  530. package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
  531. package/src/__tests__/resolverBase.fls.test.ts +146 -97
  532. package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
  533. package/src/__tests__/runParamsTimeZone.test.ts +179 -0
  534. package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
  535. package/src/__tests__/runViewProperties.test.ts +114 -0
  536. package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
  537. package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
  538. package/src/__tests__/securityHardeningPr6034.test.ts +120 -0
  539. package/src/__tests__/sessionDeadline.test.ts +51 -0
  540. package/src/__tests__/sessionUserClone.test.ts +5 -1
  541. package/src/__tests__/sharedCache.test.ts +11 -0
  542. package/src/__tests__/startupSweepOrder.test.ts +40 -0
  543. package/src/__tests__/unifiedAuth.test.ts +101 -1
  544. package/src/__tests__/widgetGuestElevation.test.ts +2 -0
  545. package/src/agentSessions/BridgeHostInstance.ts +20 -5
  546. package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
  547. package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
  548. package/src/agentSessions/SessionJanitor.ts +95 -45
  549. package/src/agentSessions/SessionManager.ts +73 -20
  550. package/src/agentSessions/conversationBrowsers.ts +143 -0
  551. package/src/agentSessions/sessionDeadline.ts +81 -0
  552. package/src/auth/APIKeyScopeAuth.ts +5 -4
  553. package/src/auth/AuthProviderCatalogRouter.ts +3 -0
  554. package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
  555. package/src/auth/index.ts +56 -12
  556. package/src/auth/initializeProviders.ts +43 -1
  557. package/src/auth/localDevAuth.ts +528 -0
  558. package/src/auth/loginEmailResolution.ts +67 -0
  559. package/src/auth/magicLink/MagicLinkKeys.ts +147 -15
  560. package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
  561. package/src/auth/magicLink/MagicLinkService.ts +250 -10
  562. package/src/auth/magicLink/index.ts +1 -1
  563. package/src/auth/magicLink/redeemLanding.ts +7 -4
  564. package/src/auth/magicLink/types.ts +38 -3
  565. package/src/auth/newUsers.ts +1 -0
  566. package/src/auth/sessionUserClone.ts +3 -2
  567. package/src/backgroundSweepConfigUnits.ts +213 -0
  568. package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
  569. package/src/broadcast/index.ts +5 -0
  570. package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
  571. package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
  572. package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
  573. package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
  574. package/src/cache.ts +2 -1
  575. package/src/config.ts +138 -0
  576. package/src/context.ts +71 -14
  577. package/src/coreRoutes.ts +29 -7
  578. package/src/generated/graphql-schemas/__mj.ts +4145 -1193
  579. package/src/generic/CacheInvalidationResolver.ts +135 -78
  580. package/src/generic/OrphanedConversationDetailReconciler.ts +36 -3
  581. package/src/generic/PubSubManager.ts +54 -1
  582. package/src/generic/PushStatusResolver.ts +108 -11
  583. package/src/generic/ResolverBase.ts +635 -234
  584. package/src/generic/RunViewResolver.ts +176 -64
  585. package/src/generic/actionOutputFieldSecurity.ts +75 -0
  586. package/src/generic/fieldSecurityTransport.ts +62 -0
  587. package/src/index.ts +310 -85
  588. package/src/integration/ConnectionPause.ts +222 -0
  589. package/src/integration/CustomColumnPromoter.ts +129 -54
  590. package/src/integration/EntityMapLifecycle.ts +229 -6
  591. package/src/integration/InactiveRowWarnings.ts +50 -0
  592. package/src/integration/ObjectNamesByID.ts +97 -0
  593. package/src/integration/PostRestartIntrospect.ts +49 -0
  594. package/src/integration/RSUPostRestartProgress.ts +359 -0
  595. package/src/integration/RSUProgressBridge.ts +85 -2
  596. package/src/integration/RunArtifactAuthorization.ts +65 -0
  597. package/src/integration/SchemaRefreshLaunch.ts +12 -2
  598. package/src/integration/ScopedFieldsForBuild.ts +113 -0
  599. package/src/integration/TargetConfigGuard.ts +71 -0
  600. package/src/logging/variablesLoggingMiddleware.ts +59 -3
  601. package/src/realtimeSessions/README.md +7 -3
  602. package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
  603. package/src/realtimeSessions/ownedRealtimeSession.ts +16 -6
  604. package/src/realtimeSessions/sessionAccess.ts +211 -25
  605. package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
  606. package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
  607. package/src/realtimeSessions/verificationWorkflow.ts +3 -1
  608. package/src/realtimeWidget/WidgetRouter.ts +22 -4
  609. package/src/realtimeWidget/WidgetSessionService.ts +254 -17
  610. package/src/realtimeWidget/host-identity.ts +1 -1
  611. package/src/realtimeWidget/visitorIdentity.ts +1 -0
  612. package/src/realtimeWidget/widgetCore.ts +34 -9
  613. package/src/realtimeWidget/widgetGuestElevation.ts +3 -1
  614. package/src/requestOrigin.ts +64 -0
  615. package/src/resolvers/ActionResolver.ts +78 -15
  616. package/src/resolvers/AdhocQueryResolver.ts +1 -0
  617. package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
  618. package/src/resolvers/AgentSessionResolver.ts +50 -18
  619. package/src/resolvers/AutotagPipelineResolver.ts +2 -1
  620. package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
  621. package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
  622. package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
  623. package/src/resolvers/FetchEntityVectorsResolver.ts +132 -21
  624. package/src/resolvers/FileCategoryResolver.ts +1 -0
  625. package/src/resolvers/FileResolver.ts +14 -4
  626. package/src/resolvers/GetDataResolver.ts +35 -13
  627. package/src/resolvers/IntegrationDiscoveryResolver.ts +1570 -209
  628. package/src/resolvers/MCPResolver.ts +15 -2
  629. package/src/resolvers/MergeRecordsResolver.ts +23 -2
  630. package/src/resolvers/PipelineProgressResolver.ts +12 -3
  631. package/src/resolvers/QueryResolver.ts +20 -6
  632. package/src/resolvers/QuerySystemUserResolver.ts +207 -99
  633. package/src/resolvers/RSUResolver.ts +12 -0
  634. package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
  635. package/src/resolvers/RealtimeClientSessionResolver.ts +144 -40
  636. package/src/resolvers/RemoteBrowserActionResolver.ts +252 -37
  637. package/src/resolvers/RunAIAgentResolver.ts +518 -163
  638. package/src/resolvers/RunAIPromptResolver.ts +18 -18
  639. package/src/resolvers/RunTemplateResolver.ts +9 -5
  640. package/src/resolvers/RunTestResolver.ts +3 -1
  641. package/src/resolvers/SyncDataResolver.ts +4 -0
  642. package/src/resolvers/TestQuerySQLResolver.ts +1 -0
  643. package/src/resolvers/TransactionGroupResolver.ts +66 -15
  644. package/src/resolvers/UserViewResolver.ts +2 -1
  645. package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
  646. package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
  647. package/src/resolvers/meetingRecordingRegistration.ts +2 -0
  648. package/src/rest/EntityCRUDHandler.ts +22 -5
  649. package/src/rest/MediaAccessKeys.ts +6 -2
  650. package/src/rest/OAuthCallbackHandler.ts +13 -5
  651. package/src/rest/RESTEndpointHandler.ts +8 -5
  652. package/src/rest/RealtimeRecordingHandler.ts +9 -10
  653. package/src/rest/ViewOperationsHandler.ts +26 -7
  654. package/src/rest/setupRESTEndpoints.ts +11 -2
  655. package/src/serverRoleConfigUnits.ts +48 -0
  656. package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
  657. package/src/services/TaskGraphActionRunner.ts +2 -23
  658. package/src/services/TaskGraphAgentRunner.ts +43 -0
  659. package/src/services/TaskGraphContinuationDeliverer.ts +53 -20
  660. package/src/services/WorkQueueHostService.ts +26 -4
  661. package/src/services/workQueueConfig.ts +5 -5
  662. package/src/sharedCache.ts +1 -1
  663. package/src/types.ts +41 -1
  664. package/src/services/TaskOrchestration-Integration.md +0 -188
@@ -0,0 +1,18 @@
1
+ import { HandoffOfferRegistry } from '@memberjunction/livekit-room-server';
2
+ import type { HandoffOfferSweepSettings } from '../backgroundSweepConfigUnits.js';
3
+
4
+ /**
5
+ * Applies `agentSessions.handoffOfferExpiry` to the process-wide handoff offer registry. The registry
6
+ * starts its expiry sweep (a read of `MJ: Interaction Offers` every 15 seconds) as soon as it loads, on
7
+ * every MJAPI whatever its role; this either stops that sweep, so an idle server sends no periodic
8
+ * query for it, or restarts it on the configured interval. Overdue offers still read as expired when
9
+ * the sweep is off. See the Serverless Database Auto-Pause guide.
10
+ */
11
+ export function ApplyHandoffOfferExpirySettings(settings: HandoffOfferSweepSettings): void {
12
+ const registry = HandoffOfferRegistry.Instance;
13
+ if (settings.enabled) {
14
+ registry.StartPeriodicSweep(settings.sweepIntervalMs);
15
+ } else {
16
+ registry.StopPeriodicSweep();
17
+ }
18
+ }
@@ -146,6 +146,7 @@ async function recapAlreadyExists(conversationId: string, contextUser: UserInfo)
146
146
  ExtraFilter: `SourceConversationID = '${conversationId}' AND IsAutoGenerated = 1 AND Type = 'Context'`,
147
147
  Fields: ['ID'],
148
148
  MaxRows: 1,
149
+ SkipTotalRowCount: true,
149
150
  ResultType: 'simple',
150
151
  },
151
152
  contextUser,
@@ -19,6 +19,8 @@ import {
19
19
  } from '@memberjunction/ai-agents';
20
20
  import { GetCurrentHostInstance, GetHostInstanceID, HostInstanceIdentity } from './HostInstance.js';
21
21
  import { SessionManager, SessionCloseReason } from './SessionManager.js';
22
+ import type { SessionJanitorSettings } from '../backgroundSweepConfigUnits.js';
23
+ import { ExpiryCloseReason, ExpiryReason } from './sessionDeadline.js';
22
24
 
23
25
  /** Entity name for session rows (kept in sync with {@link SessionManager}). */
24
26
  const SESSION_ENTITY = 'MJ: AI Agent Sessions';
@@ -195,6 +197,24 @@ interface RecoveryVisit {
195
197
  Recovered: boolean;
196
198
  }
197
199
 
200
+ /**
201
+ * The close reason for a row the staleness sweep's SQL already judged stale (`LastActiveAt < cutoff`).
202
+ * {@link ExpiryCloseReason} returns null for such a row only when `LastActiveAt` will not parse (or the
203
+ * threshold is non-finite); skipping it would leave it `Active` forever, so it closes as `'Idle'` and the
204
+ * fallback is logged with the session ID.
205
+ */
206
+ function staleRowCloseReason(session: MJAIAgentSessionEntity, nowMs: number, thresholdMs: number): ExpiryReason {
207
+ const reason = ExpiryCloseReason(session, nowMs, thresholdMs);
208
+ if (reason !== null) {
209
+ return reason;
210
+ }
211
+ LogError(
212
+ `[SessionJanitor] Staleness sweep: session ${session.ID} has LastActiveAt ${String(session.LastActiveAt)}; ` +
213
+ 'LastActiveAt unparseable; closing as Idle',
214
+ );
215
+ return 'Idle';
216
+ }
217
+
198
218
  /**
199
219
  * `BaseSingleton` background reconciler that keeps the durable `AIAgentSession` state from drifting
200
220
  * away from volatile process reality. A crash/redeploy vaporizes a host's in-memory sockets but
@@ -212,9 +232,12 @@ interface RecoveryVisit {
212
232
  * `closeThresholdMinutes`, regardless of host. Catches sessions whose owner died without a clean
213
233
  * reboot (OOM, scaled-down pod).
214
234
  * 3. **Max-duration sweep ({@link RunMaxDurationSweep})** — run on every periodic tick after the
215
- * staleness sweep. Closes any session past its stored hard deadline (the public voice cost cap).
235
+ * staleness sweep. Closes any session past its stored hard deadline (the public voice cost cap), and
236
+ * any deadline-carrying session whose idle moment has passed; it stamps that row `'Idle'` when the idle
237
+ * moment came before the deadline.
216
238
  *
217
- * The close sweeps stamp `CloseReason = 'Janitor'`. A shutdown-time path — {@link RunShutdownDrain},
239
+ * Startup recovery stamps `CloseReason = 'Janitor'`; the staleness and max-duration sweeps stamp `'Idle'` or
240
+ * `'TimeLimit'`, whichever expiry moment passed first ({@link ExpiryCloseReason}). A shutdown-time path — {@link RunShutdownDrain},
218
241
  * invoked from {@link Shutdown} during the graceful ShutdownRegistry drain — closes this exact host
219
242
  * instance's own live sessions with `CloseReason = 'Shutdown'`.
220
243
  *
@@ -318,6 +341,39 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
318
341
  this.scheduleSweep();
319
342
  }
320
343
 
344
+ /**
345
+ * Starts the janitor the way the host's `agentSessions.janitor` settings ask: applies the interval
346
+ * and close threshold, then {@link Start} when enabled, or {@link StartRecoveryOnly} when not.
347
+ * Throws (before doing any work) on an invalid interval or threshold; see {@link Configure}.
348
+ */
349
+ public async StartWithSettings(settings: SessionJanitorSettings, provider: DatabaseProviderBase, systemUser: UserInfo): Promise<void> {
350
+ this.Configure({ sweepIntervalMs: settings.sweepIntervalMs, closeThresholdMinutes: settings.closeThresholdMinutes });
351
+ if (settings.enabled) {
352
+ await this.Start(provider, systemUser);
353
+ } else {
354
+ await this.StartRecoveryOnly(provider, systemUser);
355
+ }
356
+ }
357
+
358
+ /**
359
+ * {@link Start} without the periodic tick, for hosts that turned the janitor off: run own-host
360
+ * startup recovery once and register for the graceful-shutdown drain, but schedule nothing, so an
361
+ * idle process issues no periodic queries. Stale-session, max-duration and recording-recovery
362
+ * sweeps then do not run in this process. Stops a tick an earlier {@link Start} scheduled.
363
+ */
364
+ public async StartRecoveryOnly(provider: DatabaseProviderBase, systemUser: UserInfo): Promise<void> {
365
+ this.Stop();
366
+ this._provider = provider;
367
+ this._systemUser = systemUser;
368
+ this.ensureRegistered();
369
+ await this.RunStartupRecovery(provider, systemUser);
370
+ }
371
+
372
+ /** Whether the periodic tick is currently scheduled (diagnostics and tests). */
373
+ public get IsSweepScheduled(): boolean {
374
+ return this._sweepTimer !== null;
375
+ }
376
+
321
377
  /**
322
378
  * Stops the periodic tick and keeps any new recording recovery pass from starting until the next
323
379
  * {@link Start}, including one a tick already in progress would have started. A pass that is already
@@ -335,7 +391,7 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
335
391
  * {@link IShutdownable}: stop the timer, then drain this host's own live sessions so a
336
392
  * graceful stop never strands `Active`/`Idle` rows for the next boot's janitor to mop up, then wait
337
393
  * (at most {@link RECOVERY_SHUTDOWN_WAIT_MS}) for an in-flight recording recovery pass.
338
- * Drained sessions are stamped `CloseReason = 'Shutdown'` (vs. `'Janitor'` for crash orphans),
394
+ * Drained sessions are stamped `CloseReason = 'Shutdown'` (vs. `'Janitor'` for crash orphans from an earlier boot),
339
395
  * so the dashboards can tell a clean redeploy from a reconciled crash. Never throws; the drain
340
396
  * is skipped when {@link Start} was never called (no captured provider/user).
341
397
  */
@@ -360,7 +416,7 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
360
416
  public async RunShutdownDrain(provider: IMetadataProvider, systemUser: UserInfo): Promise<number> {
361
417
  const current = GetHostInstanceID().replace(/'/g, "''");
362
418
  const filter = `Status IN ('Active','Idle') AND HostInstanceID = '${current}'`;
363
- const closed = await this.sweepAndClose(filter, provider, systemUser, 'Shutdown');
419
+ const closed = await this.sweepAndClose(filter, provider, systemUser, () => 'Shutdown');
364
420
  if (closed > 0) {
365
421
  LogStatus(`[SessionJanitor] Shutdown drain closed ${closed} live session(s) owned by this host instance`);
366
422
  }
@@ -389,8 +445,9 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
389
445
  `AND HostInstanceID LIKE '${prefix}%' ` +
390
446
  `AND HostInstanceID <> '${current}'`;
391
447
  // The LIKE narrows the read; the exact check decides, since LIKE reads a `_` in a host name as any character.
392
- const isPriorBoot = (session: MJAIAgentSessionEntity): boolean => hostInstance.IsPriorBoot(session.HostInstanceID);
393
- const closed = await this.sweepAndClose(filter, provider, systemUser, 'Janitor', isPriorBoot);
448
+ const reasonFor = (session: MJAIAgentSessionEntity): SessionCloseReason | null =>
449
+ hostInstance.IsPriorBoot(session.HostInstanceID) ? 'Janitor' : null;
450
+ const closed = await this.sweepAndClose(filter, provider, systemUser, reasonFor);
394
451
  if (closed > 0) {
395
452
  LogStatus(
396
453
  `[SessionJanitor] Startup recovery closed ${closed} orphaned session(s) from an earlier boot of this instance ` +
@@ -402,12 +459,18 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
402
459
 
403
460
  /**
404
461
  * Force-close any `Active`/`Idle` session whose `LastActiveAt` is older than the configured
405
- * close threshold, regardless of host. Idempotent and concurrency-safe. Returns the count closed.
462
+ * close threshold, regardless of host. Stamped `'Idle'`, or `'TimeLimit'` when the row's authored deadline
463
+ * passed before its idle moment ({@link ExpiryCloseReason}). A row the SQL judged stale is never skipped:
464
+ * when its `LastActiveAt` will not parse it closes as `'Idle'` with a `LogError` ({@link staleRowCloseReason}).
465
+ * Idempotent and concurrency-safe. Returns the count closed.
406
466
  */
407
467
  public async RunStalenessSweep(provider: IMetadataProvider, systemUser: UserInfo): Promise<number> {
408
- const cutoffIso = new Date(Date.now() - this._config.closeThresholdMinutes * 60_000).toISOString();
468
+ // One clock read feeds both the SQL cutoff and the per-row decision, so they cannot disagree.
469
+ const nowMs = Date.now();
470
+ const thresholdMs = this._config.closeThresholdMinutes * 60_000;
471
+ const cutoffIso = new Date(nowMs - thresholdMs).toISOString();
409
472
  const filter = `Status IN ('Active','Idle') AND LastActiveAt < '${cutoffIso}'`;
410
- const closed = await this.sweepAndClose(filter, provider, systemUser, 'Janitor');
473
+ const closed = await this.sweepAndClose(filter, provider, systemUser, s => staleRowCloseReason(s, nowMs, thresholdMs));
411
474
  if (closed > 0) {
412
475
  LogStatus(`[SessionJanitor] Staleness sweep closed ${closed} stale session(s) (>${this._config.closeThresholdMinutes}m idle)`);
413
476
  }
@@ -422,20 +485,18 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
422
485
  *
423
486
  * Only sessions that CARRY a deadline are loaded (a cheap `Config_ LIKE` pre-filter), then the exact
424
487
  * ISO deadline is parsed and compared in JS (`Config_` is JSON, not a queryable column). Stamped
425
- * `CloseReason = 'Janitor'`, idempotent + concurrency-safe like the other sweeps. Returns the count closed.
488
+ * `'TimeLimit'`, or `'Idle'` when the row's idle moment passed before its deadline ({@link ExpiryCloseReason});
489
+ * idempotent + concurrency-safe like the other sweeps. Returns the count closed.
426
490
  */
427
491
  public async RunMaxDurationSweep(provider: IMetadataProvider, systemUser: UserInfo): Promise<number> {
428
492
  const nowMs = Date.now();
429
493
  // Only consider sessions that carry a deadline marker — keeps this sweep cheap (it never touches
430
494
  // the far-more-common uncapped sessions) while the JS check below enforces the exact deadline.
431
495
  const filter = `Status IN ('Active','Idle') AND Config LIKE '%maxSessionDeadlineIso%'`;
432
- const isExpired = (session: MJAIAgentSessionEntity): boolean => {
433
- const deadlineMs = this.parseSessionDeadlineMs(session.Config_);
434
- return deadlineMs != null && deadlineMs <= nowMs;
435
- };
436
- const closed = await this.sweepAndClose(filter, provider, systemUser, 'Janitor', isExpired);
496
+ const thresholdMs = this._config.closeThresholdMinutes * 60_000;
497
+ const closed = await this.sweepAndClose(filter, provider, systemUser, s => ExpiryCloseReason(s, nowMs, thresholdMs));
437
498
  if (closed > 0) {
438
- LogStatus(`[SessionJanitor] Max-duration sweep closed ${closed} session(s) past their hard duration cap`);
499
+ LogStatus(`[SessionJanitor] Max-duration sweep closed ${closed} capped session(s) past their deadline or idle threshold`);
439
500
  }
440
501
  return closed;
441
502
  }
@@ -647,9 +708,9 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
647
708
 
648
709
  /**
649
710
  * Gives a status-less session with ledger shards back a `Pending` status so it can be claimed (the
650
- * claim only takes Pending/Partial/stale Assembling). The status is lost when a `BaseEntity.Save` of
651
- * the session (e.g. its close) loaded the row before a shard or terminal proc wrote it and saved
652
- * after: `spUpdate` rewrites every column, so it puts back the stale NULL status and counts.
711
+ * claim only takes Pending/Partial/stale Assembling). That is how statuses were lost before #6010
712
+ * made the ledger columns not updatable through an entity save (a stale `Save` of the session, e.g. its
713
+ * close, put back the NULL status and counts). The restore stays for rows hit before then.
653
714
  *
654
715
  * The terminal proc is the existing way to set a NULL status to `Pending`. It is stamped with the
655
716
  * counts the session still stores, or 0 for a NULL count (the proc accepts any count over NULL), and
@@ -705,23 +766,6 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
705
766
  }
706
767
  }
707
768
 
708
- /** Parses the absolute deadline (ms) from a session's `Config_` JSON, or null when absent/malformed. */
709
- private parseSessionDeadlineMs(configJson: string | null | undefined): number | null {
710
- if (!configJson) {
711
- return null;
712
- }
713
- try {
714
- const parsed = JSON.parse(configJson) as { maxSessionDeadlineIso?: string };
715
- if (typeof parsed.maxSessionDeadlineIso !== 'string') {
716
- return null;
717
- }
718
- const ms = Date.parse(parsed.maxSessionDeadlineIso);
719
- return Number.isNaN(ms) ? null : ms;
720
- } catch {
721
- return null;
722
- }
723
- }
724
-
725
769
  // ----- internals -------------------------------------------------------------------------
726
770
 
727
771
  /** Register for graceful shutdown exactly once. */
@@ -993,7 +1037,9 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
993
1037
 
994
1038
  /**
995
1039
  * Page through every session matching `filter` with keyset (`AfterKey`) pagination and close each
996
- * via {@link SessionManager.CloseSession}, stamping `closeReason` on every row it transitions.
1040
+ * via {@link SessionManager.CloseSession}, stamping the reason `reasonFor` returns for that row.
1041
+ * A `null` reason skips the row (the SQL filter only narrows; `reasonFor` decides), and skipped rows
1042
+ * are dropped before the channel batch load so it covers only rows that will close.
997
1043
  * Returns the number successfully closed. A `Closed`-by-now row (raced by another instance) is a
998
1044
  * harmless no-op that keeps its original reason.
999
1045
  */
@@ -1001,30 +1047,34 @@ export class SessionJanitor extends BaseSingleton<SessionJanitor> implements ISh
1001
1047
  filter: string,
1002
1048
  provider: IMetadataProvider,
1003
1049
  systemUser: UserInfo,
1004
- closeReason: SessionCloseReason,
1005
- shouldClose?: (session: MJAIAgentSessionEntity) => boolean,
1050
+ reasonFor: (session: MJAIAgentSessionEntity) => SessionCloseReason | null,
1006
1051
  ): Promise<number> {
1007
1052
  let closedCount = 0;
1008
1053
  await this.forEachSessionPage(filter, provider, systemUser, async fetched => {
1009
- // Optional in-JS narrowing (e.g. exact deadline check the SQL pre-filter can't express).
1010
- const page = shouldClose ? fetched.filter(shouldClose) : fetched;
1011
- if (page.length === 0) {
1054
+ const toClose: Array<{ session: MJAIAgentSessionEntity; reason: SessionCloseReason }> = [];
1055
+ for (const session of fetched) {
1056
+ const reason = reasonFor(session);
1057
+ if (reason !== null) {
1058
+ toClose.push({ session, reason });
1059
+ }
1060
+ }
1061
+ if (toClose.length === 0) {
1012
1062
  return;
1013
1063
  }
1014
1064
  // Batch-load every channel for this whole page of sessions in ONE query, then hand each
1015
1065
  // session its own slice to CloseSession — avoids the N+1 channel read (one RunView per
1016
1066
  // closing session) that tripped the sequential / multiple-same-entity telemetry.
1017
1067
  const channelsBySession = await this.sessionManager.LoadActiveChannelsBySession(
1018
- page.map(s => s.ID),
1068
+ toClose.map(c => c.session.ID),
1019
1069
  systemUser,
1020
1070
  provider,
1021
1071
  );
1022
- for (const session of page) {
1072
+ for (const { session, reason } of toClose) {
1023
1073
  const closed = await this.sessionManager.CloseSession(
1024
1074
  session.ID,
1025
1075
  systemUser,
1026
1076
  provider,
1027
- closeReason,
1077
+ reason,
1028
1078
  channelsBySession.get(session.ID.toLowerCase()) ?? [],
1029
1079
  );
1030
1080
  if (closed) {
@@ -1,18 +1,21 @@
1
- import { IMetadataProvider, UserInfo, LogError, RunView } from '@memberjunction/core';
1
+ import { IMetadataProvider, UserInfo, LogError, LogStatus, RunView } from '@memberjunction/core';
2
2
  import { MJLruCache } from '@memberjunction/global';
3
3
  import {
4
4
  MJAIAgentSessionEntity,
5
5
  MJAIAgentSessionChannelEntity,
6
6
  MJConversationEntity,
7
7
  } from '@memberjunction/core-entities';
8
+ import { RunWithTrustedSessionConfigWrites } from '@memberjunction/core-entities-server';
8
9
  import { AIAgentPermissionHelper } from '@memberjunction/ai-engine-base';
9
10
  import { RealtimeClientSessionService, RealtimeChannelServerHost } from '@memberjunction/ai-agents';
10
11
  import type { BridgeDisconnectReason } from '@memberjunction/ai-bridge-base';
12
+ import { ParseSessionDeadlineMs, VerifyTimeLimitClaim } from './sessionDeadline.js';
11
13
  import { GetHostInstanceID } from './HostInstance.js';
12
14
  import { WriteReturningVisitorRecap } from './ReturningVisitorRecap.js';
13
15
  import { SessionRunIDVerifier, SessionRunIDs } from './SessionRunIDVerifier.js';
14
16
  import { ResolveScopedAnonymousRunUser } from '../realtimeWidget/widgetGuestElevation.js';
15
17
  import { RecordingAssemblyScheduler } from '../realtimeSessions/RecordingAssemblyScheduler.js';
18
+ import { ResolveSessionScopeIdentity } from '../realtimeSessions/sessionAccess.js';
16
19
 
17
20
  /** Entity names — centralised so the `MJ:`-prefix convention is applied in exactly one place. */
18
21
  const SESSION_ENTITY = 'MJ: AI Agent Sessions';
@@ -39,11 +42,14 @@ export interface CreateSessionInput {
39
42
  /**
40
43
  * Why a session was closed — persisted to `AIAgentSession.CloseReason` alongside the
41
44
  * `Status = 'Closed'` transition so the admin dashboards can distinguish a user hanging up
42
- * (`Explicit`) from janitor reconciliation (`Janitor`), a graceful host drain (`Shutdown`),
43
- * or a failure-path teardown (`Error`). `NULL` in the column means "legacy/unknown" — rows
44
- * closed before this column existed.
45
+ * (`Explicit`) from janitor reconciliation (`Janitor`, an orphan from an earlier boot), a graceful
46
+ * host drain (`Shutdown`), a failure-path teardown (`Error`), an expired authored deadline
47
+ * (`TimeLimit`) or a session left quiet past the idle threshold (`Idle`). `NULL` in the column means
48
+ * "legacy/unknown" — rows closed before this column existed.
49
+ *
50
+ * Derived from the generated entity so the column's CHECK constraint stays the single source of truth.
45
51
  */
46
- export type SessionCloseReason = 'Explicit' | 'Janitor' | 'Shutdown' | 'Error';
52
+ export type SessionCloseReason = NonNullable<MJAIAgentSessionEntity['CloseReason']>;
47
53
 
48
54
  /**
49
55
  * The {@link SessionCloseReason} for a session whose bridged agent has left (see
@@ -153,11 +159,13 @@ export class SessionManager {
153
159
  /**
154
160
  * Authorize and create a new session. Flow:
155
161
  * 1. `CanRun` check on the agent — denied → {@link SessionAuthorizationError}, no row written.
156
- * 2. Resolve the conversation (use the supplied one, or create+link a fresh Conversation).
162
+ * 2. Resolve the conversation (use the supplied one, or create+link a fresh Conversation). An anonymous
163
+ * caller may only supply a conversation stamped with its own scope identity.
157
164
  * 3. Persist the `AIAgentSession` as `Active`, stamped with this host and `LastActiveAt = now`.
158
165
  *
159
166
  * @returns the saved {@link MJAIAgentSessionEntity}.
160
- * @throws {SessionAuthorizationError} when the user may not run the agent.
167
+ * @throws {SessionAuthorizationError} when the user may not run the agent, or an anonymous caller supplies a
168
+ * conversation that is not its own.
161
169
  * @throws {Error} when conversation creation or session save fails.
162
170
  */
163
171
  public async CreateSession(
@@ -166,6 +174,9 @@ export class SessionManager {
166
174
  provider: IMetadataProvider,
167
175
  ): Promise<MJAIAgentSessionEntity> {
168
176
  await this.assertCanRun(input.agentID, contextUser);
177
+ if (input.conversationID && contextUser.IsMagicLinkAnonymous) {
178
+ await this.assertAnonymousOwnsConversation(input.conversationID, contextUser, provider);
179
+ }
169
180
 
170
181
  const conversationID = input.conversationID
171
182
  ?? await this.createConversation(input, contextUser, provider);
@@ -185,6 +196,8 @@ export class SessionManager {
185
196
  * call sites (the user-initiated close mutations) stamp the common case without modification;
186
197
  * background callers (janitor sweeps, shutdown drain, error teardowns) must pass their reason
187
198
  * explicitly. `NULL` rows remain only for legacy data closed before the column existed.
199
+ * A `'TimeLimit'` is verified against the session's stored deadline ({@link VerifyTimeLimitClaim}); a claim the
200
+ * deadline does not back is recorded as `'Explicit'` and logged, never refused.
188
201
  *
189
202
  * @remarks P5 adds in-flight-run abort + `ClientToolRequestManager.ClearSession` here.
190
203
  */
@@ -209,7 +222,9 @@ export class SessionManager {
209
222
  return true;
210
223
  }
211
224
 
212
- const closed = await this.markSessionClosed(session, closeReason);
225
+ // Verified once: the stamped reason and the plugin notification must agree, so a client's unbacked claim steers neither.
226
+ const verifiedReason = this.verifiedCloseReason(session, closeReason);
227
+ const closed = await this.markSessionClosed(session, verifiedReason);
213
228
  if (!closed) {
214
229
  return false;
215
230
  }
@@ -222,7 +237,7 @@ export class SessionManager {
222
237
  }
223
238
  await this.disconnectChannels(agentSessionID, contextUser, provider, preloadedChannels);
224
239
  await this.finalizeObservabilityRuns(session, contextUser, provider);
225
- await this.notifyChannelPluginsSessionClosed(agentSessionID, closeReason);
240
+ await this.notifyChannelPluginsSessionClosed(agentSessionID, verifiedReason);
226
241
  // Returning-visitor recap (RV2): if this session's conversation is returning-visitor-enabled,
227
242
  // summarize it into an Active memory note so the visitor's next session opens with prior context.
228
243
  // Best-effort + no-op for non-returning-visitor conversations; never blocks teardown.
@@ -230,6 +245,25 @@ export class SessionManager {
230
245
  return true;
231
246
  }
232
247
 
248
+ /**
249
+ * Returns the reason to stamp: a `'TimeLimit'` claim the session's stored deadline does not back becomes
250
+ * `'Explicit'` (logged with the stored deadline); every other reason passes through.
251
+ */
252
+ private verifiedCloseReason(session: MJAIAgentSessionEntity, closeReason: SessionCloseReason): SessionCloseReason {
253
+ if (closeReason !== 'TimeLimit') {
254
+ return closeReason;
255
+ }
256
+ const verified = VerifyTimeLimitClaim(session, Date.now());
257
+ if (verified === 'Explicit') {
258
+ const deadlineMs = ParseSessionDeadlineMs(session.Config_);
259
+ LogStatus(
260
+ `SessionManager.CloseSession: TimeLimit claim for session ${session.ID} not backed by its stored deadline ` +
261
+ `(${deadlineMs === null ? 'none stored' : new Date(deadlineMs).toISOString()}); closing as Explicit.`,
262
+ );
263
+ }
264
+ return verified;
265
+ }
266
+
233
267
  /**
234
268
  * Closes a session that was created for one bridged agent (a bot in a meeting room) once that agent's bridge has
235
269
  * ended, whatever ended it: the agent was stopped, the meeting was ended, everyone left, the model session was lost.
@@ -448,6 +482,23 @@ export class SessionManager {
448
482
 
449
483
  // ----- internals -------------------------------------------------------------------------
450
484
 
485
+ /**
486
+ * Throws {@link SessionAuthorizationError} unless the anonymous caller owns the conversation it wants to bind a
487
+ * new session to: the conversation, read as the caller, loads, and its `ExternalID` equals the caller's scope
488
+ * identity ({@link ResolveSessionScopeIdentity}). A caller with no scope identity is refused. Every anonymous
489
+ * visitor shares one Anonymous user, so row-level security alone may let one visitor read another's
490
+ * conversation; without this check the new session row and its relays would point into that conversation.
491
+ */
492
+ private async assertAnonymousOwnsConversation(conversationID: string, contextUser: UserInfo, provider: IMetadataProvider): Promise<void> {
493
+ const conversation = await provider.GetEntityObject<MJConversationEntity>(CONVERSATION_ENTITY, contextUser);
494
+ const loaded = await conversation.Load(conversationID);
495
+ const scopeIdentity = ResolveSessionScopeIdentity(contextUser);
496
+ if (!loaded || !scopeIdentity || conversation.ExternalID !== scopeIdentity) {
497
+ LogError(`SessionManager.CreateSession: refused anonymous user ${contextUser.ID} binding a session to conversation ${conversationID} (${loaded ? 'not its own' : 'not readable'}).`);
498
+ throw new SessionAuthorizationError('Not authorized to start a session on this conversation.');
499
+ }
500
+ }
501
+
451
502
  /** Throws {@link SessionAuthorizationError} unless the user has `CanRun` on the agent. */
452
503
  private async assertCanRun(agentID: string, contextUser: UserInfo): Promise<void> {
453
504
  const canRun = await AIAgentPermissionHelper.HasPermission(agentID, contextUser, 'run');
@@ -468,13 +519,13 @@ export class SessionManager {
468
519
  conversation.NewRecord();
469
520
  conversation.UserID = input.userID;
470
521
  conversation.Name = 'Agent Session';
471
- // For a magic-link-anonymous principal (e.g. a public web-widget voice guest), stamp the
472
- // session's conversation with the signed per-session scope so the Widget Guest RLS filters
473
- // ({{ScopeResourceID}}) isolate this session — and everything chained to it (AI Agent
474
- // Sessions via ConversationID, Session Channels via the session) — from other guests
475
- // sharing the Anonymous UserID. No-op for named principals (no scope → default ExternalID).
476
- if (contextUser.MagicLinkScope?.ResourceID) {
477
- conversation.ExternalID = contextUser.MagicLinkScope.ResourceID;
522
+ // Stamp the scope identity AuthorizeSessionAccess compares against (one rule, one place:
523
+ // ResolveSessionScopeIdentity) — the token's resource scope when it has one, else an anonymous
524
+ // visitor's mj_sid. This isolates anonymous visitors that share the Anonymous UserID, and keeps
525
+ // the {{ScopeResourceID}} RLS filters matching the visitor's own rows. No-op for unscoped named principals.
526
+ const scopeIdentity = ResolveSessionScopeIdentity(contextUser);
527
+ if (scopeIdentity) {
528
+ conversation.ExternalID = scopeIdentity;
478
529
  }
479
530
 
480
531
  // Returning-visitor memory (RV1/RV2/RV4) for the VOICE path: the widget guest token carries the
@@ -539,9 +590,9 @@ export class SessionManager {
539
590
  }
540
591
 
541
592
  /**
542
- * Loads a session entity by ID, returning null when it cannot be loaded. The server entity
543
- * (`MJAIAgentSessionEntityServer`) keeps the lifecycle saves that follow from writing back the
544
- * recording ledger's columns (#5294).
593
+ * Loads a session entity by ID, returning null when it cannot be loaded. The lifecycle saves that
594
+ * follow cannot write back the recording ledger's columns: those have `AllowUpdateAPI=0`, so they are
595
+ * not parameters of `spUpdateAIAgentSession` (#5294, #6010).
545
596
  */
546
597
  private async loadSession(
547
598
  agentSessionID: string,
@@ -561,7 +612,9 @@ export class SessionManager {
561
612
  session.Status = 'Closed';
562
613
  session.ClosedAt = new Date();
563
614
  session.CloseReason = closeReason;
564
- return this.saveOrLog(session, 'CloseSession');
615
+ // The session entity refuses a server-only CloseReason from an untrusted save; this is the server's own
616
+ // (already verified) close, so it saves inside the trusted session-write scope.
617
+ return RunWithTrustedSessionConfigWrites(() => this.saveOrLog(session, 'CloseSession'));
565
618
  }
566
619
 
567
620
  /** Marks every channel row of the session `Disconnected` (with `DisconnectedAt`), if not already. */
@@ -0,0 +1,143 @@
1
+ /**
2
+ * @fileoverview The remote browsers this process holds for TEXT conversations: who owns each and when it
3
+ * was last used. Backs the caps (`realtime.conversationBrowser.maxPerUser` and `maxAnonymousTotal`) and ends browsers
4
+ * nobody uses any more, since a reloaded or closed tab never ends its own
5
+ * (`realtime.conversationBrowser.idleMinutes`). Realtime calls' browsers are not tracked here: they end
6
+ * with their session.
7
+ *
8
+ * @module @memberjunction/server/agentSessions
9
+ */
10
+ import { GraphQLError } from 'graphql';
11
+ import { LogError, LogStatus } from '@memberjunction/core';
12
+ import { BaseSingleton, IShutdownable, ShutdownRegistry } from '@memberjunction/global';
13
+ import { RemoteBrowserEngine } from '@memberjunction/remote-browser-server';
14
+ import type { ConversationBrowserConfig } from '../config.js';
15
+
16
+ /** How often idle conversation browsers are looked for. */
17
+ const REAP_INTERVAL_MS = 60_000;
18
+
19
+ /** The `extensions.code` of a {@link RemoteBrowserRefusedError}, which a client reads to stop asking. */
20
+ export const REMOTE_BROWSER_REFUSED = 'REMOTE_BROWSER_REFUSED';
21
+
22
+ /**
23
+ * A remote-browser request this server refuses however often it is asked: browsers not enabled, a session
24
+ * that is not the caller's or does not exist, or a cap reached.
25
+ */
26
+ export class RemoteBrowserRefusedError extends GraphQLError {
27
+ constructor(message: string) {
28
+ super(message, { extensions: { code: REMOTE_BROWSER_REFUSED } });
29
+ this.name = 'RemoteBrowserRefusedError';
30
+ }
31
+ }
32
+
33
+ /** Who a conversation browser counts against: a user, or an anonymous guest's own scope. */
34
+ export interface ConversationBrowserOwner {
35
+ Key: string;
36
+ Anonymous: boolean;
37
+ }
38
+
39
+ interface HeldBrowser {
40
+ Owner: ConversationBrowserOwner;
41
+ LastUsedAt: number;
42
+ IdleMs: number;
43
+ }
44
+
45
+ export class ConversationBrowserLedger extends BaseSingleton<ConversationBrowserLedger> implements IShutdownable {
46
+ public readonly ShutdownName = 'ConversationBrowserLedger';
47
+ private readonly held = new Map<string, HeldBrowser>();
48
+ private reapTimer: ReturnType<typeof setInterval> | null = null;
49
+
50
+ /**
51
+ * How an idle browser is ended. The resolver points this at its own end path, so a reaped browser
52
+ * leaves no stream bookkeeping behind; until then the engine ends it directly.
53
+ */
54
+ public EndBrowser: (conversationID: string) => Promise<unknown> = (conversationID) =>
55
+ RemoteBrowserEngine.Instance.EndSessionForAgentSession(conversationID);
56
+
57
+ protected constructor() {
58
+ super();
59
+ }
60
+
61
+ public static get Instance(): ConversationBrowserLedger {
62
+ return super.getInstance<ConversationBrowserLedger>();
63
+ }
64
+
65
+ /**
66
+ * Records that a conversation's browser is about to be used. A conversation the ledger does not hold
67
+ * yet counts against its owner's cap and, for an anonymous guest, against the cap all guests share: a
68
+ * guest can start a new scope cheaply, so its own cap alone bounds nothing.
69
+ *
70
+ * @throws RemoteBrowserRefusedError when the owner already holds `maxPerUser` conversation browsers, or
71
+ * guests together already hold `maxAnonymousTotal`.
72
+ */
73
+ public Claim(conversationID: string, owner: ConversationBrowserOwner, limits: Pick<ConversationBrowserConfig, 'maxPerUser' | 'maxAnonymousTotal' | 'idleMinutes'>): void {
74
+ const key = conversationID.toLowerCase();
75
+ if (!this.held.has(key)) {
76
+ const held = Array.from(this.held.values());
77
+ const count = held.filter((b) => b.Owner.Key === owner.Key).length;
78
+ if (count >= limits.maxPerUser) {
79
+ throw new RemoteBrowserRefusedError(`You already have ${count} conversation browser(s) open, the most this server allows. Close one first.`);
80
+ }
81
+ if (owner.Anonymous && held.filter((b) => b.Owner.Anonymous).length >= limits.maxAnonymousTotal) {
82
+ throw new RemoteBrowserRefusedError('Every conversation browser this server allows for guests is in use. Try again later.');
83
+ }
84
+ }
85
+ this.held.set(key, { Owner: owner, LastUsedAt: Date.now(), IdleMs: limits.idleMinutes * 60_000 });
86
+ this.startReaper();
87
+ }
88
+
89
+ /** Marks a held browser as used (an action, a snapshot poll, human input), which puts off its idle end. */
90
+ public Touch(conversationID: string): void {
91
+ const browser = this.held.get(conversationID.toLowerCase());
92
+ if (browser) {
93
+ browser.LastUsedAt = Date.now();
94
+ }
95
+ }
96
+
97
+ /** Forgets a conversation's browser once it has been ended. */
98
+ public Release(conversationID: string): void {
99
+ this.held.delete(conversationID.toLowerCase());
100
+ }
101
+
102
+ /** Ends every held browser unused for longer than its idle limit. Returns how many were ended. */
103
+ public async ReapIdle(): Promise<number> {
104
+ const now = Date.now();
105
+ const idle = Array.from(this.held).filter(([, b]) => now - b.LastUsedAt > b.IdleMs).map(([id]) => id);
106
+ for (const conversationID of idle) {
107
+ this.held.delete(conversationID);
108
+ try {
109
+ await this.EndBrowser(conversationID);
110
+ } catch (err) {
111
+ LogError(`[ConversationBrowsers] Failed to end the idle browser of conversation ${conversationID}: ${err instanceof Error ? err.message : String(err)}`);
112
+ }
113
+ }
114
+ if (idle.length > 0) {
115
+ LogStatus(`[ConversationBrowsers] Ended ${idle.length} idle conversation browser(s).`);
116
+ }
117
+ return idle.length;
118
+ }
119
+
120
+ /** Ends every held browser on a graceful shutdown, so none outlives the server. Idempotent. */
121
+ public async Shutdown(): Promise<void> {
122
+ if (this.reapTimer) {
123
+ clearInterval(this.reapTimer);
124
+ this.reapTimer = null;
125
+ }
126
+ const held = Array.from(this.held.keys());
127
+ this.held.clear();
128
+ await Promise.allSettled(held.map((conversationID) => this.EndBrowser(conversationID)));
129
+ }
130
+
131
+ /**
132
+ * One unref'd timer per process, started with the first browser, so the reaper costs nothing until then.
133
+ * The ledger joins the graceful shutdown at the same time.
134
+ */
135
+ private startReaper(): void {
136
+ if (this.reapTimer) {
137
+ return;
138
+ }
139
+ this.reapTimer = setInterval(() => void this.ReapIdle(), REAP_INTERVAL_MS);
140
+ this.reapTimer.unref?.();
141
+ ShutdownRegistry.Instance.Register(this);
142
+ }
143
+ }