@memberjunction/server 6.2.0-edge.4 → 6.2.0-edge.6
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 +47 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +91 -30
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +311 -81
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +17 -3
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +44 -10
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/apiRoot.d.ts +32 -0
- package/dist/apiRoot.d.ts.map +1 -0
- package/dist/apiRoot.js +67 -0
- package/dist/apiRoot.js.map +1 -0
- package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -1
- package/dist/auth/AuthProviderCatalogRouter.js +27 -0
- package/dist/auth/AuthProviderCatalogRouter.js.map +1 -1
- package/dist/auth/LoginScreenEngine.d.ts +22 -0
- package/dist/auth/LoginScreenEngine.d.ts.map +1 -0
- package/dist/auth/LoginScreenEngine.js +57 -0
- package/dist/auth/LoginScreenEngine.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +52 -10
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/initializeProviders.d.ts +10 -0
- package/dist/auth/initializeProviders.d.ts.map +1 -1
- package/dist/auth/initializeProviders.js +37 -1
- package/dist/auth/initializeProviders.js.map +1 -1
- package/dist/auth/localDevAuth.d.ts +79 -0
- package/dist/auth/localDevAuth.d.ts.map +1 -0
- package/dist/auth/localDevAuth.js +439 -0
- package/dist/auth/localDevAuth.js.map +1 -0
- package/dist/auth/magicLink/MagicLinkKeys.d.ts +2 -2
- package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +3 -2
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +12 -0
- package/dist/auth/magicLink/types.d.ts.map +1 -1
- package/dist/auth/sessionUserClone.d.ts +1 -1
- package/dist/auth/sessionUserClone.d.ts.map +1 -1
- package/dist/auth/sessionUserClone.js +3 -2
- package/dist/auth/sessionUserClone.js.map +1 -1
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts +292 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +442 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -0
- package/dist/broadcast/index.d.ts +6 -0
- package/dist/broadcast/index.d.ts.map +1 -0
- package/dist/broadcast/index.js +6 -0
- package/dist/broadcast/index.js.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts +43 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js +144 -0
- package/dist/broadcast/providers/AWSIoTCoreBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts +46 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js +149 -0
- package/dist/broadcast/providers/AzureWebPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts +49 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js +131 -0
- package/dist/broadcast/providers/GCPPubSubBroadcastProvider.js.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts +24 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.d.ts.map +1 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js +51 -0
- package/dist/broadcast/providers/SequencedRoleBucketBroadcastProvider.js.map +1 -0
- package/dist/cache.d.ts +3 -2
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js.map +1 -1
- package/dist/config.d.ts +632 -22
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +104 -4
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +3 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +29 -8
- package/dist/context.js.map +1 -1
- package/dist/coreRoutes.d.ts +29 -0
- package/dist/coreRoutes.d.ts.map +1 -0
- package/dist/coreRoutes.js +156 -0
- package/dist/coreRoutes.js.map +1 -0
- package/dist/generated/graphql-schemas/__mj.d.ts +1016 -29
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +5125 -434
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +85 -30
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +175 -60
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +2 -0
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/PubSubManager.d.ts +10 -0
- package/dist/generic/PubSubManager.d.ts.map +1 -1
- package/dist/generic/PubSubManager.js +44 -1
- package/dist/generic/PubSubManager.js.map +1 -1
- package/dist/generic/PushStatusResolver.d.ts +39 -6
- package/dist/generic/PushStatusResolver.d.ts.map +1 -1
- package/dist/generic/PushStatusResolver.js +94 -12
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +168 -69
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +464 -405
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +11 -3
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +91 -13
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/generic/actionOutputFieldSecurity.d.ts +26 -0
- package/dist/generic/actionOutputFieldSecurity.d.ts.map +1 -0
- package/dist/generic/actionOutputFieldSecurity.js +47 -0
- package/dist/generic/actionOutputFieldSecurity.js.map +1 -0
- package/dist/generic/fieldSecurityTransport.d.ts +30 -0
- package/dist/generic/fieldSecurityTransport.d.ts.map +1 -0
- package/dist/generic/fieldSecurityTransport.js +30 -0
- package/dist/generic/fieldSecurityTransport.js.map +1 -0
- package/dist/globalCors.d.ts +33 -0
- package/dist/globalCors.d.ts.map +1 -0
- package/dist/globalCors.js +58 -0
- package/dist/globalCors.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +230 -222
- package/dist/index.js.map +1 -1
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +6 -1
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.d.ts +12 -0
- package/dist/logging/variablesLoggingMiddleware.d.ts.map +1 -1
- package/dist/logging/variablesLoggingMiddleware.js +50 -1
- package/dist/logging/variablesLoggingMiddleware.js.map +1 -1
- package/dist/multiTenancy/index.d.ts.map +1 -1
- package/dist/multiTenancy/index.js +22 -2
- package/dist/multiTenancy/index.js.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js +2 -1
- package/dist/realtimeSessions/RealtimeSessionVerificationService.js.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.d.ts.map +1 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js +2 -1
- package/dist/realtimeSessions/RealtimeVerifyRouter.js.map +1 -1
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts +100 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.d.ts.map +1 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js +173 -0
- package/dist/realtimeSessions/RecordingAssemblyScheduler.js.map +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.d.ts.map +1 -1
- package/dist/realtimeSessions/SessionVerificationPortsBase.js +1 -0
- package/dist/realtimeSessions/SessionVerificationPortsBase.js.map +1 -1
- package/dist/realtimeSessions/index.d.ts +2 -0
- package/dist/realtimeSessions/index.d.ts.map +1 -1
- package/dist/realtimeSessions/index.js +2 -0
- package/dist/realtimeSessions/index.js.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts +32 -0
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js +56 -0
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -0
- package/dist/realtimeSessions/sessionAccess.d.ts +91 -8
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +127 -20
- package/dist/realtimeSessions/sessionAccess.js.map +1 -1
- package/dist/realtimeSessions/sessionConfigStamps.js +1 -1
- package/dist/realtimeSessions/sessionConfigStamps.js.map +1 -1
- package/dist/realtimeSessions/subscriptionAuthorization.d.ts.map +1 -1
- package/dist/realtimeSessions/subscriptionAuthorization.js +5 -2
- package/dist/realtimeSessions/subscriptionAuthorization.js.map +1 -1
- package/dist/realtimeSessions/verificationWorkflow.d.ts +2 -0
- package/dist/realtimeSessions/verificationWorkflow.d.ts.map +1 -1
- package/dist/realtimeSessions/verificationWorkflow.js +1 -1
- package/dist/realtimeSessions/verificationWorkflow.js.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetRouter.js +19 -3
- package/dist/realtimeWidget/WidgetRouter.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.d.ts +67 -7
- package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.js +201 -19
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
- package/dist/realtimeWidget/host-identity.d.ts +1 -1
- package/dist/realtimeWidget/host-identity.js +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts +20 -1
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +17 -1
- package/dist/realtimeWidget/widgetCore.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +2 -1
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/resolvers/ActionResolver.d.ts +19 -1
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +63 -12
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +1 -0
- package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.d.ts +18 -4
- package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.js +32 -8
- package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
- package/dist/resolvers/AgentSessionResolver.d.ts +10 -4
- package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/AgentSessionResolver.js +40 -17
- package/dist/resolvers/AgentSessionResolver.js.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts +5 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.js +9 -7
- package/dist/resolvers/ArtifactFileResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts +8 -4
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +6 -6
- package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
- package/dist/resolvers/DatasetResolver.d.ts +24 -3
- package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
- package/dist/resolvers/DatasetResolver.js +57 -8
- package/dist/resolvers/DatasetResolver.js.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts +13 -1
- package/dist/resolvers/EntityCommunicationsResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityCommunicationsResolver.js +50 -14
- package/dist/resolvers/EntityCommunicationsResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +2 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +3 -2
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts +46 -3
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +211 -50
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/FileCategoryResolver.d.ts.map +1 -1
- package/dist/resolvers/FileCategoryResolver.js +1 -0
- package/dist/resolvers/FileCategoryResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts +87 -11
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +292 -105
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
- package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +117 -38
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +6 -3
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +49 -9
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts +8 -1
- package/dist/resolvers/MergeRecordsResolver.d.ts.map +1 -1
- package/dist/resolvers/MergeRecordsResolver.js +31 -3
- package/dist/resolvers/MergeRecordsResolver.js.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.d.ts +6 -0
- package/dist/resolvers/PipelineProgressResolver.d.ts.map +1 -1
- package/dist/resolvers/PipelineProgressResolver.js +5 -3
- package/dist/resolvers/PipelineProgressResolver.js.map +1 -1
- package/dist/resolvers/QueryResolver.d.ts +2 -0
- package/dist/resolvers/QueryResolver.d.ts.map +1 -1
- package/dist/resolvers/QueryResolver.js +33 -6
- package/dist/resolvers/QueryResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +2 -0
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +15 -6
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/dist/resolvers/RSUResolver.d.ts.map +1 -1
- package/dist/resolvers/RSUResolver.js +12 -0
- package/dist/resolvers/RSUResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +18 -10
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +92 -54
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +11 -9
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +56 -8
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +241 -67
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +4 -4
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTestResolver.js +3 -1
- package/dist/resolvers/RunTestResolver.js.map +1 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts +12 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.d.ts.map +1 -1
- package/dist/resolvers/SearchKnowledgeStreamResolver.js +15 -2
- package/dist/resolvers/SearchKnowledgeStreamResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +2 -3
- package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
- package/dist/resolvers/SyncDataResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncDataResolver.js +4 -0
- package/dist/resolvers/SyncDataResolver.js.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts +2 -1
- package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
- package/dist/resolvers/TaskGraphFrameResolver.js +28 -1
- package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.d.ts +24 -0
- package/dist/resolvers/TestQuerySQLResolver.d.ts.map +1 -1
- package/dist/resolvers/TestQuerySQLResolver.js +66 -13
- package/dist/resolvers/TestQuerySQLResolver.js.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.d.ts +34 -2
- package/dist/resolvers/TransactionGroupResolver.d.ts.map +1 -1
- package/dist/resolvers/TransactionGroupResolver.js +150 -27
- package/dist/resolvers/TransactionGroupResolver.js.map +1 -1
- package/dist/resolvers/UserViewResolver.d.ts +1 -1
- package/dist/resolvers/UserViewResolver.d.ts.map +1 -1
- package/dist/resolvers/UserViewResolver.js +2 -1
- package/dist/resolvers/UserViewResolver.js.map +1 -1
- package/dist/resolvers/agent-run-data-guard.d.ts +31 -0
- package/dist/resolvers/agent-run-data-guard.d.ts.map +1 -0
- package/dist/resolvers/agent-run-data-guard.js +72 -0
- package/dist/resolvers/agent-run-data-guard.js.map +1 -0
- package/dist/rest/EntityCRUDHandler.d.ts +6 -0
- package/dist/rest/EntityCRUDHandler.d.ts.map +1 -1
- package/dist/rest/EntityCRUDHandler.js +19 -5
- package/dist/rest/EntityCRUDHandler.js.map +1 -1
- package/dist/rest/RESTEndpointHandler.d.ts.map +1 -1
- package/dist/rest/RESTEndpointHandler.js +8 -5
- package/dist/rest/RESTEndpointHandler.js.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.d.ts +49 -0
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -0
- package/dist/rest/RealtimeRecordingHandler.js +383 -0
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -0
- package/dist/rest/ViewOperationsHandler.d.ts +9 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +43 -17
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +6 -0
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +6 -0
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/serverExtensionReservedRoots.d.ts +12 -10
- package/dist/serverExtensionReservedRoots.d.ts.map +1 -1
- package/dist/serverExtensionReservedRoots.js +14 -17
- package/dist/serverExtensionReservedRoots.js.map +1 -1
- package/dist/serverRoleConfigUnits.d.ts +29 -0
- package/dist/serverRoleConfigUnits.d.ts.map +1 -0
- package/dist/serverRoleConfigUnits.js +33 -0
- package/dist/serverRoleConfigUnits.js.map +1 -0
- package/dist/services/MJStorageBlobStore.d.ts +8 -1
- package/dist/services/MJStorageBlobStore.d.ts.map +1 -1
- package/dist/services/MJStorageBlobStore.js +25 -19
- package/dist/services/MJStorageBlobStore.js.map +1 -1
- package/dist/services/StartTaskGraphDispatcher.js +2 -2
- package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts +5 -3
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +27 -5
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +14 -2
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +157 -9
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts +59 -2
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +626 -16
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/sharedCache.d.ts.map +1 -1
- package/dist/sharedCache.js +3 -0
- package/dist/sharedCache.js.map +1 -1
- package/dist/types.d.ts +23 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +99 -98
- package/src/__tests__/ActionResolver.fieldSecurity.test.ts +237 -0
- package/src/__tests__/AdhocQueryResolver.dialect.test.ts +137 -0
- package/src/__tests__/AgentRunStatusPublisher.test.ts +49 -0
- package/src/__tests__/AgentSessionResolver.ownership.test.ts +137 -0
- package/src/__tests__/CustomColumnPromoterOnePass.test.ts +15 -1
- package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
- package/src/__tests__/EntityCommunicationsResolver.actingUser.test.ts +151 -0
- package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
- package/src/__tests__/EvolutionActsOnWhatItDetects.test.ts +113 -0
- package/src/__tests__/FetchEntityVectorsResolver.test.ts +369 -18
- package/src/__tests__/FileResolver.fieldSecurity.test.ts +82 -0
- package/src/__tests__/FileResolver.storageAccess.test.ts +562 -0
- package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
- package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +137 -0
- package/src/__tests__/LoginScreenEngine.test.ts +86 -0
- package/src/__tests__/MJStorageBlobStore.storageGate.test.ts +63 -0
- package/src/__tests__/PipelineProgressResolver.filter.test.ts +58 -0
- package/src/__tests__/QuerySystemUserResolver.fieldSecurity.test.ts +49 -0
- package/src/__tests__/RESTEndpointHandler.test.ts +25 -0
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +23 -3
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +324 -46
- package/src/__tests__/RecordingAssemblyScheduler.test.ts +178 -0
- package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +98 -0
- package/src/__tests__/ResolverBase.adhocReadScope.test.ts +133 -2
- package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
- package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +127 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +243 -7
- package/src/__tests__/ResolverBase.deleteReturnProjection.test.ts +52 -0
- package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +176 -0
- package/src/__tests__/ResolverBase.filterEscaping.test.ts +5 -2
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +23 -1
- package/src/__tests__/ResolverBase.publishStatusUpdate.test.ts +68 -0
- package/src/__tests__/ResolverBase.userViewCacheAndDedup.test.ts +130 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +69 -13
- package/src/__tests__/RunAIAgentResolver.conversationWriter.test.ts +210 -0
- package/src/__tests__/RunAIAgentResolver.fireAndForgetCompletion.test.ts +209 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +20 -28
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +264 -0
- package/src/__tests__/RunAIAgentResolver.serverReply.test.ts +358 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +4 -1
- package/src/__tests__/RunTemplateResolver.test.ts +35 -2
- package/src/__tests__/RunViewResolver.cacheCheckForwarding.test.ts +11 -0
- package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +165 -0
- package/src/__tests__/SearchKnowledgeStreamResolver.test.ts +161 -0
- package/src/__tests__/SessionJanitor.test.ts +365 -10
- package/src/__tests__/SessionManager.test.ts +122 -0
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +25 -0
- package/src/__tests__/TaskGraphAgentRunner.test.ts +266 -0
- package/src/__tests__/TaskGraphContinuationDeliverer.test.ts +468 -23
- package/src/__tests__/TaskGraphFrameResolver.test.ts +22 -0
- package/src/__tests__/TestQuerySQLResolver.test.ts +274 -0
- package/src/__tests__/TransactionGroupResolver.fieldSecurity.test.ts +199 -0
- package/src/__tests__/TransactionGroupResolver.refusals.test.ts +98 -1
- package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
- package/src/__tests__/UserViewResolver.updateWhereClause.test.ts +15 -0
- package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +157 -0
- package/src/__tests__/ViewOperationsHandler.test.ts +7 -2
- package/src/__tests__/WidgetSessionService.test.ts +583 -4
- package/src/__tests__/agent-run-data-guard.test.ts +130 -0
- package/src/__tests__/apiRootBoot.test.ts +202 -0
- package/src/__tests__/buildMagicLinkSessionUser.test.ts +96 -0
- package/src/__tests__/cacheBroadcastProviders.test.ts +403 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +109 -0
- package/src/__tests__/conversationRunEvents.test.ts +56 -14
- package/src/__tests__/fieldSecurityFixtures.ts +91 -0
- package/src/__tests__/globalCors.test.ts +217 -0
- package/src/__tests__/localDevAuth.test.ts +196 -0
- package/src/__tests__/multiTenancy.postgresRewrite.test.ts +181 -0
- package/src/__tests__/multiTenancy.security.test.ts +51 -0
- package/src/__tests__/multiTenancy.test.ts +1 -1
- package/src/__tests__/orphanedConversationDetailReconciler.test.ts +10 -0
- package/src/__tests__/ownedRealtimeSession.test.ts +39 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +64 -1
- package/src/__tests__/realtimeRecordingHandler.test.ts +669 -0
- package/src/__tests__/realtimeSessions/RealtimeSessionEventsResolver.test.ts +29 -1
- package/src/__tests__/realtimeSessions/ownedRealtimeSession.anonymous.test.ts +31 -0
- package/src/__tests__/realtimeSessions/ownedRealtimeSession.namedScoped.test.ts +37 -0
- package/src/__tests__/realtimeSessions/sessionAccess.test.ts +146 -7
- package/src/__tests__/realtimeSessions/sessionConfigStamps.test.ts +1 -1
- package/src/__tests__/realtimeSessions/verificationWorkflow.test.ts +25 -4
- package/src/__tests__/resolverBase.cloudEventChangedFields.test.ts +157 -0
- package/src/__tests__/resolverBase.fieldSecurityTransport.test.ts +222 -0
- package/src/__tests__/resolverBase.fls.test.ts +146 -97
- package/src/__tests__/restTransport.fieldSecurity.test.ts +148 -0
- package/src/__tests__/runParamsTimeZone.test.ts +179 -0
- package/src/__tests__/runStreams.fieldSecurity.test.ts +100 -0
- package/src/__tests__/runViewProperties.test.ts +114 -0
- package/src/__tests__/scalabilityBenchmarks.test.ts +765 -0
- package/src/__tests__/scalabilityDatabaseIntegration.test.ts +207 -0
- package/src/__tests__/serverExtensionHostOverlay.test.ts +66 -0
- package/src/__tests__/serverExtensionReservedRoots.test.ts +11 -98
- package/src/__tests__/sessionUserClone.test.ts +5 -1
- package/src/__tests__/sharedCache.test.ts +5 -3
- package/src/__tests__/startupSweepOrder.test.ts +40 -0
- package/src/__tests__/unifiedAuth.test.ts +28 -0
- package/src/__tests__/widgetGuestElevation.test.ts +2 -0
- package/src/agentSessions/SessionJanitor.ts +369 -93
- package/src/agentSessions/SessionManager.ts +45 -10
- package/src/apiRoot.ts +78 -0
- package/src/auth/AuthProviderCatalogRouter.ts +29 -0
- package/src/auth/LoginScreenEngine.ts +50 -0
- package/src/auth/index.ts +57 -12
- package/src/auth/initializeProviders.ts +43 -1
- package/src/auth/localDevAuth.ts +528 -0
- package/src/auth/magicLink/MagicLinkKeys.ts +2 -2
- package/src/auth/magicLink/MagicLinkRouter.ts +3 -2
- package/src/auth/magicLink/types.ts +10 -0
- package/src/auth/sessionUserClone.ts +3 -2
- package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +674 -0
- package/src/broadcast/index.ts +5 -0
- package/src/broadcast/providers/AWSIoTCoreBroadcastProvider.ts +180 -0
- package/src/broadcast/providers/AzureWebPubSubBroadcastProvider.ts +182 -0
- package/src/broadcast/providers/GCPPubSubBroadcastProvider.ts +169 -0
- package/src/broadcast/providers/SequencedRoleBucketBroadcastProvider.ts +57 -0
- package/src/cache.ts +2 -1
- package/src/config.ts +115 -5
- package/src/context.ts +32 -8
- package/src/coreRoutes.ts +181 -0
- package/src/generated/graphql-schemas/__mj.ts +3684 -284
- package/src/generic/CacheInvalidationResolver.ts +172 -60
- package/src/generic/OrphanedConversationDetailReconciler.ts +4 -2
- package/src/generic/PubSubManager.ts +54 -1
- package/src/generic/PushStatusResolver.ts +109 -12
- package/src/generic/ResolverBase.ts +540 -431
- package/src/generic/RunViewResolver.ts +97 -15
- package/src/generic/actionOutputFieldSecurity.ts +75 -0
- package/src/generic/fieldSecurityTransport.ts +62 -0
- package/src/globalCors.ts +71 -0
- package/src/index.ts +239 -238
- package/src/integration/CustomColumnPromoter.ts +6 -1
- package/src/logging/variablesLoggingMiddleware.ts +59 -3
- package/src/multiTenancy/index.ts +24 -2
- package/src/realtimeSessions/README.md +7 -3
- package/src/realtimeSessions/RealtimeSessionVerificationService.ts +2 -1
- package/src/realtimeSessions/RealtimeVerifyRouter.ts +2 -1
- package/src/realtimeSessions/RecordingAssemblyScheduler.ts +234 -0
- package/src/realtimeSessions/SessionVerificationPortsBase.ts +1 -0
- package/src/realtimeSessions/index.ts +2 -0
- package/src/realtimeSessions/ownedRealtimeSession.ts +69 -0
- package/src/realtimeSessions/sessionAccess.ts +183 -23
- package/src/realtimeSessions/sessionConfigStamps.ts +1 -1
- package/src/realtimeSessions/subscriptionAuthorization.ts +4 -2
- package/src/realtimeSessions/verificationWorkflow.ts +3 -1
- package/src/realtimeWidget/WidgetRouter.ts +22 -4
- package/src/realtimeWidget/WidgetSessionService.ts +252 -17
- package/src/realtimeWidget/host-identity.ts +1 -1
- package/src/realtimeWidget/widgetCore.ts +30 -1
- package/src/realtimeWidget/widgetGuestElevation.ts +2 -1
- package/src/resolvers/ActionResolver.ts +78 -15
- package/src/resolvers/AdhocQueryResolver.ts +1 -0
- package/src/resolvers/AgentRunStatusPublisher.ts +36 -8
- package/src/resolvers/AgentSessionResolver.ts +46 -18
- package/src/resolvers/ArtifactFileResolver.ts +9 -8
- package/src/resolvers/ConversationRunEventsResolver.ts +15 -11
- package/src/resolvers/DatasetResolver.ts +70 -10
- package/src/resolvers/EntityCommunicationsResolver.ts +56 -15
- package/src/resolvers/EntityRecordNameResolver.ts +3 -2
- package/src/resolvers/FetchEntityVectorsResolver.ts +248 -55
- package/src/resolvers/FileCategoryResolver.ts +1 -0
- package/src/resolvers/FileResolver.ts +334 -109
- package/src/resolvers/GetDataContextDataResolver.ts +139 -41
- package/src/resolvers/GetDataResolver.ts +6 -3
- package/src/resolvers/IntegrationDiscoveryResolver.ts +53 -9
- package/src/resolvers/MergeRecordsResolver.ts +23 -2
- package/src/resolvers/PipelineProgressResolver.ts +12 -3
- package/src/resolvers/QueryResolver.ts +31 -6
- package/src/resolvers/QuerySystemUserResolver.ts +15 -6
- package/src/resolvers/RSUResolver.ts +12 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +114 -66
- package/src/resolvers/RemoteBrowserActionResolver.ts +15 -10
- package/src/resolvers/RunAIAgentResolver.ts +296 -85
- package/src/resolvers/RunTemplateResolver.ts +6 -4
- package/src/resolvers/RunTestResolver.ts +3 -1
- package/src/resolvers/SearchKnowledgeStreamResolver.ts +19 -3
- package/src/resolvers/SqlLoggingConfigResolver.ts +2 -4
- package/src/resolvers/SyncDataResolver.ts +4 -0
- package/src/resolvers/TaskGraphFrameResolver.ts +33 -1
- package/src/resolvers/TestQuerySQLResolver.ts +69 -13
- package/src/resolvers/TransactionGroupResolver.ts +185 -30
- package/src/resolvers/UserViewResolver.ts +2 -1
- package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
- package/src/resolvers/__tests__/MergeRecordsResolver.test.ts +43 -0
- package/src/resolvers/agent-run-data-guard.ts +89 -0
- package/src/rest/EntityCRUDHandler.ts +22 -5
- package/src/rest/RESTEndpointHandler.ts +8 -5
- package/src/rest/RealtimeRecordingHandler.ts +467 -0
- package/src/rest/ViewOperationsHandler.ts +52 -18
- package/src/rest/setupRESTEndpoints.ts +6 -0
- package/src/serverExtensionReservedRoots.ts +14 -17
- package/src/serverRoleConfigUnits.ts +48 -0
- package/src/services/MJStorageBlobStore.ts +31 -30
- package/src/services/StartTaskGraphDispatcher.ts +2 -2
- package/src/services/TaskGraphActionRunner.ts +25 -5
- package/src/services/TaskGraphAgentRunner.ts +188 -11
- package/src/services/TaskGraphContinuationDeliverer.ts +738 -16
- package/src/sharedCache.ts +3 -0
- package/src/types.ts +23 -1
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { Resolver, Mutation, Query, Arg, Ctx, ObjectType, Field, PubSub, PubSubEngine, Subscription, Root, ResolverFilterData, ID, Int } from 'type-graphql';
|
|
2
2
|
import { AppContext, UserPayload } from '../types.js';
|
|
3
3
|
import { DatabaseProviderBase, LogError, LogStatus, Metadata, RunView, UserInfo, IMetadataProvider } from '@memberjunction/core';
|
|
4
|
-
import { MJConversationDetailEntity, MJConversationDetailAttachmentEntity, MJConversationDetailArtifactEntity, MJArtifactVersionEntity, MJAIAgentRequestEntity, ArtifactMetadataEngine, ConversationEngine } from '@memberjunction/core-entities';
|
|
4
|
+
import { MJConversationDetailEntity, MJConversationDetailEntityExtended, MJConversationDetailAttachmentEntity, MJConversationDetailArtifactEntity, MJArtifactVersionEntity, MJAIAgentRequestEntity, ArtifactMetadataEngine, ConversationEngine } from '@memberjunction/core-entities';
|
|
5
5
|
import { RouteArtifact } from './artifact-routing.js';
|
|
6
6
|
import { AgentRunner, ArtifactToolManager } from '@memberjunction/ai-agents';
|
|
7
|
-
import { MJAIAgentEntityExtended, MJAIAgentRunEntityExtended, ExecuteAgentResult, ConversationUtility, AttachmentData } from '@memberjunction/ai-core-plus';
|
|
7
|
+
import { MJAIAgentEntityExtended, MJAIAgentRunEntityExtended, ExecuteAgentResult, ConversationUtility, AttachmentData, ContinuationAnnouncementText } from '@memberjunction/ai-core-plus';
|
|
8
8
|
import { AIEngine } from '@memberjunction/aiengine';
|
|
9
9
|
import { ChatMessage, ChatMessageContent } from '@memberjunction/ai';
|
|
10
10
|
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
11
11
|
import { AgentRunStatusPublisher } from './AgentRunStatusPublisher.js';
|
|
12
|
+
import { ProjectEntityObjectForCaller } from '../generic/fieldSecurityTransport.js';
|
|
12
13
|
import { StartLivenessPulse } from '../generic/FireAndForgetHeartbeat.js';
|
|
14
|
+
import { StatusUpdateOwnerID } from '../generic/PushStatusResolver.js';
|
|
13
15
|
import { RequireSystemUser } from '../directives/RequireSystemUser.js';
|
|
14
16
|
import { GetReadWriteProvider } from '../util.js';
|
|
15
17
|
import { ResolveWidgetGuestRunContext, ElevateUserPayload } from '../realtimeWidget/widgetGuestElevation.js';
|
|
18
|
+
import { AuthorizeConversationTurn } from '../realtimeSessions/sessionAccess.js';
|
|
19
|
+
import { IsTrustedAgentRunCaller } from './agent-run-data-guard.js';
|
|
16
20
|
import { SafeJSONParse, UUIDsEqual } from '@memberjunction/global';
|
|
17
21
|
import { GetAttachmentService } from '@memberjunction/aiengine';
|
|
18
22
|
import { NotificationEngine } from '@memberjunction/notifications';
|
|
@@ -31,6 +35,17 @@ function isAgentRunEntity(value: unknown): value is MJAIAgentRunEntityExtended {
|
|
|
31
35
|
return typeof value === 'object' && value !== null && 'ID' in value;
|
|
32
36
|
}
|
|
33
37
|
|
|
38
|
+
/** What a conversation turn asks for, before its agent runs (see `RunAIAgentFromConversationDetail`). */
|
|
39
|
+
interface ConversationTurnRequest {
|
|
40
|
+
UserMessageId: string;
|
|
41
|
+
AgentId: string;
|
|
42
|
+
MaxHistoryMessages: number;
|
|
43
|
+
HistoryFrom?: Date;
|
|
44
|
+
ReplyParentId?: string;
|
|
45
|
+
AnnouncedByAgentId?: string;
|
|
46
|
+
ReplyBranchId?: string | null;
|
|
47
|
+
}
|
|
48
|
+
|
|
34
49
|
@ObjectType()
|
|
35
50
|
export class AIAgentRunResult {
|
|
36
51
|
@Field()
|
|
@@ -172,7 +187,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
172
187
|
* Sanitize ExecuteAgentResult for JSON serialization
|
|
173
188
|
* Removes circular references and non-serializable objects
|
|
174
189
|
*/
|
|
175
|
-
private sanitizeAgentResult(result: ExecuteAgentResult): any {
|
|
190
|
+
private sanitizeAgentResult(result: ExecuteAgentResult, recipient?: UserInfo): any {
|
|
176
191
|
const sanitized: any = {
|
|
177
192
|
success: result.success,
|
|
178
193
|
payload: result.payload,
|
|
@@ -188,8 +203,9 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
188
203
|
|
|
189
204
|
// Safely extract agent run data using GetAll() for proper serialization
|
|
190
205
|
if (result.agentRun && typeof result.agentRun.GetAll === 'function') {
|
|
191
|
-
//
|
|
192
|
-
|
|
206
|
+
// GetAll() for the full serialized object including extended properties, projected for
|
|
207
|
+
// the recipient: the run comes from the agent engine, not from a load bound to them
|
|
208
|
+
sanitized.agentRun = ProjectEntityObjectForCaller(result.agentRun, recipient);
|
|
193
209
|
}
|
|
194
210
|
else {
|
|
195
211
|
// shouldn't ever get here
|
|
@@ -252,6 +268,14 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
252
268
|
throw new Error(`AI Agent "${agentEntity.Name}" is not active (Status: ${agentEntity.Status})`);
|
|
253
269
|
}
|
|
254
270
|
|
|
271
|
+
// Enforce agent run permissions for the calling user
|
|
272
|
+
if (currentUser && typeof AIEngine.Instance.CanUserRunAgent === 'function') {
|
|
273
|
+
const canRun = await AIEngine.Instance.CanUserRunAgent(agentEntity.ID, currentUser);
|
|
274
|
+
if (!canRun) {
|
|
275
|
+
throw new Error(`User does not have permission to run AI Agent "${agentEntity.Name}" (${agentEntity.ID})`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
255
279
|
return agentEntity;
|
|
256
280
|
}
|
|
257
281
|
|
|
@@ -294,8 +318,13 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
294
318
|
/** History floor for a conversation run — threaded into ExecuteAgentParams.ConversationHistoryFrom,
|
|
295
319
|
* so the framework's own conversation reads (retrieval tools, artifacts, compaction) honour it too. */
|
|
296
320
|
conversationHistoryFrom?: Date,
|
|
321
|
+
/** ExecuteAgentParams.TrustReservedRunData: true only for a caller IsTrustedAgentRunCaller accepts. */
|
|
322
|
+
trustReservedRunData: boolean = false,
|
|
297
323
|
/** The conversation branch of the run — threaded into ExecuteAgentParams.ConversationBranchID. */
|
|
298
|
-
conversationBranchId?: string | null
|
|
324
|
+
conversationBranchId?: string | null,
|
|
325
|
+
/** The reply row this request created on the server for the run (`conversationDetailId` is its ID). The run
|
|
326
|
+
* writes into this instance, so its writes carry the server-authored marker and the user it was made as. */
|
|
327
|
+
replyDetail?: MJConversationDetailEntityExtended
|
|
299
328
|
): Promise<AIAgentRunResult> {
|
|
300
329
|
const startTime = Date.now();
|
|
301
330
|
// Best-effort handle for persistInFlightAgentFailure. Populated from a
|
|
@@ -304,6 +333,8 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
304
333
|
// run is not marked Failed — the early-failure case we most want to
|
|
305
334
|
// persist, but we have no run object yet.
|
|
306
335
|
const agentRunRef = runRef ?? { current: null as MJAIAgentRunEntityExtended | null };
|
|
336
|
+
// The publisher owns every status message, including the failure completion the catch below sends.
|
|
337
|
+
const statusPublisher = new AgentRunStatusPublisher(pubSub, userPayload, sessionId, conversationDetailId);
|
|
307
338
|
|
|
308
339
|
try {
|
|
309
340
|
LogStatus(`=== RUNNING AI AGENT FOR ID: ${agentId} ===`);
|
|
@@ -337,9 +368,8 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
337
368
|
|
|
338
369
|
console.log(`🚀 Starting agent execution with sessionId: ${sessionId}`);
|
|
339
370
|
|
|
340
|
-
// The
|
|
341
|
-
//
|
|
342
|
-
const statusPublisher = new AgentRunStatusPublisher(pubSub, userPayload, sessionId);
|
|
371
|
+
// The resolver still copies the run into agentRunRef, including noise steps, for the
|
|
372
|
+
// fire-and-forget liveness pulse.
|
|
343
373
|
const publishProgress = statusPublisher.OnProgress;
|
|
344
374
|
|
|
345
375
|
// Execute the agent in conversation context - handles conversation, artifacts, etc.
|
|
@@ -366,15 +396,20 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
366
396
|
ConversationHistoryFrom: conversationHistoryFrom,
|
|
367
397
|
...(conversationBranchId ? { ConversationBranchID: conversationBranchId } : {}),
|
|
368
398
|
data: parsedData,
|
|
399
|
+
// Whether the run may read the reserved data keys (scope, agent-type params); BaseAgent drops them otherwise.
|
|
400
|
+
TrustReservedRunData: trustReservedRunData,
|
|
369
401
|
context: {
|
|
370
402
|
dataSource: dataSource
|
|
371
403
|
}
|
|
372
404
|
}, {
|
|
373
405
|
conversationDetailId: conversationDetailId, // Use existing if provided
|
|
406
|
+
agentResponseDetail: replyDetail, // the reply row this request created, when it did
|
|
374
407
|
conversationId: conversationId, // LATENCY OPT #2: pre-resolved to skip redundant load in AgentRunner
|
|
375
408
|
userMessage: userMessage, // Provide user message when conversationDetailId not provided
|
|
376
409
|
createArtifacts: createArtifacts || false,
|
|
377
|
-
sourceArtifactId: sourceArtifactId
|
|
410
|
+
sourceArtifactId: sourceArtifactId,
|
|
411
|
+
// A widget guest runs as the system user, but its conversation stays the guest's to write (MJ#4791).
|
|
412
|
+
ConversationWriter: userPayload.ElevatedFrom,
|
|
378
413
|
});
|
|
379
414
|
|
|
380
415
|
const result = conversationResult.agentResult;
|
|
@@ -437,7 +472,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
437
472
|
}
|
|
438
473
|
|
|
439
474
|
// Create sanitized payload for JSON serialization
|
|
440
|
-
const sanitizedResult = this.sanitizeAgentResult(result);
|
|
475
|
+
const sanitizedResult = this.sanitizeAgentResult(result, currentUser);
|
|
441
476
|
const returnResult = JSON.stringify(sanitizedResult);
|
|
442
477
|
|
|
443
478
|
// Publish final events with enriched result data for fire-and-forget clients
|
|
@@ -460,11 +495,18 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
460
495
|
} catch (error) {
|
|
461
496
|
const executionTime = Date.now() - startTime;
|
|
462
497
|
LogError(`AI Agent run failed:`, undefined, error);
|
|
463
|
-
|
|
498
|
+
// Never dereference a non-Error throw: this catch must not itself throw, since executeAIAgent resolves on
|
|
499
|
+
// every failure (executeAgentInBackground relies on it).
|
|
500
|
+
const errorMessage = (error instanceof Error && error.message) || 'Unknown error occurred';
|
|
464
501
|
|
|
465
502
|
// Fire-and-forget clients otherwise leave the run Running and the
|
|
466
503
|
// conversation detail In-Progress (Explorer red-pill timer).
|
|
467
|
-
await this.persistInFlightAgentFailure(p, userPayload, agentRunRef.current, conversationDetailId, errorMessage);
|
|
504
|
+
await this.persistInFlightAgentFailure(p, userPayload, agentRunRef.current, conversationDetailId, errorMessage, replyDetail);
|
|
505
|
+
// A fire-and-forget client has only this message to learn the run ended: without it, it waits out its
|
|
506
|
+
// idle timeout and then reconciles the run as a success. Published after the rows are closed, so a
|
|
507
|
+
// client that reloads the reply on this message reads the error. PublishFinal is the try's last step
|
|
508
|
+
// that can throw, so a run gets one completion or the other, never both.
|
|
509
|
+
statusPublisher.PublishFailure(conversationDetailId, errorMessage);
|
|
468
510
|
|
|
469
511
|
const errorResult = {
|
|
470
512
|
success: false,
|
|
@@ -490,7 +532,9 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
490
532
|
userPayload: UserPayload,
|
|
491
533
|
run: MJAIAgentRunEntityExtended | null | undefined,
|
|
492
534
|
conversationDetailId: string | undefined,
|
|
493
|
-
errorMessage: string
|
|
535
|
+
errorMessage: string,
|
|
536
|
+
/** The run's reply row, when this request created it: written in place, as the server. */
|
|
537
|
+
replyDetail?: MJConversationDetailEntityExtended
|
|
494
538
|
): Promise<void> {
|
|
495
539
|
try {
|
|
496
540
|
if (run && run.Status === 'Running') {
|
|
@@ -507,10 +551,11 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
507
551
|
return;
|
|
508
552
|
}
|
|
509
553
|
if (conversationDetailId) {
|
|
510
|
-
const detail = await provider.GetEntityObject<MJConversationDetailEntity>(
|
|
554
|
+
const detail = replyDetail ?? await provider.GetEntityObject<MJConversationDetailEntity>(
|
|
511
555
|
'MJ: Conversation Details',
|
|
512
556
|
user
|
|
513
557
|
);
|
|
558
|
+
await detail.EnsureSaveComplete(); // the run may still be saving into the same reply instance
|
|
514
559
|
if (await detail.Load(conversationDetailId) && detail.Status === 'In-Progress') {
|
|
515
560
|
await detail.EnsureSaveComplete();
|
|
516
561
|
detail.Status = 'Error';
|
|
@@ -564,6 +609,9 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
564
609
|
await this.CheckAPIKeyScopeAuthorization('agent:execute', agentId, userPayload);
|
|
565
610
|
|
|
566
611
|
const p = GetReadWriteProvider(providers);
|
|
612
|
+
// Only the system user or an API key holding the agent:trusted scope may set a run's scope and agent-type
|
|
613
|
+
// params through data; for anyone else BaseAgent drops those keys (ExecuteAgentParams.TrustReservedRunData).
|
|
614
|
+
const trustRunData = await IsTrustedAgentRunCaller({ UserPayload: userPayload, IsWidgetGuestRun: false, AgentID: agentId });
|
|
567
615
|
|
|
568
616
|
if (fireAndForget) {
|
|
569
617
|
// Fire-and-forget mode: start execution in background, return immediately.
|
|
@@ -572,7 +620,8 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
572
620
|
p, dataSource, agentId, userPayload, messagesJson, sessionId, pubSub,
|
|
573
621
|
data, payload, lastRunId, autoPopulateLastRunPayload, configurationId,
|
|
574
622
|
conversationDetailId, createArtifacts || false, createNotification || false,
|
|
575
|
-
sourceArtifactId, sourceArtifactVersionId, undefined /*conversationId*/, planMode, requestedSkillIDs, taskGraphDebug
|
|
623
|
+
sourceArtifactId, sourceArtifactVersionId, undefined /*conversationId*/, planMode, requestedSkillIDs, taskGraphDebug,
|
|
624
|
+
undefined /*conversationHistoryFrom*/, trustRunData
|
|
576
625
|
);
|
|
577
626
|
|
|
578
627
|
LogStatus(`🔥 Fire-and-forget: Agent ${agentId} execution started in background for session ${sessionId}`);
|
|
@@ -607,7 +656,9 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
607
656
|
undefined, // runRef
|
|
608
657
|
planMode,
|
|
609
658
|
requestedSkillIDs,
|
|
610
|
-
taskGraphDebug
|
|
659
|
+
taskGraphDebug,
|
|
660
|
+
undefined, // conversationHistoryFrom
|
|
661
|
+
trustRunData
|
|
611
662
|
);
|
|
612
663
|
}
|
|
613
664
|
|
|
@@ -640,6 +691,9 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
640
691
|
@Arg('requestedSkillIDs', () => [String], { nullable: true }) requestedSkillIDs?: string[]
|
|
641
692
|
): Promise<AIAgentRunResult> {
|
|
642
693
|
const p = GetReadWriteProvider(providers);
|
|
694
|
+
// @RequireSystemUser admits only the system user, whom the rule trusts; it is still asked, so every
|
|
695
|
+
// resolver entry that takes a client's data decides the same way.
|
|
696
|
+
const trustRunData = await IsTrustedAgentRunCaller({ UserPayload: userPayload, IsWidgetGuestRun: false, AgentID: agentId });
|
|
643
697
|
return this.executeAIAgent(
|
|
644
698
|
p,
|
|
645
699
|
dataSource,
|
|
@@ -662,7 +716,10 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
662
716
|
undefined, // conversationId (not pre-resolved on this path)
|
|
663
717
|
undefined, // runRef
|
|
664
718
|
planMode,
|
|
665
|
-
requestedSkillIDs
|
|
719
|
+
requestedSkillIDs,
|
|
720
|
+
undefined, // taskGraphDebug
|
|
721
|
+
undefined, // conversationHistoryFrom
|
|
722
|
+
trustRunData
|
|
666
723
|
);
|
|
667
724
|
}
|
|
668
725
|
|
|
@@ -900,16 +957,27 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
900
957
|
}
|
|
901
958
|
|
|
902
959
|
/**
|
|
903
|
-
*
|
|
904
|
-
*
|
|
960
|
+
* Runs an agent's turn in a conversation: the server loads the history (attachments included, so the client never
|
|
961
|
+
* sends them), creates the agent's reply row, and runs the agent into it.
|
|
962
|
+
*
|
|
963
|
+
* Only the server writes agent replies (A19). The reply row (`Role` `AI`, In-Progress, its `ParentID` the user's
|
|
964
|
+
* message) is created here, as the person asking, before the run starts. In fire-and-forget mode the
|
|
965
|
+
* acknowledgement names it, `{ accepted, fireAndForget, conversationDetailId, createdAt }`, and is returned before
|
|
966
|
+
* the run publishes anything; every progress, streaming and completion message carries the same
|
|
967
|
+
* `conversationDetailId`. In synchronous mode the result's `agentRun.ConversationDetailID` names it.
|
|
905
968
|
*
|
|
906
|
-
*
|
|
969
|
+
* Threading, both optional: `replyParentId` puts the reply under another message of the same conversation the
|
|
970
|
+
* caller can read (MJ's chat threads a delegate's reply under the manager's); `announcedByAgentId` has the server
|
|
971
|
+
* first post that agent's fixed line "Continuing with **{agent}** for refinement..." and thread the reply under
|
|
972
|
+
* it, and the acknowledgement then also carries `announcementDetailId`.
|
|
973
|
+
*
|
|
974
|
+
* @param userMessageId - The person's message this turn answers, already saved.
|
|
907
975
|
* @param agentId - The agent to execute
|
|
908
976
|
* @param maxHistoryMessages - Maximum number of history messages to include (default: 20)
|
|
909
977
|
*/
|
|
910
978
|
@Mutation(() => AIAgentRunResult)
|
|
911
979
|
async RunAIAgentFromConversationDetail(
|
|
912
|
-
@Arg('
|
|
980
|
+
@Arg('userMessageId') userMessageId: string,
|
|
913
981
|
@Arg('agentId') agentId: string,
|
|
914
982
|
@Ctx() { userPayload, providers, dataSource }: AppContext,
|
|
915
983
|
@Arg('sessionId') sessionId: string,
|
|
@@ -932,11 +1000,17 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
932
1000
|
* run's own conversation reads honour it too. Omitted (clients send it only when set, so an
|
|
933
1001
|
* older client never does), the run reads the whole conversation as before. An unreadable
|
|
934
1002
|
* value fails the request rather than being dropped. */
|
|
935
|
-
@Arg('agentHistoryFrom', { nullable: true }) agentHistoryFrom?: string
|
|
1003
|
+
@Arg('agentHistoryFrom', { nullable: true }) agentHistoryFrom?: string,
|
|
1004
|
+
/** The message the reply threads under, when not the user's message: one in the same conversation the
|
|
1005
|
+
* caller can read. */
|
|
1006
|
+
@Arg('replyParentId', { nullable: true }) replyParentId?: string,
|
|
1007
|
+
/** An active agent (MJ's chat passes its conversation manager) whose fixed line "Continuing with
|
|
1008
|
+
* **{agent}** for refinement..." the server posts before the reply, which then threads under it. */
|
|
1009
|
+
@Arg('announcedByAgentId', { nullable: true }) announcedByAgentId?: string,
|
|
1010
|
+
/** The fork the reply and history run on, when the turn forks from `userMessageId` (such as Regenerate).
|
|
1011
|
+
* Checked to be a branch of the conversation whose path holds `userMessageId`. */
|
|
1012
|
+
@Arg('replyBranchId', { nullable: true }) replyBranchId?: string
|
|
936
1013
|
): Promise<AIAgentRunResult> {
|
|
937
|
-
// Check API key scope authorization for agent execution
|
|
938
|
-
await this.CheckAPIKeyScopeAuthorization('agent:execute', agentId, userPayload);
|
|
939
|
-
|
|
940
1014
|
const p = GetReadWriteProvider(providers);
|
|
941
1015
|
const currentUser = this.GetUserFromPayload(userPayload);
|
|
942
1016
|
|
|
@@ -953,31 +1027,44 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
953
1027
|
// AUTHORITATIVELY from the widget instance (never the client-supplied arg) — so a guest needs
|
|
954
1028
|
// no grants to WRITE the AI run entities and cannot run an arbitrary agent under elevation.
|
|
955
1029
|
// Conversation OWNERSHIP is still enforced under the guest principal below: the guest loads its
|
|
956
|
-
// own ConversationDetail through
|
|
957
|
-
//
|
|
1030
|
+
// own ConversationDetail through its role's RLS filters, and startConversationTurn then checks
|
|
1031
|
+
// the conversation's scope stamp against the visitor (MJ#6032), so a detail id from another
|
|
1032
|
+
// visitor's session is refused before any elevated work happens. The reply row is written
|
|
1033
|
+
// as the guest too, never as the elevated principal, which owns no guest's conversation.
|
|
958
1034
|
const widgetElevation = await ResolveWidgetGuestRunContext(userPayload, p);
|
|
959
1035
|
const effectiveAgentId = widgetElevation ? widgetElevation.PinnedAgentId : agentId;
|
|
1036
|
+
// Check API key scope authorization for agent execution against the resolved agent id.
|
|
1037
|
+
await this.CheckAPIKeyScopeAuthorization('agent:execute', effectiveAgentId, userPayload);
|
|
1038
|
+
// A widget guest has one pinned agent and never posts a continuation announcement as another agent;
|
|
1039
|
+
// an API-key caller must hold agent:execute for the announcing agent as well as the running agent.
|
|
1040
|
+
const effectiveAnnouncedByAgentId = widgetElevation ? undefined : announcedByAgentId;
|
|
1041
|
+
if (effectiveAnnouncedByAgentId) {
|
|
1042
|
+
await this.CheckAPIKeyScopeAuthorization('agent:execute', effectiveAnnouncedByAgentId, userPayload);
|
|
1043
|
+
}
|
|
960
1044
|
const effectiveUserPayload = widgetElevation ? ElevateUserPayload(userPayload, widgetElevation.ElevatedUser) : userPayload;
|
|
1045
|
+
// Only the system user or an API key holding the agent:trusted scope may set a run's scope and agent-type
|
|
1046
|
+
// params through data (ExecuteAgentParams.TrustReservedRunData). Judged on the caller's own payload: a widget
|
|
1047
|
+
// guest runs under an elevated server principal but is never trusted.
|
|
1048
|
+
const trustRunData = await IsTrustedAgentRunCaller({
|
|
1049
|
+
UserPayload: userPayload, IsWidgetGuestRun: widgetElevation !== null, AgentID: agentId,
|
|
1050
|
+
});
|
|
961
1051
|
|
|
962
1052
|
try {
|
|
963
1053
|
// Parsed before anything loads: a floor the caller asked for must never be dropped.
|
|
964
1054
|
const historyFrom = parseAgentHistoryFrom(agentHistoryFrom);
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
const conversationId = currentDetail.ConversationID;
|
|
979
|
-
// The branch the placeholder row was created on decides which path the run reads.
|
|
980
|
-
const branchId: string | null = currentDetail.BranchID ?? null;
|
|
1055
|
+
const turn = await this.startConversationTurn(p, currentUser, {
|
|
1056
|
+
UserMessageId: userMessageId,
|
|
1057
|
+
AgentId: effectiveAgentId,
|
|
1058
|
+
MaxHistoryMessages: maxHistoryMessages || 20,
|
|
1059
|
+
HistoryFrom: historyFrom,
|
|
1060
|
+
ReplyParentId: replyParentId,
|
|
1061
|
+
AnnouncedByAgentId: effectiveAnnouncedByAgentId,
|
|
1062
|
+
ReplyBranchId: replyBranchId
|
|
1063
|
+
});
|
|
1064
|
+
const reply = turn.Reply;
|
|
1065
|
+
// The turn's branch (the message's own branch, or a validated fork whose path holds the message)
|
|
1066
|
+
// decides which path the run reads.
|
|
1067
|
+
const branchId = turn.BranchId;
|
|
981
1068
|
|
|
982
1069
|
// A turn that follows a run the user STOPPED continues that run rather than starting
|
|
983
1070
|
// over: chain it by LastRunID (the chat client never sends one) and, when the caller
|
|
@@ -985,7 +1072,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
985
1072
|
let effectiveLastRunId = lastRunId;
|
|
986
1073
|
let effectiveAutoPopulate = autoPopulateLastRunPayload;
|
|
987
1074
|
if (!effectiveLastRunId) {
|
|
988
|
-
const stoppedRunId = await this.findUserStoppedPredecessorRunId(
|
|
1075
|
+
const stoppedRunId = await this.findUserStoppedPredecessorRunId(turn.ConversationId, effectiveAgentId, branchId, currentUser, p);
|
|
989
1076
|
if (stoppedRunId) {
|
|
990
1077
|
effectiveLastRunId = stoppedRunId;
|
|
991
1078
|
if (effectiveAutoPopulate === undefined && payload == null) {
|
|
@@ -995,40 +1082,32 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
995
1082
|
}
|
|
996
1083
|
}
|
|
997
1084
|
|
|
998
|
-
// Load conversation history with attachments from DB
|
|
999
|
-
const messages = await this.loadConversationHistoryWithAttachments(
|
|
1000
|
-
conversationId,
|
|
1001
|
-
currentUser,
|
|
1002
|
-
maxHistoryMessages || 20,
|
|
1003
|
-
p,
|
|
1004
|
-
// The UI creates the agent-response placeholder row ('⏳ ...') before invoking
|
|
1005
|
-
// this mutation — exclude it so the model never sees an empty assistant turn.
|
|
1006
|
-
[conversationDetailId],
|
|
1007
|
-
historyFrom,
|
|
1008
|
-
branchId
|
|
1009
|
-
);
|
|
1010
|
-
|
|
1011
|
-
// Convert to JSON string for the existing executeAIAgent method
|
|
1012
|
-
const messagesJson = JSON.stringify(messages);
|
|
1013
|
-
|
|
1014
1085
|
if (fireAndForget) {
|
|
1015
1086
|
// Fire-and-forget mode: start execution in background, return immediately.
|
|
1016
1087
|
// The client will receive the result via WebSocket PubSub completion event.
|
|
1017
1088
|
this.executeAgentInBackground(
|
|
1018
|
-
p, dataSource, effectiveAgentId, effectiveUserPayload,
|
|
1089
|
+
p, dataSource, effectiveAgentId, effectiveUserPayload, turn.MessagesJson, sessionId, pubSub,
|
|
1019
1090
|
data, payload, effectiveLastRunId, effectiveAutoPopulate, configurationId,
|
|
1020
|
-
|
|
1021
|
-
sourceArtifactId, sourceArtifactVersionId,
|
|
1091
|
+
reply.ID, createArtifacts || false, createNotification || false,
|
|
1092
|
+
sourceArtifactId, sourceArtifactVersionId, turn.ConversationId, planMode, requestedSkillIDs,
|
|
1022
1093
|
undefined, // taskGraphDebug
|
|
1023
1094
|
historyFrom,
|
|
1024
|
-
|
|
1095
|
+
trustRunData,
|
|
1096
|
+
branchId,
|
|
1097
|
+
reply
|
|
1025
1098
|
);
|
|
1026
1099
|
|
|
1027
1100
|
LogStatus(`🔥 Fire-and-forget: Agent ${effectiveAgentId} execution started in background for session ${sessionId}`);
|
|
1028
1101
|
|
|
1029
1102
|
return {
|
|
1030
1103
|
success: true,
|
|
1031
|
-
result: JSON.stringify({
|
|
1104
|
+
result: JSON.stringify({
|
|
1105
|
+
accepted: true,
|
|
1106
|
+
fireAndForget: true,
|
|
1107
|
+
conversationDetailId: reply.ID,
|
|
1108
|
+
createdAt: reply.__mj_CreatedAt,
|
|
1109
|
+
...(turn.Announcement ? { announcementDetailId: turn.Announcement.ID } : {})
|
|
1110
|
+
})
|
|
1032
1111
|
};
|
|
1033
1112
|
}
|
|
1034
1113
|
|
|
@@ -1038,7 +1117,7 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
1038
1117
|
dataSource,
|
|
1039
1118
|
effectiveAgentId,
|
|
1040
1119
|
effectiveUserPayload,
|
|
1041
|
-
|
|
1120
|
+
turn.MessagesJson,
|
|
1042
1121
|
sessionId,
|
|
1043
1122
|
pubSub,
|
|
1044
1123
|
data,
|
|
@@ -1047,18 +1126,20 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
1047
1126
|
effectiveLastRunId,
|
|
1048
1127
|
effectiveAutoPopulate,
|
|
1049
1128
|
configurationId,
|
|
1050
|
-
|
|
1129
|
+
reply.ID,
|
|
1051
1130
|
createArtifacts || false,
|
|
1052
1131
|
createNotification || false,
|
|
1053
1132
|
sourceArtifactId,
|
|
1054
1133
|
sourceArtifactVersionId,
|
|
1055
|
-
|
|
1134
|
+
turn.ConversationId, // LATENCY OPT #2: pass pre-resolved conversationId
|
|
1056
1135
|
undefined, // runRef
|
|
1057
1136
|
planMode,
|
|
1058
1137
|
requestedSkillIDs,
|
|
1059
1138
|
undefined, // taskGraphDebug
|
|
1060
1139
|
historyFrom,
|
|
1061
|
-
|
|
1140
|
+
trustRunData,
|
|
1141
|
+
branchId,
|
|
1142
|
+
reply
|
|
1062
1143
|
);
|
|
1063
1144
|
} catch (error) {
|
|
1064
1145
|
const errorMessage = (error as Error).message || 'Unknown error loading conversation history';
|
|
@@ -1071,6 +1152,137 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
1071
1152
|
}
|
|
1072
1153
|
}
|
|
1073
1154
|
|
|
1155
|
+
/**
|
|
1156
|
+
* Everything a conversation turn needs before its agent runs: the user's message (read as the caller, so a
|
|
1157
|
+
* message they can't see is "not found", and for an anonymous visitor also checked against the conversation's
|
|
1158
|
+
* scope stamp), the conversation history, the optional announcement line, and the reply
|
|
1159
|
+
* row, created last so the history never holds the empty reply. Every row is written as `user`, the person asking,
|
|
1160
|
+
* and marked as server-authored by {@link AgentRunner.CreateAgentReplyDetail}.
|
|
1161
|
+
*/
|
|
1162
|
+
private async startConversationTurn(
|
|
1163
|
+
p: DatabaseProviderBase,
|
|
1164
|
+
user: UserInfo,
|
|
1165
|
+
request: ConversationTurnRequest
|
|
1166
|
+
): Promise<{ ConversationId: string; BranchId: string | null; MessagesJson: string; Reply: MJConversationDetailEntityExtended; Announcement?: MJConversationDetailEntityExtended }> {
|
|
1167
|
+
// LATENCY OPTIMIZATION (Opt #2 + #3): the user's message is loaded once here for its conversation and
|
|
1168
|
+
// branch, which are threaded through the call chain rather than reloaded downstream.
|
|
1169
|
+
const placement = await this.loadPlacementOf(p, user, request.UserMessageId);
|
|
1170
|
+
const conversationId = placement.ConversationId;
|
|
1171
|
+
// Loading the message as the caller is the whole ownership check for a named user. It is not for an
|
|
1172
|
+
// anonymous visitor: every visitor is the one shared Anonymous user, so under a guest role whose row
|
|
1173
|
+
// filters key on UserID another visitor's message loads fine (MJ#6032). The conversation's scope stamp
|
|
1174
|
+
// decides instead, exactly as it does for the realtime gates — and before any row is written.
|
|
1175
|
+
const access = await AuthorizeConversationTurn(conversationId, user, p);
|
|
1176
|
+
if (!access.Allowed) {
|
|
1177
|
+
LogError(`RunAIAgentFromConversationDetail: anonymous visitor ${user.AnonymousVisitorID ?? '(no visitor id)'} refused a turn in conversation ${conversationId} (${access.Reason})`);
|
|
1178
|
+
throw new Error('Not authorized: you do not own this conversation');
|
|
1179
|
+
}
|
|
1180
|
+
const branchId = request.ReplyBranchId
|
|
1181
|
+
? await this.validateReplyBranch(p, user, conversationId, placement, request.ReplyBranchId)
|
|
1182
|
+
: placement.BranchId;
|
|
1183
|
+
const parentId = request.ReplyParentId
|
|
1184
|
+
? await this.validateReplyParent(p, user, request.ReplyParentId, conversationId)
|
|
1185
|
+
: request.UserMessageId;
|
|
1186
|
+
const messages = await this.loadConversationHistoryWithAttachments(conversationId, user, request.MaxHistoryMessages, p, undefined, request.HistoryFrom, branchId);
|
|
1187
|
+
const runner = new AgentRunner(p);
|
|
1188
|
+
const announcement = request.AnnouncedByAgentId
|
|
1189
|
+
? await this.postContinuationAnnouncement(runner, user, conversationId, branchId, parentId, request.AnnouncedByAgentId, request.AgentId)
|
|
1190
|
+
: undefined;
|
|
1191
|
+
const reply = await runner.CreateAgentReplyDetail({
|
|
1192
|
+
conversationId,
|
|
1193
|
+
branchId,
|
|
1194
|
+
agentId: request.AgentId,
|
|
1195
|
+
contextUser: user,
|
|
1196
|
+
parentId: announcement?.ID ?? parentId,
|
|
1197
|
+
provider: p
|
|
1198
|
+
});
|
|
1199
|
+
return { ConversationId: conversationId, BranchId: branchId, MessagesJson: JSON.stringify(messages), Reply: reply, Announcement: announcement };
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
/** The conversation, branch (null is Main) and sequence of a message, read as `user`; throws when they can't read it. */
|
|
1203
|
+
private async loadPlacementOf(
|
|
1204
|
+
p: DatabaseProviderBase,
|
|
1205
|
+
user: UserInfo,
|
|
1206
|
+
messageId: string
|
|
1207
|
+
): Promise<{ ConversationId: string; BranchId: string | null; Sequence: number }> {
|
|
1208
|
+
const message = await p.GetEntityObject<MJConversationDetailEntity>('MJ: Conversation Details', user);
|
|
1209
|
+
if (!await message.Load(messageId)) {
|
|
1210
|
+
throw new Error(`Conversation detail ${messageId} not found`);
|
|
1211
|
+
}
|
|
1212
|
+
return { ConversationId: message.ConversationID, BranchId: message.BranchID ?? null, Sequence: message.Sequence ?? -1 };
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* When a turn forks from an earlier message (such as Regenerate), the reply and history run on the fork while the
|
|
1217
|
+
* user's message stays on the branch it was written on. Checks that `replyBranchId` is a branch of the turn's
|
|
1218
|
+
* conversation whose path holds the user's message (`IsRowOnBranchPath` rather than exact `ForkFromSequence`
|
|
1219
|
+
* equality is deliberate: `ConversationEngine.ForkPointFrom` sets `ForkFromSequence = message.Sequence` and the
|
|
1220
|
+
* fork belongs to this conversation); returns `replyBranchId`, or throws before any row is created.
|
|
1221
|
+
*/
|
|
1222
|
+
private async validateReplyBranch(
|
|
1223
|
+
p: DatabaseProviderBase,
|
|
1224
|
+
user: UserInfo,
|
|
1225
|
+
conversationId: string,
|
|
1226
|
+
userMessage: { BranchId: string | null; Sequence: number },
|
|
1227
|
+
replyBranchId: string
|
|
1228
|
+
): Promise<string> {
|
|
1229
|
+
if (UUIDsEqual(replyBranchId, userMessage.BranchId)) {
|
|
1230
|
+
return replyBranchId;
|
|
1231
|
+
}
|
|
1232
|
+
if (userMessage.Sequence < 0) {
|
|
1233
|
+
throw new Error(`Conversation detail is not on branch ${replyBranchId}'s path, so the reply cannot be written on that branch`);
|
|
1234
|
+
}
|
|
1235
|
+
const branches = await ConversationEngine.LoadBranchesFresh(conversationId, user, p);
|
|
1236
|
+
const chain = ConversationEngine.BuildBranchChain(branches, replyBranchId);
|
|
1237
|
+
if (!ConversationEngine.IsRowOnBranchPath({ BranchID: userMessage.BranchId, Sequence: userMessage.Sequence }, chain)) {
|
|
1238
|
+
throw new Error(`Conversation detail is not on branch ${replyBranchId}'s path, so the reply cannot be written on that branch`);
|
|
1239
|
+
}
|
|
1240
|
+
return replyBranchId;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* A reply's parent is part of what the reply says, so the server sets it, from a checked input: a message the
|
|
1245
|
+
* caller can read, in the turn's own conversation. Returns its ID; throws otherwise.
|
|
1246
|
+
*/
|
|
1247
|
+
private async validateReplyParent(p: DatabaseProviderBase, user: UserInfo, parentId: string, conversationId: string): Promise<string> {
|
|
1248
|
+
const { ConversationId: parentConversationId } = await this.loadPlacementOf(p, user, parentId);
|
|
1249
|
+
if (!UUIDsEqual(parentConversationId, conversationId)) {
|
|
1250
|
+
throw new Error(`Conversation detail ${parentId} is not in this turn's conversation, so the reply cannot thread under it`);
|
|
1251
|
+
}
|
|
1252
|
+
return parentId;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
/**
|
|
1256
|
+
* Posts the announcing agent's line, "Continuing with **{agent}** for refinement...", as a completed reply of the
|
|
1257
|
+
* announcing agent. Its text is fixed and names the agent from metadata, so a caller chooses only whether it is
|
|
1258
|
+
* posted and by which active agent, never what it says.
|
|
1259
|
+
*/
|
|
1260
|
+
private async postContinuationAnnouncement(
|
|
1261
|
+
runner: AgentRunner,
|
|
1262
|
+
user: UserInfo,
|
|
1263
|
+
conversationId: string,
|
|
1264
|
+
branchId: string | null,
|
|
1265
|
+
parentId: string,
|
|
1266
|
+
announcerId: string,
|
|
1267
|
+
agentId: string
|
|
1268
|
+
): Promise<MJConversationDetailEntityExtended> {
|
|
1269
|
+
await AIEngine.Instance.Config(false, user);
|
|
1270
|
+
const announcer = AIEngine.Instance.GetAgentByID(announcerId);
|
|
1271
|
+
if (!announcer || announcer.Status !== 'Active') {
|
|
1272
|
+
throw new Error(`Agent ${announcerId} cannot announce the turn: it is not an active agent`);
|
|
1273
|
+
}
|
|
1274
|
+
const agentName = AIEngine.Instance.GetAgentByID(agentId)?.Name ?? 'the agent';
|
|
1275
|
+
return runner.CreateAgentReplyDetail({
|
|
1276
|
+
conversationId,
|
|
1277
|
+
branchId,
|
|
1278
|
+
agentId: announcer.ID,
|
|
1279
|
+
contextUser: user,
|
|
1280
|
+
parentId,
|
|
1281
|
+
message: ContinuationAnnouncementText(agentName),
|
|
1282
|
+
status: 'Complete'
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1074
1286
|
/**
|
|
1075
1287
|
* Respond to a pending AIAgentRequest from the dashboard or API.
|
|
1076
1288
|
* Updates the request record with the response and optionally spawns a
|
|
@@ -1250,9 +1462,8 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
1250
1462
|
|
|
1251
1463
|
/**
|
|
1252
1464
|
* Execute agent in background (fire-and-forget).
|
|
1253
|
-
*
|
|
1254
|
-
*
|
|
1255
|
-
* has already been sent.
|
|
1465
|
+
* The client learns the outcome only from the run's completion status message (executeAIAgent publishes it,
|
|
1466
|
+
* failure included), since the HTTP response has already been sent. A liveness pulse runs until the run ends.
|
|
1256
1467
|
*/
|
|
1257
1468
|
private executeAgentInBackground(
|
|
1258
1469
|
p: DatabaseProviderBase,
|
|
@@ -1281,37 +1492,37 @@ export class RunAIAgentResolver extends ResolverBase {
|
|
|
1281
1492
|
taskGraphDebug?: string,
|
|
1282
1493
|
/** History floor — threaded through to ExecuteAgentParams.ConversationHistoryFrom. */
|
|
1283
1494
|
conversationHistoryFrom?: Date,
|
|
1495
|
+
/** ExecuteAgentParams.TrustReservedRunData — see executeAIAgent. */
|
|
1496
|
+
trustReservedRunData: boolean = false,
|
|
1284
1497
|
/** The conversation branch of the run — threaded through to ExecuteAgentParams.ConversationBranchID. */
|
|
1285
|
-
conversationBranchId?: string | null
|
|
1498
|
+
conversationBranchId?: string | null,
|
|
1499
|
+
/** The reply row this request created for the run — see executeAIAgent. */
|
|
1500
|
+
replyDetail?: MJConversationDetailEntityExtended
|
|
1286
1501
|
): void {
|
|
1287
1502
|
// Ref the liveness pulse reads to enrich heartbeats once the run is created.
|
|
1288
1503
|
const runRef: { current: MJAIAgentRunEntityExtended | null } = { current: null };
|
|
1289
1504
|
const pulse = StartLivenessPulse({
|
|
1290
1505
|
pubSub,
|
|
1291
1506
|
sessionId,
|
|
1292
|
-
ownerUserId: userPayload
|
|
1507
|
+
ownerUserId: StatusUpdateOwnerID(userPayload),
|
|
1293
1508
|
resolver: 'RunAIAgentResolver',
|
|
1294
1509
|
readStatus: () => runRef.current
|
|
1295
1510
|
? { runId: runRef.current.ID, status: runRef.current.Status }
|
|
1296
1511
|
: undefined,
|
|
1297
1512
|
});
|
|
1298
1513
|
|
|
1299
|
-
//
|
|
1514
|
+
// executeAIAgent resolves on every failure and publishes the run's completion itself (PublishFinal, or
|
|
1515
|
+
// PublishFailure from its catch), so nothing here publishes one.
|
|
1300
1516
|
this.executeAIAgent(
|
|
1301
1517
|
p, dataSource, agentId, userPayload, messagesJson, sessionId, pubSub,
|
|
1302
1518
|
data, payload, undefined, lastRunId, autoPopulateLastRunPayload,
|
|
1303
1519
|
configurationId, conversationDetailId, createArtifacts, createNotification,
|
|
1304
1520
|
sourceArtifactId, sourceArtifactVersionId, conversationId, runRef, planMode, requestedSkillIDs, taskGraphDebug,
|
|
1305
|
-
conversationHistoryFrom, conversationBranchId
|
|
1521
|
+
conversationHistoryFrom, trustReservedRunData, conversationBranchId, replyDetail
|
|
1306
1522
|
).catch((error: unknown) => {
|
|
1307
|
-
//
|
|
1308
|
-
//
|
|
1309
|
-
|
|
1310
|
-
LogError(`🔥 Fire-and-forget background execution failed: ${errorMessage}`, undefined, error);
|
|
1311
|
-
|
|
1312
|
-
// Publish error completion event so the client knows the agent failed.
|
|
1313
|
-
// The publisher is created inside executeAIAgent, which rejected before returning one.
|
|
1314
|
-
new AgentRunStatusPublisher(pubSub, userPayload, sessionId).PublishFailure(conversationDetailId, errorMessage);
|
|
1523
|
+
// Only a broken executeAIAgent contract lands here. Logged rather than left as an unhandled rejection;
|
|
1524
|
+
// no completion is published, because executeAIAgent may already have sent one.
|
|
1525
|
+
LogError(`🔥 Fire-and-forget run of agent ${agentId} for session ${sessionId} rejected, which executeAIAgent never should`, undefined, error);
|
|
1315
1526
|
}).finally(() => pulse.Stop());
|
|
1316
1527
|
}
|
|
1317
1528
|
|