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

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 (463) hide show
  1. package/README.md +69 -0
  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 +31 -8
  14. package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
  15. package/dist/agentSessions/SessionJanitor.js +85 -41
  16. package/dist/agentSessions/SessionJanitor.js.map +1 -1
  17. package/dist/agentSessions/SessionManager.d.ts +14 -4
  18. package/dist/agentSessions/SessionManager.d.ts.map +1 -1
  19. package/dist/agentSessions/SessionManager.js +28 -4
  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/loginEmailResolution.d.ts +41 -0
  33. package/dist/auth/loginEmailResolution.d.ts.map +1 -0
  34. package/dist/auth/loginEmailResolution.js +47 -0
  35. package/dist/auth/loginEmailResolution.js.map +1 -0
  36. package/dist/auth/magicLink/MagicLinkKeys.d.ts +50 -2
  37. package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
  38. package/dist/auth/magicLink/MagicLinkKeys.js +129 -12
  39. package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
  40. package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
  41. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  42. package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
  43. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  44. package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
  45. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  46. package/dist/auth/magicLink/MagicLinkService.js +221 -9
  47. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  48. package/dist/auth/magicLink/index.d.ts +1 -1
  49. package/dist/auth/magicLink/index.d.ts.map +1 -1
  50. package/dist/auth/magicLink/index.js +1 -1
  51. package/dist/auth/magicLink/index.js.map +1 -1
  52. package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
  53. package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
  54. package/dist/auth/magicLink/redeemLanding.js +7 -4
  55. package/dist/auth/magicLink/redeemLanding.js.map +1 -1
  56. package/dist/auth/magicLink/types.d.ts +27 -3
  57. package/dist/auth/magicLink/types.d.ts.map +1 -1
  58. package/dist/auth/magicLink/types.js +0 -4
  59. package/dist/auth/magicLink/types.js.map +1 -1
  60. package/dist/auth/newUsers.d.ts.map +1 -1
  61. package/dist/auth/newUsers.js +1 -0
  62. package/dist/auth/newUsers.js.map +1 -1
  63. package/dist/backgroundSweepConfigUnits.d.ts +231 -0
  64. package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
  65. package/dist/backgroundSweepConfigUnits.js +180 -0
  66. package/dist/backgroundSweepConfigUnits.js.map +1 -0
  67. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -1
  68. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +2 -1
  69. package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -1
  70. package/dist/config.d.ts +906 -8
  71. package/dist/config.d.ts.map +1 -1
  72. package/dist/config.js +59 -0
  73. package/dist/config.js.map +1 -1
  74. package/dist/context.d.ts +2 -0
  75. package/dist/context.d.ts.map +1 -1
  76. package/dist/context.js +41 -12
  77. package/dist/context.js.map +1 -1
  78. package/dist/coreRoutes.d.ts +3 -1
  79. package/dist/coreRoutes.d.ts.map +1 -1
  80. package/dist/coreRoutes.js +6 -4
  81. package/dist/coreRoutes.js.map +1 -1
  82. package/dist/generated/graphql-schemas/__mj.d.ts +1072 -5
  83. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  84. package/dist/generated/graphql-schemas/__mj.js +10174 -4618
  85. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  86. package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
  87. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
  88. package/dist/generic/OrphanedConversationDetailReconciler.js +27 -1
  89. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
  90. package/dist/generic/ResolverBase.d.ts +50 -5
  91. package/dist/generic/ResolverBase.d.ts.map +1 -1
  92. package/dist/generic/ResolverBase.js +329 -132
  93. package/dist/generic/ResolverBase.js.map +1 -1
  94. package/dist/generic/RunViewResolver.d.ts +4 -0
  95. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  96. package/dist/generic/RunViewResolver.js +47 -7
  97. package/dist/generic/RunViewResolver.js.map +1 -1
  98. package/dist/globalCors.d.ts.map +1 -1
  99. package/dist/globalCors.js +1 -0
  100. package/dist/globalCors.js.map +1 -1
  101. package/dist/index.d.ts +3 -0
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js +201 -43
  104. package/dist/index.js.map +1 -1
  105. package/dist/integration/ConnectionPause.d.ts +121 -0
  106. package/dist/integration/ConnectionPause.d.ts.map +1 -0
  107. package/dist/integration/ConnectionPause.js +183 -0
  108. package/dist/integration/ConnectionPause.js.map +1 -0
  109. package/dist/integration/CustomColumnPromoter.d.ts +72 -6
  110. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  111. package/dist/integration/CustomColumnPromoter.js +87 -46
  112. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  113. package/dist/integration/EntityMapLifecycle.d.ts +78 -4
  114. package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
  115. package/dist/integration/EntityMapLifecycle.js +199 -5
  116. package/dist/integration/EntityMapLifecycle.js.map +1 -1
  117. package/dist/integration/InactiveRowWarnings.d.ts +31 -0
  118. package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
  119. package/dist/integration/InactiveRowWarnings.js +29 -0
  120. package/dist/integration/InactiveRowWarnings.js.map +1 -1
  121. package/dist/integration/ObjectNamesByID.d.ts +28 -0
  122. package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
  123. package/dist/integration/ObjectNamesByID.js +87 -0
  124. package/dist/integration/ObjectNamesByID.js.map +1 -0
  125. package/dist/integration/PostRestartIntrospect.d.ts +26 -0
  126. package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
  127. package/dist/integration/PostRestartIntrospect.js +27 -0
  128. package/dist/integration/PostRestartIntrospect.js.map +1 -0
  129. package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
  130. package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
  131. package/dist/integration/RSUPostRestartProgress.js +323 -0
  132. package/dist/integration/RSUPostRestartProgress.js.map +1 -0
  133. package/dist/integration/RSUProgressBridge.d.ts +41 -2
  134. package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
  135. package/dist/integration/RSUProgressBridge.js +84 -1
  136. package/dist/integration/RSUProgressBridge.js.map +1 -1
  137. package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
  138. package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
  139. package/dist/integration/RunArtifactAuthorization.js +45 -0
  140. package/dist/integration/RunArtifactAuthorization.js.map +1 -0
  141. package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
  142. package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
  143. package/dist/integration/SchemaRefreshLaunch.js +3 -2
  144. package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
  145. package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
  146. package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
  147. package/dist/integration/ScopedFieldsForBuild.js +91 -0
  148. package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
  149. package/dist/integration/TargetConfigGuard.d.ts +40 -0
  150. package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
  151. package/dist/integration/TargetConfigGuard.js +40 -0
  152. package/dist/integration/TargetConfigGuard.js.map +1 -0
  153. package/dist/logging/StartupLogger.d.ts +50 -0
  154. package/dist/logging/StartupLogger.d.ts.map +1 -1
  155. package/dist/logging/StartupLogger.js +15 -22
  156. package/dist/logging/StartupLogger.js.map +1 -1
  157. package/dist/middleware/BaseServerMiddleware.d.ts +21 -3
  158. package/dist/middleware/BaseServerMiddleware.d.ts.map +1 -1
  159. package/dist/middleware/BaseServerMiddleware.js +4 -2
  160. package/dist/middleware/BaseServerMiddleware.js.map +1 -1
  161. package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
  162. package/dist/realtimeSessions/ownedRealtimeSession.js +2 -3
  163. package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
  164. package/dist/realtimeSessions/sessionAccess.d.ts +15 -0
  165. package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
  166. package/dist/realtimeSessions/sessionAccess.js +22 -0
  167. package/dist/realtimeSessions/sessionAccess.js.map +1 -1
  168. package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
  169. package/dist/realtimeWidget/WidgetSessionService.js +2 -0
  170. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  171. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
  172. package/dist/realtimeWidget/visitorIdentity.js +1 -0
  173. package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
  174. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  175. package/dist/realtimeWidget/widgetCore.js +4 -7
  176. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  177. package/dist/realtimeWidget/widgetGuestElevation.js +1 -0
  178. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  179. package/dist/requestOrigin.d.ts +22 -0
  180. package/dist/requestOrigin.d.ts.map +1 -0
  181. package/dist/requestOrigin.js +60 -0
  182. package/dist/requestOrigin.js.map +1 -0
  183. package/dist/resolvers/AgentRunStatusPublisher.d.ts +10 -0
  184. package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
  185. package/dist/resolvers/AgentRunStatusPublisher.js +18 -2
  186. package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
  187. package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
  188. package/dist/resolvers/AgentSessionResolver.js +6 -2
  189. package/dist/resolvers/AgentSessionResolver.js.map +1 -1
  190. package/dist/resolvers/AutotagPipelineResolver.d.ts +1 -1
  191. package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
  192. package/dist/resolvers/AutotagPipelineResolver.js +61 -16
  193. package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
  194. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
  195. package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
  196. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
  197. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +6 -0
  198. package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
  199. package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
  200. package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
  201. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  202. package/dist/resolvers/GetDataResolver.js +34 -13
  203. package/dist/resolvers/GetDataResolver.js.map +1 -1
  204. package/dist/resolvers/InfoResolver.js +1 -1
  205. package/dist/resolvers/InfoResolver.js.map +1 -1
  206. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
  207. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  208. package/dist/resolvers/IntegrationDiscoveryResolver.js +2690 -1305
  209. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  210. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  211. package/dist/resolvers/MCPResolver.js +13 -2
  212. package/dist/resolvers/MCPResolver.js.map +1 -1
  213. package/dist/resolvers/QuerySystemUserResolver.d.ts +38 -1
  214. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  215. package/dist/resolvers/QuerySystemUserResolver.js +181 -88
  216. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  217. package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
  218. package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
  219. package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
  220. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +6 -0
  221. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  222. package/dist/resolvers/RealtimeClientSessionResolver.js +36 -5
  223. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  224. package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
  225. package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
  226. package/dist/resolvers/RemoteBrowserActionResolver.js +217 -34
  227. package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
  228. package/dist/resolvers/RunAIAgentResolver.d.ts +24 -8
  229. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  230. package/dist/resolvers/RunAIAgentResolver.js +185 -67
  231. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  232. package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
  233. package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
  234. package/dist/resolvers/RunAIPromptResolver.js +19 -18
  235. package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
  236. package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
  237. package/dist/resolvers/RunTemplateResolver.js +3 -1
  238. package/dist/resolvers/RunTemplateResolver.js.map +1 -1
  239. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  240. package/dist/resolvers/SqlLoggingConfigResolver.js +7 -8
  241. package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
  242. package/dist/resolvers/TagGovernanceResolver.d.ts +12 -0
  243. package/dist/resolvers/TagGovernanceResolver.d.ts.map +1 -1
  244. package/dist/resolvers/TagGovernanceResolver.js +84 -0
  245. package/dist/resolvers/TagGovernanceResolver.js.map +1 -1
  246. package/dist/resolvers/TelemetryResolver.d.ts +13 -8
  247. package/dist/resolvers/TelemetryResolver.d.ts.map +1 -1
  248. package/dist/resolvers/TelemetryResolver.js +40 -9
  249. package/dist/resolvers/TelemetryResolver.js.map +1 -1
  250. package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
  251. package/dist/resolvers/meetingRecordingRegistration.js +2 -0
  252. package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
  253. package/dist/resolvers/meetings/meetingMutations.d.ts.map +1 -1
  254. package/dist/resolvers/meetings/meetingMutations.js +34 -4
  255. package/dist/resolvers/meetings/meetingMutations.js.map +1 -1
  256. package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
  257. package/dist/rest/MediaAccessKeys.js +6 -2
  258. package/dist/rest/MediaAccessKeys.js.map +1 -1
  259. package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
  260. package/dist/rest/OAuthCallbackHandler.js +11 -5
  261. package/dist/rest/OAuthCallbackHandler.js.map +1 -1
  262. package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
  263. package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
  264. package/dist/rest/RealtimeRecordingHandler.js +2 -4
  265. package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
  266. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  267. package/dist/rest/ViewOperationsHandler.js +2 -1
  268. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  269. package/dist/rest/setupRESTEndpoints.d.ts +3 -1
  270. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  271. package/dist/rest/setupRESTEndpoints.js +11 -2
  272. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  273. package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
  274. package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
  275. package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
  276. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  277. package/dist/services/TaskGraphActionRunner.js +2 -26
  278. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  279. package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
  280. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  281. package/dist/services/TaskGraphAgentRunner.js +38 -0
  282. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  283. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  284. package/dist/services/TaskGraphContinuationDeliverer.js +1 -0
  285. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  286. package/dist/services/WorkQueueHostService.d.ts +2 -1
  287. package/dist/services/WorkQueueHostService.d.ts.map +1 -1
  288. package/dist/services/WorkQueueHostService.js +19 -4
  289. package/dist/services/WorkQueueHostService.js.map +1 -1
  290. package/dist/services/workQueueConfig.d.ts +2 -2
  291. package/dist/services/workQueueConfig.js +5 -5
  292. package/dist/services/workQueueConfig.js.map +1 -1
  293. package/dist/sharedCache.js +1 -1
  294. package/dist/sharedCache.js.map +1 -1
  295. package/dist/types.d.ts +17 -0
  296. package/dist/types.d.ts.map +1 -1
  297. package/dist/types.js.map +1 -1
  298. package/dist/util.d.ts.map +1 -1
  299. package/dist/util.js +55 -2
  300. package/dist/util.js.map +1 -1
  301. package/package.json +107 -100
  302. package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
  303. package/src/__tests__/ActiveOperations.test.ts +68 -0
  304. package/src/__tests__/AgentSessionResolver.ownership.test.ts +13 -0
  305. package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
  306. package/src/__tests__/BatchApplyParity.test.ts +109 -0
  307. package/src/__tests__/BridgeHostInstance.test.ts +42 -0
  308. package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
  309. package/src/__tests__/ConnectionPause.test.ts +192 -0
  310. package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
  311. package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
  312. package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
  313. package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
  314. package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
  315. package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
  316. package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
  317. package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
  318. package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
  319. package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
  320. package/src/__tests__/MagicLinkKeys.test.ts +102 -0
  321. package/src/__tests__/MediaAccessKeys.test.ts +57 -10
  322. package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
  323. package/src/__tests__/ObjectNamesByID.test.ts +176 -0
  324. package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
  325. package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
  326. package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
  327. package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
  328. package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
  329. package/src/__tests__/RSUProgressBridge.test.ts +188 -5
  330. package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
  331. package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
  332. package/src/__tests__/RealtimeClientSessionResolver.test.ts +22 -0
  333. package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
  334. package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
  335. package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
  336. package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +6 -4
  337. package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
  338. package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
  339. package/src/__tests__/ResolverBase.clientOldValues.test.ts +327 -26
  340. package/src/__tests__/ResolverBase.diagnosticSenderRegistrations.test.ts +26 -0
  341. package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
  342. package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +53 -2
  343. package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +60 -0
  344. package/src/__tests__/RunAIAgentResolver.branch.test.ts +4 -0
  345. package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
  346. package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
  347. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +2 -0
  348. package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +2 -0
  349. package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +87 -12
  350. package/src/__tests__/RunAIAgentResolver.streaming.test.ts +28 -4
  351. package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
  352. package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
  353. package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
  354. package/src/__tests__/SessionJanitor.test.ts +195 -4
  355. package/src/__tests__/SessionManager.test.ts +69 -0
  356. package/src/__tests__/TagGovernanceAndAutotagResolvers.test.ts +261 -0
  357. package/src/__tests__/TagGovernanceResolver.test.ts +60 -2
  358. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
  359. package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
  360. package/src/__tests__/ViewOperationsHandler.test.ts +2 -5
  361. package/src/__tests__/WorkQueueHostService.test.ts +25 -7
  362. package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
  363. package/src/__tests__/contextRequestOrigin.test.ts +105 -0
  364. package/src/__tests__/conversationBrowsers.test.ts +62 -0
  365. package/src/__tests__/globalCors.test.ts +12 -0
  366. package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
  367. package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
  368. package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
  369. package/src/__tests__/realtimeRecordingHandler.test.ts +7 -2
  370. package/src/__tests__/realtimeSessions/sessionAccess.test.ts +79 -1
  371. package/src/__tests__/requestOrigin.test.ts +104 -0
  372. package/src/__tests__/review-capture-valid-token-log.test.ts +98 -0
  373. package/src/__tests__/runStreams.fieldSecurity.test.ts +5 -5
  374. package/src/__tests__/securityHardeningPr6034.test.ts +120 -0
  375. package/src/__tests__/sessionDeadline.test.ts +51 -0
  376. package/src/__tests__/sharedCache.test.ts +11 -0
  377. package/src/__tests__/unifiedAuth.test.ts +73 -1
  378. package/src/agentSessions/BridgeHostInstance.ts +20 -5
  379. package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
  380. package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
  381. package/src/agentSessions/SessionJanitor.ts +92 -42
  382. package/src/agentSessions/SessionManager.ts +38 -8
  383. package/src/agentSessions/conversationBrowsers.ts +143 -0
  384. package/src/agentSessions/sessionDeadline.ts +81 -0
  385. package/src/auth/APIKeyScopeAuth.ts +5 -4
  386. package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
  387. package/src/auth/loginEmailResolution.ts +67 -0
  388. package/src/auth/magicLink/MagicLinkKeys.ts +146 -14
  389. package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
  390. package/src/auth/magicLink/MagicLinkService.ts +250 -10
  391. package/src/auth/magicLink/index.ts +1 -1
  392. package/src/auth/magicLink/redeemLanding.ts +7 -4
  393. package/src/auth/magicLink/types.ts +28 -3
  394. package/src/auth/newUsers.ts +1 -0
  395. package/src/backgroundSweepConfigUnits.ts +213 -0
  396. package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +2 -1
  397. package/src/config.ts +69 -0
  398. package/src/context.ts +46 -15
  399. package/src/coreRoutes.ts +14 -7
  400. package/src/generated/graphql-schemas/__mj.ts +10360 -6479
  401. package/src/generic/OrphanedConversationDetailReconciler.ts +32 -1
  402. package/src/generic/ResolverBase.ts +422 -143
  403. package/src/generic/RunViewResolver.ts +96 -49
  404. package/src/globalCors.ts +1 -0
  405. package/src/index.ts +246 -44
  406. package/src/integration/ConnectionPause.ts +222 -0
  407. package/src/integration/CustomColumnPromoter.ts +123 -53
  408. package/src/integration/EntityMapLifecycle.ts +229 -6
  409. package/src/integration/InactiveRowWarnings.ts +50 -0
  410. package/src/integration/ObjectNamesByID.ts +97 -0
  411. package/src/integration/PostRestartIntrospect.ts +49 -0
  412. package/src/integration/RSUPostRestartProgress.ts +359 -0
  413. package/src/integration/RSUProgressBridge.ts +85 -2
  414. package/src/integration/RunArtifactAuthorization.ts +65 -0
  415. package/src/integration/SchemaRefreshLaunch.ts +12 -2
  416. package/src/integration/ScopedFieldsForBuild.ts +113 -0
  417. package/src/integration/TargetConfigGuard.ts +71 -0
  418. package/src/logging/StartupLogger.ts +24 -0
  419. package/src/middleware/BaseServerMiddleware.ts +20 -3
  420. package/src/realtimeSessions/ownedRealtimeSession.ts +2 -6
  421. package/src/realtimeSessions/sessionAccess.ts +30 -0
  422. package/src/realtimeWidget/WidgetSessionService.ts +2 -0
  423. package/src/realtimeWidget/visitorIdentity.ts +1 -0
  424. package/src/realtimeWidget/widgetCore.ts +4 -8
  425. package/src/realtimeWidget/widgetGuestElevation.ts +1 -0
  426. package/src/requestOrigin.ts +64 -0
  427. package/src/resolvers/AgentRunStatusPublisher.ts +27 -2
  428. package/src/resolvers/AgentSessionResolver.ts +6 -2
  429. package/src/resolvers/AutotagPipelineResolver.ts +59 -14
  430. package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
  431. package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
  432. package/src/resolvers/GetDataResolver.ts +35 -13
  433. package/src/resolvers/InfoResolver.ts +1 -1
  434. package/src/resolvers/IntegrationDiscoveryResolver.ts +1522 -203
  435. package/src/resolvers/MCPResolver.ts +15 -2
  436. package/src/resolvers/QuerySystemUserResolver.ts +211 -100
  437. package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
  438. package/src/resolvers/RealtimeClientSessionResolver.ts +40 -7
  439. package/src/resolvers/RemoteBrowserActionResolver.ts +242 -32
  440. package/src/resolvers/RunAIAgentResolver.ts +265 -86
  441. package/src/resolvers/RunAIPromptResolver.ts +18 -18
  442. package/src/resolvers/RunTemplateResolver.ts +3 -1
  443. package/src/resolvers/SqlLoggingConfigResolver.ts +7 -9
  444. package/src/resolvers/TagGovernanceResolver.ts +65 -0
  445. package/src/resolvers/TelemetryResolver.ts +44 -9
  446. package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
  447. package/src/resolvers/meetingRecordingRegistration.ts +2 -0
  448. package/src/resolvers/meetings/meetingMutations.ts +37 -7
  449. package/src/rest/MediaAccessKeys.ts +6 -2
  450. package/src/rest/OAuthCallbackHandler.ts +13 -5
  451. package/src/rest/RealtimeRecordingHandler.ts +5 -9
  452. package/src/rest/ViewOperationsHandler.ts +2 -1
  453. package/src/rest/setupRESTEndpoints.ts +11 -2
  454. package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
  455. package/src/services/TaskGraphActionRunner.ts +2 -23
  456. package/src/services/TaskGraphAgentRunner.ts +43 -0
  457. package/src/services/TaskGraphContinuationDeliverer.ts +1 -0
  458. package/src/services/WorkQueueHostService.ts +26 -4
  459. package/src/services/workQueueConfig.ts +5 -5
  460. package/src/sharedCache.ts +1 -1
  461. package/src/types.ts +18 -0
  462. package/src/util.ts +55 -3
  463. package/src/services/TaskOrchestration-Integration.md +0 -188
@@ -14,7 +14,7 @@ import { Resolver, Mutation, Query, Arg, Ctx, ObjectType, Field, PubSub, PubSubE
14
14
  import { LogError, LogStatus, RunView } from '@memberjunction/core';
15
15
  import { ArtifactMetadataEngine, ConversationEngine } from '@memberjunction/core-entities';
16
16
  import { RouteArtifact } from './artifact-routing.js';
17
- import { AgentRunner, ArtifactToolManager } from '@memberjunction/ai-agents';
17
+ import { AgentRunner, ArtifactToolManager, CanAgentOwnSubAgentConsults, LoadOpenSubAgentConsults, HostAllowedAgentIDs } from '@memberjunction/ai-agents';
18
18
  import { MJAIAgentRunEntityExtended, ConversationUtility, ContinuationAnnouncementText } from '@memberjunction/ai-core-plus';
19
19
  import { AIEngine } from '@memberjunction/aiengine';
20
20
  import { ResolverBase } from '../generic/ResolverBase.js';
@@ -27,7 +27,7 @@ import { GetReadWriteProvider } from '../util.js';
27
27
  import { ResolveWidgetGuestRunContext, ElevateUserPayload } from '../realtimeWidget/widgetGuestElevation.js';
28
28
  import { AuthorizeConversationTurn } from '../realtimeSessions/sessionAccess.js';
29
29
  import { IsTrustedAgentRunCaller } from './agent-run-data-guard.js';
30
- import { SafeJSONParse, UUIDsEqual } from '@memberjunction/global';
30
+ import { EscapeSQLString, IsValidUUID, SafeJSONParse, UUIDsEqual } from '@memberjunction/global';
31
31
  import { GetAttachmentService } from '@memberjunction/aiengine';
32
32
  import { NotificationEngine } from '@memberjunction/notifications';
33
33
  /**
@@ -211,6 +211,15 @@ AgentExecutionStreamMessage = __decorate([
211
211
  ], AgentExecutionStreamMessage);
212
212
  export { AgentExecutionStreamMessage };
213
213
  let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
214
+ constructor() {
215
+ super(...arguments);
216
+ /**
217
+ * Tracks `userPayload` instances originating from interactive user mutations (`RunAIAgent` and
218
+ * `RunAIAgentFromConversationDetail` without API key or widget guest elevation) that may expose
219
+ * `Handoff` and follow returned handoff decisions.
220
+ */
221
+ this.handoffEligiblePayloads = new WeakSet();
222
+ }
214
223
  /**
215
224
  * Sanitize ExecuteAgentResult for JSON serialization
216
225
  * Removes circular references and non-serializable objects
@@ -226,7 +235,8 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
226
235
  finalStep: result.agentRun?.FinalStep,
227
236
  cancelled: result.agentRun?.Status === 'Cancelled',
228
237
  cancellationReason: result.agentRun?.CancellationReason,
229
- feedbackRequestId: result.feedbackRequestId
238
+ feedbackRequestId: result.feedbackRequestId,
239
+ handoff: result.handoff
230
240
  };
231
241
  // Safely extract agent run data using GetAll() for proper serialization
232
242
  if (result.agentRun && typeof result.agentRun.GetAll === 'function') {
@@ -321,7 +331,9 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
321
331
  conversationBranchId,
322
332
  /** The reply row this request created on the server for the run (`conversationDetailId` is its ID). The run
323
333
  * writes into this instance, so its writes carry the server-authored marker and the user it was made as. */
324
- replyDetail) {
334
+ replyDetail,
335
+ /** Optional explicit handoff override; defaults to whether the caller registered `userPayload` as interactive. */
336
+ followHandoffs) {
325
337
  const startTime = Date.now();
326
338
  // Best-effort handle for persistInFlightAgentFailure. Populated from a
327
339
  // progress event carrying metadata.agentRun, or from the successful
@@ -355,13 +367,19 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
355
367
  // singleton's transaction state with concurrent requests (e.g. conversation deletes).
356
368
  const agentRunner = new AgentRunner(p);
357
369
  console.log(`🚀 Starting agent execution with sessionId: ${sessionId}`);
358
- // The resolver still copies the run into agentRunRef, including noise steps, for the
359
- // fire-and-forget liveness pulse.
360
- const publishProgress = statusPublisher.OnProgress;
361
- // Execute the agent in conversation context - handles conversation, artifacts, etc.
362
- const conversationResult = await agentRunner.RunAgentInConversation({
370
+ // The publisher owns every status message. The resolver still copies the run into
371
+ // agentRunRef, including noise steps, for the fire-and-forget liveness pulse.
372
+ const sourcePublisher = statusPublisher;
373
+ let currentPublisher = sourcePublisher;
374
+ // A widget- or guest-hosted run must not get a handoffChain unless the host also passes an
375
+ // allow-list under trusted run data.
376
+ const effectiveFollowHandoffs = followHandoffs ?? this.handoffEligiblePayloads.has(userPayload);
377
+ const isGuestOrWidgetUser = Boolean(currentUser.IsMagicLinkAnonymous || currentUser.WidgetGuestContext);
378
+ const allowHandoff = effectiveFollowHandoffs && (!isGuestOrWidgetUser
379
+ || (trustReservedRunData && HostAllowedAgentIDs(parsedData) !== undefined));
380
+ const sourceParams = {
363
381
  agent: agentEntity,
364
- conversationMessages: parsedMessages,
382
+ conversationMessages: [...parsedMessages],
365
383
  payload: payload ? SafeJSONParse(payload) : undefined,
366
384
  contextUser: currentUser,
367
385
  sessionID: sessionId,
@@ -370,9 +388,9 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
370
388
  if (isAgentRunEntity(fromEvent)) {
371
389
  agentRunRef.current = fromEvent;
372
390
  }
373
- publishProgress(progress);
391
+ sourcePublisher.OnProgress(progress);
374
392
  },
375
- onStreaming: statusPublisher.OnStreaming,
393
+ onStreaming: sourcePublisher.OnStreaming,
376
394
  lastRunId: lastRunId,
377
395
  autoPopulateLastRunPayload: autoPopulateLastRunPayload,
378
396
  configurationId: configurationId,
@@ -381,13 +399,16 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
381
399
  taskGraphDebug: parseTaskGraphDebug(taskGraphDebug),
382
400
  ConversationHistoryFrom: conversationHistoryFrom,
383
401
  ...(conversationBranchId ? { ConversationBranchID: conversationBranchId } : {}),
402
+ ...(allowHandoff ? { handoffChain: [] } : {}),
384
403
  data: parsedData,
385
404
  // Whether the run may read the reserved data keys (scope, agent-type params); BaseAgent drops them otherwise.
386
405
  TrustReservedRunData: trustReservedRunData,
387
406
  context: {
388
407
  dataSource: dataSource
389
408
  }
390
- }, {
409
+ };
410
+ // Execute the agent in conversation context - handles conversation, artifacts, etc.
411
+ const conversationResult = await agentRunner.RunAgentInConversation(sourceParams, {
391
412
  conversationDetailId: conversationDetailId, // Use existing if provided
392
413
  agentResponseDetail: replyDetail, // the reply row this request created, when it did
393
414
  conversationId: conversationId, // LATENCY OPT #2: pre-resolved to skip redundant load in AgentRunner
@@ -397,7 +418,7 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
397
418
  // A widget guest runs as the system user, but its conversation stays the guest's to write (MJ#4791).
398
419
  ConversationWriter: userPayload.ElevatedFrom,
399
420
  });
400
- const result = conversationResult.agentResult;
421
+ let result = conversationResult.agentResult;
401
422
  // Use agent response detail ID if available, otherwise fall back to user message detail ID
402
423
  const finalConversationDetailId = conversationResult.agentResponseDetailId || conversationResult.userMessageDetailId;
403
424
  const artifactInfo = conversationResult.artifactInfo;
@@ -405,40 +426,70 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
405
426
  if (result.agentRun) {
406
427
  agentRunRef.current = result.agentRun;
407
428
  }
408
- const executionTime = Date.now() - startTime;
409
- // LATENCY OPTIMIZATION (Opt #6): These three post-execution operations are independent
410
- // of each other — none reads the output of another. Previously they ran sequentially,
411
- // adding their latencies together (~50ms total). Now they run in parallel via Promise.all,
412
- // so we only pay the cost of the slowest one.
413
- //
414
- // 1. syncFeedbackRequestFromConversation — links a prior Chat-step feedback request to
415
- // the new agent run so the conversation thread stays coherent.
416
- // 2. sendFeedbackRequestNotification — sends an in-app/email/SMS notification when the
417
- // agent paused for human input (Chat step).
418
- // 3. createCompletionNotification — sends an in-app/email/SMS notification that the
419
- // agent finished and created an artifact.
420
- const postExecutionOps = [];
421
- if (lastRunId && result.agentRun?.ID) {
422
- postExecutionOps.push(this.syncFeedbackRequestFromConversation(lastRunId, result.agentRun.ID, userMessage, currentUser, p));
423
- }
424
- if (result.feedbackRequestId) {
425
- postExecutionOps.push(this.sendFeedbackRequestNotification(result, currentUser, pubSub, userPayload));
426
- }
427
- if (createNotification && result.success && artifactInfo && artifactInfo.artifactId && artifactInfo.versionId && artifactInfo.versionNumber) {
428
- postExecutionOps.push(this.createCompletionNotification(result.agentRun, {
429
- artifactId: artifactInfo.artifactId,
430
- versionId: artifactInfo.versionId,
431
- versionNumber: artifactInfo.versionNumber
432
- }, conversationResult.conversationId, finalConversationDetailId, currentUser, pubSub, userPayload));
433
- }
434
- if (postExecutionOps.length > 0) {
435
- await Promise.all(postExecutionOps);
429
+ await this.runPostExecutionNotifications(result, artifactInfo, conversationResult.conversationId, finalConversationDetailId, lastRunId, userMessage, createNotification, currentUser, pubSub, userPayload, p);
430
+ let handoffPublishedFinal = false;
431
+ if (allowHandoff && result.handoff && conversationResult.conversationId && conversationResult.agentResponseDetailId) {
432
+ const outcomes = await agentRunner.FollowHandoffs({
433
+ params: { ...sourceParams, conversationMessages: parsedMessages },
434
+ sourceResult: result,
435
+ conversationId: conversationResult.conversationId,
436
+ sourceConversationDetailId: conversationResult.agentResponseDetailId,
437
+ createArtifacts: createArtifacts || false,
438
+ ConversationWriter: userPayload.ElevatedFrom,
439
+ sourceConversationDetail: replyDetail,
440
+ hooks: {
441
+ OnHopStart: (hop, previousRun) => {
442
+ const prevSanitized = JSON.stringify(this.sanitizeAgentResult(previousRun.agentResult, currentUser));
443
+ currentPublisher.PublishFinal(previousRun.agentResult, previousRun.agentResult.agentRun?.ConversationDetailID ?? previousRun.conversationDetailId, prevSanitized);
444
+ currentPublisher = new AgentRunStatusPublisher(pubSub, userPayload, sessionId, hop.targetConversationDetailId);
445
+ return {
446
+ onProgress: (progress) => {
447
+ const fromEvent = progress.metadata?.agentRun;
448
+ if (isAgentRunEntity(fromEvent)) {
449
+ agentRunRef.current = fromEvent;
450
+ }
451
+ currentPublisher.OnProgress(progress);
452
+ },
453
+ onStreaming: currentPublisher.OnStreaming,
454
+ };
455
+ },
456
+ OnHopEnd: async (_hop, outcome) => {
457
+ if (!outcome.agentResult) {
458
+ return;
459
+ }
460
+ if (outcome.agentResult.agentRun) {
461
+ agentRunRef.current = outcome.agentResult.agentRun;
462
+ }
463
+ await this.runPostExecutionNotifications(outcome.agentResult, outcome.artifactInfo, conversationResult.conversationId, outcome.targetConversationDetailId, undefined, undefined, createNotification, currentUser, pubSub, userPayload, p);
464
+ },
465
+ },
466
+ });
467
+ const lastOutcome = outcomes[outcomes.length - 1];
468
+ if (lastOutcome?.error) {
469
+ const executionTime = Date.now() - startTime;
470
+ currentPublisher.PublishFailure(lastOutcome.targetConversationDetailId, lastOutcome.error);
471
+ LogError(`AI Agent handoff hop failed: ${lastOutcome.error}`);
472
+ return {
473
+ success: false,
474
+ errorMessage: lastOutcome.error,
475
+ executionTimeMs: executionTime,
476
+ result: JSON.stringify({ success: false, errorMessage: lastOutcome.error })
477
+ };
478
+ }
479
+ if (lastOutcome?.agentResult) {
480
+ const lastHopSanitized = JSON.stringify(this.sanitizeAgentResult(lastOutcome.agentResult, currentUser));
481
+ currentPublisher.PublishFinal(lastOutcome.agentResult, lastOutcome.agentResult.agentRun?.ConversationDetailID ?? lastOutcome.targetConversationDetailId, lastHopSanitized);
482
+ handoffPublishedFinal = true;
483
+ }
436
484
  }
437
- // Create sanitized payload for JSON serialization
485
+ const executionTime = Date.now() - startTime;
486
+ // Create sanitized payload for JSON serialization (always tied to the source detail)
438
487
  const sanitizedResult = this.sanitizeAgentResult(result, currentUser);
439
488
  const returnResult = JSON.stringify(sanitizedResult);
440
- // Publish final events with enriched result data for fire-and-forget clients
441
- statusPublisher.PublishFinal(result, result.agentRun?.ConversationDetailID, returnResult);
489
+ // Publish final events with enriched result data when no handoff hop already finalized via OnHopStart
490
+ if (!handoffPublishedFinal) {
491
+ currentPublisher.PublishFinal(result, result.agentRun?.ConversationDetailID, returnResult);
492
+ }
442
493
  // Log completion
443
494
  if (result.success) {
444
495
  LogStatus(`=== AI AGENT RUN COMPLETED FOR: ${agentEntity.Name} (${executionTime}ms) ===`);
@@ -480,6 +531,38 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
480
531
  };
481
532
  }
482
533
  }
534
+ /**
535
+ * LATENCY OPTIMIZATION (Opt #6): Runs the three independent post-execution notification/sync
536
+ * operations in parallel via `Promise.all` (shared by the initial run and each handoff hop):
537
+ * 1. `syncFeedbackRequestFromConversation` — links a prior Chat-step feedback request to the new run.
538
+ * 2. `sendFeedbackRequestNotification` — sends an in-app/email/SMS notification when paused for human input.
539
+ * 3. `createCompletionNotification` — sends an in-app/email/SMS notification when an artifact was created.
540
+ */
541
+ async runPostExecutionNotifications(result, artifactInfo, conversationId, conversationDetailId, lastRunId, userMessage, createNotification, currentUser, pubSub, userPayload, provider) {
542
+ const postExecutionOps = [];
543
+ if (lastRunId && result.agentRun?.ID) {
544
+ postExecutionOps.push(this.syncFeedbackRequestFromConversation(lastRunId, result.agentRun.ID, userMessage, currentUser, provider));
545
+ }
546
+ if (result.feedbackRequestId) {
547
+ postExecutionOps.push(this.sendFeedbackRequestNotification(result, currentUser, pubSub, userPayload));
548
+ }
549
+ if (createNotification
550
+ && result.success
551
+ && artifactInfo
552
+ && artifactInfo.artifactId
553
+ && artifactInfo.versionId
554
+ && artifactInfo.versionNumber
555
+ && conversationDetailId) {
556
+ postExecutionOps.push(this.createCompletionNotification(result.agentRun, {
557
+ artifactId: artifactInfo.artifactId,
558
+ versionId: artifactInfo.versionId,
559
+ versionNumber: artifactInfo.versionNumber
560
+ }, conversationId, conversationDetailId, currentUser, pubSub, userPayload));
561
+ }
562
+ if (postExecutionOps.length > 0) {
563
+ await Promise.all(postExecutionOps);
564
+ }
565
+ }
483
566
  /**
484
567
  * When executeAIAgent throws after the run/detail exist, close them so Explorer
485
568
  * does not leave a red-pill timer on Status=Running / ConversationDetail In-Progress.
@@ -531,6 +614,9 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
531
614
  // Only the system user or an API key holding the agent:trusted scope may set a run's scope and agent-type
532
615
  // params through data; for anyone else BaseAgent drops those keys (ExecuteAgentParams.TrustReservedRunData).
533
616
  const trustRunData = await IsTrustedAgentRunCaller({ UserPayload: userPayload, IsWidgetGuestRun: false, AgentID: agentId });
617
+ if (!userPayload.apiKeyHash) {
618
+ this.handoffEligiblePayloads.add(userPayload);
619
+ }
534
620
  if (fireAndForget) {
535
621
  // Fire-and-forget mode: start execution in background, return immediately.
536
622
  // The client will receive the result via WebSocket PubSub completion event.
@@ -641,15 +727,17 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
641
727
  }
642
728
  }
643
729
  /**
644
- * The ID of this agent's newest root run in the conversation IF the user stopped it, else
645
- * null. The query spans the runs that could be the predecessor (settled, or stopped by the
646
- * user) and the newest decides, so a stopped run that a later settled run already followed
647
- * is not chained to again. Uses the same filter and recognizer as `BaseAgent.findUserStoppedPredecessorRunId`
648
- * (`MJAIAgentRunEntityExtended.BuildStoppedPredecessorFilter` / `IsUserStopped`), which carries the stopped run's
649
- * completed results into the new run's context, so the two cannot pick different runs.
650
- * Fail-soft: a lookup failure means no chaining, never a failed turn.
730
+ * Discovers whether this agent's newest root run on this conversation/branch path should be
731
+ * chained by `LastRunID` on a chat-thread reply — either because the user stopped it
732
+ * (`reason: 'stopped'`) or because it paused on `FinalStep === 'Chat'` with one or more
733
+ * unanswered sub-agent consultations (`reason: 'open-consult'`).
734
+ *
735
+ * The query spans the runs that could be the predecessor (settled, or stopped by the user)
736
+ * and the newest decides, so a stopped or paused-consult run that a later settled run already
737
+ * followed is not chained to again. Fail-soft: a lookup failure means no chaining, never a
738
+ * failed turn.
651
739
  */
652
- async findUserStoppedPredecessorRunId(conversationId, agentId, branchId, contextUser, provider) {
740
+ async findChainablePredecessor(conversationId, agentId, branchId, contextUser, provider) {
653
741
  try {
654
742
  // The run must have replied on this turn's branch path: a run stopped on a sibling branch is not
655
743
  // this path's history. The trunk needs no branch rows; a branch needs them to walk its ancestry.
@@ -660,16 +748,29 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
660
748
  ExtraFilter: MJAIAgentRunEntityExtended.BuildStoppedPredecessorFilter(conversationId, agentId, branchId, branches),
661
749
  OrderBy: '__mj_CreatedAt DESC',
662
750
  MaxRows: 1,
663
- Fields: ['ID', 'Status', 'CancellationReason'],
751
+ SkipTotalRowCount: true,
752
+ Fields: ['ID', 'Status', 'CancellationReason', 'FinalStep'],
664
753
  ResultType: 'simple',
665
- // The row this looks for was written by the Stop button moments ago; read the database, not a cache.
754
+ // The row this looks for was written by the Stop button or a Chat pause moments ago; read the database, not a cache.
666
755
  BypassCache: true,
667
756
  }, contextUser);
668
757
  const run = newest.Success ? newest.Results?.[0] : undefined;
669
- return run && MJAIAgentRunEntityExtended.IsUserStopped(run.Status, run.CancellationReason) ? run.ID : null;
758
+ if (!run) {
759
+ return null;
760
+ }
761
+ if (MJAIAgentRunEntityExtended.IsUserStopped(run.Status, run.CancellationReason)) {
762
+ return { runId: run.ID, reason: 'stopped' };
763
+ }
764
+ if (run.FinalStep === 'Chat' && CanAgentOwnSubAgentConsults(agentId)) {
765
+ const open = await LoadOpenSubAgentConsults(provider, run.ID, contextUser);
766
+ if (open.length > 0) {
767
+ return { runId: run.ID, reason: 'open-consult' };
768
+ }
769
+ }
770
+ return null;
670
771
  }
671
772
  catch (error) {
672
- LogError(`findUserStoppedPredecessorRunId failed; the turn runs unchained: ${error instanceof Error ? error.message : String(error)}`);
773
+ LogError(`findChainablePredecessor failed; the turn runs unchained: ${error instanceof Error ? error.message : String(error)}`);
673
774
  return null;
674
775
  }
675
776
  }
@@ -682,11 +783,16 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
682
783
  */
683
784
  async syncFeedbackRequestFromConversation(lastRunId, newRunId, userMessage, contextUser, provider) {
684
785
  try {
786
+ const trimmedLastRunId = typeof lastRunId === 'string' ? lastRunId.trim() : '';
787
+ if (!IsValidUUID(trimmedLastRunId)) {
788
+ return;
789
+ }
685
790
  const rv = RunView.FromMetadataProvider(provider);
686
791
  const result = await rv.RunView({
687
792
  EntityName: 'MJ: AI Agent Requests',
688
- ExtraFilter: `OriginatingAgentRunID='${lastRunId}' AND Status='Requested'`,
793
+ ExtraFilter: `OriginatingAgentRunID='${EscapeSQLString(trimmedLastRunId)}' AND Status='Requested'`,
689
794
  MaxRows: 1,
795
+ SkipTotalRowCount: true,
690
796
  ResultType: 'entity_object'
691
797
  }, contextUser);
692
798
  if (!result.Success || !result.Results || result.Results.length === 0) {
@@ -816,6 +922,9 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
816
922
  const trustRunData = await IsTrustedAgentRunCaller({
817
923
  UserPayload: userPayload, IsWidgetGuestRun: widgetElevation !== null, AgentID: agentId,
818
924
  });
925
+ if (!userPayload.apiKeyHash && !widgetElevation) {
926
+ this.handoffEligiblePayloads.add(effectiveUserPayload);
927
+ }
819
928
  try {
820
929
  // Parsed before anything loads: a floor the caller asked for must never be dropped.
821
930
  const historyFrom = parseAgentHistoryFrom(agentHistoryFrom);
@@ -832,19 +941,25 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
832
941
  // The turn's branch (the message's own branch, or a validated fork whose path holds the message)
833
942
  // decides which path the run reads.
834
943
  const branchId = turn.BranchId;
835
- // A turn that follows a run the user STOPPED continues that run rather than starting
836
- // over: chain it by LastRunID (the chat client never sends one) and, when the caller
837
- // supplied no payload, roll the stopped run's FinalPayload into this run's start.
944
+ // A turn that follows a run the user STOPPED or a run paused on FinalStep === 'Chat'
945
+ // with an open sub-agent consult continues that run rather than starting over: chain it
946
+ // by LastRunID (the chat client never sends one) and, when the caller supplied no
947
+ // payload, roll the prior run's FinalPayload into this run's start.
838
948
  let effectiveLastRunId = lastRunId;
839
949
  let effectiveAutoPopulate = autoPopulateLastRunPayload;
840
950
  if (!effectiveLastRunId) {
841
- const stoppedRunId = await this.findUserStoppedPredecessorRunId(turn.ConversationId, effectiveAgentId, branchId, currentUser, p);
842
- if (stoppedRunId) {
843
- effectiveLastRunId = stoppedRunId;
951
+ const chainable = await this.findChainablePredecessor(turn.ConversationId, effectiveAgentId, branchId, currentUser, p);
952
+ if (chainable) {
953
+ effectiveLastRunId = chainable.runId;
844
954
  if (effectiveAutoPopulate === undefined && payload == null) {
845
955
  effectiveAutoPopulate = true;
846
956
  }
847
- LogStatus(`↩️ Continuing from user-stopped run ${stoppedRunId} (chained by LastRunID)`);
957
+ if (chainable.reason === 'stopped') {
958
+ LogStatus(`↩️ Continuing from user-stopped run ${chainable.runId} (chained by LastRunID)`);
959
+ }
960
+ else {
961
+ LogStatus(`Resuming open sub-agent consult(s) from run ${chainable.runId} (chained by LastRunID)`);
962
+ }
848
963
  }
849
964
  }
850
965
  if (fireAndForget) {
@@ -1190,7 +1305,9 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
1190
1305
  /** History floor: only rows written at or after it are loaded, and no summary is used. */
1191
1306
  historyFrom,
1192
1307
  /** The branch whose path to load; null reads the trunk. */
1193
- branchId) {
1308
+ branchId,
1309
+ /** Speaker attribution mode forwarded to `ConversationEngine.AssembleContextWindow`. */
1310
+ speakerAttribution) {
1194
1311
  // Context windowing (summary boundary + raw tail, or legacy last-N when no
1195
1312
  // summary exists) shares ONE fold implementation with all other callers —
1196
1313
  // ConversationEngine.AssembleContextWindow — and the ROWS come from the
@@ -1210,7 +1327,8 @@ let RunAIAgentResolver = class RunAIAgentResolver extends ResolverBase {
1210
1327
  const window = ConversationEngine.AssembleContextWindow(rows, {
1211
1328
  maxTailMessages: maxMessages,
1212
1329
  excludeDetailIds,
1213
- historyFrom
1330
+ historyFrom,
1331
+ speakerAttribution
1214
1332
  });
1215
1333
  // Batch load input artifacts for the windowed messages. Since the backfill migration
1216
1334
  // (V202605271400__Backfill_Attachment_Artifacts) converted all legacy