@memberjunction/server 6.2.0-edge.0 → 6.2.0-edge.2

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 (459) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/agentSessions/ReturningVisitorRecap.d.ts +2 -0
  3. package/dist/agentSessions/ReturningVisitorRecap.d.ts.map +1 -1
  4. package/dist/agentSessions/ReturningVisitorRecap.js +5 -1
  5. package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
  6. package/dist/agentSessions/SessionManager.js +2 -2
  7. package/dist/agentSessions/remoteBrowserGoalEngine.d.ts +8 -0
  8. package/dist/agentSessions/remoteBrowserGoalEngine.d.ts.map +1 -1
  9. package/dist/agentSessions/remoteBrowserGoalEngine.js +21 -5
  10. package/dist/agentSessions/remoteBrowserGoalEngine.js.map +1 -1
  11. package/dist/auth/AuthProviderCatalogRouter.d.ts +2 -0
  12. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
  13. package/dist/auth/AuthProviderCatalogRouter.js +5 -1
  14. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
  15. package/dist/auth/index.d.ts +20 -1
  16. package/dist/auth/index.d.ts.map +1 -1
  17. package/dist/auth/index.js +20 -10
  18. package/dist/auth/index.js.map +1 -1
  19. package/dist/auth/initializeProviders.d.ts +8 -0
  20. package/dist/auth/initializeProviders.d.ts.map +1 -1
  21. package/dist/auth/initializeProviders.js +21 -5
  22. package/dist/auth/initializeProviders.js.map +1 -1
  23. package/dist/auth/magicLink/MagicLinkRouter.d.ts +9 -0
  24. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  25. package/dist/auth/magicLink/MagicLinkRouter.js +22 -10
  26. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  27. package/dist/auth/magicLink/MagicLinkService.d.ts +17 -15
  28. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  29. package/dist/auth/magicLink/MagicLinkService.js +65 -51
  30. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  31. package/dist/auth/magicLink/index.d.ts +2 -2
  32. package/dist/auth/magicLink/index.d.ts.map +1 -1
  33. package/dist/auth/magicLink/index.js +2 -2
  34. package/dist/auth/magicLink/index.js.map +1 -1
  35. package/dist/auth/magicLink/magicLinkCore.d.ts +54 -33
  36. package/dist/auth/magicLink/magicLinkCore.d.ts.map +1 -1
  37. package/dist/auth/magicLink/magicLinkCore.js +61 -61
  38. package/dist/auth/magicLink/magicLinkCore.js.map +1 -1
  39. package/dist/auth/magicLink/redeemLanding.d.ts +4 -0
  40. package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
  41. package/dist/auth/magicLink/redeemLanding.js +12 -4
  42. package/dist/auth/magicLink/redeemLanding.js.map +1 -1
  43. package/dist/auth/magicLink/types.d.ts +4 -4
  44. package/dist/auth/principals.d.ts +2 -0
  45. package/dist/auth/principals.d.ts.map +1 -1
  46. package/dist/auth/principals.js +6 -2
  47. package/dist/auth/principals.js.map +1 -1
  48. package/dist/cache.d.ts +2 -0
  49. package/dist/cache.d.ts.map +1 -1
  50. package/dist/cache.js +3 -1
  51. package/dist/cache.js.map +1 -1
  52. package/dist/config.d.ts +346 -2
  53. package/dist/config.d.ts.map +1 -1
  54. package/dist/config.js +34 -4
  55. package/dist/config.js.map +1 -1
  56. package/dist/context.d.ts +20 -0
  57. package/dist/context.d.ts.map +1 -1
  58. package/dist/context.js +27 -19
  59. package/dist/context.js.map +1 -1
  60. package/dist/directives/Public.d.ts +2 -0
  61. package/dist/directives/Public.d.ts.map +1 -1
  62. package/dist/directives/Public.js +3 -1
  63. package/dist/directives/Public.js.map +1 -1
  64. package/dist/directives/RequireSystemUser.d.ts +2 -0
  65. package/dist/directives/RequireSystemUser.d.ts.map +1 -1
  66. package/dist/directives/RequireSystemUser.js +3 -1
  67. package/dist/directives/RequireSystemUser.js.map +1 -1
  68. package/dist/generated/graphql-schemas/__mj.d.ts +1021 -0
  69. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  70. package/dist/generated/graphql-schemas/__mj.js +7368 -2145
  71. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  72. package/dist/generic/CacheInvalidationResolver.d.ts +94 -4
  73. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  74. package/dist/generic/CacheInvalidationResolver.js +122 -3
  75. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  76. package/dist/generic/DeleteOptionsInput.d.ts +8 -1
  77. package/dist/generic/DeleteOptionsInput.d.ts.map +1 -1
  78. package/dist/generic/DeleteOptionsInput.js +1 -1
  79. package/dist/generic/DeleteOptionsInput.js.map +1 -1
  80. package/dist/generic/FireAndForgetHeartbeat.d.ts +18 -2
  81. package/dist/generic/FireAndForgetHeartbeat.d.ts.map +1 -1
  82. package/dist/generic/FireAndForgetHeartbeat.js +24 -6
  83. package/dist/generic/FireAndForgetHeartbeat.js.map +1 -1
  84. package/dist/generic/OrphanedConversationDetailReconciler.d.ts +31 -0
  85. package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -0
  86. package/dist/generic/OrphanedConversationDetailReconciler.js +215 -0
  87. package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -0
  88. package/dist/generic/PushStatusResolver.d.ts +48 -1
  89. package/dist/generic/PushStatusResolver.d.ts.map +1 -1
  90. package/dist/generic/PushStatusResolver.js +95 -4
  91. package/dist/generic/PushStatusResolver.js.map +1 -1
  92. package/dist/generic/ResolverBase.d.ts +18 -2
  93. package/dist/generic/ResolverBase.d.ts.map +1 -1
  94. package/dist/generic/ResolverBase.js +64 -55
  95. package/dist/generic/ResolverBase.js.map +1 -1
  96. package/dist/index.d.ts +9 -0
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +120 -11
  99. package/dist/index.js.map +1 -1
  100. package/dist/integration/CustomColumnPromoter.d.ts +2 -0
  101. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  102. package/dist/integration/CustomColumnPromoter.js +5 -1
  103. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  104. package/dist/integration/EntityMapLifecycle.d.ts +4 -0
  105. package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
  106. package/dist/integration/EntityMapLifecycle.js +10 -2
  107. package/dist/integration/EntityMapLifecycle.js.map +1 -1
  108. package/dist/logging/NoLog.d.ts +4 -0
  109. package/dist/logging/NoLog.d.ts.map +1 -1
  110. package/dist/logging/NoLog.js +10 -2
  111. package/dist/logging/NoLog.js.map +1 -1
  112. package/dist/logging/StartupLogger.d.ts +2 -0
  113. package/dist/logging/StartupLogger.d.ts.map +1 -1
  114. package/dist/logging/StartupLogger.js +5 -1
  115. package/dist/logging/StartupLogger.js.map +1 -1
  116. package/dist/logging/bootAudit.d.ts +11 -7
  117. package/dist/logging/bootAudit.d.ts.map +1 -1
  118. package/dist/logging/bootAudit.js +15 -7
  119. package/dist/logging/bootAudit.js.map +1 -1
  120. package/dist/logging/boundaryLogPayload.d.ts +4 -0
  121. package/dist/logging/boundaryLogPayload.d.ts.map +1 -1
  122. package/dist/logging/boundaryLogPayload.js +5 -1
  123. package/dist/logging/boundaryLogPayload.js.map +1 -1
  124. package/dist/logging/secretRedactor.d.ts +2 -0
  125. package/dist/logging/secretRedactor.d.ts.map +1 -1
  126. package/dist/logging/secretRedactor.js +8 -4
  127. package/dist/logging/secretRedactor.js.map +1 -1
  128. package/dist/logging/shortenForLog.d.ts +2 -0
  129. package/dist/logging/shortenForLog.d.ts.map +1 -1
  130. package/dist/logging/shortenForLog.js +7 -3
  131. package/dist/logging/shortenForLog.js.map +1 -1
  132. package/dist/logging/variablesLoggingMiddleware.d.ts +2 -0
  133. package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
  134. package/dist/logging/variablesLoggingMiddleware.js +8 -6
  135. package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
  136. package/dist/metadataRefreshSignal.d.ts +19 -0
  137. package/dist/metadataRefreshSignal.d.ts.map +1 -0
  138. package/dist/metadataRefreshSignal.js +45 -0
  139. package/dist/metadataRefreshSignal.js.map +1 -0
  140. package/dist/middleware/MJTenantFilterMiddleware.js +4 -4
  141. package/dist/multiTenancy/index.d.ts +8 -0
  142. package/dist/multiTenancy/index.d.ts.map +1 -1
  143. package/dist/multiTenancy/index.js +21 -5
  144. package/dist/multiTenancy/index.js.map +1 -1
  145. package/dist/realtimeWidget/WidgetRouter.d.ts +5 -0
  146. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
  147. package/dist/realtimeWidget/WidgetRouter.js +14 -10
  148. package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
  149. package/dist/realtimeWidget/WidgetSessionService.d.ts +6 -6
  150. package/dist/realtimeWidget/WidgetSessionService.js +27 -27
  151. package/dist/realtimeWidget/host-identity.d.ts +5 -1
  152. package/dist/realtimeWidget/host-identity.d.ts.map +1 -1
  153. package/dist/realtimeWidget/host-identity.js +11 -3
  154. package/dist/realtimeWidget/host-identity.js.map +1 -1
  155. package/dist/realtimeWidget/index.d.ts +2 -2
  156. package/dist/realtimeWidget/index.d.ts.map +1 -1
  157. package/dist/realtimeWidget/index.js +2 -2
  158. package/dist/realtimeWidget/index.js.map +1 -1
  159. package/dist/realtimeWidget/visitorIdentity.d.ts +21 -1
  160. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
  161. package/dist/realtimeWidget/visitorIdentity.js +16 -4
  162. package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
  163. package/dist/realtimeWidget/widgetCore.d.ts +48 -0
  164. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  165. package/dist/realtimeWidget/widgetCore.js +38 -10
  166. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  167. package/dist/realtimeWidget/widgetGuestElevation.d.ts +10 -6
  168. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  169. package/dist/realtimeWidget/widgetGuestElevation.js +14 -6
  170. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  171. package/dist/resolvers/AdhocQueryResolver.js +3 -3
  172. package/dist/resolvers/AgentRunStatusPublisher.d.ts +55 -0
  173. package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -0
  174. package/dist/resolvers/AgentRunStatusPublisher.js +141 -0
  175. package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -0
  176. package/dist/resolvers/ConversationRunEventsResolver.d.ts +90 -0
  177. package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -0
  178. package/dist/resolvers/ConversationRunEventsResolver.js +283 -0
  179. package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -0
  180. package/dist/resolvers/DuplicateEntryCheckResolver.d.ts +98 -0
  181. package/dist/resolvers/DuplicateEntryCheckResolver.d.ts.map +1 -0
  182. package/dist/resolvers/DuplicateEntryCheckResolver.js +227 -0
  183. package/dist/resolvers/DuplicateEntryCheckResolver.js.map +1 -0
  184. package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
  185. package/dist/resolvers/FetchEntityVectorsResolver.js +2 -1
  186. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  187. package/dist/resolvers/FileResolver.js +3 -3
  188. package/dist/resolvers/GeoResolver.d.ts +2 -2
  189. package/dist/resolvers/GeoResolver.js +4 -4
  190. package/dist/resolvers/GetDataResolver.d.ts +14 -0
  191. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  192. package/dist/resolvers/GetDataResolver.js +43 -15
  193. package/dist/resolvers/GetDataResolver.js.map +1 -1
  194. package/dist/resolvers/IntegrationDiscoveryResolver.js +2 -2
  195. package/dist/resolvers/ListOperationsResolver.d.ts +20 -0
  196. package/dist/resolvers/ListOperationsResolver.d.ts.map +1 -1
  197. package/dist/resolvers/ListOperationsResolver.js +68 -28
  198. package/dist/resolvers/ListOperationsResolver.js.map +1 -1
  199. package/dist/resolvers/MCPResolver.d.ts +11 -1
  200. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  201. package/dist/resolvers/MCPResolver.js +7 -3
  202. package/dist/resolvers/MCPResolver.js.map +1 -1
  203. package/dist/resolvers/MergeRecordsResolver.d.ts +7 -0
  204. package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
  205. package/dist/resolvers/MergeRecordsResolver.js +16 -2
  206. package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
  207. package/dist/resolvers/RealtimeBridgeResolver.js +3 -3
  208. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +44 -6
  209. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  210. package/dist/resolvers/RealtimeClientSessionResolver.js +93 -37
  211. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  212. package/dist/resolvers/RemoteBrowserActionResolver.js +5 -5
  213. package/dist/resolvers/RunAIAgentResolver.d.ts +8 -18
  214. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  215. package/dist/resolvers/RunAIAgentResolver.js +85 -184
  216. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  217. package/dist/resolvers/RunAIPromptResolver.d.ts +1 -1
  218. package/dist/resolvers/RunAIPromptResolver.js +2 -2
  219. package/dist/resolvers/RunDecisionResolver.d.ts +149 -0
  220. package/dist/resolvers/RunDecisionResolver.d.ts.map +1 -0
  221. package/dist/resolvers/RunDecisionResolver.js +396 -0
  222. package/dist/resolvers/RunDecisionResolver.js.map +1 -0
  223. package/dist/resolvers/RunTestResolver.js +5 -5
  224. package/dist/resolvers/SqlLoggingConfigResolver.d.ts +8 -4
  225. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  226. package/dist/resolvers/SqlLoggingConfigResolver.js +5 -5
  227. package/dist/resolvers/TaskGraphFrameResolver.d.ts +8 -1
  228. package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
  229. package/dist/resolvers/TaskGraphFrameResolver.js +6 -2
  230. package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
  231. package/dist/resolvers/VectorizeEntityResolver.d.ts +1 -1
  232. package/dist/resolvers/VectorizeEntityResolver.d.ts.map +1 -1
  233. package/dist/resolvers/VectorizeEntityResolver.js +14 -10
  234. package/dist/resolvers/VectorizeEntityResolver.js.map +1 -1
  235. package/dist/resolvers/adhoc-query-helpers.d.ts +6 -0
  236. package/dist/resolvers/adhoc-query-helpers.d.ts.map +1 -1
  237. package/dist/resolvers/adhoc-query-helpers.js +10 -2
  238. package/dist/resolvers/adhoc-query-helpers.js.map +1 -1
  239. package/dist/resolvers/artifact-routing.d.ts +8 -8
  240. package/dist/resolvers/artifact-routing.js +2 -2
  241. package/dist/resolvers/artifact-routing.js.map +1 -1
  242. package/dist/resolvers/meetingRecordingRegistration.d.ts +10 -2
  243. package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
  244. package/dist/resolvers/meetingRecordingRegistration.js +24 -8
  245. package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
  246. package/dist/resolvers/peaksSidecar.d.ts +4 -0
  247. package/dist/resolvers/peaksSidecar.d.ts.map +1 -1
  248. package/dist/resolvers/peaksSidecar.js +10 -2
  249. package/dist/resolvers/peaksSidecar.js.map +1 -1
  250. package/dist/rest/EntityCRUDHandler.d.ts +28 -0
  251. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  252. package/dist/rest/EntityCRUDHandler.js +20 -4
  253. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  254. package/dist/rest/MediaStreamHandler.d.ts +2 -0
  255. package/dist/rest/MediaStreamHandler.d.ts.map +1 -1
  256. package/dist/rest/MediaStreamHandler.js +10 -6
  257. package/dist/rest/MediaStreamHandler.js.map +1 -1
  258. package/dist/rest/OAuthCallbackHandler.d.ts +9 -0
  259. package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
  260. package/dist/rest/OAuthCallbackHandler.js +15 -3
  261. package/dist/rest/OAuthCallbackHandler.js.map +1 -1
  262. package/dist/rest/RESTEndpointHandler.d.ts +6 -4
  263. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  264. package/dist/rest/RESTEndpointHandler.js +15 -11
  265. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  266. package/dist/rest/RealtimeSdpBrokerHandler.d.ts +5 -1
  267. package/dist/rest/RealtimeSdpBrokerHandler.d.ts.map +1 -1
  268. package/dist/rest/RealtimeSdpBrokerHandler.js +12 -4
  269. package/dist/rest/RealtimeSdpBrokerHandler.js.map +1 -1
  270. package/dist/rest/SignatureWebhookHandler.d.ts +2 -0
  271. package/dist/rest/SignatureWebhookHandler.d.ts.map +1 -1
  272. package/dist/rest/SignatureWebhookHandler.js +5 -1
  273. package/dist/rest/SignatureWebhookHandler.js.map +1 -1
  274. package/dist/rest/UploadTokenManager.d.ts +24 -8
  275. package/dist/rest/UploadTokenManager.d.ts.map +1 -1
  276. package/dist/rest/UploadTokenManager.js +53 -21
  277. package/dist/rest/UploadTokenManager.js.map +1 -1
  278. package/dist/rest/ViewOperationsHandler.d.ts +20 -0
  279. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  280. package/dist/rest/ViewOperationsHandler.js +20 -4
  281. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  282. package/dist/rest/mediaRange.d.ts +4 -0
  283. package/dist/rest/mediaRange.d.ts.map +1 -1
  284. package/dist/rest/mediaRange.js +10 -2
  285. package/dist/rest/mediaRange.js.map +1 -1
  286. package/dist/rest/setupRESTEndpoints.d.ts +4 -0
  287. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  288. package/dist/rest/setupRESTEndpoints.js +13 -7
  289. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  290. package/dist/serverExtensionReservedRoots.d.ts +2 -0
  291. package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
  292. package/dist/serverExtensionReservedRoots.js +5 -1
  293. package/dist/serverExtensionReservedRoots.js.map +1 -1
  294. package/dist/services/TaskGraphActionRunner.d.ts +13 -8
  295. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  296. package/dist/services/TaskGraphActionRunner.js +16 -15
  297. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  298. package/dist/types.d.ts +2 -0
  299. package/dist/types.d.ts.map +1 -1
  300. package/dist/types.js +7 -3
  301. package/dist/types.js.map +1 -1
  302. package/dist/util.d.ts +6 -0
  303. package/dist/util.d.ts.map +1 -1
  304. package/dist/util.js +13 -5
  305. package/dist/util.js.map +1 -1
  306. package/package.json +94 -92
  307. package/src/__tests__/AgentRunStatusPublisher.test.ts +175 -0
  308. package/src/__tests__/DeleteOptionsInput.wireShape.test.ts +62 -0
  309. package/src/__tests__/DuplicateEntryCheckResolver.test.ts +300 -0
  310. package/src/__tests__/FileResolverPeaks.test.ts +13 -13
  311. package/src/__tests__/ListOperationsResolver.test.ts +17 -17
  312. package/src/__tests__/MediaStreamHandler.test.ts +28 -28
  313. package/src/__tests__/NoLog.test.ts +11 -11
  314. package/src/__tests__/PrimaryKeyAlwaysMapped.test.ts +10 -10
  315. package/src/__tests__/RESTEndpointHandler.test.ts +14 -14
  316. package/src/__tests__/RealtimeBridgeResolver.test.ts +4 -2
  317. package/src/__tests__/RealtimeClientSessionResolver.test.ts +216 -2
  318. package/src/__tests__/RealtimeSdpBrokerHandler.test.ts +6 -6
  319. package/src/__tests__/RefreshAdoptsNewColumns.test.ts +8 -8
  320. package/src/__tests__/RemoteBrowserActionRecovery.test.ts +7 -1
  321. package/src/__tests__/RemoteBrowserAudioStream.test.ts +7 -1
  322. package/src/__tests__/RemoteBrowserGoalEngine.test.ts +18 -18
  323. package/src/__tests__/RemoteBrowserSnapshot.test.ts +7 -1
  324. package/src/__tests__/ResolverBase.clientOldValues.test.ts +52 -0
  325. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +398 -0
  326. package/src/__tests__/RunAIAgentResolver.streaming.test.ts +18 -27
  327. package/src/__tests__/RunDecisionResolver.test.ts +699 -0
  328. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +131 -0
  329. package/src/__tests__/TaskGraphFrameResolver.test.ts +2 -2
  330. package/src/__tests__/VectorizeEntityResolver.test.ts +106 -0
  331. package/src/__tests__/WidgetSessionService.test.ts +8 -4
  332. package/src/__tests__/adhoc-query-helpers.test.ts +21 -21
  333. package/src/__tests__/bootAudit.test.ts +11 -11
  334. package/src/__tests__/boundaryLogPayload.test.ts +6 -6
  335. package/src/__tests__/cacheInvalidationRecordData.test.ts +177 -0
  336. package/src/__tests__/conversationRunEvents.test.ts +399 -0
  337. package/src/__tests__/databaseAbstraction.test.ts +12 -6
  338. package/src/__tests__/getDataTokenRedaction.test.ts +7 -7
  339. package/src/__tests__/initializeProviders.refresh.test.ts +4 -4
  340. package/src/__tests__/magicLink.test.ts +73 -134
  341. package/src/__tests__/magicLinkService.consume.test.ts +224 -0
  342. package/src/__tests__/meetingRecordingRegistration.test.ts +12 -12
  343. package/src/__tests__/metadataRefreshSignal.test.ts +78 -0
  344. package/src/__tests__/multiTenancy.security.test.ts +40 -40
  345. package/src/__tests__/multiTenancy.test.ts +18 -18
  346. package/src/__tests__/newUsers.test.ts +24 -23
  347. package/src/__tests__/orphanedConversationDetailReconciler.test.ts +283 -0
  348. package/src/__tests__/principals.test.ts +22 -22
  349. package/src/__tests__/pushStatusFanOut.test.ts +206 -0
  350. package/src/__tests__/pushStatusResolver.filter.test.ts +8 -8
  351. package/src/__tests__/secretRedactor.failOpen.test.ts +12 -12
  352. package/src/__tests__/secretRedactor.test.ts +12 -12
  353. package/src/__tests__/serverExtensionReservedRoots.test.ts +7 -7
  354. package/src/__tests__/subscriptionRedaction.test.ts +5 -5
  355. package/src/__tests__/unifiedAuth.test.ts +15 -9
  356. package/src/__tests__/visitorIdentity.resolve.test.ts +6 -6
  357. package/src/__tests__/widget.test.ts +45 -45
  358. package/src/__tests__/widgetGuestElevation.test.ts +7 -7
  359. package/src/__tests__/widgetHostIdentity.test.ts +14 -14
  360. package/src/agentSessions/ReturningVisitorRecap.ts +12 -1
  361. package/src/agentSessions/SessionManager.ts +2 -2
  362. package/src/agentSessions/remoteBrowserGoalEngine.ts +30 -5
  363. package/src/auth/AuthProviderCatalogRouter.ts +6 -1
  364. package/src/auth/__tests__/backward-compatibility.test.ts +4 -3
  365. package/src/auth/index.ts +43 -28
  366. package/src/auth/initializeProviders.ts +25 -5
  367. package/src/auth/magicLink/MagicLinkRouter.ts +28 -10
  368. package/src/auth/magicLink/MagicLinkService.ts +71 -52
  369. package/src/auth/magicLink/index.ts +7 -7
  370. package/src/auth/magicLink/magicLinkCore.ts +96 -64
  371. package/src/auth/magicLink/redeemLanding.ts +14 -4
  372. package/src/auth/magicLink/types.ts +54 -54
  373. package/src/auth/newUsers.ts +1 -1
  374. package/src/auth/principals.ts +11 -2
  375. package/src/cache.ts +4 -1
  376. package/src/config.ts +37 -4
  377. package/src/context.ts +37 -24
  378. package/src/directives/Public.ts +4 -1
  379. package/src/directives/RequireSystemUser.ts +4 -1
  380. package/src/generated/graphql-schemas/__mj.ts +3674 -4
  381. package/src/generic/CacheInvalidationResolver.ts +148 -4
  382. package/src/generic/DeleteOptionsInput.ts +9 -2
  383. package/src/generic/FireAndForgetHeartbeat.ts +35 -16
  384. package/src/generic/OrphanedConversationDetailReconciler.ts +267 -0
  385. package/src/generic/PushStatusResolver.ts +118 -8
  386. package/src/generic/ResolverBase.ts +65 -57
  387. package/src/generic/RunViewResolver.ts +22 -22
  388. package/src/generic/__tests__/FireAndForgetHeartbeat.test.ts +7 -7
  389. package/src/index.ts +137 -11
  390. package/src/integration/CustomColumnPromoter.ts +6 -1
  391. package/src/integration/EntityMapLifecycle.ts +20 -2
  392. package/src/logging/NoLog.ts +16 -2
  393. package/src/logging/StartupLogger.ts +6 -1
  394. package/src/logging/bootAudit.ts +26 -16
  395. package/src/logging/boundaryLogPayload.ts +8 -1
  396. package/src/logging/secretRedactor.ts +14 -9
  397. package/src/logging/shortenForLog.ts +8 -3
  398. package/src/logging/variablesLoggingMiddleware.ts +9 -6
  399. package/src/metadataRefreshSignal.ts +45 -0
  400. package/src/middleware/MJTenantFilterMiddleware.ts +4 -4
  401. package/src/multiTenancy/index.ts +29 -5
  402. package/src/realtimeWidget/WidgetRouter.ts +15 -10
  403. package/src/realtimeWidget/WidgetSessionService.ts +76 -76
  404. package/src/realtimeWidget/host-identity.ts +24 -10
  405. package/src/realtimeWidget/index.ts +3 -3
  406. package/src/realtimeWidget/visitorIdentity.ts +39 -8
  407. package/src/realtimeWidget/widgetCore.ts +75 -10
  408. package/src/realtimeWidget/widgetGuestElevation.ts +25 -12
  409. package/src/resolvers/AdhocQueryResolver.ts +3 -3
  410. package/src/resolvers/AgentRunStatusPublisher.ts +175 -0
  411. package/src/resolvers/AgentSessionResolver.ts +3 -3
  412. package/src/resolvers/ColorResolver.ts +6 -6
  413. package/src/resolvers/ComponentRegistryResolver.ts +36 -36
  414. package/src/resolvers/ConversationRunEventsResolver.ts +308 -0
  415. package/src/resolvers/DuplicateEntryCheckResolver.ts +232 -0
  416. package/src/resolvers/EntityCommunicationsResolver.ts +4 -4
  417. package/src/resolvers/ExecuteRemoteOperationResolver.ts +9 -9
  418. package/src/resolvers/FetchEntityVectorsResolver.ts +2 -1
  419. package/src/resolvers/FileResolver.ts +42 -42
  420. package/src/resolvers/GeoResolver.ts +4 -4
  421. package/src/resolvers/GetDataResolver.ts +50 -15
  422. package/src/resolvers/IntegrationDiscoveryResolver.ts +2 -2
  423. package/src/resolvers/ListOperationsResolver.ts +78 -28
  424. package/src/resolvers/MCPResolver.ts +30 -15
  425. package/src/resolvers/MergeRecordsResolver.ts +14 -2
  426. package/src/resolvers/QueryResolver.ts +13 -13
  427. package/src/resolvers/RealtimeBridgeResolver.ts +3 -3
  428. package/src/resolvers/RealtimeClientSessionResolver.ts +96 -38
  429. package/src/resolvers/RemoteBrowserActionResolver.ts +5 -5
  430. package/src/resolvers/RunAIAgentResolver.ts +134 -239
  431. package/src/resolvers/RunAIPromptResolver.ts +22 -22
  432. package/src/resolvers/RunDecisionResolver.ts +435 -0
  433. package/src/resolvers/RunTemplateResolver.ts +4 -4
  434. package/src/resolvers/RunTestResolver.ts +25 -25
  435. package/src/resolvers/SqlLoggingConfigResolver.ts +56 -56
  436. package/src/resolvers/TaskGraphFrameResolver.ts +37 -28
  437. package/src/resolvers/TelemetryResolver.ts +79 -79
  438. package/src/resolvers/VectorizeEntityResolver.ts +16 -11
  439. package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +40 -38
  440. package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +93 -0
  441. package/src/resolvers/__tests__/artifact-routing.test.ts +23 -23
  442. package/src/resolvers/adhoc-query-helpers.ts +19 -2
  443. package/src/resolvers/artifact-routing.ts +19 -19
  444. package/src/resolvers/meetingRecordingRegistration.ts +44 -10
  445. package/src/resolvers/peaksSidecar.ts +12 -2
  446. package/src/rest/EntityCRUDHandler.ts +24 -4
  447. package/src/rest/MediaStreamHandler.ts +11 -6
  448. package/src/rest/OAuthCallbackHandler.ts +25 -7
  449. package/src/rest/RESTEndpointHandler.ts +20 -15
  450. package/src/rest/RealtimeSdpBrokerHandler.ts +14 -4
  451. package/src/rest/SignatureWebhookHandler.ts +6 -1
  452. package/src/rest/UploadTokenManager.ts +66 -30
  453. package/src/rest/ViewOperationsHandler.ts +24 -4
  454. package/src/rest/mediaRange.ts +16 -6
  455. package/src/rest/setupRESTEndpoints.ts +24 -12
  456. package/src/serverExtensionReservedRoots.ts +6 -1
  457. package/src/services/TaskGraphActionRunner.ts +16 -15
  458. package/src/types.ts +21 -16
  459. package/src/util.ts +16 -6
@@ -9,7 +9,7 @@ import { CreateBridgeRealtimeSession, FinalizeBridgeCoAgentRuns, GetRealtimeMode
9
9
  import { AIBridgeEngine } from '@memberjunction/ai-bridge-server';
10
10
  import { SessionManager } from '../agentSessions/SessionManager.js';
11
11
  import { NotificationEngine } from '@memberjunction/notifications';
12
- import { registerMeetingRecordingFile, correlateRecordingStart } from './meetingRecordingRegistration.js';
12
+ import { RegisterMeetingRecordingFile, CorrelateRecordingStart } from './meetingRecordingRegistration.js';
13
13
 
14
14
  /**
15
15
  * Binds the agent realtime-session factory onto the LiveKit room coordinator's model-session creation seam.
@@ -458,7 +458,7 @@ export class RealtimeBridgeResolver extends ResolverBase {
458
458
  // Best-effort: correlate the live recording with the room's Meeting-Room Conversation (if it exists
459
459
  // yet) by stamping its EgressID. Never fail the start on this — the stop-flow resolves/creates it.
460
460
  const provider = GetReadWriteProvider(context.providers) as unknown as IMetadataProvider;
461
- void correlateRecordingStart(input.RoomName, info.EgressID, user, provider);
461
+ void CorrelateRecordingStart(input.RoomName, info.EgressID, user, provider);
462
462
 
463
463
  return { Success: true, EgressID: info.EgressID, Status: info.Status };
464
464
  } catch (error) {
@@ -487,7 +487,7 @@ export class RealtimeBridgeResolver extends ResolverBase {
487
487
  // Register the completed egress MP4 as a Files row on the Meeting-Room Conversation. Best-effort:
488
488
  // any failure (e.g. storage provider not configured) leaves RecordingFileID unset but still
489
489
  // returns the successful stop result.
490
- const registration = await registerMeetingRecordingFile(
490
+ const registration = await RegisterMeetingRecordingFile(
491
491
  { EgressID: info.EgressID, RoomName: info.RoomName, OutputLocation: info.OutputLocation, OutputSizeBytes: info.OutputSizeBytes },
492
492
  user,
493
493
  provider,
@@ -26,7 +26,7 @@
26
26
  */
27
27
  import { Resolver, Mutation, Arg, Ctx, Int, Float, ObjectType, Field, PubSub, PubSubEngine } from 'type-graphql';
28
28
  import { AppContext, UserPayload } from '../types.js';
29
- import { AuthorizationEvaluator, UserInfo, IMetadataProvider, LogError, LogStatus, RunView } from '@memberjunction/core';
29
+ import { AuthorizationEvaluator, UserInfo, IMetadataProvider, LogError, LogStatus, RunView, BaseEntity } from '@memberjunction/core';
30
30
  import { UUIDsEqual, IsValidUUID } from '@memberjunction/global';
31
31
  import {
32
32
  MJAIAgentEntity,
@@ -62,7 +62,7 @@ import { ResolverBase } from '../generic/ResolverBase.js';
62
62
  import { PUSH_STATUS_UPDATES_TOPIC } from '../generic/PushStatusResolver.js';
63
63
  import { GetReadWriteProvider } from '../util.js';
64
64
  import { SessionManager } from '../agentSessions/index.js';
65
- import { resolveWidgetGuestRunContext, ResolveScopedAnonymousRunUser } from '../realtimeWidget/widgetGuestElevation.js';
65
+ import { ResolveWidgetGuestRunContext, ResolveScopedAnonymousRunUser } from '../realtimeWidget/widgetGuestElevation.js';
66
66
 
67
67
  /**
68
68
  * Progress steps worth narrating to the realtime model — mirrors the normal agent-run path's filter
@@ -381,6 +381,31 @@ export class RealtimeClientSessionResolver extends ResolverBase {
381
381
  private readonly clientSessionService = new RealtimeClientSessionService();
382
382
  private readonly sessionManager = new SessionManager(this.clientSessionService);
383
383
 
384
+ /**
385
+ * The reason a `Save()`/`Delete()` returned false, for a log line. `CompleteMessage` renders
386
+ * `Message`, `Error` and every `Errors[]` entry (validation errors included, since `Save()`
387
+ * runs `Validate()` and records its errors there), so there is no separate `Validate()` call.
388
+ * When a subclass refused the write without recording anything, say so explicitly instead of
389
+ * "unknown error", which is what hid MJ#4791.
390
+ *
391
+ * Only a NULL `LatestResult` proves the refusal happened before the provider (nothing was
392
+ * registered at all). A SUCCESS `LatestResult` is an earlier save on the same instance — the
393
+ * refusal registered nothing — so its text must never be reported as this failure's reason.
394
+ */
395
+ private describeSaveFailure(entity: BaseEntity): string {
396
+ const latest = entity.LatestResult;
397
+ if (!latest) {
398
+ return `no failure detail recorded (LatestResult null; ResultHistory length ${entity.ResultHistory.length}) ` +
399
+ '— the write was refused before reaching the provider';
400
+ }
401
+ if (latest.Success) {
402
+ return 'no failure detail recorded (latest result entry is a prior success; ' +
403
+ `ResultHistory length ${entity.ResultHistory.length})`;
404
+ }
405
+ const detail = latest.CompleteMessage?.trim();
406
+ return detail || `no failure detail recorded (LatestResult empty; ResultHistory length ${entity.ResultHistory.length})`;
407
+ }
408
+
384
409
  /**
385
410
  * Start a client-direct realtime voice session targeting `targetAgentId`.
386
411
  *
@@ -593,7 +618,9 @@ export class RealtimeClientSessionResolver extends ResolverBase {
593
618
  // Junction-link any artifacts the delegated run produced into the session's conversation
594
619
  // history (best-effort) — so chat, session review, and resume carryover can all see them.
595
620
  // Runs as `runUser`: the junction entity is not among an anonymous caller's relay grants.
596
- await this.linkDelegatedArtifactsToConversation(session, Artifacts, runUser, provider);
621
+ // The hidden anchor detail it may need to create, though, is written by the CALLER (#4791)
622
+ // — same reason `persistDirectActionTurn` is: the System user is not the conversation owner.
623
+ await this.linkDelegatedArtifactsToConversation(session, Artifacts, runUser, contextUser, provider);
597
624
 
598
625
  await this.sessionManager.Heartbeat(agentSessionId, contextUser, provider);
599
626
  return ResultJson;
@@ -657,7 +684,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
657
684
  session.Config_ = JSON.stringify(next);
658
685
  if (!(await session.Save())) {
659
686
  LogError(
660
- `RealtimeClientSessionResolver.updatePendingFeedbackRunID save failed: ${session.LatestResult?.CompleteMessage ?? 'unknown error'}`,
687
+ `RealtimeClientSessionResolver.updatePendingFeedbackRunID save failed for session ${session.ID}: ${this.describeSaveFailure(session)}`,
661
688
  );
662
689
  }
663
690
  }
@@ -1812,7 +1839,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
1812
1839
  const saved = await session.Save();
1813
1840
  if (!saved) {
1814
1841
  LogError(
1815
- `RealtimeClientSessionResolver.persistObservabilityRunIDs save failed: ${session.LatestResult?.CompleteMessage ?? 'unknown error'}`,
1842
+ `RealtimeClientSessionResolver.persistObservabilityRunIDs save failed for session ${session.ID}: ${this.describeSaveFailure(session)}`,
1816
1843
  );
1817
1844
  }
1818
1845
  }
@@ -1930,7 +1957,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
1930
1957
  if (!saved) {
1931
1958
  LogError(
1932
1959
  `SaveSessionChannelState: save failed for session ${agentSessionID} / channel ${channelID}: ` +
1933
- `${row.LatestResult?.CompleteMessage ?? 'unknown error'}`,
1960
+ `${this.describeSaveFailure(row)}`,
1934
1961
  );
1935
1962
  }
1936
1963
  return saved;
@@ -2313,7 +2340,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2313
2340
  artifact.UserID = contextUser.ID;
2314
2341
  artifact.Visibility = 'Always';
2315
2342
  if (!(await artifact.Save())) {
2316
- const message = `SaveSessionChannelArtifact: artifact save failed: ${artifact.LatestResult?.CompleteMessage ?? 'unknown error'}`;
2343
+ const message = `SaveSessionChannelArtifact: artifact save failed for session ${session.ID}: ${this.describeSaveFailure(artifact)}`;
2317
2344
  LogError(message);
2318
2345
  return { Success: false, ErrorMessage: message, ConversationDetailLinked: false };
2319
2346
  }
@@ -2325,7 +2352,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2325
2352
  version.Content = contentJson;
2326
2353
  version.UserID = contextUser.ID;
2327
2354
  if (!(await version.Save())) {
2328
- const message = `SaveSessionChannelArtifact: artifact version save failed: ${version.LatestResult?.CompleteMessage ?? 'unknown error'}`;
2355
+ const message = `SaveSessionChannelArtifact: artifact version save failed for session ${session.ID} (artifact ${artifact.ID}): ${this.describeSaveFailure(version)}`;
2329
2356
  LogError(message);
2330
2357
  return { Success: false, ErrorMessage: message, ArtifactID: artifact.ID, ConversationDetailLinked: false };
2331
2358
  }
@@ -2383,13 +2410,22 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2383
2410
  * queries (which scan junctions across ALL details) still surface the artifact. This is the
2384
2411
  * least-invasive correct anchor — no fake visible message, no orphaned artifact.
2385
2412
  *
2413
+ * TWO PRINCIPALS, deliberately: the lookup (`findLatestSessionDetailID`) and the junction row
2414
+ * itself (`saveDetailArtifactJunction`, `MJ: Conversation Detail Artifacts`) run as `runUser`
2415
+ * (elevated for a scoped-anonymous caller) — that junction entity is outside an anonymous
2416
+ * caller's relay grants. The hidden ANCHOR `Conversation Detail` this may need to create runs as
2417
+ * `callerUser` instead: like every other `MJ: Conversation Details` write, the System user is
2418
+ * refused because it is not the conversation's owner (see {@link persistDirectActionTurn},
2419
+ * issue #4791) — only the actual caller can create it.
2420
+ *
2386
2421
  * Strictly best-effort: every failure path logs and returns; a relayed tool call NEVER fails
2387
2422
  * because history linking did.
2388
2423
  */
2389
2424
  private async linkDelegatedArtifactsToConversation(
2390
2425
  session: MJAIAgentSessionEntity,
2391
2426
  artifacts: DelegatedRunArtifact[] | undefined,
2392
- contextUser: UserInfo,
2427
+ runUser: UserInfo,
2428
+ callerUser: UserInfo,
2393
2429
  provider: IMetadataProvider,
2394
2430
  ): Promise<void> {
2395
2431
  if (!artifacts || artifacts.length === 0 || !session.ConversationID) {
@@ -2397,13 +2433,13 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2397
2433
  }
2398
2434
  try {
2399
2435
  const detailID =
2400
- (await this.findLatestSessionDetailID(session, contextUser, provider)) ??
2401
- (await this.createHiddenSessionAnchorDetail(session, contextUser, provider));
2436
+ (await this.findLatestSessionDetailID(session, runUser, provider)) ??
2437
+ (await this.createHiddenSessionAnchorDetail(session, callerUser, provider));
2402
2438
  if (!detailID) {
2403
2439
  return; // anchor unavailable — logged in the helpers
2404
2440
  }
2405
2441
  for (const artifact of artifacts) {
2406
- await this.saveDetailArtifactJunction(detailID, artifact.ArtifactVersionID, contextUser, provider);
2442
+ await this.saveDetailArtifactJunction(detailID, artifact.ArtifactVersionID, runUser, provider);
2407
2443
  }
2408
2444
  } catch (error) {
2409
2445
  LogError(`ExecuteRealtimeSessionTool: delegated-artifact history link failed: ${(error as Error).message}`);
@@ -2444,25 +2480,25 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2444
2480
  */
2445
2481
  private async createHiddenSessionAnchorDetail(
2446
2482
  session: MJAIAgentSessionEntity,
2447
- contextUser: UserInfo,
2483
+ callerUser: UserInfo,
2448
2484
  provider: IMetadataProvider,
2449
2485
  ): Promise<string | null> {
2450
- const detail = await provider.GetEntityObject<MJConversationDetailEntity>(CONVERSATION_DETAIL_ENTITY, contextUser);
2486
+ const detail = await provider.GetEntityObject<MJConversationDetailEntity>(CONVERSATION_DETAIL_ENTITY, callerUser);
2451
2487
  detail.NewRecord();
2452
2488
  detail.ConversationID = session.ConversationID;
2453
2489
  detail.Role = 'AI';
2454
2490
  detail.HiddenToUser = true;
2455
2491
  detail.Message = 'Artifacts produced during a realtime session (system anchor).';
2456
2492
  detail.AgentSessionID = session.ID;
2457
- // Attribute the anchor to the SESSION owner, not the (possibly elevated) writer — identical
2458
- // for every non-elevated caller, whose ownership of the session is already proven.
2493
+ // Attribute to the SESSION owner — the caller writing this row, whose ownership
2494
+ // `loadOwnedActiveSession` already proved.
2459
2495
  detail.UserID = session.UserID;
2460
2496
  if (await detail.Save()) {
2461
2497
  return detail.ID;
2462
2498
  }
2463
2499
  LogError(
2464
2500
  `ExecuteRealtimeSessionTool: hidden anchor detail save failed for session ${session.ID}: ` +
2465
- `${detail.LatestResult?.CompleteMessage ?? 'unknown error'}`,
2501
+ `${this.describeSaveFailure(detail)}`,
2466
2502
  );
2467
2503
  return null;
2468
2504
  }
@@ -2489,7 +2525,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2489
2525
  if (!saved) {
2490
2526
  LogError(
2491
2527
  `RealtimeClientSessionResolver: artifact junction save failed for detail ${conversationDetailID} / version ${artifactVersionID}: ` +
2492
- `${junction.LatestResult?.CompleteMessage ?? 'unknown error'}`,
2528
+ `${this.describeSaveFailure(junction)}`,
2493
2529
  );
2494
2530
  }
2495
2531
  return saved;
@@ -2529,7 +2565,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2529
2565
  if (!(await row.Save())) {
2530
2566
  LogError(
2531
2567
  `SaveSessionChannelArtifact: LastActiveAt stamp failed for session ${agentSessionID} / channel ${channelID}: ` +
2532
- `${row.LatestResult?.CompleteMessage ?? 'unknown error'}`,
2568
+ `${this.describeSaveFailure(row)}`,
2533
2569
  );
2534
2570
  }
2535
2571
  } catch (error) {
@@ -2668,17 +2704,11 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2668
2704
  userPayload: UserPayload,
2669
2705
  providers: AppContext['providers'],
2670
2706
  ): Promise<number | undefined> {
2671
- const elevation = await resolveWidgetGuestRunContext(userPayload, GetReadWriteProvider(providers));
2672
- const minutes = elevation?.widget.VoiceMaxSessionMinutes;
2707
+ const elevation = await ResolveWidgetGuestRunContext(userPayload, GetReadWriteProvider(providers));
2708
+ const minutes = elevation?.Widget.VoiceMaxSessionMinutes;
2673
2709
  return minutes && minutes > 0 ? minutes * 60 : undefined;
2674
2710
  }
2675
2711
 
2676
- /**
2677
- * Persists a single transcript turn as a `Conversation Detail` stamped with the session's
2678
- * conversation, the mapped role, the turn text, the session id, and the owning user.
2679
- *
2680
- * @returns The boolean save result (logs `CompleteMessage` on failure).
2681
- */
2682
2712
  /**
2683
2713
  * Stamps `RecordingStartedAt` (the recording `t0` alignment origin) + `RecordingMedia` on a
2684
2714
  * just-started session when the browser captured WITH consent. Best-effort: a parse/save failure
@@ -2705,11 +2735,18 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2705
2735
  session.RecordingMedia = 'Audio';
2706
2736
  if (!(await session.Save())) {
2707
2737
  LogError(
2708
- `RealtimeClientSessionResolver.stampRecordingStart save failed: ${session.LatestResult?.CompleteMessage ?? 'unknown error'}`,
2738
+ `RealtimeClientSessionResolver.stampRecordingStart save failed for session ${session.ID}: ${this.describeSaveFailure(session)}`,
2709
2739
  );
2710
2740
  }
2711
2741
  }
2712
2742
 
2743
+ /**
2744
+ * Persists a single transcript turn as a `Conversation Detail` stamped with the session's
2745
+ * conversation, the mapped role, the turn text, the session id, and the owning user.
2746
+ *
2747
+ * @returns The boolean save result. On failure it logs the session, the write user and the
2748
+ * reason from {@link describeSaveFailure}.
2749
+ */
2713
2750
  private async persistTranscriptTurn(
2714
2751
  session: MJAIAgentSessionEntity,
2715
2752
  role: string,
@@ -2739,7 +2776,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2739
2776
  const saved = await detail.Save();
2740
2777
  if (!saved) {
2741
2778
  LogError(
2742
- `RealtimeClientSessionResolver.persistTranscriptTurn save failed: ${detail.LatestResult?.CompleteMessage ?? 'unknown error'}`,
2779
+ `RealtimeClientSessionResolver.persistTranscriptTurn save failed for session ${session.ID} (write user ${contextUser.ID}): ${this.describeSaveFailure(detail)}`,
2743
2780
  );
2744
2781
  }
2745
2782
  return saved;
@@ -2780,8 +2817,13 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2780
2817
  // ⚠️ ELEVATING INSTEAD WAS TRIED AND IS A TRAP. `ResolveScopedAnonymousRunUser` returns
2781
2818
  // `UserCache.GetSystemUser()`, which on this deployment resolves to the unconfigured
2782
2819
  // placeholder `not.set@nowhere.com` ("Configured provisioning user not found; falling back
2783
- // to an Owner"). Saving as a user that does not exist returns false with a NULL
2784
- // `LatestResult` — indistinguishable from a permission denial, and just as silent.
2820
+ // to an Owner"). That user EXISTS — it is not a missing/invalid principal — and even carries
2821
+ // full CRUD on `MJ: Conversation Details`. It is refused anyway:
2822
+ // `MJConversationDetailEntityExtended`'s owner gate accepts only the conversation's OWNER or
2823
+ // an Edit/Owner Resource Permission grantee, and the System user is neither. Measured on
2824
+ // MJ#4791 (before the core-entities fix that now records the denial): `Save()` → `false`,
2825
+ // `LatestResult` null — indistinguishable from a permission denial, and just as silent. The
2826
+ // denial itself still happens; that fix only made it stop being silent.
2785
2827
  const writeUser = contextUser;
2786
2828
  const rv = RunView.FromMetadataProvider(provider);
2787
2829
  const result = await rv.RunView<MJConversationDetailEntity>(
@@ -2802,8 +2844,8 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2802
2844
  //
2803
2845
  // `ResultType: 'entity_object'` hands back hydrated entities, but they do not carry the
2804
2846
  // context user the way `GetEntityObject(entity, user)` does — so `Save()` ran with no
2805
- // principal and failed with an EMPTY message ("unknown error"), which is what the elevation
2806
- // fix above looked like when it was still broken. The insert path beside this one has
2847
+ // principal and failed with an EMPTY message ("unknown error"), which is what an empty-message
2848
+ // failure here looked like before the re-load. The insert path beside this one has
2807
2849
  // always used `GetEntityObject`; this now matches it, which is also why they now succeed
2808
2850
  // and fail for the same reasons.
2809
2851
  const previous = await provider.GetEntityObject<MJConversationDetailEntity>(
@@ -2835,7 +2877,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2835
2877
  `RealtimeClientSessionResolver.replacePreviousTranscriptTurn save failed for session `
2836
2878
  + `${session.ID} — the ${mappedRole} turn keeps its PREVIOUS, shorter text and the `
2837
2879
  + `transcript now understates what was said: `
2838
- + `${previous.LatestResult?.CompleteMessage || JSON.stringify(previous.LatestResult ?? null)}`,
2880
+ + `${this.describeSaveFailure(previous)}`,
2839
2881
  );
2840
2882
  }
2841
2883
  return saved;
@@ -2855,6 +2897,23 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2855
2897
  * Stored as stable facts (Role: 'AI', HiddenToUser: true, ExternalID: callId, CompletionTime: durationMs,
2856
2898
  * Message: JSON-serialized tool facts) so that session review can reconstruct the action card dynamically
2857
2899
  * on load (Option 1) without polluting user-facing speech chat bubbles.
2900
+ *
2901
+ * Writes as the CALLER, never the elevated run user (issue #4791). Owning the session
2902
+ * (`loadOwnedActiveSession`'s gate has already run on every path here) does NOT imply owning
2903
+ * the conversation: the conversation id was client-supplied at session start. What authorizes
2904
+ * this write is the save itself, evaluated for the caller — the conversation owner gate in
2905
+ * `MJConversationDetailEntityExtended`, plus the caller's own entity permission and Create RLS
2906
+ * on `MJ: Conversation Details` (for the magic-link role that RLS scopes by the invite's
2907
+ * `ScopeResourceID`, and the role belongs to a downstream app, not MJ core). That is why
2908
+ * writing as the caller is safe even though the conversation id originated client-side.
2909
+ * Elevating to the System user would bypass RLS entirely, and the owner gate refuses it anyway
2910
+ * because the System user is not the conversation owner. Measured on MJ#4791 (before the
2911
+ * core-entities fix that now records the denial): `Save()` returned `false` with a NULL `LatestResult` and an empty
2912
+ * `ResultHistory` — indistinguishable from any other silent failure. Elevating this write is
2913
+ * what silently dropped both hidden tool-execution turns of a real magic-link session; the
2914
+ * denial itself still happens today, only its silence was fixed separately.
2915
+ * `ResolveScopedAnonymousRunUser` elevates AI-**run**-entity writes only (prompt runs, agent
2916
+ * runs, the relayed dispatch itself) — never this one.
2858
2917
  */
2859
2918
  private async persistDirectActionTurn(
2860
2919
  session: MJAIAgentSessionEntity,
@@ -2870,10 +2929,9 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2870
2929
  return false;
2871
2930
  }
2872
2931
  try {
2873
- const writeUser = ResolveScopedAnonymousRunUser(contextUser);
2874
2932
  const detail = await provider.GetEntityObject<MJConversationDetailEntity>(
2875
2933
  CONVERSATION_DETAIL_ENTITY,
2876
- writeUser,
2934
+ contextUser,
2877
2935
  );
2878
2936
  detail.NewRecord();
2879
2937
  detail.ConversationID = session.ConversationID;
@@ -2915,13 +2973,13 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2915
2973
  const saved = await detail.Save();
2916
2974
  if (!saved) {
2917
2975
  LogError(
2918
- `RealtimeClientSessionResolver.persistDirectActionTurn save failed: ${detail.LatestResult?.CompleteMessage ?? 'unknown error'}`,
2976
+ `RealtimeClientSessionResolver.persistDirectActionTurn save failed for session ${session.ID} (tool '${toolName}', call ${callId ?? 'n/a'}, write user ${contextUser.ID}): ${this.describeSaveFailure(detail)}`,
2919
2977
  );
2920
2978
  }
2921
2979
  return saved;
2922
2980
  } catch (error) {
2923
2981
  const message = error instanceof Error ? error.message : String(error);
2924
- LogError(`RealtimeClientSessionResolver.persistDirectActionTurn unexpected error: ${message}`);
2982
+ LogError(`RealtimeClientSessionResolver.persistDirectActionTurn unexpected error for session ${session.ID}: ${message}`);
2925
2983
  return false;
2926
2984
  }
2927
2985
  }
@@ -22,7 +22,7 @@ import { UserInfo, IMetadataProvider, LogError } from '@memberjunction/core';
22
22
  import { UUIDsEqual } from '@memberjunction/global';
23
23
  import { MJAIAgentSessionEntity, MJAIAgentEntity } from '@memberjunction/core-entities';
24
24
  import { NormalizeInstanceKey, RemoteBrowserEngine } from '@memberjunction/remote-browser-server';
25
- import { beginBrowserGoalStep, finalizeBrowserGoalStep, extractCoAgentRunID } from '../agentSessions/remoteBrowserGoalEngine.js';
25
+ import { BeginBrowserGoalStep, FinalizeBrowserGoalStep, ExtractCoAgentRunID } from '../agentSessions/remoteBrowserGoalEngine.js';
26
26
  import { RemoteBrowserGoalRegistry } from '../agentSessions/remoteBrowserGoalRegistry.js';
27
27
  import { randomUUID } from 'node:crypto';
28
28
  import {
@@ -400,8 +400,8 @@ export class RemoteBrowserActionResolver extends ResolverBase {
400
400
  const providerName = await this.resolveProviderName(session, contextUser, provider);
401
401
  // Observability: nest this goal's many prompt runs under ONE "Browser goal" step on the realtime
402
402
  // co-agent run (when the session has one). Best-effort — a null step just means the goal runs unlinked.
403
- const coAgentRunID = extractCoAgentRunID(session.Config_);
404
- const goalStep = await beginBrowserGoalStep(provider, contextUser, coAgentRunID, goal);
403
+ const coAgentRunID = ExtractCoAgentRunID(session.Config_);
404
+ const goalStep = await BeginBrowserGoalStep(provider, contextUser, coAgentRunID, goal);
405
405
 
406
406
  // ASYNC START: a goal loop can run for minutes; do NOT hold this request open for it (browser
407
407
  // fetch / proxy / janitor timeouts would kill the request while the loop runs on, and the agent
@@ -420,14 +420,14 @@ export class RemoteBrowserActionResolver extends ResolverBase {
420
420
  AgentRunStepID: goalStep?.ID,
421
421
  })
422
422
  .then(async (result) => {
423
- await finalizeBrowserGoalStep(goalStep, result);
423
+ await FinalizeBrowserGoalStep(goalStep, result);
424
424
  RemoteBrowserGoalRegistry.Instance.Complete(agentSessionID, goalRunID, result);
425
425
  })
426
426
  .catch(async (err) => {
427
427
  const message = err instanceof Error ? err.message : String(err);
428
428
  LogError(`ExecuteRemoteBrowserGoal failed (provider='${providerName}'): ${message}`);
429
429
  const failure = { Success: false, Status: 'Error', Detail: `Remote browser error (${providerName}): ${message}` };
430
- await finalizeBrowserGoalStep(goalStep, failure);
430
+ await FinalizeBrowserGoalStep(goalStep, failure);
431
431
  RemoteBrowserGoalRegistry.Instance.Complete(agentSessionID, goalRunID, failure);
432
432
  });
433
433