@memberjunction/server 6.2.0-edge.6 → 6.2.0-edge.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/BridgeHostInstance.d.ts +8 -3
- package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -1
- package/dist/agentSessions/BridgeHostInstance.js +14 -4
- package/dist/agentSessions/BridgeHostInstance.js.map +1 -1
- package/dist/agentSessions/HandoffOfferExpiry.d.ts +10 -0
- package/dist/agentSessions/HandoffOfferExpiry.d.ts.map +1 -0
- package/dist/agentSessions/HandoffOfferExpiry.js +18 -0
- package/dist/agentSessions/HandoffOfferExpiry.js.map +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +31 -8
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +85 -41
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +14 -4
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +28 -4
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/agentSessions/conversationBrowsers.d.ts +61 -0
- package/dist/agentSessions/conversationBrowsers.d.ts.map +1 -0
- package/dist/agentSessions/conversationBrowsers.js +118 -0
- package/dist/agentSessions/conversationBrowsers.js.map +1 -0
- package/dist/agentSessions/sessionDeadline.d.ts +43 -0
- package/dist/agentSessions/sessionDeadline.d.ts.map +1 -0
- package/dist/agentSessions/sessionDeadline.js +68 -0
- package/dist/agentSessions/sessionDeadline.js.map +1 -0
- package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
- package/dist/auth/APIKeyScopeAuth.js +5 -4
- package/dist/auth/APIKeyScopeAuth.js.map +1 -1
- package/dist/auth/loginEmailResolution.d.ts +41 -0
- package/dist/auth/loginEmailResolution.d.ts.map +1 -0
- package/dist/auth/loginEmailResolution.js +47 -0
- package/dist/auth/loginEmailResolution.js.map +1 -0
- package/dist/auth/magicLink/MagicLinkKeys.d.ts +50 -2
- package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js +129 -12
- package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +221 -9
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/magicLink/index.d.ts +1 -1
- package/dist/auth/magicLink/index.d.ts.map +1 -1
- package/dist/auth/magicLink/index.js +1 -1
- package/dist/auth/magicLink/index.js.map +1 -1
- package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
- package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
- package/dist/auth/magicLink/redeemLanding.js +7 -4
- package/dist/auth/magicLink/redeemLanding.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +27 -3
- package/dist/auth/magicLink/types.d.ts.map +1 -1
- package/dist/auth/magicLink/types.js +0 -4
- package/dist/auth/magicLink/types.js.map +1 -1
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +1 -0
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/backgroundSweepConfigUnits.d.ts +231 -0
- package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
- package/dist/backgroundSweepConfigUnits.js +180 -0
- package/dist/backgroundSweepConfigUnits.js.map +1 -0
- package/dist/config.d.ts +906 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +59 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +35 -4
- package/dist/context.js.map +1 -1
- package/dist/coreRoutes.d.ts +3 -1
- package/dist/coreRoutes.d.ts.map +1 -1
- package/dist/coreRoutes.js +6 -4
- package/dist/coreRoutes.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +228 -0
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +1163 -6
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +27 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +50 -5
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +321 -132
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +4 -0
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +47 -7
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +157 -35
- package/dist/index.js.map +1 -1
- package/dist/integration/ConnectionPause.d.ts +121 -0
- package/dist/integration/ConnectionPause.d.ts.map +1 -0
- package/dist/integration/ConnectionPause.js +183 -0
- package/dist/integration/ConnectionPause.js.map +1 -0
- package/dist/integration/CustomColumnPromoter.d.ts +72 -6
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +87 -46
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/integration/EntityMapLifecycle.d.ts +78 -4
- package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
- package/dist/integration/EntityMapLifecycle.js +199 -5
- package/dist/integration/EntityMapLifecycle.js.map +1 -1
- package/dist/integration/InactiveRowWarnings.d.ts +31 -0
- package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
- package/dist/integration/InactiveRowWarnings.js +29 -0
- package/dist/integration/InactiveRowWarnings.js.map +1 -1
- package/dist/integration/ObjectNamesByID.d.ts +28 -0
- package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
- package/dist/integration/ObjectNamesByID.js +87 -0
- package/dist/integration/ObjectNamesByID.js.map +1 -0
- package/dist/integration/PostRestartIntrospect.d.ts +26 -0
- package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
- package/dist/integration/PostRestartIntrospect.js +27 -0
- package/dist/integration/PostRestartIntrospect.js.map +1 -0
- package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
- package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
- package/dist/integration/RSUPostRestartProgress.js +323 -0
- package/dist/integration/RSUPostRestartProgress.js.map +1 -0
- package/dist/integration/RSUProgressBridge.d.ts +41 -2
- package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
- package/dist/integration/RSUProgressBridge.js +84 -1
- package/dist/integration/RSUProgressBridge.js.map +1 -1
- package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
- package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
- package/dist/integration/RunArtifactAuthorization.js +45 -0
- package/dist/integration/RunArtifactAuthorization.js.map +1 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
- package/dist/integration/SchemaRefreshLaunch.js +3 -2
- package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
- package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
- package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
- package/dist/integration/ScopedFieldsForBuild.js +91 -0
- package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
- package/dist/integration/TargetConfigGuard.d.ts +40 -0
- package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
- package/dist/integration/TargetConfigGuard.js +40 -0
- package/dist/integration/TargetConfigGuard.js.map +1 -0
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.js +2 -3
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
- package/dist/realtimeSessions/sessionAccess.d.ts +15 -0
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +22 -0
- package/dist/realtimeSessions/sessionAccess.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.js +2 -0
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.js +1 -0
- package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +4 -7
- package/dist/realtimeWidget/widgetCore.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +1 -0
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/requestOrigin.d.ts +22 -0
- package/dist/requestOrigin.d.ts.map +1 -0
- package/dist/requestOrigin.js +60 -0
- package/dist/requestOrigin.js.map +1 -0
- package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/AgentSessionResolver.js +6 -2
- package/dist/resolvers/AgentSessionResolver.js.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.js +2 -1
- package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
- package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +6 -0
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
- package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
- package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +34 -13
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +2690 -1305
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +13 -2
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +36 -0
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +174 -87
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
- package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +6 -0
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +36 -5
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +217 -34
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +24 -8
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +185 -67
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
- package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +19 -18
- package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +3 -1
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.js +2 -0
- package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
- package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
- package/dist/rest/MediaAccessKeys.js +6 -2
- package/dist/rest/MediaAccessKeys.js.map +1 -1
- package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
- package/dist/rest/OAuthCallbackHandler.js +11 -5
- package/dist/rest/OAuthCallbackHandler.js.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.js +2 -4
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +2 -1
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +3 -1
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +11 -2
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +2 -26
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +38 -0
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +1 -0
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/services/WorkQueueHostService.d.ts +2 -1
- package/dist/services/WorkQueueHostService.d.ts.map +1 -1
- package/dist/services/WorkQueueHostService.js +19 -4
- package/dist/services/WorkQueueHostService.js.map +1 -1
- package/dist/services/workQueueConfig.d.ts +2 -2
- package/dist/services/workQueueConfig.js +5 -5
- package/dist/services/workQueueConfig.js.map +1 -1
- package/dist/sharedCache.js +1 -1
- package/dist/sharedCache.js.map +1 -1
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +98 -98
- package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
- package/src/__tests__/ActiveOperations.test.ts +68 -0
- package/src/__tests__/AgentSessionResolver.ownership.test.ts +13 -0
- package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
- package/src/__tests__/BatchApplyParity.test.ts +109 -0
- package/src/__tests__/BridgeHostInstance.test.ts +42 -0
- package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
- package/src/__tests__/ConnectionPause.test.ts +192 -0
- package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
- package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
- package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
- package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
- package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
- package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
- package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
- package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
- package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
- package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
- package/src/__tests__/MagicLinkKeys.test.ts +102 -0
- package/src/__tests__/MediaAccessKeys.test.ts +57 -10
- package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
- package/src/__tests__/ObjectNamesByID.test.ts +176 -0
- package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
- package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
- package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
- package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
- package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
- package/src/__tests__/RSUProgressBridge.test.ts +188 -5
- package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
- package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +22 -0
- package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
- package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
- package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
- package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +6 -4
- package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
- package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +323 -26
- package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
- package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +53 -2
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +60 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +4 -0
- package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
- package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +2 -0
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +2 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +87 -12
- package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
- package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
- package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
- package/src/__tests__/SessionJanitor.test.ts +195 -4
- package/src/__tests__/SessionManager.test.ts +69 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
- package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
- package/src/__tests__/ViewOperationsHandler.test.ts +2 -5
- package/src/__tests__/WorkQueueHostService.test.ts +25 -7
- package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
- package/src/__tests__/contextRequestOrigin.test.ts +105 -0
- package/src/__tests__/conversationBrowsers.test.ts +62 -0
- package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
- package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
- package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
- package/src/__tests__/realtimeRecordingHandler.test.ts +7 -2
- package/src/__tests__/realtimeSessions/sessionAccess.test.ts +79 -1
- package/src/__tests__/requestOrigin.test.ts +104 -0
- package/src/__tests__/securityHardeningPr6034.test.ts +120 -0
- package/src/__tests__/sessionDeadline.test.ts +51 -0
- package/src/__tests__/sharedCache.test.ts +11 -0
- package/src/__tests__/unifiedAuth.test.ts +73 -1
- package/src/agentSessions/BridgeHostInstance.ts +20 -5
- package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
- package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
- package/src/agentSessions/SessionJanitor.ts +92 -42
- package/src/agentSessions/SessionManager.ts +38 -8
- package/src/agentSessions/conversationBrowsers.ts +143 -0
- package/src/agentSessions/sessionDeadline.ts +81 -0
- package/src/auth/APIKeyScopeAuth.ts +5 -4
- package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
- package/src/auth/loginEmailResolution.ts +67 -0
- package/src/auth/magicLink/MagicLinkKeys.ts +146 -14
- package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
- package/src/auth/magicLink/MagicLinkService.ts +250 -10
- package/src/auth/magicLink/index.ts +1 -1
- package/src/auth/magicLink/redeemLanding.ts +7 -4
- package/src/auth/magicLink/types.ts +28 -3
- package/src/auth/newUsers.ts +1 -0
- package/src/backgroundSweepConfigUnits.ts +213 -0
- package/src/config.ts +69 -0
- package/src/context.ts +39 -6
- package/src/coreRoutes.ts +14 -7
- package/src/generated/graphql-schemas/__mj.ts +822 -7
- package/src/generic/OrphanedConversationDetailReconciler.ts +32 -1
- package/src/generic/ResolverBase.ts +414 -143
- package/src/generic/RunViewResolver.ts +96 -49
- package/src/index.ts +201 -35
- package/src/integration/ConnectionPause.ts +222 -0
- package/src/integration/CustomColumnPromoter.ts +123 -53
- package/src/integration/EntityMapLifecycle.ts +229 -6
- package/src/integration/InactiveRowWarnings.ts +50 -0
- package/src/integration/ObjectNamesByID.ts +97 -0
- package/src/integration/PostRestartIntrospect.ts +49 -0
- package/src/integration/RSUPostRestartProgress.ts +359 -0
- package/src/integration/RSUProgressBridge.ts +85 -2
- package/src/integration/RunArtifactAuthorization.ts +65 -0
- package/src/integration/SchemaRefreshLaunch.ts +12 -2
- package/src/integration/ScopedFieldsForBuild.ts +113 -0
- package/src/integration/TargetConfigGuard.ts +71 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +2 -6
- package/src/realtimeSessions/sessionAccess.ts +30 -0
- package/src/realtimeWidget/WidgetSessionService.ts +2 -0
- package/src/realtimeWidget/visitorIdentity.ts +1 -0
- package/src/realtimeWidget/widgetCore.ts +4 -8
- package/src/realtimeWidget/widgetGuestElevation.ts +1 -0
- package/src/requestOrigin.ts +64 -0
- package/src/resolvers/AgentSessionResolver.ts +6 -2
- package/src/resolvers/AutotagPipelineResolver.ts +2 -1
- package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
- package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
- package/src/resolvers/GetDataResolver.ts +35 -13
- package/src/resolvers/IntegrationDiscoveryResolver.ts +1522 -203
- package/src/resolvers/MCPResolver.ts +15 -2
- package/src/resolvers/QuerySystemUserResolver.ts +197 -98
- package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +40 -7
- package/src/resolvers/RemoteBrowserActionResolver.ts +242 -32
- package/src/resolvers/RunAIAgentResolver.ts +265 -86
- package/src/resolvers/RunAIPromptResolver.ts +18 -18
- package/src/resolvers/RunTemplateResolver.ts +3 -1
- package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
- package/src/resolvers/meetingRecordingRegistration.ts +2 -0
- package/src/rest/MediaAccessKeys.ts +6 -2
- package/src/rest/OAuthCallbackHandler.ts +13 -5
- package/src/rest/RealtimeRecordingHandler.ts +5 -9
- package/src/rest/ViewOperationsHandler.ts +2 -1
- package/src/rest/setupRESTEndpoints.ts +11 -2
- package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
- package/src/services/TaskGraphActionRunner.ts +2 -23
- package/src/services/TaskGraphAgentRunner.ts +43 -0
- package/src/services/TaskGraphContinuationDeliverer.ts +1 -0
- package/src/services/WorkQueueHostService.ts +26 -4
- package/src/services/workQueueConfig.ts +5 -5
- package/src/sharedCache.ts +1 -1
- package/src/types.ts +18 -0
- package/src/services/TaskOrchestration-Integration.md +0 -188
|
@@ -30,6 +30,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
30
30
|
*/
|
|
31
31
|
import { Resolver, Mutation, Query, Arg, Ctx, Float, Int, ObjectType, Field, PubSub, PubSubEngine } from 'type-graphql';
|
|
32
32
|
import { LogError } from '@memberjunction/core';
|
|
33
|
+
import { NormalizeUUID } from '@memberjunction/global';
|
|
33
34
|
import { NormalizeInstanceKey, RemoteBrowserEngine } from '@memberjunction/remote-browser-server';
|
|
34
35
|
import { BeginBrowserGoalStep, FinalizeBrowserGoalStep, ExtractCoAgentRunID } from '../agentSessions/remoteBrowserGoalEngine.js';
|
|
35
36
|
import { RemoteBrowserGoalRegistry } from '../agentSessions/remoteBrowserGoalRegistry.js';
|
|
@@ -39,9 +40,14 @@ import { RemoteBrowserCapabilityNotSupportedError, } from '@memberjunction/remot
|
|
|
39
40
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
40
41
|
import { GetReadWriteProvider } from '../util.js';
|
|
41
42
|
import { LoadOwnedRealtimeSession, RealtimeSessionNotFoundError, RealtimeSessionOwnershipError, } from '../realtimeSessions/ownedRealtimeSession.js';
|
|
43
|
+
import { AuthorizeSessionAccess, ResolveSessionScopeIdentity } from '../realtimeSessions/sessionAccess.js';
|
|
44
|
+
import { ConversationBrowserLedger, RemoteBrowserRefusedError } from '../agentSessions/conversationBrowsers.js';
|
|
45
|
+
import { configInfo } from '../config.js';
|
|
42
46
|
import { AIEngine } from '@memberjunction/aiengine';
|
|
43
47
|
import { AIPromptRunner } from '@memberjunction/ai-prompts';
|
|
44
48
|
import { AIPromptParams } from '@memberjunction/ai-core-plus';
|
|
49
|
+
/** Entity name for turn-based text conversations that scope a live Remote Browser session. */
|
|
50
|
+
const CONVERSATION_ENTITY = 'MJ: Conversations';
|
|
45
51
|
/** Entity name for the agent whose `TypeConfiguration` carries the remote-browser provider preference. */
|
|
46
52
|
const AGENT_ENTITY = 'MJ: AI Agents';
|
|
47
53
|
/**
|
|
@@ -53,7 +59,7 @@ const AGENT_ENTITY = 'MJ: AI Agents';
|
|
|
53
59
|
const VISUAL_INTERPRETER_PROMPT_NAME = 'Remote Browser Visual Interpreter';
|
|
54
60
|
/**
|
|
55
61
|
* Result of {@link RemoteBrowserActionResolver.ExecuteRemoteBrowserAction} — the outcome of one browser
|
|
56
|
-
* action plus the resulting URL
|
|
62
|
+
* action plus the resulting URL and optional structured DOM observation / filled-field list.
|
|
57
63
|
*/
|
|
58
64
|
let RemoteBrowserActionResult = class RemoteBrowserActionResult {
|
|
59
65
|
};
|
|
@@ -69,6 +75,14 @@ __decorate([
|
|
|
69
75
|
Field(() => String, { nullable: true }),
|
|
70
76
|
__metadata("design:type", String)
|
|
71
77
|
], RemoteBrowserActionResult.prototype, "Detail", void 0);
|
|
78
|
+
__decorate([
|
|
79
|
+
Field(() => String, { nullable: true }),
|
|
80
|
+
__metadata("design:type", String)
|
|
81
|
+
], RemoteBrowserActionResult.prototype, "ObservationJson", void 0);
|
|
82
|
+
__decorate([
|
|
83
|
+
Field(() => String, { nullable: true }),
|
|
84
|
+
__metadata("design:type", String)
|
|
85
|
+
], RemoteBrowserActionResult.prototype, "FilledJson", void 0);
|
|
72
86
|
RemoteBrowserActionResult = __decorate([
|
|
73
87
|
ObjectType()
|
|
74
88
|
], RemoteBrowserActionResult);
|
|
@@ -248,7 +262,7 @@ export { RemoteBrowserInterpretation };
|
|
|
248
262
|
const MAX_STREAM_ENTRY_AGE_MS = 4 * 60 * 60 * 1000; // 4 hours — generous vs. SessionJanitor's 15-minute idle threshold
|
|
249
263
|
let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends ResolverBase {
|
|
250
264
|
constructor() {
|
|
251
|
-
super(
|
|
265
|
+
super();
|
|
252
266
|
/**
|
|
253
267
|
* Surfaces whose live CDP screencast this resolver has already started, keyed by
|
|
254
268
|
* {@link RemoteBrowserActionResolver.streamKey} (agent session **plus** instance) so a re-issued
|
|
@@ -272,6 +286,15 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
272
286
|
* {@link RemoteBrowserActionResolver.startedScreencasts} for why the value is a timestamp.
|
|
273
287
|
*/
|
|
274
288
|
this.startedAudioStreams = new Map();
|
|
289
|
+
/**
|
|
290
|
+
* The push session each surface's frames and audio go to, by stream key. A reloaded tab starts again
|
|
291
|
+
* from a new push session while the browser keeps streaming; it takes the frames over here instead of
|
|
292
|
+
* being told "already streaming" while they still go to the old session. An entry whose streams have
|
|
293
|
+
* stopped is dropped by {@link sweepStreamEntries}.
|
|
294
|
+
*/
|
|
295
|
+
this.streamTargets = new Map();
|
|
296
|
+
// The idle reaper ends a conversation browser the way EndRemoteBrowserSession does.
|
|
297
|
+
ConversationBrowserLedger.Instance.EndBrowser = (conversationID) => this.endBrowser(conversationID);
|
|
275
298
|
}
|
|
276
299
|
/**
|
|
277
300
|
* Drops any {@link startedScreencasts} / {@link startedAudioStreams} entry older than
|
|
@@ -291,6 +314,12 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
291
314
|
this.startedAudioStreams.delete(key);
|
|
292
315
|
}
|
|
293
316
|
}
|
|
317
|
+
// A target outlives its streams only until here (a stop, a failed start, a voice session's end).
|
|
318
|
+
for (const key of this.streamTargets.keys()) {
|
|
319
|
+
if (!this.startedScreencasts.has(key) && !this.startedAudioStreams.has(key)) {
|
|
320
|
+
this.streamTargets.delete(key);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
294
323
|
}
|
|
295
324
|
/**
|
|
296
325
|
* Execute ONE browser action relayed from the client-direct realtime session, returning the outcome +
|
|
@@ -308,18 +337,24 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
308
337
|
* @param kind The action kind (`'navigate' | 'click' | 'type' | 'key' | 'scroll' | 'back' | 'forward' | 'wait'`).
|
|
309
338
|
* @returns The action result (success + resulting URL + detail).
|
|
310
339
|
*/
|
|
311
|
-
async ExecuteRemoteBrowserAction(agentSessionID, kind, { userPayload, providers }, url, selector, x, y, text, key, deltaX, deltaY, ms, instanceKey) {
|
|
340
|
+
async ExecuteRemoteBrowserAction(agentSessionID, kind, { userPayload, providers }, url, selector, x, y, text, key, deltaX, deltaY, ms, instanceKey, ref, valuesJson) {
|
|
312
341
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
313
|
-
const session = await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
314
|
-
const action = this.buildAction({ kind, url, selector, x, y, text, key, deltaX, deltaY, ms });
|
|
342
|
+
const session = await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
343
|
+
const action = this.buildAction({ kind, url, selector, ref, x, y, text, key, deltaX, deltaY, ms, valuesJson });
|
|
315
344
|
if (!action) {
|
|
316
345
|
return { Success: false, Detail: `Unknown or incomplete remote-browser action '${kind}'.` };
|
|
317
346
|
}
|
|
318
347
|
const providerName = await this.resolveProviderName(session, contextUser, provider);
|
|
319
348
|
try {
|
|
320
|
-
const liveSession = await
|
|
349
|
+
const liveSession = await this.startBrowser(agentSessionID, session, contextUser, providerName, instanceKey);
|
|
321
350
|
const result = await liveSession.ExecuteAction(action);
|
|
322
|
-
return {
|
|
351
|
+
return {
|
|
352
|
+
Success: result.Success,
|
|
353
|
+
CurrentUrl: result.CurrentUrl,
|
|
354
|
+
Detail: result.Detail,
|
|
355
|
+
...(result.Observation ? { ObservationJson: JSON.stringify(result.Observation) } : {}),
|
|
356
|
+
...(result.Filled ? { FilledJson: JSON.stringify(result.Filled) } : {}),
|
|
357
|
+
};
|
|
323
358
|
}
|
|
324
359
|
catch (err) {
|
|
325
360
|
// A dead handle is not a failure to report, it is a mapping to delete (#3598) — and this is the
|
|
@@ -345,6 +380,8 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
345
380
|
Detail: retried.Success
|
|
346
381
|
? retried.Detail
|
|
347
382
|
: `The browser had closed and was replaced (it is now on a blank page). ${retried.Detail ?? ''}`.trim(),
|
|
383
|
+
...(retried.Observation ? { ObservationJson: JSON.stringify(retried.Observation) } : {}),
|
|
384
|
+
...(retried.Filled ? { FilledJson: JSON.stringify(retried.Filled) } : {}),
|
|
348
385
|
};
|
|
349
386
|
}
|
|
350
387
|
catch (retryError) {
|
|
@@ -374,7 +411,11 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
374
411
|
*/
|
|
375
412
|
async ExecuteRemoteBrowserGoal(agentSessionID, goal, { userPayload, providers }, startUrl, maxSteps, preferredStrategy, instanceKey) {
|
|
376
413
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
377
|
-
const session = await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
414
|
+
const session = await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
415
|
+
if (session.IsConversation) {
|
|
416
|
+
// A goal loop clicks and navigates on its own, past the click guard the browser_* tools go through.
|
|
417
|
+
return { Success: false, Status: 'Error', Detail: 'Goal runs are not available in a text conversation; use the browser_* tools.' };
|
|
418
|
+
}
|
|
378
419
|
const providerName = await this.resolveProviderName(session, contextUser, provider);
|
|
379
420
|
// Observability: nest this goal's many prompt runs under ONE "Browser goal" step on the realtime
|
|
380
421
|
// co-agent run (when the session has one). Best-effort — a null step just means the goal runs unlinked.
|
|
@@ -442,7 +483,7 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
442
483
|
*/
|
|
443
484
|
async RemoteBrowserSnapshot(agentSessionID, { userPayload, providers }, instanceKey) {
|
|
444
485
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
445
|
-
await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
486
|
+
await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
446
487
|
const liveSession = RemoteBrowserEngine.Instance.GetSessionForAgentSession(agentSessionID, instanceKey);
|
|
447
488
|
if (!liveSession) {
|
|
448
489
|
return {};
|
|
@@ -515,7 +556,7 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
515
556
|
*/
|
|
516
557
|
async InterpretRemoteBrowserPage(agentSessionID, { userPayload, providers }, query, instanceKey) {
|
|
517
558
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
518
|
-
await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
559
|
+
await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
519
560
|
const liveSession = RemoteBrowserEngine.Instance.GetSessionForAgentSession(agentSessionID, instanceKey);
|
|
520
561
|
if (!liveSession) {
|
|
521
562
|
return { Description: undefined, Elements: [], Detail: 'no live browser' };
|
|
@@ -549,18 +590,19 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
549
590
|
*/
|
|
550
591
|
async StartRemoteBrowserScreencast(agentSessionID, { userPayload, providers }, pubSub, instanceKey) {
|
|
551
592
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
552
|
-
const session = await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
593
|
+
const session = await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
553
594
|
// Idempotent PER SURFACE: a re-bind must not stack a second screencast on the one live browser,
|
|
554
595
|
// but a SECOND surface binding for the first time is not a re-bind (#3531).
|
|
555
596
|
this.sweepStreamEntries();
|
|
556
597
|
const streamKey = this.streamKey(agentSessionID, instanceKey);
|
|
598
|
+
this.streamTargets.set(streamKey, userPayload);
|
|
557
599
|
if (this.startedScreencasts.has(streamKey)) {
|
|
558
600
|
return { Streaming: true };
|
|
559
601
|
}
|
|
560
602
|
const providerName = await this.resolveProviderName(session, contextUser, provider);
|
|
561
603
|
try {
|
|
562
|
-
const liveSession = await
|
|
563
|
-
await liveSession.StartScreencast((frame) => this.publishFrame(pubSub, userPayload, agentSessionID, instanceKey, frame, liveSession.GetCurrentUrl()));
|
|
604
|
+
const liveSession = await this.startBrowser(agentSessionID, session, contextUser, providerName, instanceKey);
|
|
605
|
+
await liveSession.StartScreencast((frame) => this.publishFrame(pubSub, this.streamTargets.get(streamKey) ?? userPayload, agentSessionID, instanceKey, frame, liveSession.GetCurrentUrl()));
|
|
564
606
|
this.startedScreencasts.set(streamKey, Date.now());
|
|
565
607
|
return { Streaming: true };
|
|
566
608
|
}
|
|
@@ -569,6 +611,9 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
569
611
|
// Backend can't stream — the client keeps polling. Not an error condition.
|
|
570
612
|
return { Streaming: false };
|
|
571
613
|
}
|
|
614
|
+
if (err instanceof RemoteBrowserRefusedError) {
|
|
615
|
+
throw err; // the client must stop and say so, not poll for a browser that will never start
|
|
616
|
+
}
|
|
572
617
|
const message = err instanceof Error ? err.message : String(err);
|
|
573
618
|
LogError(`StartRemoteBrowserScreencast failed (provider='${providerName}'): ${message}`);
|
|
574
619
|
return { Streaming: false };
|
|
@@ -584,7 +629,7 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
584
629
|
*/
|
|
585
630
|
async StopRemoteBrowserScreencast(agentSessionID, { userPayload, providers }, instanceKey) {
|
|
586
631
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
587
|
-
await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
632
|
+
await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
588
633
|
this.startedScreencasts.delete(this.streamKey(agentSessionID, instanceKey));
|
|
589
634
|
const liveSession = RemoteBrowserEngine.Instance.GetSessionForAgentSession(agentSessionID, instanceKey);
|
|
590
635
|
if (liveSession) {
|
|
@@ -599,6 +644,33 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
599
644
|
}
|
|
600
645
|
return true;
|
|
601
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* Ends the browser the caller's own session or conversation started, and forgets its stream
|
|
649
|
+
* bookkeeping. Ownership-gated. Idempotent: ending a scope that holds no browser resolves `false`.
|
|
650
|
+
* A text chat calls this when its browser drawer closes, the conversation changes, or the chat is
|
|
651
|
+
* destroyed, so a closed drawer never leaves a Chromium process (or a billed hosted browser) running.
|
|
652
|
+
*
|
|
653
|
+
* @param agentSessionID The `AIAgentSession` id or `Conversation` id.
|
|
654
|
+
* @returns `true` when a live browser was ended.
|
|
655
|
+
*/
|
|
656
|
+
async EndRemoteBrowserSession(agentSessionID, { userPayload, providers }, instanceKey) {
|
|
657
|
+
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
658
|
+
await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
659
|
+
return this.endBrowser(agentSessionID, instanceKey);
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Ends a scope's browser and everything kept about it: the ledger slot (released first, so an action
|
|
663
|
+
* landing during teardown is counted again), the stream entries (so the next open streams the next
|
|
664
|
+
* browser) and the browser itself. The idle reaper ends conversation browsers through here too.
|
|
665
|
+
*/
|
|
666
|
+
async endBrowser(agentSessionID, instanceKey) {
|
|
667
|
+
ConversationBrowserLedger.Instance.Release(agentSessionID);
|
|
668
|
+
const streamKey = this.streamKey(agentSessionID, instanceKey);
|
|
669
|
+
this.startedScreencasts.delete(streamKey);
|
|
670
|
+
this.startedAudioStreams.delete(streamKey);
|
|
671
|
+
this.streamTargets.delete(streamKey);
|
|
672
|
+
return RemoteBrowserEngine.Instance.EndSessionForAgentSession(agentSessionID, instanceKey);
|
|
673
|
+
}
|
|
602
674
|
/**
|
|
603
675
|
* Starts streaming the session browser's TAB AUDIO and PUSHES each encoded chunk to the calling user's
|
|
604
676
|
* push-status topic — so a co-agent demoing a video/audio site is HEARD, not just seen. Ownership-gated.
|
|
@@ -614,17 +686,18 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
614
686
|
*/
|
|
615
687
|
async StartRemoteBrowserAudioStream(agentSessionID, { userPayload, providers }, pubSub, instanceKey) {
|
|
616
688
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
617
|
-
const session = await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
689
|
+
const session = await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
618
690
|
// Idempotent PER SURFACE — same reasoning as the screencast map (#3531).
|
|
619
691
|
this.sweepStreamEntries();
|
|
620
692
|
const streamKey = this.streamKey(agentSessionID, instanceKey);
|
|
693
|
+
this.streamTargets.set(streamKey, userPayload);
|
|
621
694
|
if (this.startedAudioStreams.has(streamKey)) {
|
|
622
695
|
return { Streaming: true };
|
|
623
696
|
}
|
|
624
697
|
const providerName = await this.resolveProviderName(session, contextUser, provider);
|
|
625
698
|
try {
|
|
626
|
-
const liveSession = await
|
|
627
|
-
await liveSession.StartAudioStream((chunk) => this.publishAudioChunk(pubSub, userPayload, agentSessionID, instanceKey, chunk));
|
|
699
|
+
const liveSession = await this.startBrowser(agentSessionID, session, contextUser, providerName, instanceKey);
|
|
700
|
+
await liveSession.StartAudioStream((chunk) => this.publishAudioChunk(pubSub, this.streamTargets.get(streamKey) ?? userPayload, agentSessionID, instanceKey, chunk));
|
|
628
701
|
this.startedAudioStreams.set(streamKey, Date.now());
|
|
629
702
|
return { Streaming: true };
|
|
630
703
|
}
|
|
@@ -633,6 +706,9 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
633
706
|
// Backend can't capture audio — the client plays no audio. Not an error condition.
|
|
634
707
|
return { Streaming: false };
|
|
635
708
|
}
|
|
709
|
+
if (err instanceof RemoteBrowserRefusedError) {
|
|
710
|
+
throw err;
|
|
711
|
+
}
|
|
636
712
|
const message = err instanceof Error ? err.message : String(err);
|
|
637
713
|
LogError(`StartRemoteBrowserAudioStream failed (provider='${providerName}'): ${message}`);
|
|
638
714
|
return { Streaming: false };
|
|
@@ -648,7 +724,7 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
648
724
|
*/
|
|
649
725
|
async StopRemoteBrowserAudioStream(agentSessionID, { userPayload, providers }, instanceKey) {
|
|
650
726
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
651
|
-
await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
727
|
+
await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
652
728
|
this.startedAudioStreams.delete(this.streamKey(agentSessionID, instanceKey));
|
|
653
729
|
const liveSession = RemoteBrowserEngine.Instance.GetSessionForAgentSession(agentSessionID, instanceKey);
|
|
654
730
|
if (liveSession) {
|
|
@@ -689,7 +765,7 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
689
765
|
*/
|
|
690
766
|
async RelayRemoteBrowserHumanInput(agentSessionID, kind, { userPayload, providers }, x, y, button, key, text, deltaX, deltaY, modifiers, instanceKey) {
|
|
691
767
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
692
|
-
await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
768
|
+
await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
693
769
|
const liveSession = RemoteBrowserEngine.Instance.GetSessionForAgentSession(agentSessionID, instanceKey);
|
|
694
770
|
if (!liveSession) {
|
|
695
771
|
return false;
|
|
@@ -728,7 +804,7 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
728
804
|
*/
|
|
729
805
|
async GetRemoteBrowserSelection(agentSessionID, { userPayload, providers }, instanceKey) {
|
|
730
806
|
const { contextUser, provider } = this.requireUserAndProvider(userPayload, providers);
|
|
731
|
-
await this.loadOwnedSession(agentSessionID, contextUser, provider);
|
|
807
|
+
await this.loadOwnedSession(agentSessionID, contextUser, provider, instanceKey);
|
|
732
808
|
const liveSession = RemoteBrowserEngine.Instance.GetSessionForAgentSession(agentSessionID, instanceKey);
|
|
733
809
|
if (!liveSession) {
|
|
734
810
|
return { Text: '' };
|
|
@@ -937,22 +1013,80 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
937
1013
|
return { contextUser, provider: GetReadWriteProvider(providers) };
|
|
938
1014
|
}
|
|
939
1015
|
/**
|
|
940
|
-
* Loads the
|
|
941
|
-
*
|
|
1016
|
+
* Loads the owning scope and enforces inbound ownership: an `MJ: AI Agent Sessions` row (a realtime
|
|
1017
|
+
* call, via `LoadOwnedRealtimeSession`) or, failing that, an `MJ: Conversations` row (a text chat's
|
|
1018
|
+
* browser), both under `AuthorizeSessionAccess`. Throws when neither exists or the caller may not use it.
|
|
942
1019
|
*
|
|
943
|
-
* @param agentSessionID The `AIAgentSession` id.
|
|
944
|
-
* @returns The
|
|
1020
|
+
* @param agentSessionID The `AIAgentSession` id or `Conversation` id.
|
|
1021
|
+
* @returns The owned scope.
|
|
945
1022
|
*/
|
|
946
|
-
async loadOwnedSession(agentSessionID, contextUser, provider) {
|
|
1023
|
+
async loadOwnedSession(agentSessionID, contextUser, provider, instanceKey) {
|
|
947
1024
|
try {
|
|
948
1025
|
return await LoadOwnedRealtimeSession(agentSessionID, contextUser, provider);
|
|
949
1026
|
}
|
|
950
1027
|
catch (err) {
|
|
951
|
-
if (err instanceof RealtimeSessionNotFoundError) {
|
|
952
|
-
throw new Error(`Remote-browser session ${agentSessionID} not found.`);
|
|
953
|
-
}
|
|
954
1028
|
if (err instanceof RealtimeSessionOwnershipError) {
|
|
955
|
-
throw new
|
|
1029
|
+
throw new RemoteBrowserRefusedError(`Not authorized: remote-browser session ${agentSessionID} is not owned by you.`);
|
|
1030
|
+
}
|
|
1031
|
+
if (!(err instanceof RealtimeSessionNotFoundError)) {
|
|
1032
|
+
throw err;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
// Not a realtime session: a text chat scopes its browser to a conversation, which this server must opt
|
|
1036
|
+
// into (each browser is a server Chromium or a billed hosted session), under the same access rule
|
|
1037
|
+
// (owner, and for an anonymous widget guest its scope id), loaded as the caller so its RLS applies too.
|
|
1038
|
+
const settings = this.ConversationBrowserSettings();
|
|
1039
|
+
if (!settings.enabled) {
|
|
1040
|
+
throw new RemoteBrowserRefusedError(`Remote-browser session ${agentSessionID} not found. Conversation browsers are not enabled on this server (realtime.conversationBrowser.enabled).`);
|
|
1041
|
+
}
|
|
1042
|
+
if (contextUser.IsMagicLinkAnonymous && !settings.allowAnonymous) {
|
|
1043
|
+
throw new RemoteBrowserRefusedError(`Not authorized: anonymous users cannot open a conversation browser on this server.`);
|
|
1044
|
+
}
|
|
1045
|
+
// One browser per conversation: an instance key would key a second one past the cap, the network
|
|
1046
|
+
// policy and the reaper (the client never sends one).
|
|
1047
|
+
if (instanceKey?.trim()) {
|
|
1048
|
+
throw new RemoteBrowserRefusedError('A conversation browser has no instances; instanceKey is not accepted.');
|
|
1049
|
+
}
|
|
1050
|
+
const conversation = await provider.GetEntityObject(CONVERSATION_ENTITY, contextUser);
|
|
1051
|
+
if (!(await conversation.Load(agentSessionID))) {
|
|
1052
|
+
throw new RemoteBrowserRefusedError(`Remote-browser session ${agentSessionID} not found.`);
|
|
1053
|
+
}
|
|
1054
|
+
const access = AuthorizeSessionAccess({ SessionUserID: conversation.UserID, ConversationExternalID: conversation.ExternalID, ConversationReadable: true }, contextUser);
|
|
1055
|
+
if (!access.Allowed) {
|
|
1056
|
+
throw new RemoteBrowserRefusedError(`Not authorized: remote-browser session ${agentSessionID} is not owned by you.`);
|
|
1057
|
+
}
|
|
1058
|
+
// Each use puts off the browser's idle end.
|
|
1059
|
+
ConversationBrowserLedger.Instance.Touch(agentSessionID);
|
|
1060
|
+
return { ID: conversation.ID, AgentID: null, Config_: null, IsConversation: true };
|
|
1061
|
+
}
|
|
1062
|
+
/** This server's conversation-browser settings (a seam for tests). */
|
|
1063
|
+
ConversationBrowserSettings() {
|
|
1064
|
+
return configInfo.realtime.conversationBrowser;
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Starts (or reuses) the scope's browser. A conversation's browser first counts against its owner's
|
|
1068
|
+
* cap, and gives the slot back when it fails to start.
|
|
1069
|
+
*/
|
|
1070
|
+
async startBrowser(agentSessionID, scope, contextUser, providerName, instanceKey) {
|
|
1071
|
+
if (scope.IsConversation) {
|
|
1072
|
+
const settings = this.ConversationBrowserSettings();
|
|
1073
|
+
// ponytail: an action that joins a launch a concurrent End then tears down keeps this slot until the
|
|
1074
|
+
// reaper frees it (idleMinutes); release it on that teardown if users hit maxPerUser this way.
|
|
1075
|
+
// An anonymous guest's cap is its own: every guest is the one shared Anonymous user.
|
|
1076
|
+
const guestScope = contextUser.IsMagicLinkAnonymous ? ResolveSessionScopeIdentity(contextUser) : undefined;
|
|
1077
|
+
const owner = { Key: guestScope ? `scope:${guestScope}` : `user:${NormalizeUUID(contextUser.ID)}`, Anonymous: Boolean(contextUser.IsMagicLinkAnonymous) };
|
|
1078
|
+
ConversationBrowserLedger.Instance.Claim(agentSessionID, owner, settings);
|
|
1079
|
+
// Set once, before the browser launches; the engine re-applies it to any replacement.
|
|
1080
|
+
if (!RemoteBrowserEngine.Instance.GetSessionForAgentSession(agentSessionID, instanceKey)) {
|
|
1081
|
+
await RemoteBrowserEngine.Instance.RestrictPrivateNetworkForAgentSession(agentSessionID, settings.allowedPrivateHosts);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
try {
|
|
1085
|
+
return await RemoteBrowserEngine.Instance.StartSessionForAgentSession(agentSessionID, contextUser, providerName, instanceKey);
|
|
1086
|
+
}
|
|
1087
|
+
catch (err) {
|
|
1088
|
+
if (scope.IsConversation && !RemoteBrowserEngine.Instance.GetSessionForAgentSession(agentSessionID, instanceKey)) {
|
|
1089
|
+
ConversationBrowserLedger.Instance.Release(agentSessionID);
|
|
956
1090
|
}
|
|
957
1091
|
throw err;
|
|
958
1092
|
}
|
|
@@ -963,10 +1097,13 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
963
1097
|
* config, or unparseable JSON all yield `undefined`, letting the engine fall back to the single Active
|
|
964
1098
|
* provider.
|
|
965
1099
|
*
|
|
966
|
-
* @param session The owned
|
|
1100
|
+
* @param session The owned scope (supplies the agent id; a conversation has none).
|
|
967
1101
|
* @returns The configured backend name, or `undefined` to let the engine auto-select.
|
|
968
1102
|
*/
|
|
969
1103
|
async resolveProviderName(session, contextUser, provider) {
|
|
1104
|
+
if (!session.AgentID) {
|
|
1105
|
+
return undefined;
|
|
1106
|
+
}
|
|
970
1107
|
// The session's agent IS the co-agent (the realtime voice agent), and the interactive channels
|
|
971
1108
|
// (Remote Browser, Whiteboard) are the CO-AGENT's abilities — so the remoteBrowser backend config
|
|
972
1109
|
// lives on the co-agent's TypeConfiguration, not on the target agent it voices.
|
|
@@ -1016,8 +1153,15 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
1016
1153
|
case 'navigate':
|
|
1017
1154
|
return input.url ? { Kind: 'navigate', Url: input.url } : null;
|
|
1018
1155
|
case 'click':
|
|
1019
|
-
if (input.selector || (typeof input.x === 'number' && typeof input.y === 'number')) {
|
|
1020
|
-
return {
|
|
1156
|
+
if (input.selector || input.ref || input.text || (typeof input.x === 'number' && typeof input.y === 'number')) {
|
|
1157
|
+
return {
|
|
1158
|
+
Kind: 'click',
|
|
1159
|
+
Selector: input.selector,
|
|
1160
|
+
Ref: input.ref,
|
|
1161
|
+
Text: input.text,
|
|
1162
|
+
X: input.x,
|
|
1163
|
+
Y: input.y,
|
|
1164
|
+
};
|
|
1021
1165
|
}
|
|
1022
1166
|
return null;
|
|
1023
1167
|
case 'type':
|
|
@@ -1038,10 +1182,37 @@ let RemoteBrowserActionResolver = class RemoteBrowserActionResolver extends Reso
|
|
|
1038
1182
|
return { Kind: 'wait', Ms: input.ms, Selector: input.selector };
|
|
1039
1183
|
}
|
|
1040
1184
|
return null;
|
|
1185
|
+
case 'inspect':
|
|
1186
|
+
return { Kind: 'inspect' };
|
|
1187
|
+
case 'getPageText':
|
|
1188
|
+
return { Kind: 'getPageText' };
|
|
1189
|
+
case 'fill': {
|
|
1190
|
+
const values = this.parseFillValues(input.valuesJson);
|
|
1191
|
+
return values.length > 0 ? { Kind: 'fill', Values: values } : null;
|
|
1192
|
+
}
|
|
1041
1193
|
default:
|
|
1042
1194
|
return null;
|
|
1043
1195
|
}
|
|
1044
1196
|
}
|
|
1197
|
+
/**
|
|
1198
|
+
* Parses the `valuesJson` payload for a `fill` action: a JSON object mapping a field ref (`f1`) or
|
|
1199
|
+
* label to its value (`string`, or `boolean` for a checkbox). Anything else yields no values.
|
|
1200
|
+
*/
|
|
1201
|
+
parseFillValues(valuesJson) {
|
|
1202
|
+
let parsed;
|
|
1203
|
+
try {
|
|
1204
|
+
parsed = JSON.parse(valuesJson ?? '');
|
|
1205
|
+
}
|
|
1206
|
+
catch {
|
|
1207
|
+
return [];
|
|
1208
|
+
}
|
|
1209
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
1210
|
+
return [];
|
|
1211
|
+
}
|
|
1212
|
+
return Object.entries(parsed)
|
|
1213
|
+
.filter(([target, value]) => target.trim().length > 0 && value !== undefined && value !== null)
|
|
1214
|
+
.map(([target, value]) => ({ Target: target.trim(), Value: typeof value === 'boolean' ? value : String(value) }));
|
|
1215
|
+
}
|
|
1045
1216
|
/**
|
|
1046
1217
|
* Builds a strongly-typed {@link RemoteBrowserHumanInput} from the relayed `kind` + fields, validating
|
|
1047
1218
|
* each kind's required field(s). Returns `null` for an unknown kind or a kind missing its required
|
|
@@ -1140,8 +1311,10 @@ __decorate([
|
|
|
1140
1311
|
__param(10, Arg('deltaY', () => Float, { nullable: true })),
|
|
1141
1312
|
__param(11, Arg('ms', () => Float, { nullable: true })),
|
|
1142
1313
|
__param(12, Arg('instanceKey', () => String, { nullable: true })),
|
|
1314
|
+
__param(13, Arg('ref', () => String, { nullable: true })),
|
|
1315
|
+
__param(14, Arg('valuesJson', () => String, { nullable: true })),
|
|
1143
1316
|
__metadata("design:type", Function),
|
|
1144
|
-
__metadata("design:paramtypes", [String, String, Object, String, String, Number, Number, String, String, Number, Number, Number, String]),
|
|
1317
|
+
__metadata("design:paramtypes", [String, String, Object, String, String, Number, Number, String, String, Number, Number, Number, String, String, String]),
|
|
1145
1318
|
__metadata("design:returntype", Promise)
|
|
1146
1319
|
], RemoteBrowserActionResolver.prototype, "ExecuteRemoteBrowserAction", null);
|
|
1147
1320
|
__decorate([
|
|
@@ -1204,6 +1377,15 @@ __decorate([
|
|
|
1204
1377
|
__metadata("design:paramtypes", [String, Object, String]),
|
|
1205
1378
|
__metadata("design:returntype", Promise)
|
|
1206
1379
|
], RemoteBrowserActionResolver.prototype, "StopRemoteBrowserScreencast", null);
|
|
1380
|
+
__decorate([
|
|
1381
|
+
Mutation(() => Boolean),
|
|
1382
|
+
__param(0, Arg('agentSessionID', () => String)),
|
|
1383
|
+
__param(1, Ctx()),
|
|
1384
|
+
__param(2, Arg('instanceKey', () => String, { nullable: true })),
|
|
1385
|
+
__metadata("design:type", Function),
|
|
1386
|
+
__metadata("design:paramtypes", [String, Object, String]),
|
|
1387
|
+
__metadata("design:returntype", Promise)
|
|
1388
|
+
], RemoteBrowserActionResolver.prototype, "EndRemoteBrowserSession", null);
|
|
1207
1389
|
__decorate([
|
|
1208
1390
|
Mutation(() => RemoteBrowserAudioStreamResult),
|
|
1209
1391
|
__param(0, Arg('agentSessionID', () => String)),
|
|
@@ -1251,7 +1433,8 @@ __decorate([
|
|
|
1251
1433
|
__metadata("design:returntype", Promise)
|
|
1252
1434
|
], RemoteBrowserActionResolver.prototype, "GetRemoteBrowserSelection", null);
|
|
1253
1435
|
RemoteBrowserActionResolver = __decorate([
|
|
1254
|
-
Resolver()
|
|
1436
|
+
Resolver(),
|
|
1437
|
+
__metadata("design:paramtypes", [])
|
|
1255
1438
|
], RemoteBrowserActionResolver);
|
|
1256
1439
|
export { RemoteBrowserActionResolver };
|
|
1257
1440
|
//# sourceMappingURL=RemoteBrowserActionResolver.js.map
|