@memberjunction/server 6.1.4 → 6.2.0-edge.1

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 (435) 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/exampleNewUserSubClass.js +2 -1
  16. package/dist/auth/exampleNewUserSubClass.js.map +1 -1
  17. package/dist/auth/index.d.ts +20 -1
  18. package/dist/auth/index.d.ts.map +1 -1
  19. package/dist/auth/index.js +20 -10
  20. package/dist/auth/index.js.map +1 -1
  21. package/dist/auth/initializeProviders.d.ts +8 -0
  22. package/dist/auth/initializeProviders.d.ts.map +1 -1
  23. package/dist/auth/initializeProviders.js +21 -5
  24. package/dist/auth/initializeProviders.js.map +1 -1
  25. package/dist/auth/magicLink/MagicLinkRouter.d.ts +9 -0
  26. package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
  27. package/dist/auth/magicLink/MagicLinkRouter.js +22 -10
  28. package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
  29. package/dist/auth/magicLink/MagicLinkService.d.ts +17 -15
  30. package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
  31. package/dist/auth/magicLink/MagicLinkService.js +65 -51
  32. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  33. package/dist/auth/magicLink/index.d.ts +2 -2
  34. package/dist/auth/magicLink/index.d.ts.map +1 -1
  35. package/dist/auth/magicLink/index.js +2 -2
  36. package/dist/auth/magicLink/index.js.map +1 -1
  37. package/dist/auth/magicLink/magicLinkCore.d.ts +54 -33
  38. package/dist/auth/magicLink/magicLinkCore.d.ts.map +1 -1
  39. package/dist/auth/magicLink/magicLinkCore.js +61 -61
  40. package/dist/auth/magicLink/magicLinkCore.js.map +1 -1
  41. package/dist/auth/magicLink/redeemLanding.d.ts +4 -0
  42. package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
  43. package/dist/auth/magicLink/redeemLanding.js +12 -4
  44. package/dist/auth/magicLink/redeemLanding.js.map +1 -1
  45. package/dist/auth/magicLink/types.d.ts +4 -4
  46. package/dist/auth/principals.d.ts +2 -0
  47. package/dist/auth/principals.d.ts.map +1 -1
  48. package/dist/auth/principals.js +6 -2
  49. package/dist/auth/principals.js.map +1 -1
  50. package/dist/cache.d.ts +2 -0
  51. package/dist/cache.d.ts.map +1 -1
  52. package/dist/cache.js +3 -1
  53. package/dist/cache.js.map +1 -1
  54. package/dist/config.d.ts +293 -2
  55. package/dist/config.d.ts.map +1 -1
  56. package/dist/config.js +11 -4
  57. package/dist/config.js.map +1 -1
  58. package/dist/context.d.ts +20 -0
  59. package/dist/context.d.ts.map +1 -1
  60. package/dist/context.js +27 -19
  61. package/dist/context.js.map +1 -1
  62. package/dist/directives/Public.d.ts +2 -0
  63. package/dist/directives/Public.d.ts.map +1 -1
  64. package/dist/directives/Public.js +3 -1
  65. package/dist/directives/Public.js.map +1 -1
  66. package/dist/directives/RequireSystemUser.d.ts +2 -0
  67. package/dist/directives/RequireSystemUser.d.ts.map +1 -1
  68. package/dist/directives/RequireSystemUser.js +3 -1
  69. package/dist/directives/RequireSystemUser.js.map +1 -1
  70. package/dist/generated/graphql-schemas/__mj.d.ts +266 -4
  71. package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
  72. package/dist/generated/graphql-schemas/__mj.js +1304 -0
  73. package/dist/generated/graphql-schemas/__mj.js.map +1 -1
  74. package/dist/generic/CacheInvalidationResolver.d.ts +8 -2
  75. package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
  76. package/dist/generic/CacheInvalidationResolver.js +7 -3
  77. package/dist/generic/CacheInvalidationResolver.js.map +1 -1
  78. package/dist/generic/FireAndForgetHeartbeat.d.ts +3 -1
  79. package/dist/generic/FireAndForgetHeartbeat.d.ts.map +1 -1
  80. package/dist/generic/FireAndForgetHeartbeat.js +8 -4
  81. package/dist/generic/FireAndForgetHeartbeat.js.map +1 -1
  82. package/dist/generic/PushStatusResolver.d.ts +10 -1
  83. package/dist/generic/PushStatusResolver.d.ts.map +1 -1
  84. package/dist/generic/PushStatusResolver.js +11 -3
  85. package/dist/generic/PushStatusResolver.js.map +1 -1
  86. package/dist/generic/ResolverBase.d.ts +27 -1
  87. package/dist/generic/ResolverBase.d.ts.map +1 -1
  88. package/dist/generic/ResolverBase.js +64 -6
  89. package/dist/generic/ResolverBase.js.map +1 -1
  90. package/dist/index.d.ts +6 -0
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +29 -6
  93. package/dist/index.js.map +1 -1
  94. package/dist/integration/CustomColumnPromoter.d.ts +2 -0
  95. package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
  96. package/dist/integration/CustomColumnPromoter.js +5 -1
  97. package/dist/integration/CustomColumnPromoter.js.map +1 -1
  98. package/dist/integration/EntityMapLifecycle.d.ts +4 -0
  99. package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
  100. package/dist/integration/EntityMapLifecycle.js +10 -2
  101. package/dist/integration/EntityMapLifecycle.js.map +1 -1
  102. package/dist/logging/NoLog.d.ts +4 -0
  103. package/dist/logging/NoLog.d.ts.map +1 -1
  104. package/dist/logging/NoLog.js +10 -2
  105. package/dist/logging/NoLog.js.map +1 -1
  106. package/dist/logging/StartupLogger.d.ts +2 -0
  107. package/dist/logging/StartupLogger.d.ts.map +1 -1
  108. package/dist/logging/StartupLogger.js +5 -1
  109. package/dist/logging/StartupLogger.js.map +1 -1
  110. package/dist/logging/bootAudit.d.ts +11 -7
  111. package/dist/logging/bootAudit.d.ts.map +1 -1
  112. package/dist/logging/bootAudit.js +15 -7
  113. package/dist/logging/bootAudit.js.map +1 -1
  114. package/dist/logging/boundaryLogPayload.d.ts +4 -0
  115. package/dist/logging/boundaryLogPayload.d.ts.map +1 -1
  116. package/dist/logging/boundaryLogPayload.js +5 -1
  117. package/dist/logging/boundaryLogPayload.js.map +1 -1
  118. package/dist/logging/secretRedactor.d.ts +2 -0
  119. package/dist/logging/secretRedactor.d.ts.map +1 -1
  120. package/dist/logging/secretRedactor.js +8 -4
  121. package/dist/logging/secretRedactor.js.map +1 -1
  122. package/dist/logging/shortenForLog.d.ts +2 -0
  123. package/dist/logging/shortenForLog.d.ts.map +1 -1
  124. package/dist/logging/shortenForLog.js +7 -3
  125. package/dist/logging/shortenForLog.js.map +1 -1
  126. package/dist/logging/variablesLoggingMiddleware.d.ts +2 -0
  127. package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
  128. package/dist/logging/variablesLoggingMiddleware.js +8 -6
  129. package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
  130. package/dist/metadataRefreshSignal.d.ts +19 -0
  131. package/dist/metadataRefreshSignal.d.ts.map +1 -0
  132. package/dist/metadataRefreshSignal.js +45 -0
  133. package/dist/metadataRefreshSignal.js.map +1 -0
  134. package/dist/middleware/MJTenantFilterMiddleware.js +4 -4
  135. package/dist/multiTenancy/index.d.ts +8 -0
  136. package/dist/multiTenancy/index.d.ts.map +1 -1
  137. package/dist/multiTenancy/index.js +21 -5
  138. package/dist/multiTenancy/index.js.map +1 -1
  139. package/dist/realtimeWidget/WidgetRouter.d.ts +5 -0
  140. package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
  141. package/dist/realtimeWidget/WidgetRouter.js +14 -10
  142. package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
  143. package/dist/realtimeWidget/WidgetSessionService.d.ts +6 -6
  144. package/dist/realtimeWidget/WidgetSessionService.js +27 -27
  145. package/dist/realtimeWidget/host-identity.d.ts +5 -1
  146. package/dist/realtimeWidget/host-identity.d.ts.map +1 -1
  147. package/dist/realtimeWidget/host-identity.js +11 -3
  148. package/dist/realtimeWidget/host-identity.js.map +1 -1
  149. package/dist/realtimeWidget/index.d.ts +2 -2
  150. package/dist/realtimeWidget/index.d.ts.map +1 -1
  151. package/dist/realtimeWidget/index.js +2 -2
  152. package/dist/realtimeWidget/index.js.map +1 -1
  153. package/dist/realtimeWidget/visitorIdentity.d.ts +21 -1
  154. package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
  155. package/dist/realtimeWidget/visitorIdentity.js +16 -4
  156. package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
  157. package/dist/realtimeWidget/widgetCore.d.ts +48 -0
  158. package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
  159. package/dist/realtimeWidget/widgetCore.js +38 -10
  160. package/dist/realtimeWidget/widgetCore.js.map +1 -1
  161. package/dist/realtimeWidget/widgetGuestElevation.d.ts +10 -6
  162. package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
  163. package/dist/realtimeWidget/widgetGuestElevation.js +14 -6
  164. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  165. package/dist/resolvers/AdhocQueryResolver.js +3 -3
  166. package/dist/resolvers/FetchEntityVectorsResolver.js +2 -2
  167. package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
  168. package/dist/resolvers/FileResolver.js +3 -3
  169. package/dist/resolvers/GeoResolver.d.ts +2 -2
  170. package/dist/resolvers/GeoResolver.js +4 -4
  171. package/dist/resolvers/GetDataResolver.d.ts +14 -0
  172. package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
  173. package/dist/resolvers/GetDataResolver.js +43 -15
  174. package/dist/resolvers/GetDataResolver.js.map +1 -1
  175. package/dist/resolvers/IntegrationDiscoveryResolver.js +2 -2
  176. package/dist/resolvers/ListOperationsResolver.d.ts +20 -0
  177. package/dist/resolvers/ListOperationsResolver.d.ts.map +1 -1
  178. package/dist/resolvers/ListOperationsResolver.js +68 -28
  179. package/dist/resolvers/ListOperationsResolver.js.map +1 -1
  180. package/dist/resolvers/MCPResolver.d.ts +11 -1
  181. package/dist/resolvers/MCPResolver.d.ts.map +1 -1
  182. package/dist/resolvers/MCPResolver.js +7 -3
  183. package/dist/resolvers/MCPResolver.js.map +1 -1
  184. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  185. package/dist/resolvers/QuerySystemUserResolver.js +2 -1
  186. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  187. package/dist/resolvers/RealtimeBridgeResolver.js +3 -3
  188. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +37 -0
  189. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  190. package/dist/resolvers/RealtimeClientSessionResolver.js +101 -11
  191. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  192. package/dist/resolvers/RemoteBrowserActionResolver.js +5 -5
  193. package/dist/resolvers/RunAIAgentResolver.d.ts +10 -4
  194. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  195. package/dist/resolvers/RunAIAgentResolver.js +74 -42
  196. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  197. package/dist/resolvers/RunAIPromptResolver.d.ts +1 -1
  198. package/dist/resolvers/RunAIPromptResolver.js +2 -2
  199. package/dist/resolvers/RunTestResolver.js +5 -5
  200. package/dist/resolvers/SearchEntitiesResolver.d.ts.map +1 -1
  201. package/dist/resolvers/SearchEntitiesResolver.js +3 -1
  202. package/dist/resolvers/SearchEntitiesResolver.js.map +1 -1
  203. package/dist/resolvers/SearchKnowledgeResolver.d.ts +1 -0
  204. package/dist/resolvers/SearchKnowledgeResolver.d.ts.map +1 -1
  205. package/dist/resolvers/SearchKnowledgeResolver.js +5 -0
  206. package/dist/resolvers/SearchKnowledgeResolver.js.map +1 -1
  207. package/dist/resolvers/SearchKnowledgeSystemUserResolver.d.ts.map +1 -1
  208. package/dist/resolvers/SearchKnowledgeSystemUserResolver.js +1 -0
  209. package/dist/resolvers/SearchKnowledgeSystemUserResolver.js.map +1 -1
  210. package/dist/resolvers/SqlLoggingConfigResolver.d.ts +8 -4
  211. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  212. package/dist/resolvers/SqlLoggingConfigResolver.js +5 -5
  213. package/dist/resolvers/TaskGraphFrameResolver.d.ts +8 -1
  214. package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
  215. package/dist/resolvers/TaskGraphFrameResolver.js +6 -2
  216. package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
  217. package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
  218. package/dist/resolvers/TransactionGroupResolver.js +53 -4
  219. package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
  220. package/dist/resolvers/adhoc-query-helpers.d.ts +6 -0
  221. package/dist/resolvers/adhoc-query-helpers.d.ts.map +1 -1
  222. package/dist/resolvers/adhoc-query-helpers.js +10 -2
  223. package/dist/resolvers/adhoc-query-helpers.js.map +1 -1
  224. package/dist/resolvers/artifact-routing.d.ts +8 -8
  225. package/dist/resolvers/artifact-routing.js +2 -2
  226. package/dist/resolvers/artifact-routing.js.map +1 -1
  227. package/dist/resolvers/meetingRecordingRegistration.d.ts +10 -2
  228. package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
  229. package/dist/resolvers/meetingRecordingRegistration.js +24 -8
  230. package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
  231. package/dist/resolvers/peaksSidecar.d.ts +4 -0
  232. package/dist/resolvers/peaksSidecar.d.ts.map +1 -1
  233. package/dist/resolvers/peaksSidecar.js +10 -2
  234. package/dist/resolvers/peaksSidecar.js.map +1 -1
  235. package/dist/rest/EntityCRUDHandler.d.ts +28 -0
  236. package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
  237. package/dist/rest/EntityCRUDHandler.js +20 -4
  238. package/dist/rest/EntityCRUDHandler.js.map +1 -1
  239. package/dist/rest/MediaStreamHandler.d.ts +2 -0
  240. package/dist/rest/MediaStreamHandler.d.ts.map +1 -1
  241. package/dist/rest/MediaStreamHandler.js +10 -6
  242. package/dist/rest/MediaStreamHandler.js.map +1 -1
  243. package/dist/rest/OAuthCallbackHandler.d.ts +9 -0
  244. package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
  245. package/dist/rest/OAuthCallbackHandler.js +15 -3
  246. package/dist/rest/OAuthCallbackHandler.js.map +1 -1
  247. package/dist/rest/RESTEndpointHandler.d.ts +6 -4
  248. package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
  249. package/dist/rest/RESTEndpointHandler.js +15 -11
  250. package/dist/rest/RESTEndpointHandler.js.map +1 -1
  251. package/dist/rest/RealtimeSdpBrokerHandler.d.ts +5 -1
  252. package/dist/rest/RealtimeSdpBrokerHandler.d.ts.map +1 -1
  253. package/dist/rest/RealtimeSdpBrokerHandler.js +12 -4
  254. package/dist/rest/RealtimeSdpBrokerHandler.js.map +1 -1
  255. package/dist/rest/SignatureWebhookHandler.d.ts +2 -0
  256. package/dist/rest/SignatureWebhookHandler.d.ts.map +1 -1
  257. package/dist/rest/SignatureWebhookHandler.js +5 -1
  258. package/dist/rest/SignatureWebhookHandler.js.map +1 -1
  259. package/dist/rest/UploadTokenManager.d.ts +24 -8
  260. package/dist/rest/UploadTokenManager.d.ts.map +1 -1
  261. package/dist/rest/UploadTokenManager.js +53 -21
  262. package/dist/rest/UploadTokenManager.js.map +1 -1
  263. package/dist/rest/ViewOperationsHandler.d.ts +20 -0
  264. package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
  265. package/dist/rest/ViewOperationsHandler.js +20 -4
  266. package/dist/rest/ViewOperationsHandler.js.map +1 -1
  267. package/dist/rest/mediaRange.d.ts +4 -0
  268. package/dist/rest/mediaRange.d.ts.map +1 -1
  269. package/dist/rest/mediaRange.js +10 -2
  270. package/dist/rest/mediaRange.js.map +1 -1
  271. package/dist/rest/setupRESTEndpoints.d.ts +4 -0
  272. package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
  273. package/dist/rest/setupRESTEndpoints.js +13 -7
  274. package/dist/rest/setupRESTEndpoints.js.map +1 -1
  275. package/dist/serverExtensionReservedRoots.d.ts +2 -0
  276. package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
  277. package/dist/serverExtensionReservedRoots.js +5 -1
  278. package/dist/serverExtensionReservedRoots.js.map +1 -1
  279. package/dist/services/MJStorageBlobStore.d.ts +41 -0
  280. package/dist/services/MJStorageBlobStore.d.ts.map +1 -0
  281. package/dist/services/MJStorageBlobStore.js +160 -0
  282. package/dist/services/MJStorageBlobStore.js.map +1 -0
  283. package/dist/services/TaskGraphActionRunner.d.ts +13 -8
  284. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
  285. package/dist/services/TaskGraphActionRunner.js +16 -15
  286. package/dist/services/TaskGraphActionRunner.js.map +1 -1
  287. package/dist/types.d.ts +2 -0
  288. package/dist/types.d.ts.map +1 -1
  289. package/dist/types.js +7 -3
  290. package/dist/types.js.map +1 -1
  291. package/dist/util.d.ts +12 -3
  292. package/dist/util.d.ts.map +1 -1
  293. package/dist/util.js +19 -8
  294. package/dist/util.js.map +1 -1
  295. package/package.json +92 -92
  296. package/src/__tests__/FileResolverPeaks.test.ts +13 -13
  297. package/src/__tests__/ListOperationsResolver.test.ts +17 -17
  298. package/src/__tests__/MediaStreamHandler.test.ts +28 -28
  299. package/src/__tests__/NoLog.test.ts +11 -11
  300. package/src/__tests__/PrimaryKeyAlwaysMapped.test.ts +10 -10
  301. package/src/__tests__/RESTEndpointHandler.test.ts +14 -14
  302. package/src/__tests__/RealtimeBridgeResolver.test.ts +4 -2
  303. package/src/__tests__/RealtimeClientSessionResolver.test.ts +229 -0
  304. package/src/__tests__/RealtimeSdpBrokerHandler.test.ts +6 -6
  305. package/src/__tests__/RefreshAdoptsNewColumns.test.ts +8 -8
  306. package/src/__tests__/RemoteBrowserGoalEngine.test.ts +18 -18
  307. package/src/__tests__/ResolverBase.isaPromotionCreate.test.ts +412 -0
  308. package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +228 -0
  309. package/src/__tests__/SearchEntitiesResolver.readOnlyFallback.test.ts +78 -0
  310. package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +129 -0
  311. package/src/__tests__/TaskGraphFrameResolver.test.ts +2 -2
  312. package/src/__tests__/TransactionGroupResolver.refusals.test.ts +290 -0
  313. package/src/__tests__/WidgetSessionService.test.ts +8 -4
  314. package/src/__tests__/adhoc-query-helpers.test.ts +21 -21
  315. package/src/__tests__/bootAudit.test.ts +11 -11
  316. package/src/__tests__/boundaryLogPayload.test.ts +6 -6
  317. package/src/__tests__/databaseAbstraction.test.ts +12 -6
  318. package/src/__tests__/getDataTokenRedaction.test.ts +7 -7
  319. package/src/__tests__/initializeProviders.refresh.test.ts +4 -4
  320. package/src/__tests__/magicLink.test.ts +73 -134
  321. package/src/__tests__/magicLinkService.consume.test.ts +224 -0
  322. package/src/__tests__/meetingRecordingRegistration.test.ts +12 -12
  323. package/src/__tests__/metadataRefreshSignal.test.ts +78 -0
  324. package/src/__tests__/multiTenancy.security.test.ts +40 -40
  325. package/src/__tests__/multiTenancy.test.ts +18 -18
  326. package/src/__tests__/newUsers.test.ts +24 -23
  327. package/src/__tests__/principals.test.ts +22 -22
  328. package/src/__tests__/pushStatusResolver.filter.test.ts +8 -8
  329. package/src/__tests__/secretRedactor.failOpen.test.ts +12 -12
  330. package/src/__tests__/secretRedactor.test.ts +12 -12
  331. package/src/__tests__/serverExtensionReservedRoots.test.ts +7 -7
  332. package/src/__tests__/subscriptionRedaction.test.ts +5 -5
  333. package/src/__tests__/unifiedAuth.test.ts +15 -9
  334. package/src/__tests__/visitorIdentity.resolve.test.ts +6 -6
  335. package/src/__tests__/widget.test.ts +45 -45
  336. package/src/__tests__/widgetGuestElevation.test.ts +7 -7
  337. package/src/__tests__/widgetHostIdentity.test.ts +14 -14
  338. package/src/agentSessions/ReturningVisitorRecap.ts +12 -1
  339. package/src/agentSessions/SessionManager.ts +2 -2
  340. package/src/agentSessions/remoteBrowserGoalEngine.ts +30 -5
  341. package/src/auth/AuthProviderCatalogRouter.ts +6 -1
  342. package/src/auth/__tests__/backward-compatibility.test.ts +3 -3
  343. package/src/auth/exampleNewUserSubClass.ts +2 -2
  344. package/src/auth/index.ts +43 -28
  345. package/src/auth/initializeProviders.ts +25 -5
  346. package/src/auth/magicLink/MagicLinkRouter.ts +28 -10
  347. package/src/auth/magicLink/MagicLinkService.ts +71 -52
  348. package/src/auth/magicLink/index.ts +7 -7
  349. package/src/auth/magicLink/magicLinkCore.ts +96 -64
  350. package/src/auth/magicLink/redeemLanding.ts +14 -4
  351. package/src/auth/magicLink/types.ts +54 -54
  352. package/src/auth/newUsers.ts +1 -1
  353. package/src/auth/principals.ts +11 -2
  354. package/src/cache.ts +4 -1
  355. package/src/config.ts +14 -4
  356. package/src/context.ts +37 -24
  357. package/src/directives/Public.ts +4 -1
  358. package/src/directives/RequireSystemUser.ts +4 -1
  359. package/src/generated/graphql-schemas/__mj.ts +933 -5
  360. package/src/generic/CacheInvalidationResolver.ts +12 -4
  361. package/src/generic/FireAndForgetHeartbeat.ts +19 -14
  362. package/src/generic/PushStatusResolver.ts +21 -7
  363. package/src/generic/ResolverBase.ts +66 -5
  364. package/src/generic/RunViewResolver.ts +22 -22
  365. package/src/generic/__tests__/FireAndForgetHeartbeat.test.ts +7 -7
  366. package/src/index.ts +34 -7
  367. package/src/integration/CustomColumnPromoter.ts +6 -1
  368. package/src/integration/EntityMapLifecycle.ts +20 -2
  369. package/src/logging/NoLog.ts +16 -2
  370. package/src/logging/StartupLogger.ts +6 -1
  371. package/src/logging/bootAudit.ts +26 -16
  372. package/src/logging/boundaryLogPayload.ts +8 -1
  373. package/src/logging/secretRedactor.ts +14 -9
  374. package/src/logging/shortenForLog.ts +8 -3
  375. package/src/logging/variablesLoggingMiddleware.ts +9 -6
  376. package/src/metadataRefreshSignal.ts +45 -0
  377. package/src/middleware/MJTenantFilterMiddleware.ts +4 -4
  378. package/src/multiTenancy/index.ts +29 -5
  379. package/src/realtimeWidget/WidgetRouter.ts +15 -10
  380. package/src/realtimeWidget/WidgetSessionService.ts +76 -76
  381. package/src/realtimeWidget/host-identity.ts +24 -10
  382. package/src/realtimeWidget/index.ts +3 -3
  383. package/src/realtimeWidget/visitorIdentity.ts +39 -8
  384. package/src/realtimeWidget/widgetCore.ts +75 -10
  385. package/src/realtimeWidget/widgetGuestElevation.ts +25 -12
  386. package/src/resolvers/AdhocQueryResolver.ts +3 -3
  387. package/src/resolvers/AgentSessionResolver.ts +3 -3
  388. package/src/resolvers/ColorResolver.ts +6 -6
  389. package/src/resolvers/ComponentRegistryResolver.ts +36 -36
  390. package/src/resolvers/EntityCommunicationsResolver.ts +4 -4
  391. package/src/resolvers/ExecuteRemoteOperationResolver.ts +9 -9
  392. package/src/resolvers/FetchEntityVectorsResolver.ts +2 -2
  393. package/src/resolvers/FileResolver.ts +42 -42
  394. package/src/resolvers/GeoResolver.ts +4 -4
  395. package/src/resolvers/GetDataResolver.ts +50 -15
  396. package/src/resolvers/IntegrationDiscoveryResolver.ts +2 -2
  397. package/src/resolvers/ListOperationsResolver.ts +78 -28
  398. package/src/resolvers/MCPResolver.ts +30 -15
  399. package/src/resolvers/QueryResolver.ts +13 -13
  400. package/src/resolvers/QuerySystemUserResolver.ts +2 -1
  401. package/src/resolvers/RealtimeBridgeResolver.ts +3 -3
  402. package/src/resolvers/RealtimeClientSessionResolver.ts +126 -13
  403. package/src/resolvers/RemoteBrowserActionResolver.ts +5 -5
  404. package/src/resolvers/RunAIAgentResolver.ts +118 -76
  405. package/src/resolvers/RunAIPromptResolver.ts +22 -22
  406. package/src/resolvers/RunTemplateResolver.ts +4 -4
  407. package/src/resolvers/RunTestResolver.ts +25 -25
  408. package/src/resolvers/SearchEntitiesResolver.ts +3 -1
  409. package/src/resolvers/SearchKnowledgeResolver.ts +4 -0
  410. package/src/resolvers/SearchKnowledgeSystemUserResolver.ts +1 -0
  411. package/src/resolvers/SqlLoggingConfigResolver.ts +56 -56
  412. package/src/resolvers/TaskGraphFrameResolver.ts +37 -28
  413. package/src/resolvers/TelemetryResolver.ts +79 -79
  414. package/src/resolvers/TransactionGroupResolver.ts +57 -4
  415. package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +40 -38
  416. package/src/resolvers/__tests__/artifact-routing.test.ts +23 -23
  417. package/src/resolvers/adhoc-query-helpers.ts +19 -2
  418. package/src/resolvers/artifact-routing.ts +19 -19
  419. package/src/resolvers/meetingRecordingRegistration.ts +44 -10
  420. package/src/resolvers/peaksSidecar.ts +12 -2
  421. package/src/rest/EntityCRUDHandler.ts +24 -4
  422. package/src/rest/MediaStreamHandler.ts +11 -6
  423. package/src/rest/OAuthCallbackHandler.ts +25 -7
  424. package/src/rest/RESTEndpointHandler.ts +20 -15
  425. package/src/rest/RealtimeSdpBrokerHandler.ts +14 -4
  426. package/src/rest/SignatureWebhookHandler.ts +6 -1
  427. package/src/rest/UploadTokenManager.ts +66 -30
  428. package/src/rest/ViewOperationsHandler.ts +24 -4
  429. package/src/rest/mediaRange.ts +16 -6
  430. package/src/rest/setupRESTEndpoints.ts +24 -12
  431. package/src/serverExtensionReservedRoots.ts +6 -1
  432. package/src/services/MJStorageBlobStore.ts +209 -0
  433. package/src/services/TaskGraphActionRunner.ts +16 -15
  434. package/src/types.ts +21 -16
  435. package/src/util.ts +22 -9
@@ -19,7 +19,7 @@ import {
19
19
  } from '@memberjunction/ai-mcp-client';
20
20
  import { AppContext } from '../types.js';
21
21
  import { ResolverBase } from '../generic/ResolverBase.js';
22
- import { publishStatusUpdate } from '../generic/PushStatusResolver.js';
22
+ import { PublishStatusUpdate } from '../generic/PushStatusResolver.js';
23
23
  import { GraphQLJSONObject } from 'graphql-type-json';
24
24
  import { configInfo } from '../config.js';
25
25
 
@@ -493,13 +493,13 @@ export class MCPToolSummary {
493
493
  @ObjectType()
494
494
  export class MCPToolPageResult {
495
495
  @Field(() => [MCPToolSummary])
496
- items: MCPToolSummary[];
496
+ items: MCPToolSummary[]; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
497
497
 
498
498
  @Field(() => Int)
499
- totalCount: number;
499
+ totalCount: number; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
500
500
 
501
501
  @Field()
502
- hasMore: boolean;
502
+ hasMore: boolean; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
503
503
  }
504
504
 
505
505
  /**
@@ -508,13 +508,13 @@ export class MCPToolPageResult {
508
508
  @ObjectType()
509
509
  export class MCPToolServerCount {
510
510
  @Field()
511
- serverID: string;
511
+ serverID: string; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
512
512
 
513
513
  @Field()
514
- serverName: string;
514
+ serverName: string; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
515
515
 
516
516
  @Field(() => Int)
517
- count: number;
517
+ count: number; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
518
518
  }
519
519
 
520
520
  /**
@@ -524,10 +524,10 @@ export class MCPToolServerCount {
524
524
  @ObjectType()
525
525
  export class MCPToolCategoryCount {
526
526
  @Field()
527
- category: string;
527
+ category: string; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
528
528
 
529
529
  @Field(() => Int)
530
- count: number;
530
+ count: number; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
531
531
  }
532
532
 
533
533
  /**
@@ -536,13 +536,13 @@ export class MCPToolCategoryCount {
536
536
  @ObjectType()
537
537
  export class MCPToolCountsResult {
538
538
  @Field(() => Int)
539
- totalCount: number;
539
+ totalCount: number; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
540
540
 
541
541
  @Field(() => [MCPToolServerCount])
542
- countByServer: MCPToolServerCount[];
542
+ countByServer: MCPToolServerCount[]; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
543
543
 
544
544
  @Field(() => [MCPToolCategoryCount])
545
- countByCategory: MCPToolCategoryCount[];
545
+ countByCategory: MCPToolCategoryCount[]; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
546
546
  }
547
547
 
548
548
  /**
@@ -1247,7 +1247,7 @@ export class MCPResolver extends ResolverBase {
1247
1247
  * @returns OAuth event notification
1248
1248
  */
1249
1249
  @Subscription(() => MCPOAuthEventNotification, { topics: MCP_OAUTH_EVENTS_TOPIC })
1250
- onMCPOAuthEvent(
1250
+ onMCPOAuthEvent( // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
1251
1251
  @Root() payload: MCPOAuthEventPayload
1252
1252
  ): MCPOAuthEventNotification {
1253
1253
  return {
@@ -1361,7 +1361,7 @@ export class MCPResolver extends ResolverBase {
1361
1361
  result
1362
1362
  };
1363
1363
 
1364
- publishStatusUpdate(pubSub, { sessionId, ownerUserId, message: JSON.stringify(progressMessage) });
1364
+ PublishStatusUpdate(pubSub, { sessionId, ownerUserId, message: JSON.stringify(progressMessage) });
1365
1365
  }
1366
1366
 
1367
1367
  /**
@@ -1653,7 +1653,7 @@ export class MCPResolver extends ResolverBase {
1653
1653
  * @param pubSub - PubSub engine
1654
1654
  * @param event - OAuth event details
1655
1655
  */
1656
- export async function publishMCPOAuthEvent(
1656
+ export async function PublishMCPOAuthEvent(
1657
1657
  pubSub: PubSubEngine,
1658
1658
  event: {
1659
1659
  eventType: MCPOAuthEventType;
@@ -1676,3 +1676,18 @@ export async function publishMCPOAuthEvent(
1676
1676
 
1677
1677
  await pubSub.publish(MCP_OAUTH_EVENTS_TOPIC, payload);
1678
1678
  }
1679
+
1680
+ /** @deprecated Use {@link PublishMCPOAuthEvent}. */
1681
+ export async function publishMCPOAuthEvent(
1682
+ pubSub: PubSubEngine,
1683
+ event: {
1684
+ eventType: MCPOAuthEventType;
1685
+ connectionId: string;
1686
+ authorizationUrl?: string;
1687
+ stateParameter?: string;
1688
+ errorMessage?: string;
1689
+ requiresReauthorization?: boolean;
1690
+ }
1691
+ ): Promise<void> {
1692
+ return PublishMCPOAuthEvent(pubSub, event);
1693
+ }
@@ -97,34 +97,34 @@ export class RunQueryResultType {
97
97
  @InputType()
98
98
  export class RunQueryCacheStatusInput {
99
99
  @Field(() => String, { description: 'The maximum __mj_UpdatedAt value from cached results' })
100
- maxUpdatedAt: string;
100
+ maxUpdatedAt: string; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
101
101
 
102
102
  @Field(() => Int, { description: 'The number of rows in cached results' })
103
- rowCount: number;
103
+ rowCount: number; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
104
104
  }
105
105
 
106
106
  @InputType()
107
107
  export class RunQueryWithCacheCheckInput {
108
108
  @Field(() => RunQueryInput, { description: 'The RunQuery parameters' })
109
- params: RunQueryInput;
109
+ params: RunQueryInput; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
110
110
 
111
111
  @Field(() => RunQueryCacheStatusInput, {
112
112
  nullable: true,
113
113
  description: 'Optional cache status - if provided, server will check if cache is current'
114
114
  })
115
- cacheStatus?: RunQueryCacheStatusInput;
115
+ cacheStatus?: RunQueryCacheStatusInput; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
116
116
  }
117
117
 
118
118
  @ObjectType()
119
119
  export class RunQueryWithCacheCheckResultOutput {
120
120
  @Field(() => Int, { description: 'The index of this query in the batch request' })
121
- queryIndex: number;
121
+ queryIndex: number; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
122
122
 
123
123
  @Field(() => String, { description: 'The query ID' })
124
- queryId: string;
124
+ queryId: string; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
125
125
 
126
126
  @Field(() => String, { description: "'current', 'stale', 'no_validation', or 'error'" })
127
- status: string;
127
+ status: string; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
128
128
 
129
129
  @Field(() => String, {
130
130
  nullable: true,
@@ -133,25 +133,25 @@ export class RunQueryWithCacheCheckResultOutput {
133
133
  Results?: string;
134
134
 
135
135
  @Field(() => String, { nullable: true, description: 'Max __mj_UpdatedAt from results when stale' })
136
- maxUpdatedAt?: string;
136
+ maxUpdatedAt?: string; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
137
137
 
138
138
  @Field(() => Int, { nullable: true, description: 'Row count of results when stale' })
139
- rowCount?: number;
139
+ rowCount?: number; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
140
140
 
141
141
  @Field(() => String, { nullable: true, description: 'Error message if status is error' })
142
- errorMessage?: string;
142
+ errorMessage?: string; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
143
143
  }
144
144
 
145
145
  @ObjectType()
146
146
  export class RunQueriesWithCacheCheckOutput {
147
147
  @Field(() => Boolean, { description: 'Whether the overall operation succeeded' })
148
- success: boolean;
148
+ success: boolean; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
149
149
 
150
150
  @Field(() => [RunQueryWithCacheCheckResultOutput], { description: 'Results for each query in the batch' })
151
- results: RunQueryWithCacheCheckResultOutput[];
151
+ results: RunQueryWithCacheCheckResultOutput[]; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
152
152
 
153
153
  @Field(() => String, { nullable: true, description: 'Overall error message if success is false' })
154
- errorMessage?: string;
154
+ errorMessage?: string; // case-violation-ok-legacy-back-compat: the property name is the GraphQL schema field name — renaming it breaks every client query
155
155
  }
156
156
 
157
157
  @Resolver()
@@ -6,6 +6,7 @@ import { MJQueryResolver, MJQuery_, MJQueryField_, MJQueryParameter_, MJQueryEnt
6
6
  import { GetReadWriteProvider } from '../util.js';
7
7
  import { DeleteOptionsInput } from '../generic/DeleteOptionsInput.js';
8
8
  import { MJQueryEntityServer } from '@memberjunction/core-entities-server';
9
+ import { EscapeSQLString } from '@memberjunction/global';
9
10
 
10
11
  /**
11
12
  * Minimal shape of a query row returned by RunView lookups (plain object, not entity instance).
@@ -493,7 +494,7 @@ export class MJQueryResolverExtended extends MJQueryResolver {
493
494
  // now make sure there is NO existing query by the same name in the specified category
494
495
  const existingQueryResult = await provider.RunView({
495
496
  EntityName: 'MJ: Queries',
496
- ExtraFilter: `Name='${input.Name}' AND CategoryID='${finalCategoryID}'`
497
+ ExtraFilter: `Name='${EscapeSQLString(input.Name)}' AND CategoryID='${EscapeSQLString(finalCategoryID)}'`
497
498
  }, context.userPayload.userRecord);
498
499
  if (existingQueryResult.Success && existingQueryResult.Results?.length > 0) {
499
500
  // we have a match! Let's return an error
@@ -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,
@@ -57,12 +57,12 @@ import {
57
57
  deleteRealtimeRecordingSegments,
58
58
  } from '@memberjunction/ai-agents';
59
59
  import { AgentExecutionProgressCallback, MJAIAgentEntityExtended, AppContextSnapshot } from '@memberjunction/ai-core-plus';
60
- import { RealtimeToolDefinition } from '@memberjunction/ai';
60
+ import { ChatMessage, RealtimeToolDefinition } from '@memberjunction/ai';
61
61
  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
@@ -136,6 +136,11 @@ const MAX_PRIOR_TRANSCRIPT_CHARS = 8_000;
136
136
  /** Maximum prior-session chain legs walked when hydrating a resumed session's transcript. */
137
137
  const MAX_PRIOR_TRANSCRIPT_LEGS = 5;
138
138
 
139
+ /** Maximum TEXT-conversation turns hydrated into a voice session's companion prompt (newest kept). */
140
+ const MAX_CONVERSATION_HISTORY_TURNS = 30;
141
+ /** Maximum TEXT-conversation CHARS hydrated into a voice session's companion prompt (oldest dropped). */
142
+ const MAX_CONVERSATION_HISTORY_CHARS = 8_000;
143
+
139
144
  /**
140
145
  * Authoritative shape persisted in `AIAgentSession.Config_` for a client-direct voice session.
141
146
  * The target agent id is stored here at start and read back on every relay — the browser never
@@ -486,10 +491,17 @@ export class RealtimeClientSessionResolver extends ResolverBase {
486
491
  // Best-effort model-context hydration: the PRIOR session chain's transcript (ownership-
487
492
  // checked, capped) is framed into the system prompt so the model REMEMBERS the last leg.
488
493
  // Strictly tolerant — any problem yields no hydration, never a failed start.
489
- const priorTranscript = await this.loadPriorTranscript(lastSessionId, contextUser, provider);
494
+ const prior = await this.loadPriorTranscript(lastSessionId, contextUser, provider);
495
+ // ...and the TEXT conversation the call is being started from, so a voice session opened
496
+ // mid-thread knows what was already typed. The legs above are excluded: they are already
497
+ // framed as the resumed transcript, and injecting the same turns twice puts two accounts of
498
+ // the same exchange in one prompt.
499
+ const conversationMessages = await this.loadConversationHistory(
500
+ conversationId, prior?.LegIDs ?? [], contextUser, provider,
501
+ );
490
502
  const result = await this.prepareClientSessionOrClose(
491
- session, coAgentID, effectiveTargetId, contextUser, provider, preferredModelId, clientTools, priorTranscript,
492
- configOverridesJson, maxSessionSeconds, applicationId, this.parseAppContext(appContextJson),
503
+ session, coAgentID, effectiveTargetId, contextUser, provider, preferredModelId, clientTools, prior?.Text,
504
+ configOverridesJson, maxSessionSeconds, applicationId, this.parseAppContext(appContextJson), conversationMessages,
493
505
  );
494
506
  // Best-effort restore of the PRIOR session's persisted channel states (e.g. the whiteboard
495
507
  // board). Strictly tolerant — any problem yields a null field, never a failed start.
@@ -1684,6 +1696,8 @@ export class RealtimeClientSessionResolver extends ResolverBase {
1684
1696
  * @param priorTranscript Optional capped, role-tagged transcript of the PRIOR session chain
1685
1697
  * (from {@link loadPriorTranscript}) — the service frames it into the system prompt so a
1686
1698
  * resumed session remembers the previous leg(s).
1699
+ * @param conversationMessages Optional capped history of the TEXT conversation this session is
1700
+ * starting from (from {@link loadConversationHistory}) — framed as "Conversation so far".
1687
1701
  */
1688
1702
  private async prepareClientSessionOrClose(
1689
1703
  session: MJAIAgentSessionEntity,
@@ -1698,6 +1712,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
1698
1712
  maxSessionSeconds?: number,
1699
1713
  applicationId?: string,
1700
1714
  appContext?: AppContextSnapshot,
1715
+ conversationMessages?: ChatMessage[],
1701
1716
  ): Promise<StartRealtimeClientSessionResult> {
1702
1717
  const prep = await this.clientSessionService.PrepareClientSession(
1703
1718
  {
@@ -1708,10 +1723,10 @@ export class RealtimeClientSessionResolver extends ResolverBase {
1708
1723
  // Server-authoritative voice duration cap (widget guests) — bounds the driver session
1709
1724
  // where supported; the janitor enforces the session deadline regardless.
1710
1725
  MaxSessionSeconds: maxSessionSeconds,
1711
- // MVP: conversation history is not yet hydrated into ChatMessage[]; the co-agent
1712
- // companion prompt runs without prior turns. A later phase loads the session's
1713
- // Conversation into ChatMessage[] for richer context.
1714
- ConversationMessages: [],
1726
+ // The TEXT conversation this call was started from, so the co-agent opens knowing
1727
+ // what the user already typed rather than asking them to say it again. Hydrated by
1728
+ // `loadConversationHistory`; empty when there is no conversation or the read failed.
1729
+ ConversationMessages: conversationMessages ?? [],
1715
1730
  UserID: contextUser.ID,
1716
1731
  PreferredModelID: preferredModelId,
1717
1732
  // Client-declared, CLIENT-EXECUTED UI tools (see the mutation's SECURITY NOTE) —
@@ -2005,7 +2020,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2005
2020
  lastSessionId: string | undefined,
2006
2021
  contextUser: UserInfo,
2007
2022
  provider: IMetadataProvider,
2008
- ): Promise<string | undefined> {
2023
+ ): Promise<{ Text: string; LegIDs: string[] } | undefined> {
2009
2024
  if (!lastSessionId) {
2010
2025
  return undefined;
2011
2026
  }
@@ -2016,7 +2031,10 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2016
2031
  }
2017
2032
  const turns = await this.loadChainTranscriptTurns(legIDs, contextUser, provider);
2018
2033
  const lines = this.capTranscriptLines(turns);
2019
- return lines.length > 0 ? lines.join('\n') : undefined;
2034
+ // The leg ids travel with the text because the CONVERSATION history hydrated alongside
2035
+ // this would otherwise re-inject the same turns: a voice turn is persisted as an
2036
+ // ordinary Conversation Detail, so these legs are part of the conversation too.
2037
+ return lines.length > 0 ? { Text: lines.join('\n'), LegIDs: legIDs } : undefined;
2020
2038
  } catch (error) {
2021
2039
  LogError(
2022
2040
  `StartRealtimeClientSession: prior-transcript hydration failed for session ${lastSessionId}: ${(error as Error).message}`,
@@ -2025,6 +2043,101 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2025
2043
  }
2026
2044
  }
2027
2045
 
2046
+ /**
2047
+ * Loads the conversation this voice session is starting from, as `ChatMessage[]` for the
2048
+ * co-agent's companion prompt.
2049
+ *
2050
+ * This is the half of the context flow that was missing. Voice turns have always been
2051
+ * persisted as `MJ: Conversation Details`, so anything SAID reaches a later text turn — but
2052
+ * nothing TYPED reached a voice session, which opened with no idea what the thread was about.
2053
+ * The symptom is not an error; it is the agent asking the user to repeat something they just
2054
+ * wrote, which is exactly when voice is least forgivable.
2055
+ *
2056
+ * Caps mirror the resume path (newest {@link MAX_CONVERSATION_HISTORY_TURNS} turns, then a
2057
+ * {@link MAX_CONVERSATION_HISTORY_CHARS} budget with the oldest dropped first) so the freshest
2058
+ * context always survives.
2059
+ *
2060
+ * Session-stamped rows are KEPT unless `coveredSessionIDs` names them: a call the user had last
2061
+ * week is part of this conversation and the model should know it. Only the legs already framed
2062
+ * as the resumed transcript are removed, so the prompt never carries two accounts of one
2063
+ * exchange.
2064
+ *
2065
+ * Strictly tolerant — no conversation, a failed read, or any throw yields `[]`, never a failed
2066
+ * session start. The call still works; it just starts cold.
2067
+ *
2068
+ * @param conversationId The conversation the session is bound to, when there is one.
2069
+ * @param coveredSessionIDs Session ids already framed via `PriorTranscript`.
2070
+ * @param contextUser The calling user (RunView scope — the read is row-level-secured).
2071
+ * @param provider The request-scoped metadata provider.
2072
+ * @returns The capped history, oldest first.
2073
+ */
2074
+ private async loadConversationHistory(
2075
+ conversationId: string | undefined,
2076
+ coveredSessionIDs: string[],
2077
+ contextUser: UserInfo,
2078
+ provider: IMetadataProvider,
2079
+ ): Promise<ChatMessage[]> {
2080
+ if (!conversationId) {
2081
+ return [];
2082
+ }
2083
+ try {
2084
+ const rv = RunView.FromMetadataProvider(provider);
2085
+ const result = await rv.RunView<{
2086
+ Role: string;
2087
+ Message: string | null;
2088
+ HiddenToUser: boolean;
2089
+ AgentSessionID: string | null;
2090
+ }>(
2091
+ {
2092
+ EntityName: CONVERSATION_DETAIL_ENTITY,
2093
+ ExtraFilter: `ConversationID='${conversationId.replace(/'/g, "''")}'`,
2094
+ Fields: ['ID', 'Role', 'Message', 'HiddenToUser', 'AgentSessionID', '__mj_CreatedAt'],
2095
+ OrderBy: '__mj_CreatedAt ASC',
2096
+ ResultType: 'simple',
2097
+ },
2098
+ contextUser,
2099
+ );
2100
+ if (!result.Success) {
2101
+ LogError(`StartRealtimeClientSession: conversation-history query failed: ${result.ErrorMessage}`);
2102
+ return [];
2103
+ }
2104
+ const covered = new Set(coveredSessionIDs.map((id) => id.trim().toLowerCase()));
2105
+ const turns = (result.Results ?? []).filter(
2106
+ (row) =>
2107
+ !row.HiddenToUser &&
2108
+ (row.Role === 'User' || row.Role === 'AI') &&
2109
+ typeof row.Message === 'string' &&
2110
+ row.Message.trim().length > 0 &&
2111
+ !covered.has((row.AgentSessionID ?? '').trim().toLowerCase()),
2112
+ );
2113
+ return this.capConversationHistory(turns);
2114
+ } catch (error) {
2115
+ LogError(
2116
+ `StartRealtimeClientSession: conversation-history hydration failed for conversation ${conversationId}: ${(error as Error).message}`,
2117
+ );
2118
+ return [];
2119
+ }
2120
+ }
2121
+
2122
+ /**
2123
+ * Applies the history caps and maps to `ChatMessage[]`: the newest
2124
+ * {@link MAX_CONVERSATION_HISTORY_TURNS} turns, then a total budget of
2125
+ * {@link MAX_CONVERSATION_HISTORY_CHARS} characters with the oldest dropped first.
2126
+ */
2127
+ private capConversationHistory(turns: Array<{ Role: string; Message: string | null }>): ChatMessage[] {
2128
+ const newest = turns.slice(-MAX_CONVERSATION_HISTORY_TURNS);
2129
+ const messages: ChatMessage[] = newest.map((t) => ({
2130
+ role: t.Role === 'AI' ? 'assistant' : 'user',
2131
+ content: (t.Message ?? '').trim(),
2132
+ }));
2133
+ let total = messages.reduce((sum, m) => sum + String(m.content).length + 1, 0);
2134
+ while (messages.length > 0 && total > MAX_CONVERSATION_HISTORY_CHARS) {
2135
+ const dropped = messages.shift() as ChatMessage;
2136
+ total -= String(dropped.content).length + 1;
2137
+ }
2138
+ return messages;
2139
+ }
2140
+
2028
2141
  /**
2029
2142
  * Walks the prior-session chain backwards from `lastSessionId`, returning the OWNED leg ids
2030
2143
  * (newest first). The first leg must exist and be owned by the caller, else `[]` (logged);
@@ -2555,8 +2668,8 @@ export class RealtimeClientSessionResolver extends ResolverBase {
2555
2668
  userPayload: UserPayload,
2556
2669
  providers: AppContext['providers'],
2557
2670
  ): Promise<number | undefined> {
2558
- const elevation = await resolveWidgetGuestRunContext(userPayload, GetReadWriteProvider(providers));
2559
- const minutes = elevation?.widget.VoiceMaxSessionMinutes;
2671
+ const elevation = await ResolveWidgetGuestRunContext(userPayload, GetReadWriteProvider(providers));
2672
+ const minutes = elevation?.Widget.VoiceMaxSessionMinutes;
2560
2673
  return minutes && minutes > 0 ? minutes * 60 : undefined;
2561
2674
  }
2562
2675
 
@@ -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