@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
@@ -10,12 +10,15 @@ import { describe, it, expect, vi, beforeEach } from 'vitest';
10
10
  * how errors are surfaced.
11
11
  */
12
12
 
13
- const { promoteCalls, rejectCalls, rebuildCalls, healthCalls, behaviorFlags } = vi.hoisted(() => ({
13
+ const { promoteCalls, rejectCalls, rebuildCalls, healthCalls, mergeCalls, recomputeCalls, configCalls, behaviorFlags } = vi.hoisted(() => ({
14
14
  promoteCalls: [] as Array<{ id: string; strategy: unknown; user: unknown }>,
15
15
  rejectCalls: [] as Array<{ id: string; notes: string | null; user: unknown }>,
16
16
  rebuildCalls: [] as Array<{ user: unknown }>,
17
17
  healthCalls: [] as Array<{ thresholds: unknown; user: unknown }>,
18
- behaviorFlags: { promoteThrows: false, rejectThrows: false, rebuildThrows: false, healthThrows: false },
18
+ mergeCalls: [] as Array<{ sourceTagIDs: string[]; survivingTagID: string; user: unknown }>,
19
+ recomputeCalls: [] as Array<{ user: unknown }>,
20
+ configCalls: [] as Array<{ forceRefresh: boolean; user: unknown }>,
21
+ behaviorFlags: { promoteThrows: false, rejectThrows: false, rebuildThrows: false, healthThrows: false, mergeThrows: false },
19
22
  }));
20
23
 
21
24
  vi.mock('@memberjunction/tag-engine', () => ({
@@ -30,10 +33,18 @@ vi.mock('@memberjunction/tag-engine', () => ({
30
33
  rejectCalls.push({ id, notes, user });
31
34
  if (behaviorFlags.rejectThrows) throw new Error('reject-fail');
32
35
  },
36
+ MergeTags: async (sourceTagIDs: string[], survivingTagID: string, user: unknown) => {
37
+ mergeCalls.push({ sourceTagIDs, survivingTagID, user });
38
+ if (behaviorFlags.mergeThrows) throw new Error('merge-fail');
39
+ return { ItemsMoved: 4, TaggedItemsMoved: 7 };
40
+ },
33
41
  },
34
42
  },
35
43
  TagEngine: {
36
44
  Instance: {
45
+ Config: async (forceRefresh: boolean, user: unknown) => {
46
+ configCalls.push({ forceRefresh, user });
47
+ },
37
48
  RebuildTagEmbeddings: async (user: unknown) => {
38
49
  rebuildCalls.push({ user });
39
50
  if (behaviorFlags.rebuildThrows) throw new Error('rebuild-fail');
@@ -59,6 +70,17 @@ vi.mock('@memberjunction/tag-engine', () => ({
59
70
  },
60
71
  }));
61
72
 
73
+ vi.mock('@memberjunction/tag-engine-base', () => ({
74
+ TagCoOccurrenceEngine: {
75
+ Instance: {
76
+ RecomputeCoOccurrence: async (user: unknown) => {
77
+ recomputeCalls.push({ user });
78
+ return { PairsUpdated: 12, PairsDeleted: 3 };
79
+ },
80
+ },
81
+ },
82
+ }));
83
+
62
84
  // Minimal type-graphql shim — we only need the decorators to be no-ops so the
63
85
  // resolver class can load. Method behavior is what we test.
64
86
  vi.mock('type-graphql', () => ({
@@ -98,10 +120,14 @@ describe('TagGovernanceResolver', () => {
98
120
  rejectCalls.length = 0;
99
121
  rebuildCalls.length = 0;
100
122
  healthCalls.length = 0;
123
+ mergeCalls.length = 0;
124
+ recomputeCalls.length = 0;
125
+ configCalls.length = 0;
101
126
  behaviorFlags.promoteThrows = false;
102
127
  behaviorFlags.rejectThrows = false;
103
128
  behaviorFlags.rebuildThrows = false;
104
129
  behaviorFlags.healthThrows = false;
130
+ behaviorFlags.mergeThrows = false;
105
131
  resolver = new TagGovernanceResolver();
106
132
  });
107
133
 
@@ -252,4 +278,36 @@ describe('TagGovernanceResolver', () => {
252
278
  expect(r.ErrorMessage).toBe('health-fail');
253
279
  });
254
280
  });
281
+
282
+ // ---- MergeTags ---------------------------------------------------------
283
+
284
+ describe('MergeTags', () => {
285
+ it('calls TagEngine.Instance.Config first and delegates to TagGovernanceEngine.Instance.MergeTags', async () => {
286
+ const r = await resolver.MergeTags(['src-1'], 'surviving-1', ctx() as never);
287
+ expect(r.Success).toBe(true);
288
+ expect(r.ItemsMoved).toBe(4);
289
+ expect(r.TaggedItemsMoved).toBe(7);
290
+ expect(configCalls).toHaveLength(1);
291
+ expect(mergeCalls[0]).toMatchObject({ sourceTagIDs: ['src-1'], survivingTagID: 'surviving-1' });
292
+ });
293
+
294
+ it('maps engine errors into ErrorMessage', async () => {
295
+ behaviorFlags.mergeThrows = true;
296
+ const r = await resolver.MergeTags(['src-1'], 'surviving-1', ctx() as never);
297
+ expect(r.Success).toBe(false);
298
+ expect(r.ItemsMoved).toBe(0);
299
+ expect(r.TaggedItemsMoved).toBe(0);
300
+ expect(r.ErrorMessage).toBe('merge-fail');
301
+ });
302
+ });
303
+
304
+ // ---- RecomputeTagCoOccurrence ------------------------------------------
305
+
306
+ describe('RecomputeTagCoOccurrence', () => {
307
+ it('delegates to TagCoOccurrenceEngine.Instance.RecomputeCoOccurrence', async () => {
308
+ const r = await resolver.RecomputeTagCoOccurrence(ctx() as never);
309
+ expect(r).toEqual({ PairsUpdated: 12, PairsDeleted: 3 });
310
+ expect(recomputeCalls).toHaveLength(1);
311
+ });
312
+ });
255
313
  });
@@ -170,7 +170,7 @@ describe('TaskGraphActionRunner: outputs must be storable', () => {
170
170
  expect(result).toMatchObject({ Success: true, Output: { AgentRunID: 'RUN-1' }, ActionLogID: 'LOG-2' });
171
171
  });
172
172
 
173
- it('merges structured JSON Message properties into Output and aliases handle/Handle', async () => {
173
+ it('merges structured JSON Message properties into Output without synthesizing handle/Handle aliases', async () => {
174
174
  vi.mocked(ActionEngineServer.Instance.RunAction).mockResolvedValue({
175
175
  Success: true,
176
176
  Message: JSON.stringify({
@@ -188,10 +188,10 @@ describe('TaskGraphActionRunner: outputs must be storable', () => {
188
188
  expect(result.Success).toBe(true);
189
189
  expect(result.Output).toMatchObject({
190
190
  handle: 'doc-handle-99',
191
- Handle: 'doc-handle-99',
192
191
  documentType: 'pdf',
193
192
  fileName: 'Sales_Demo_Report.pdf',
194
193
  });
194
+ expect(result.Output).not.toHaveProperty('Handle');
195
195
  });
196
196
  });
197
197
 
@@ -1,19 +1,54 @@
1
1
  /**
2
- * Tests for `TaskGraphAgentRunner`.
3
- *
4
- * Verifies that when a task node in a durable task graph executes a specialist agent
5
- * (such as Query Builder or Research Report Writer) and finishes with a payload,
6
- * the runner resolves the originating `ConversationDetailID` and persists artifacts
7
- * via `AgentRunner.ProcessAgentArtifacts`.
2
+ * Tests for `TaskGraphAgentRunner`:
3
+ * - VS-CON-7 preset resolution (`ConfigurationPresetName`)
4
+ * - VS-INV-2b / VS-QA-3 #9 `parentAgentHierarchy` from submitted task
5
+ * - Specialist agent artifact persistence (`ProcessAgentArtifacts`), `CanUserRunAgent` permission check,
6
+ * task Name/Description prompt formatting, and output normalization.
8
7
  */
9
8
  import 'reflect-metadata';
10
9
  import { describe, it, expect, vi, beforeEach } from 'vitest';
10
+ import type { IMetadataProvider, UserInfo } from '@memberjunction/core';
11
+ import type { TaskAgentRunParams } from '@memberjunction/task-graph';
11
12
 
12
- vi.mock('@memberjunction/core', () => ({
13
- LogError: vi.fn(),
14
- LogStatus: vi.fn(),
13
+ const {
14
+ runAgent,
15
+ processAgentArtifacts,
16
+ canUserRunAgent,
17
+ mockEngineAgents,
18
+ mockGetAgentConfigurationPresets,
19
+ mockEngineConfig,
20
+ mockRunView,
21
+ mockLogError,
22
+ } = vi.hoisted(() => ({
23
+ runAgent: vi.fn(),
24
+ processAgentArtifacts: vi.fn(),
25
+ canUserRunAgent: vi.fn().mockResolvedValue(true),
26
+ mockEngineAgents: [
27
+ { ID: 'agent-1', Name: 'Storyboard Artist' },
28
+ { ID: 'qb-agent' },
29
+ { ID: 'writer-agent' },
30
+ ] as Array<{ ID: string; Name?: string }>,
31
+ mockGetAgentConfigurationPresets: vi.fn(),
32
+ mockEngineConfig: vi.fn(),
33
+ mockRunView: vi.fn(),
34
+ mockLogError: vi.fn(),
15
35
  }));
16
36
 
37
+ const mockRunAgent = runAgent;
38
+
39
+ vi.mock('@memberjunction/core', async (importOriginal) => {
40
+ const actual = await importOriginal<typeof import('@memberjunction/core')>();
41
+ return {
42
+ ...actual,
43
+ LogError: (...args: unknown[]) => mockLogError(...args),
44
+ LogStatus: vi.fn(),
45
+ RunView: class {
46
+ static FromMetadataProvider = () => ({ RunView: mockRunView });
47
+ RunView = mockRunView;
48
+ },
49
+ };
50
+ });
51
+
17
52
  vi.mock('@memberjunction/generic-database-provider', () => ({
18
53
  UserCache: {
19
54
  Instance: { Users: [] },
@@ -31,31 +66,251 @@ vi.mock('@memberjunction/ai-core-plus', () => ({
31
66
  }));
32
67
  vi.mock('@memberjunction/ai', () => ({ ChatMessageRole: { user: 'user' } }));
33
68
 
34
- const { runAgent, processAgentArtifacts, canUserRunAgent, mockEngineAgents } = vi.hoisted(() => ({
35
- runAgent: vi.fn(),
36
- processAgentArtifacts: vi.fn(),
37
- canUserRunAgent: vi.fn().mockResolvedValue(true),
38
- mockEngineAgents: [{ ID: 'qb-agent' }, { ID: 'writer-agent' }] as Array<{ ID: string }>,
39
- }));
40
69
  vi.mock('@memberjunction/ai-agents', () => ({
41
70
  AgentRunner: class {
42
71
  RunAgent = runAgent;
43
72
  ProcessAgentArtifacts = processAgentArtifacts;
44
73
  },
45
74
  }));
75
+
46
76
  vi.mock('@memberjunction/aiengine', () => ({
47
77
  AIEngine: {
48
78
  get Instance() {
49
79
  return {
80
+ Config: mockEngineConfig,
50
81
  Agents: mockEngineAgents,
51
82
  CanUserRunAgent: canUserRunAgent,
83
+ GetAgentConfigurationPresets: mockGetAgentConfigurationPresets,
84
+ FindActiveAgentConfigurationPreset: (agentId: string, presetName: string) => {
85
+ const target = presetName.trim().toLowerCase();
86
+ if (!target) return undefined;
87
+ const presets = (mockGetAgentConfigurationPresets(agentId, true) ?? []) as Array<{
88
+ Name?: string;
89
+ DisplayName?: string;
90
+ }>;
91
+ return presets.find((p) => p.Name?.trim().toLowerCase() === target)
92
+ ?? presets.find((p) => p.DisplayName?.trim().toLowerCase() === target);
93
+ },
52
94
  };
53
95
  },
54
96
  },
55
97
  }));
56
98
 
57
99
  import { TaskGraphAgentRunner } from '../services/TaskGraphAgentRunner';
58
- import type { IMetadataProvider, UserInfo } from '@memberjunction/core';
100
+
101
+ interface SubmittingRunOverrides {
102
+ ID?: string;
103
+ ConfigurationID?: string | null;
104
+ Agent?: string | null;
105
+ AgentID?: string | null;
106
+ ParentRunID?: string | null;
107
+ LoadSuccess?: boolean;
108
+ }
109
+
110
+ function makeParams(
111
+ overrides: Partial<TaskAgentRunParams> = {},
112
+ parentConfigurationID: string | null = 'parent-cfg-1',
113
+ submittingRunOverrides: SubmittingRunOverrides = {},
114
+ ): TaskAgentRunParams {
115
+ const loadSuccess = submittingRunOverrides.LoadSuccess ?? true;
116
+ const provider = {
117
+ GetEntityObject: vi.fn().mockImplementation(async (entityName: string) => {
118
+ if (entityName === 'MJ: AI Agents') {
119
+ return {
120
+ Load: vi.fn().mockResolvedValue(true),
121
+ ID: overrides.AgentID ?? 'agent-1',
122
+ Name: 'Storyboard Artist',
123
+ };
124
+ }
125
+ if (entityName === 'MJ: Tasks') {
126
+ return {
127
+ Load: vi.fn().mockResolvedValue(false),
128
+ };
129
+ }
130
+ return {
131
+ Load: vi.fn().mockResolvedValue(loadSuccess),
132
+ ID: submittingRunOverrides.ID ?? 'submitting-run-1',
133
+ ConfigurationID:
134
+ 'ConfigurationID' in submittingRunOverrides
135
+ ? submittingRunOverrides.ConfigurationID
136
+ : parentConfigurationID,
137
+ Agent: submittingRunOverrides.Agent ?? null,
138
+ AgentID: submittingRunOverrides.AgentID ?? null,
139
+ ParentRunID: submittingRunOverrides.ParentRunID ?? null,
140
+ };
141
+ }),
142
+ } as unknown as IMetadataProvider;
143
+
144
+ return {
145
+ TaskID: 'task-1',
146
+ AgentID: 'agent-1',
147
+ InputPayload: 'Draw the opening shot',
148
+ DependencyOutputs: new Map(),
149
+ SubmittingAgentRunID: 'submitting-run-1',
150
+ Provider: provider,
151
+ ContextUser: { ID: 'user-1' } as unknown as UserInfo,
152
+ ...overrides,
153
+ };
154
+ }
155
+
156
+ describe('VS-CON-7: TaskGraphAgentRunner preset resolution', () => {
157
+ beforeEach(() => {
158
+ vi.clearAllMocks();
159
+ canUserRunAgent.mockResolvedValue(true);
160
+ processAgentArtifacts.mockResolvedValue(undefined);
161
+ mockEngineConfig.mockResolvedValue(undefined);
162
+ mockRunAgent.mockResolvedValue({
163
+ success: true,
164
+ agentRun: { ID: 'child-run-1', Message: 'Done' },
165
+ payload: { result: 'ok' },
166
+ });
167
+ });
168
+
169
+ it('resolves ConfigurationPresetName to the matching preset AIConfigurationID', async () => {
170
+ mockGetAgentConfigurationPresets.mockReturnValue([
171
+ {
172
+ ID: 'preset-draft',
173
+ Name: 'Draft',
174
+ DisplayName: 'Draft Mode',
175
+ AIConfigurationID: 'cfg-draft-1',
176
+ Status: 'Active',
177
+ },
178
+ {
179
+ ID: 'preset-high',
180
+ Name: 'High',
181
+ DisplayName: 'High Fidelity',
182
+ AIConfigurationID: 'cfg-high-1',
183
+ Status: 'Active',
184
+ },
185
+ ]);
186
+
187
+ const runner = new TaskGraphAgentRunner();
188
+ const result = await runner.RunAgentForTask(
189
+ makeParams({ ConfigurationPresetName: 'high fidelity' })
190
+ );
191
+
192
+ expect(result.Success).toBe(true);
193
+ expect(mockRunAgent).toHaveBeenCalledTimes(1);
194
+ expect(mockRunAgent.mock.calls[0][0].configurationId).toBe('cfg-high-1');
195
+ });
196
+
197
+ it('passes configurationId: undefined when the matched preset has NULL AIConfigurationID, even if the submitting run has a ConfigurationID', async () => {
198
+ mockGetAgentConfigurationPresets.mockReturnValue([
199
+ {
200
+ ID: 'preset-default',
201
+ Name: 'SystemDefault',
202
+ DisplayName: 'System Default',
203
+ AIConfigurationID: null,
204
+ Status: 'Active',
205
+ },
206
+ ]);
207
+
208
+ const runner = new TaskGraphAgentRunner();
209
+ const result = await runner.RunAgentForTask(
210
+ makeParams({ ConfigurationPresetName: 'SystemDefault' }, 'parent-cfg-1')
211
+ );
212
+
213
+ expect(result.Success).toBe(true);
214
+ expect(mockRunAgent).toHaveBeenCalledTimes(1);
215
+ expect(mockRunAgent.mock.calls[0][0].configurationId).toBeUndefined();
216
+ });
217
+
218
+ it('falls back to the submitting run ConfigurationID when ConfigurationPresetName is not specified', async () => {
219
+ const runner = new TaskGraphAgentRunner();
220
+ const result = await runner.RunAgentForTask(makeParams({}, 'parent-cfg-99'));
221
+
222
+ expect(result.Success).toBe(true);
223
+ expect(mockRunAgent).toHaveBeenCalledTimes(1);
224
+ expect(mockRunAgent.mock.calls[0][0].configurationId).toBe('parent-cfg-99');
225
+ });
226
+
227
+ it('fails the task with a clear message when ConfigurationPresetName does not match any active preset at run time', async () => {
228
+ mockGetAgentConfigurationPresets.mockReturnValue([
229
+ {
230
+ ID: 'preset-draft',
231
+ Name: 'Draft',
232
+ DisplayName: 'Draft Mode',
233
+ AIConfigurationID: 'cfg-draft-1',
234
+ Status: 'Active',
235
+ },
236
+ ]);
237
+
238
+ const runner = new TaskGraphAgentRunner();
239
+ const result = await runner.RunAgentForTask(
240
+ makeParams({ ConfigurationPresetName: 'DeletedPreset' })
241
+ );
242
+
243
+ expect(result.Success).toBe(false);
244
+ expect(result.ErrorMessage).toBe(
245
+ "Agent 'Storyboard Artist' has no active preset 'DeletedPreset'. Available: Draft."
246
+ );
247
+ expect(mockRunAgent).not.toHaveBeenCalled();
248
+ });
249
+ });
250
+
251
+ describe('VS-INV-2b / VS-QA-3 #9: TaskGraphAgentRunner parentAgentHierarchy from submitted task', () => {
252
+ const RUN_B_ID = '22222222-2222-4222-8222-222222222222';
253
+ const RUN_C_ID = '33333333-3333-4333-8333-333333333333';
254
+
255
+ beforeEach(() => {
256
+ vi.clearAllMocks();
257
+ canUserRunAgent.mockResolvedValue(true);
258
+ processAgentArtifacts.mockResolvedValue(undefined);
259
+ mockEngineConfig.mockResolvedValue(undefined);
260
+ mockRunAgent.mockResolvedValue({
261
+ success: true,
262
+ agentRun: { ID: 'child-run-1', Message: 'Done' },
263
+ payload: { result: 'ok' },
264
+ });
265
+ });
266
+
267
+ it('reads root-first ParentAgentHierarchy carried from the submitted task without running RunView in a loop (VS-QA-3 #9)', async () => {
268
+ const runner = new TaskGraphAgentRunner();
269
+ const params = makeParams(
270
+ {
271
+ SubmittingAgentRunID: RUN_C_ID,
272
+ ParentAgentHierarchy: ['A', 'B', 'C'],
273
+ },
274
+ 'parent-cfg-1',
275
+ { ID: RUN_C_ID, Agent: 'C', ParentRunID: RUN_B_ID },
276
+ );
277
+
278
+ const result = await runner.RunAgentForTask(params);
279
+
280
+ expect(result.Success).toBe(true);
281
+ expect(mockRunView).not.toHaveBeenCalled();
282
+ expect(mockRunAgent).toHaveBeenCalledTimes(1);
283
+ expect(mockRunAgent.mock.calls[0][0].parentAgentHierarchy).toEqual(['A', 'B', 'C']);
284
+ });
285
+
286
+ it('falls back to the loaded parentRun agent name when ParentAgentHierarchy is omitted, with zero RunView calls', async () => {
287
+ const runner = new TaskGraphAgentRunner();
288
+ const params = makeParams(
289
+ { SubmittingAgentRunID: RUN_C_ID },
290
+ 'parent-cfg-1',
291
+ { ID: RUN_C_ID, Agent: 'C', ParentRunID: RUN_B_ID },
292
+ );
293
+
294
+ const result = await runner.RunAgentForTask(params);
295
+
296
+ expect(result.Success).toBe(true);
297
+ expect(mockRunView).not.toHaveBeenCalled();
298
+ expect(mockRunAgent).toHaveBeenCalledTimes(1);
299
+ expect(mockRunAgent.mock.calls[0][0].parentAgentHierarchy).toEqual(['C']);
300
+ });
301
+
302
+ it('passes undefined parentAgentHierarchy and performs no RunView reads when there is no parentRun and no ParentAgentHierarchy', async () => {
303
+ const runner = new TaskGraphAgentRunner();
304
+ const result = await runner.RunAgentForTask(
305
+ makeParams({ SubmittingAgentRunID: undefined }),
306
+ );
307
+
308
+ expect(result.Success).toBe(true);
309
+ expect(mockRunView).not.toHaveBeenCalled();
310
+ expect(mockRunAgent).toHaveBeenCalledTimes(1);
311
+ expect(mockRunAgent.mock.calls[0][0].parentAgentHierarchy).toBeUndefined();
312
+ });
313
+ });
59
314
 
60
315
  describe('TaskGraphAgentRunner', () => {
61
316
  beforeEach(() => {
@@ -264,3 +519,4 @@ describe('TaskGraphAgentRunner', () => {
264
519
  });
265
520
  });
266
521
 
522
+
@@ -267,16 +267,13 @@ describe('ViewOperationsHandler.getEntityViews', () => {
267
267
  expect(outcome.error).toBe('timeout talking to DB');
268
268
  });
269
269
 
270
- it('KNOWN GAP: the entity name is interpolated into ExtraFilter without escaping', async () => {
271
- // Reachable only for names registered in metadata, so a hostile value requires a
272
- // hostile entity name — but an entity legitimately named with an apostrophe
273
- // (e.g. "O'Brien Records") already produces a broken/injectable filter today.
270
+ it('escapes single quotes in the entity name when building ExtraFilter', async () => {
274
271
  registerEntity("O'Brien Records", true);
275
272
  mockRunViewFn.mockResolvedValue({ Success: true, Results: [] });
276
273
 
277
274
  await ViewOperationsHandler.getEntityViews("O'Brien Records", makeUser());
278
275
 
279
276
  const executed = mockRunViewFn.mock.calls[0][0] as RunViewParams;
280
- expect(executed.ExtraFilter).toBe(`Entity = 'O'Brien Records'`); // quote NOT doubled
277
+ expect(executed.ExtraFilter).toBe(`Entity = 'O''Brien Records'`);
281
278
  });
282
279
  });
@@ -56,9 +56,9 @@ function enabled(overrides: Partial<WorkQueueConfig> = {}): WorkQueueConfig {
56
56
  }
57
57
 
58
58
  describe('workQueue configuration', () => {
59
- it('defaults to disabled, running every MJWorker subscription once enabled', () => {
59
+ it('defaults to enabled, running every MJWorker subscription out of the box', () => {
60
60
  expect(WorkQueueSchema.parse({})).toEqual({
61
- enabled: false, systemUserEmail: 'system@memberjunction.org', subscriptions: [{ name: '*', concurrency: 4 }],
61
+ enabled: true, systemUserEmail: 'system@memberjunction.org', subscriptions: [{ name: '*', concurrency: 4 }],
62
62
  idlePollMinMs: 250, idlePollMaxMs: 5000, shutdownDrainMs: 8000, sweeperEnabled: true, sweeperIntervalMs: 60000,
63
63
  reconcileIntervalMs: 30000,
64
64
  });
@@ -94,7 +94,7 @@ describe('host configuration helpers', () => {
94
94
  describe('StartWorkQueueHost', () => {
95
95
  it('starts nothing when the section is disabled', async () => {
96
96
  const rec = recorder();
97
- expect(await StartWorkQueueHost(WorkQueueSchema.parse({}), PROVIDER, PROVIDER_SOURCE, rec.Dependencies)).toBeNull();
97
+ expect(await StartWorkQueueHost(WorkQueueSchema.parse({ enabled: false }), PROVIDER, PROVIDER_SOURCE, rec.Dependencies)).toBeNull();
98
98
  expect(rec.EngineCalls).toBe(0);
99
99
  });
100
100
 
@@ -109,9 +109,18 @@ describe('StartWorkQueueHost', () => {
109
109
  await expect(StartWorkQueueHost(enabled(), PROVIDER, PROVIDER_SOURCE, rec.Dependencies)).rejects.toThrow('System user not found with email: system@memberjunction.org');
110
110
  });
111
111
 
112
- it('names the setting to fix when the placeholder email from DEFAULT_SERVER_CONFIG is still in effect', async () => {
113
- const rec = recorder();
114
- await expect(StartWorkQueueHost(enabled({ systemUserEmail: 'not.set@nowhere.com' }), PROVIDER, PROVIDER_SOURCE, rec.Dependencies))
112
+ it('falls back to FindSystemUser when default systemUserEmail is not literal in UserCache', async () => {
113
+ const rec = recorder([]);
114
+ rec.Dependencies.FindSystemUser = () => SYSTEM_USER;
115
+ const host = await StartWorkQueueHost(WorkQueueSchema.parse({}), PROVIDER, PROVIDER_SOURCE, rec.Dependencies);
116
+ expect(host).not.toBeNull();
117
+ expect(rec.EngineCalls).toBe(1);
118
+ });
119
+
120
+ it('names the setting to fix when an explicit custom email is not found even if FindSystemUser exists', async () => {
121
+ const rec = recorder([]);
122
+ rec.Dependencies.FindSystemUser = () => SYSTEM_USER;
123
+ await expect(StartWorkQueueHost(enabled({ systemUserEmail: 'missing-worker@example.com' }), PROVIDER, PROVIDER_SOURCE, rec.Dependencies))
115
124
  .rejects.toThrow('set workQueue.systemUserEmail');
116
125
  });
117
126
 
@@ -126,7 +135,16 @@ describe('StartWorkQueueHost', () => {
126
135
  });
127
136
 
128
137
  describe('MJServerWorkQueueProviderSource', () => {
129
- it('falls back to the shared server provider when there is no SQL Server pool', async () => {
138
+ it('mints an independent provider instance when fallback implements CreateIndependentInstance (e.g. PostgreSQL)', async () => {
139
+ const independent = { Name: 'independent-pg-provider' } as IMetadataProvider;
140
+ const createIndependent = vi.fn().mockResolvedValue(independent);
141
+ const pgFallback = Object.assign({}, PROVIDER, { CreateIndependentInstance: createIndependent });
142
+ const source = new MJServerWorkQueueProviderSource(null, pgFallback);
143
+ expect(await source.CreateProvider()).toBe(independent);
144
+ expect(createIndependent).toHaveBeenCalledTimes(1);
145
+ });
146
+
147
+ it('falls back to the shared server provider when there is no SQL Server pool and no CreateIndependentInstance', async () => {
130
148
  const source = new MJServerWorkQueueProviderSource(null, PROVIDER);
131
149
  expect(await source.CreateProvider()).toBe(PROVIDER);
132
150
  });