@mxf-dev/core 2.0.5 → 3.0.0
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/dist/config/ModelContextLimits.d.ts.map +1 -1
- package/dist/config/ModelContextLimits.js +7 -1
- package/dist/config/ModelContextLimits.js.map +1 -1
- package/dist/constants/CoreTools.d.ts +6 -5
- package/dist/constants/CoreTools.d.ts.map +1 -1
- package/dist/constants/CoreTools.js +6 -5
- package/dist/constants/CoreTools.js.map +1 -1
- package/dist/constants/DefaultPhaseProfiles.d.ts.map +1 -1
- package/dist/constants/DefaultPhaseProfiles.js +29 -0
- package/dist/constants/DefaultPhaseProfiles.js.map +1 -1
- package/dist/constants/ReservedIdentities.d.ts +14 -0
- package/dist/constants/ReservedIdentities.d.ts.map +1 -0
- package/dist/constants/ReservedIdentities.js +42 -0
- package/dist/constants/ReservedIdentities.js.map +1 -0
- package/dist/database/adapters/mongodb/MongoKnowledgeGraphRepository.d.ts +16 -16
- package/dist/database/adapters/mongodb/MongoKnowledgeGraphRepository.d.ts.map +1 -1
- package/dist/database/adapters/mongodb/MongoKnowledgeGraphRepository.js +98 -36
- package/dist/database/adapters/mongodb/MongoKnowledgeGraphRepository.js.map +1 -1
- package/dist/events/ClientEventBus.d.ts +28 -0
- package/dist/events/ClientEventBus.d.ts.map +1 -1
- package/dist/events/ClientEventBus.js +87 -40
- package/dist/events/ClientEventBus.js.map +1 -1
- package/dist/events/EventBus.d.ts +19 -1
- package/dist/events/EventBus.d.ts.map +1 -1
- package/dist/events/EventBus.js +23 -0
- package/dist/events/EventBus.js.map +1 -1
- package/dist/events/EventBusBase.d.ts +37 -6
- package/dist/events/EventBusBase.d.ts.map +1 -1
- package/dist/events/EventBusBase.js +75 -27
- package/dist/events/EventBusBase.js.map +1 -1
- package/dist/events/EventNames.d.ts +49 -36
- package/dist/events/EventNames.d.ts.map +1 -1
- package/dist/events/EventNames.js +38 -36
- package/dist/events/EventNames.js.map +1 -1
- package/dist/events/PublicEvents.d.ts +5 -1
- package/dist/events/PublicEvents.d.ts.map +1 -1
- package/dist/events/PublicEvents.js +7 -0
- package/dist/events/PublicEvents.js.map +1 -1
- package/dist/events/ServerEventBus.d.ts +7 -54
- package/dist/events/ServerEventBus.d.ts.map +1 -1
- package/dist/events/ServerEventBus.js +10 -96
- package/dist/events/ServerEventBus.js.map +1 -1
- package/dist/events/event-definitions/ControlLoopEvents.d.ts +35 -0
- package/dist/events/event-definitions/ControlLoopEvents.d.ts.map +1 -1
- package/dist/events/event-definitions/ControlLoopEvents.js +6 -0
- package/dist/events/event-definitions/ControlLoopEvents.js.map +1 -1
- package/dist/events/event-definitions/SdkEvents.d.ts +55 -0
- package/dist/events/event-definitions/SdkEvents.d.ts.map +1 -0
- package/dist/events/event-definitions/SdkEvents.js +36 -0
- package/dist/events/event-definitions/SdkEvents.js.map +1 -0
- package/dist/events/event-definitions/TaskEvents.d.ts +2 -7
- package/dist/events/event-definitions/TaskEvents.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/AgentInterfaces.d.ts +5 -0
- package/dist/interfaces/AgentInterfaces.d.ts.map +1 -1
- package/dist/interfaces/ChannelConfig.d.ts +2 -2
- package/dist/interfaces/ChannelConfig.d.ts.map +1 -1
- package/dist/interfaces/ConversationMessage.d.ts +1 -1
- package/dist/interfaces/ConversationMessage.d.ts.map +1 -1
- package/dist/interfaces/IMemoryPersistence.d.ts +47 -1
- package/dist/interfaces/IMemoryPersistence.d.ts.map +1 -1
- package/dist/interfaces/SocketServiceInterface.d.ts +3 -2
- package/dist/interfaces/SocketServiceInterface.d.ts.map +1 -1
- package/dist/interfaces/TaskInterfaces.d.ts +14 -1
- package/dist/interfaces/TaskInterfaces.d.ts.map +1 -1
- package/dist/models/agent.d.ts +0 -1
- package/dist/models/agent.d.ts.map +1 -1
- package/dist/models/agent.js +0 -5
- package/dist/models/agent.js.map +1 -1
- package/dist/models/agentIdentityReservation.d.ts +42 -0
- package/dist/models/agentIdentityReservation.d.ts.map +1 -0
- package/dist/models/agentIdentityReservation.js +52 -0
- package/dist/models/agentIdentityReservation.js.map +1 -0
- package/dist/models/channel.d.ts +2 -0
- package/dist/models/channel.d.ts.map +1 -1
- package/dist/models/channel.js.map +1 -1
- package/dist/models/channelKey.d.ts +1 -0
- package/dist/models/channelKey.d.ts.map +1 -1
- package/dist/models/channelKey.js +5 -0
- package/dist/models/channelKey.js.map +1 -1
- package/dist/models/memory.d.ts +1 -1
- package/dist/models/memory.d.ts.map +1 -1
- package/dist/models/memory.js +9 -12
- package/dist/models/memory.js.map +1 -1
- package/dist/models/memoryStrata.d.ts +3 -16
- package/dist/models/memoryStrata.d.ts.map +1 -1
- package/dist/models/memoryStrata.js +3 -5
- package/dist/models/memoryStrata.js.map +1 -1
- package/dist/models/plan.d.ts +2 -2
- package/dist/models/plan.d.ts.map +1 -1
- package/dist/models/plan.js +1 -1
- package/dist/models/plan.js.map +1 -1
- package/dist/models/taskEffectiveness.d.ts +1 -0
- package/dist/models/taskEffectiveness.d.ts.map +1 -1
- package/dist/models/taskEffectiveness.js +7 -1
- package/dist/models/taskEffectiveness.js.map +1 -1
- package/dist/models/user.d.ts +4 -0
- package/dist/models/user.d.ts.map +1 -1
- package/dist/models/user.js +8 -0
- package/dist/models/user.js.map +1 -1
- package/dist/protocols/mcp/LlmTestEnvironmentGuard.d.ts +16 -0
- package/dist/protocols/mcp/LlmTestEnvironmentGuard.d.ts.map +1 -0
- package/dist/protocols/mcp/LlmTestEnvironmentGuard.js +25 -0
- package/dist/protocols/mcp/LlmTestEnvironmentGuard.js.map +1 -0
- package/dist/protocols/mcp/McpServerTypes.d.ts +9 -0
- package/dist/protocols/mcp/McpServerTypes.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/AnthropicMcpClient.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/AnthropicMcpClient.js +1 -0
- package/dist/protocols/mcp/providers/AnthropicMcpClient.js.map +1 -1
- package/dist/protocols/mcp/providers/AzureOpenAiMcpClient.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/AzureOpenAiMcpClient.js +1 -0
- package/dist/protocols/mcp/providers/AzureOpenAiMcpClient.js.map +1 -1
- package/dist/protocols/mcp/providers/BaseMcpClient.d.ts +4 -0
- package/dist/protocols/mcp/providers/BaseMcpClient.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/BaseMcpClient.js +10 -0
- package/dist/protocols/mcp/providers/BaseMcpClient.js.map +1 -1
- package/dist/protocols/mcp/providers/CustomMcpClient.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/CustomMcpClient.js +7 -0
- package/dist/protocols/mcp/providers/CustomMcpClient.js.map +1 -1
- package/dist/protocols/mcp/providers/GeminiMcpClient.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/GeminiMcpClient.js +1 -0
- package/dist/protocols/mcp/providers/GeminiMcpClient.js.map +1 -1
- package/dist/protocols/mcp/providers/OllamaMcpClient.d.ts +1 -0
- package/dist/protocols/mcp/providers/OllamaMcpClient.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/OllamaMcpClient.js +1 -0
- package/dist/protocols/mcp/providers/OllamaMcpClient.js.map +1 -1
- package/dist/protocols/mcp/providers/OpenAiMcpClient.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/OpenAiMcpClient.js +1 -0
- package/dist/protocols/mcp/providers/OpenAiMcpClient.js.map +1 -1
- package/dist/protocols/mcp/providers/OpenRouterMcpClient.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/OpenRouterMcpClient.js +2 -0
- package/dist/protocols/mcp/providers/OpenRouterMcpClient.js.map +1 -1
- package/dist/protocols/mcp/providers/XaiMcpClient.d.ts.map +1 -1
- package/dist/protocols/mcp/providers/XaiMcpClient.js +1 -0
- package/dist/protocols/mcp/providers/XaiMcpClient.js.map +1 -1
- package/dist/protocols/mcp/security/BrowserTargetGuard.d.ts +14 -0
- package/dist/protocols/mcp/security/BrowserTargetGuard.d.ts.map +1 -0
- package/dist/protocols/mcp/security/BrowserTargetGuard.js +55 -0
- package/dist/protocols/mcp/security/BrowserTargetGuard.js.map +1 -0
- package/dist/protocols/mcp/security/ExternalMcpRegistrationPolicy.d.ts +24 -0
- package/dist/protocols/mcp/security/ExternalMcpRegistrationPolicy.d.ts.map +1 -0
- package/dist/protocols/mcp/security/ExternalMcpRegistrationPolicy.js +33 -0
- package/dist/protocols/mcp/security/ExternalMcpRegistrationPolicy.js.map +1 -0
- package/dist/protocols/mcp/security/HttpTargetGuard.d.ts.map +1 -1
- package/dist/protocols/mcp/security/HttpTargetGuard.js +68 -6
- package/dist/protocols/mcp/security/HttpTargetGuard.js.map +1 -1
- package/dist/protocols/mcp/security/McpSecurityGuard.d.ts.map +1 -1
- package/dist/protocols/mcp/security/McpSecurityGuard.js +7 -5
- package/dist/protocols/mcp/security/McpSecurityGuard.js.map +1 -1
- package/dist/protocols/mcp/security/McpToolPolicy.d.ts +18 -0
- package/dist/protocols/mcp/security/McpToolPolicy.d.ts.map +1 -1
- package/dist/protocols/mcp/security/McpToolPolicy.js +60 -0
- package/dist/protocols/mcp/security/McpToolPolicy.js.map +1 -1
- package/dist/protocols/mcp/services/ExternalMcpServerManager.d.ts +25 -0
- package/dist/protocols/mcp/services/ExternalMcpServerManager.d.ts.map +1 -1
- package/dist/protocols/mcp/services/ExternalMcpServerManager.js +93 -17
- package/dist/protocols/mcp/services/ExternalMcpServerManager.js.map +1 -1
- package/dist/protocols/mcp/services/ExternalServerConfigs.d.ts +2 -2
- package/dist/protocols/mcp/services/ExternalServerConfigs.d.ts.map +1 -1
- package/dist/protocols/mcp/services/ExternalServerConfigs.js +25 -8
- package/dist/protocols/mcp/services/ExternalServerConfigs.js.map +1 -1
- package/dist/protocols/mcp/tools/AnalyticsTools.d.ts +3 -37
- package/dist/protocols/mcp/tools/AnalyticsTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/AnalyticsTools.js +134 -614
- package/dist/protocols/mcp/tools/AnalyticsTools.js.map +1 -1
- package/dist/protocols/mcp/tools/CodeAnalysisTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/CodeAnalysisTools.js +16 -13
- package/dist/protocols/mcp/tools/CodeAnalysisTools.js.map +1 -1
- package/dist/protocols/mcp/tools/EffectivenessTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/EffectivenessTools.js +94 -30
- package/dist/protocols/mcp/tools/EffectivenessTools.js.map +1 -1
- package/dist/protocols/mcp/tools/GitTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/GitTools.js +9 -5
- package/dist/protocols/mcp/tools/GitTools.js.map +1 -1
- package/dist/protocols/mcp/tools/InfrastructureTools.d.ts +10 -40
- package/dist/protocols/mcp/tools/InfrastructureTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/InfrastructureTools.js +29 -70
- package/dist/protocols/mcp/tools/InfrastructureTools.js.map +1 -1
- package/dist/protocols/mcp/tools/JsonTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/JsonTools.js +4 -4
- package/dist/protocols/mcp/tools/JsonTools.js.map +1 -1
- package/dist/protocols/mcp/tools/KnowledgeGraphTools.d.ts +55 -592
- package/dist/protocols/mcp/tools/KnowledgeGraphTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/KnowledgeGraphTools.js +169 -119
- package/dist/protocols/mcp/tools/KnowledgeGraphTools.js.map +1 -1
- package/dist/protocols/mcp/tools/MemorySearchTools.d.ts +6 -6
- package/dist/protocols/mcp/tools/MemorySearchTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/MemorySearchTools.js +107 -39
- package/dist/protocols/mcp/tools/MemorySearchTools.js.map +1 -1
- package/dist/protocols/mcp/tools/MemoryUtilityTools.d.ts +4 -5
- package/dist/protocols/mcp/tools/MemoryUtilityTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/MemoryUtilityTools.js +59 -208
- package/dist/protocols/mcp/tools/MemoryUtilityTools.js.map +1 -1
- package/dist/protocols/mcp/tools/PlanningTools.d.ts +2 -1
- package/dist/protocols/mcp/tools/PlanningTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/PlanningTools.js +111 -49
- package/dist/protocols/mcp/tools/PlanningTools.js.map +1 -1
- package/dist/protocols/mcp/tools/ProjectContextTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/ProjectContextTools.js +18 -12
- package/dist/protocols/mcp/tools/ProjectContextTools.js.map +1 -1
- package/dist/protocols/mcp/tools/SafetyTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/SafetyTools.js +16 -13
- package/dist/protocols/mcp/tools/SafetyTools.js.map +1 -1
- package/dist/protocols/mcp/tools/SearchProjectTools.d.ts +24 -7
- package/dist/protocols/mcp/tools/SearchProjectTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/SearchProjectTools.js +226 -126
- package/dist/protocols/mcp/tools/SearchProjectTools.js.map +1 -1
- package/dist/protocols/mcp/tools/TaskPlanningTools.d.ts +0 -32
- package/dist/protocols/mcp/tools/TaskPlanningTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/TaskPlanningTools.js +363 -450
- package/dist/protocols/mcp/tools/TaskPlanningTools.js.map +1 -1
- package/dist/protocols/mcp/tools/TestTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/TestTools.js +18 -11
- package/dist/protocols/mcp/tools/TestTools.js.map +1 -1
- package/dist/protocols/mcp/tools/TypeScriptTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/TypeScriptTools.js +22 -12
- package/dist/protocols/mcp/tools/TypeScriptTools.js.map +1 -1
- package/dist/protocols/mcp/tools/UserInputTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/UserInputTools.js +14 -1
- package/dist/protocols/mcp/tools/UserInputTools.js.map +1 -1
- package/dist/protocols/mcp/tools/UserMemoryTools.d.ts +3 -1
- package/dist/protocols/mcp/tools/UserMemoryTools.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/UserMemoryTools.js +27 -62
- package/dist/protocols/mcp/tools/UserMemoryTools.js.map +1 -1
- package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.js +14 -60
- package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.js.map +1 -1
- package/dist/protocols/mcp/tools/shell/ShellSandbox.d.ts.map +1 -1
- package/dist/protocols/mcp/tools/shell/ShellSandbox.js +9 -27
- package/dist/protocols/mcp/tools/shell/ShellSandbox.js.map +1 -1
- package/dist/repositories/interfaces/IKnowledgeGraphRepository.d.ts +40 -30
- package/dist/repositories/interfaces/IKnowledgeGraphRepository.d.ts.map +1 -1
- package/dist/schemas/EventPayloadSchema.d.ts +28 -0
- package/dist/schemas/EventPayloadSchema.d.ts.map +1 -1
- package/dist/schemas/EventPayloadSchema.js +30 -1
- package/dist/schemas/EventPayloadSchema.js.map +1 -1
- package/dist/schemas/MxpProtocolSchemas.d.ts +6 -6
- package/dist/services/AgentPerformanceService.d.ts +11 -0
- package/dist/services/AgentPerformanceService.d.ts.map +1 -1
- package/dist/services/AgentPerformanceService.js +59 -33
- package/dist/services/AgentPerformanceService.js.map +1 -1
- package/dist/services/AutoCorrectionService.d.ts +3 -0
- package/dist/services/AutoCorrectionService.d.ts.map +1 -1
- package/dist/services/AutoCorrectionService.js +19 -2
- package/dist/services/AutoCorrectionService.js.map +1 -1
- package/dist/services/BackgroundTaskManager.d.ts +23 -7
- package/dist/services/BackgroundTaskManager.d.ts.map +1 -1
- package/dist/services/BackgroundTaskManager.js +137 -57
- package/dist/services/BackgroundTaskManager.js.map +1 -1
- package/dist/services/BrowserManager.d.ts +2 -0
- package/dist/services/BrowserManager.d.ts.map +1 -1
- package/dist/services/BrowserManager.js +18 -15
- package/dist/services/BrowserManager.js.map +1 -1
- package/dist/services/ChannelContextMemoryOperations.d.ts +8 -1
- package/dist/services/ChannelContextMemoryOperations.d.ts.map +1 -1
- package/dist/services/ChannelContextMemoryOperations.js +89 -165
- package/dist/services/ChannelContextMemoryOperations.js.map +1 -1
- package/dist/services/ChannelContextMessageOperations.d.ts +4 -3
- package/dist/services/ChannelContextMessageOperations.d.ts.map +1 -1
- package/dist/services/ChannelContextMessageOperations.js +72 -212
- package/dist/services/ChannelContextMessageOperations.js.map +1 -1
- package/dist/services/MemoryService.d.ts +52 -21
- package/dist/services/MemoryService.d.ts.map +1 -1
- package/dist/services/MemoryService.js +775 -548
- package/dist/services/MemoryService.js.map +1 -1
- package/dist/services/PatternLearningService.d.ts +5 -0
- package/dist/services/PatternLearningService.d.ts.map +1 -1
- package/dist/services/PatternLearningService.js +26 -3
- package/dist/services/PatternLearningService.js.map +1 -1
- package/dist/services/PerformanceOptimizationService.d.ts +2 -1
- package/dist/services/PerformanceOptimizationService.d.ts.map +1 -1
- package/dist/services/PerformanceOptimizationService.js +21 -6
- package/dist/services/PerformanceOptimizationService.js.map +1 -1
- package/dist/services/PredictiveAnalyticsService.d.ts +1 -0
- package/dist/services/PredictiveAnalyticsService.d.ts.map +1 -1
- package/dist/services/PredictiveAnalyticsService.js +18 -6
- package/dist/services/PredictiveAnalyticsService.js.map +1 -1
- package/dist/services/ProactiveValidationService.d.ts +6 -0
- package/dist/services/ProactiveValidationService.d.ts.map +1 -1
- package/dist/services/ProactiveValidationService.js +58 -39
- package/dist/services/ProactiveValidationService.js.map +1 -1
- package/dist/services/TaskEffectivenessService.d.ts +55 -31
- package/dist/services/TaskEffectivenessService.d.ts.map +1 -1
- package/dist/services/TaskEffectivenessService.js +243 -125
- package/dist/services/TaskEffectivenessService.js.map +1 -1
- package/dist/services/ToolExecutionInterceptor.d.ts +4 -0
- package/dist/services/ToolExecutionInterceptor.d.ts.map +1 -1
- package/dist/services/ToolExecutionInterceptor.js +31 -5
- package/dist/services/ToolExecutionInterceptor.js.map +1 -1
- package/dist/services/UserInputRequestManager.d.ts +13 -3
- package/dist/services/UserInputRequestManager.d.ts.map +1 -1
- package/dist/services/UserInputRequestManager.js +42 -6
- package/dist/services/UserInputRequestManager.js.map +1 -1
- package/dist/services/UserMemoryService.d.ts +2 -0
- package/dist/services/UserMemoryService.d.ts.map +1 -1
- package/dist/services/UserMemoryService.js +9 -4
- package/dist/services/UserMemoryService.js.map +1 -1
- package/dist/services/ValidationAnalyticsService.d.ts +4 -0
- package/dist/services/ValidationAnalyticsService.d.ts.map +1 -1
- package/dist/services/ValidationAnalyticsService.js +30 -8
- package/dist/services/ValidationAnalyticsService.js.map +1 -1
- package/dist/services/ValidationCacheService.d.ts +3 -1
- package/dist/services/ValidationCacheService.d.ts.map +1 -1
- package/dist/services/ValidationCacheService.js +25 -4
- package/dist/services/ValidationCacheService.js.map +1 -1
- package/dist/services/ValidationMiddleware.d.ts +7 -0
- package/dist/services/ValidationMiddleware.d.ts.map +1 -1
- package/dist/services/ValidationMiddleware.js +53 -10
- package/dist/services/ValidationMiddleware.js.map +1 -1
- package/dist/services/ValidationPerformanceService.d.ts +3 -0
- package/dist/services/ValidationPerformanceService.d.ts.map +1 -1
- package/dist/services/ValidationPerformanceService.js +28 -11
- package/dist/services/ValidationPerformanceService.js.map +1 -1
- package/dist/services/WebSearchService.d.ts.map +1 -1
- package/dist/services/WebSearchService.js +9 -0
- package/dist/services/WebSearchService.js.map +1 -1
- package/dist/services/dag/TaskDagService.d.ts +3 -0
- package/dist/services/dag/TaskDagService.d.ts.map +1 -1
- package/dist/services/dag/TaskDagService.js +18 -0
- package/dist/services/dag/TaskDagService.js.map +1 -1
- package/dist/services/kg/EntityQValueManager.d.ts +3 -1
- package/dist/services/kg/EntityQValueManager.d.ts.map +1 -1
- package/dist/services/kg/EntityQValueManager.js +10 -10
- package/dist/services/kg/EntityQValueManager.js.map +1 -1
- package/dist/services/kg/GraphSurpriseCalculator.d.ts +0 -4
- package/dist/services/kg/GraphSurpriseCalculator.d.ts.map +1 -1
- package/dist/services/kg/GraphSurpriseCalculator.js +0 -9
- package/dist/services/kg/GraphSurpriseCalculator.js.map +1 -1
- package/dist/services/kg/KnowledgeGraphService.d.ts +12 -12
- package/dist/services/kg/KnowledgeGraphService.d.ts.map +1 -1
- package/dist/services/kg/KnowledgeGraphService.js +43 -51
- package/dist/services/kg/KnowledgeGraphService.js.map +1 -1
- package/dist/services/kg/OrparGraphIntegration.d.ts.map +1 -1
- package/dist/services/kg/OrparGraphIntegration.js +6 -5
- package/dist/services/kg/OrparGraphIntegration.js.map +1 -1
- package/dist/services/orpar-memory/CycleConsolidationTrigger.d.ts +1 -0
- package/dist/services/orpar-memory/CycleConsolidationTrigger.d.ts.map +1 -1
- package/dist/services/orpar-memory/CycleConsolidationTrigger.js +8 -1
- package/dist/services/orpar-memory/CycleConsolidationTrigger.js.map +1 -1
- package/dist/services/orpar-memory/OrparMemoryCoordinator.d.ts +8 -1
- package/dist/services/orpar-memory/OrparMemoryCoordinator.d.ts.map +1 -1
- package/dist/services/orpar-memory/OrparMemoryCoordinator.js +93 -45
- package/dist/services/orpar-memory/OrparMemoryCoordinator.js.map +1 -1
- package/dist/services/orpar-memory/SurpriseOrparAdapter.d.ts +1 -0
- package/dist/services/orpar-memory/SurpriseOrparAdapter.d.ts.map +1 -1
- package/dist/services/orpar-memory/SurpriseOrparAdapter.js +8 -1
- package/dist/services/orpar-memory/SurpriseOrparAdapter.js.map +1 -1
- package/dist/types/ChannelContext.d.ts +2 -1
- package/dist/types/ChannelContext.d.ts.map +1 -1
- package/dist/types/EffectivenessTypes.d.ts +4 -1
- package/dist/types/EffectivenessTypes.d.ts.map +1 -1
- package/dist/types/TaskCompletionTypes.d.ts +7 -5
- package/dist/types/TaskCompletionTypes.d.ts.map +1 -1
- package/dist/types/TaskTypes.d.ts +8 -1
- package/dist/types/TaskTypes.d.ts.map +1 -1
- package/dist/utils/GlobMatcher.d.ts +37 -0
- package/dist/utils/GlobMatcher.d.ts.map +1 -0
- package/dist/utils/GlobMatcher.js +131 -0
- package/dist/utils/GlobMatcher.js.map +1 -0
- package/package.json +1 -1
- package/src/config/ModelContextLimits.ts +7 -1
- package/src/constants/CoreTools.ts +6 -5
- package/src/constants/DefaultPhaseProfiles.ts +29 -0
- package/src/constants/ReservedIdentities.ts +51 -0
- package/src/database/adapters/mongodb/MongoKnowledgeGraphRepository.ts +115 -36
- package/src/events/ClientEventBus.ts +117 -48
- package/src/events/EventBus.ts +32 -2
- package/src/events/EventBusBase.ts +132 -39
- package/src/events/EventNames.ts +43 -36
- package/src/events/PublicEvents.ts +8 -0
- package/src/events/ServerEventBus.ts +9 -128
- package/src/events/event-definitions/ControlLoopEvents.ts +12 -0
- package/src/events/event-definitions/SdkEvents.ts +58 -0
- package/src/events/event-definitions/TaskEvents.ts +2 -2
- package/src/index.ts +15 -0
- package/src/interfaces/AgentInterfaces.ts +5 -0
- package/src/interfaces/ChannelConfig.ts +2 -2
- package/src/interfaces/ConversationMessage.ts +5 -0
- package/src/interfaces/IMemoryPersistence.ts +55 -1
- package/src/interfaces/SocketServiceInterface.ts +3 -2
- package/src/interfaces/TaskInterfaces.ts +16 -1
- package/src/models/agent.ts +0 -6
- package/src/models/agentIdentityReservation.ts +77 -0
- package/src/models/channel.ts +2 -0
- package/src/models/channelKey.ts +10 -0
- package/src/models/memory.ts +18 -19
- package/src/models/memoryStrata.ts +9 -23
- package/src/models/plan.ts +3 -3
- package/src/models/taskEffectiveness.ts +9 -2
- package/src/models/user.ts +12 -0
- package/src/protocols/mcp/LlmTestEnvironmentGuard.ts +30 -0
- package/src/protocols/mcp/McpServerTypes.ts +9 -0
- package/src/protocols/mcp/providers/AnthropicMcpClient.ts +2 -0
- package/src/protocols/mcp/providers/AzureOpenAiMcpClient.ts +1 -0
- package/src/protocols/mcp/providers/BaseMcpClient.ts +13 -0
- package/src/protocols/mcp/providers/CustomMcpClient.ts +7 -0
- package/src/protocols/mcp/providers/GeminiMcpClient.ts +2 -0
- package/src/protocols/mcp/providers/OllamaMcpClient.ts +3 -1
- package/src/protocols/mcp/providers/OpenAiMcpClient.ts +2 -0
- package/src/protocols/mcp/providers/OpenRouterMcpClient.ts +3 -0
- package/src/protocols/mcp/providers/XaiMcpClient.ts +2 -0
- package/src/protocols/mcp/security/BrowserTargetGuard.ts +64 -0
- package/src/protocols/mcp/security/ExternalMcpRegistrationPolicy.ts +38 -0
- package/src/protocols/mcp/security/HttpTargetGuard.ts +77 -6
- package/src/protocols/mcp/security/McpSecurityGuard.ts +7 -5
- package/src/protocols/mcp/security/McpToolPolicy.ts +74 -0
- package/src/protocols/mcp/services/ExternalMcpServerManager.ts +146 -17
- package/src/protocols/mcp/services/ExternalServerConfigs.ts +26 -8
- package/src/protocols/mcp/tools/AnalyticsTools.ts +167 -641
- package/src/protocols/mcp/tools/CodeAnalysisTools.ts +44 -14
- package/src/protocols/mcp/tools/EffectivenessTools.ts +185 -45
- package/src/protocols/mcp/tools/GitTools.ts +15 -5
- package/src/protocols/mcp/tools/InfrastructureTools.ts +42 -90
- package/src/protocols/mcp/tools/JsonTools.ts +7 -4
- package/src/protocols/mcp/tools/KnowledgeGraphTools.ts +313 -164
- package/src/protocols/mcp/tools/MemorySearchTools.ts +158 -46
- package/src/protocols/mcp/tools/MemoryUtilityTools.ts +85 -232
- package/src/protocols/mcp/tools/PlanningTools.ts +137 -59
- package/src/protocols/mcp/tools/ProjectContextTools.ts +33 -12
- package/src/protocols/mcp/tools/SafetyTools.ts +49 -13
- package/src/protocols/mcp/tools/SearchProjectTools.ts +294 -153
- package/src/protocols/mcp/tools/TaskPlanningTools.ts +437 -514
- package/src/protocols/mcp/tools/TestTools.ts +41 -11
- package/src/protocols/mcp/tools/TypeScriptTools.ts +61 -12
- package/src/protocols/mcp/tools/UserInputTools.ts +15 -1
- package/src/protocols/mcp/tools/UserMemoryTools.ts +27 -62
- package/src/protocols/mcp/tools/shell/ShellExecuteHandler.ts +26 -84
- package/src/protocols/mcp/tools/shell/ShellSandbox.ts +13 -31
- package/src/repositories/interfaces/IKnowledgeGraphRepository.ts +45 -27
- package/src/schemas/EventPayloadSchema.ts +45 -1
- package/src/services/AgentPerformanceService.ts +85 -36
- package/src/services/AutoCorrectionService.ts +25 -6
- package/src/services/BackgroundTaskManager.ts +183 -76
- package/src/services/BrowserManager.ts +20 -16
- package/src/services/ChannelContextMemoryOperations.ts +169 -202
- package/src/services/ChannelContextMessageOperations.ts +112 -274
- package/src/services/MemoryService.ts +1053 -760
- package/src/services/PatternLearningService.ts +32 -7
- package/src/services/PerformanceOptimizationService.ts +26 -9
- package/src/services/PredictiveAnalyticsService.ts +23 -10
- package/src/services/ProactiveValidationService.ts +66 -40
- package/src/services/TaskEffectivenessService.ts +421 -206
- package/src/services/ToolExecutionInterceptor.ts +40 -9
- package/src/services/UserInputRequestManager.ts +51 -6
- package/src/services/UserMemoryService.ts +12 -3
- package/src/services/ValidationAnalyticsService.ts +36 -11
- package/src/services/ValidationCacheService.ts +30 -7
- package/src/services/ValidationMiddleware.ts +62 -14
- package/src/services/ValidationPerformanceService.ts +47 -25
- package/src/services/WebSearchService.ts +16 -4
- package/src/services/dag/TaskDagService.ts +20 -1
- package/src/services/kg/EntityQValueManager.ts +21 -10
- package/src/services/kg/GraphSurpriseCalculator.ts +0 -14
- package/src/services/kg/KnowledgeGraphService.ts +56 -48
- package/src/services/kg/OrparGraphIntegration.ts +11 -5
- package/src/services/orpar-memory/CycleConsolidationTrigger.ts +10 -1
- package/src/services/orpar-memory/OrparMemoryCoordinator.ts +142 -71
- package/src/services/orpar-memory/SurpriseOrparAdapter.ts +10 -1
- package/src/types/ChannelContext.ts +3 -1
- package/src/types/EffectivenessTypes.ts +6 -2
- package/src/types/TaskCompletionTypes.ts +9 -9
- package/src/types/TaskTypes.ts +12 -1
- package/src/utils/GlobMatcher.ts +157 -0
|
@@ -29,8 +29,12 @@
|
|
|
29
29
|
* for LLM workflows (observations, reasoning, plans, reflections).
|
|
30
30
|
*/
|
|
31
31
|
|
|
32
|
-
import { Observable, of } from 'rxjs';
|
|
33
|
-
import {
|
|
32
|
+
import { firstValueFrom, Observable, of, throwError } from 'rxjs';
|
|
33
|
+
import {
|
|
34
|
+
ChannelMemoryAtomicMutation,
|
|
35
|
+
ChannelMemoryAtomicMutationResult,
|
|
36
|
+
IMemoryPersistence
|
|
37
|
+
} from '../interfaces/IMemoryPersistence.js';
|
|
34
38
|
import { MxfMeilisearchService } from './MxfMeilisearchService.js';
|
|
35
39
|
import { v4 as uuidv4 } from 'uuid';
|
|
36
40
|
|
|
@@ -40,8 +44,6 @@ import {
|
|
|
40
44
|
IRelationshipMemory,
|
|
41
45
|
MemoryScope,
|
|
42
46
|
MemoryPersistenceLevel,
|
|
43
|
-
MemoryData,
|
|
44
|
-
MemoryQueryParams,
|
|
45
47
|
createMemoryValidator
|
|
46
48
|
} from '../types/MemoryTypes.js';
|
|
47
49
|
|
|
@@ -56,13 +58,12 @@ import {
|
|
|
56
58
|
import { Logger } from '../utils/Logger.js';
|
|
57
59
|
import { EventBus } from '../events/EventBus.js';
|
|
58
60
|
import { Events } from '../events/EventNames.js';
|
|
59
|
-
import { MemoryGetEvent, MemoryUpdateEvent } from '../events/event-definitions/MemoryEvents.js';
|
|
60
61
|
import { createBaseEventPayload, createMemoryUpdateResultEventPayload,
|
|
61
62
|
createMemoryDeleteResultEventPayload,
|
|
62
|
-
MemoryDeleteResultEventData,
|
|
63
63
|
MemoryUpdateResultEventData,
|
|
64
64
|
MemoryGetEventPayload,
|
|
65
65
|
MemoryUpdateEventPayload,
|
|
66
|
+
MemoryDeleteEventPayload,
|
|
66
67
|
createMemoryGetResultEventPayload,
|
|
67
68
|
MemoryGetResultEventData
|
|
68
69
|
} from '../schemas/EventPayloadSchema.js';
|
|
@@ -124,6 +125,11 @@ export interface CognitiveMemoryQueryOptions {
|
|
|
124
125
|
textQuery?: string;
|
|
125
126
|
}
|
|
126
127
|
|
|
128
|
+
interface GeneralDataRecord {
|
|
129
|
+
expiresAt?: number;
|
|
130
|
+
[key: string]: unknown;
|
|
131
|
+
}
|
|
132
|
+
|
|
127
133
|
/**
|
|
128
134
|
* Enhanced Agent Memory with cognitive operations
|
|
129
135
|
*/
|
|
@@ -186,8 +192,11 @@ export class MemoryService {
|
|
|
186
192
|
private agentMemory: Map<string, IEnhancedAgentMemory> = new Map();
|
|
187
193
|
private channelMemory: Map<string, IEnhancedChannelMemory> = new Map();
|
|
188
194
|
private relationshipMemory: Map<string, IRelationshipMemory> = new Map();
|
|
189
|
-
private generalData: Map<string,
|
|
190
|
-
private cognitiveMemory: Map<string, CognitiveMemoryEntry<
|
|
195
|
+
private generalData: Map<string, unknown> = new Map();
|
|
196
|
+
private cognitiveMemory: Map<string, CognitiveMemoryEntry<unknown>> = new Map();
|
|
197
|
+
private agentMutationTails: Map<string, Promise<void>> = new Map();
|
|
198
|
+
private channelMutationTails: Map<string, Promise<void>> = new Map();
|
|
199
|
+
private relationshipMutationTails: Map<string, Promise<void>> = new Map();
|
|
191
200
|
|
|
192
201
|
// Configuration
|
|
193
202
|
private config: MemoryServiceConfig;
|
|
@@ -209,10 +218,6 @@ export class MemoryService {
|
|
|
209
218
|
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
210
219
|
this.persistenceService = config.persistenceService;
|
|
211
220
|
|
|
212
|
-
if (this.persistenceService) {
|
|
213
|
-
} else {
|
|
214
|
-
}
|
|
215
|
-
|
|
216
221
|
// Set up event listeners
|
|
217
222
|
this.setupEventListeners();
|
|
218
223
|
}
|
|
@@ -221,373 +226,656 @@ export class MemoryService {
|
|
|
221
226
|
* Set up event listeners
|
|
222
227
|
*/
|
|
223
228
|
private setupEventListeners(): void {
|
|
224
|
-
//
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
229
|
+
// Return each request promise so EventBus.drain() retains ownership of
|
|
230
|
+
// acknowledged memory work until persistence and the response event
|
|
231
|
+
// have both completed.
|
|
232
|
+
EventBus.server.on(
|
|
233
|
+
Events.Memory.GET,
|
|
234
|
+
(event: MemoryGetEventPayload): Promise<void> => this.handleMemoryGetRequest(event)
|
|
235
|
+
);
|
|
236
|
+
EventBus.server.on(
|
|
237
|
+
Events.Memory.UPDATE,
|
|
238
|
+
(event: MemoryUpdateEventPayload): Promise<void> => this.handleMemoryUpdateRequest(event)
|
|
239
|
+
);
|
|
240
|
+
EventBus.server.on(
|
|
241
|
+
Events.Memory.DELETE,
|
|
242
|
+
(event: MemoryDeleteEventPayload): Promise<void> => this.handleMemoryDeleteRequest(event)
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private validateMemoryRequestIdentity(
|
|
247
|
+
event: MemoryGetEventPayload | MemoryUpdateEventPayload | MemoryDeleteEventPayload
|
|
248
|
+
): void {
|
|
249
|
+
this.validator.assertIsNonEmptyString(event.agentId, 'Memory request agentId is required');
|
|
250
|
+
this.validator.assertIsNonEmptyString(event.channelId, 'Memory request channelId is required');
|
|
251
|
+
this.validator.assertIsNonEmptyString(event.data.operationId, 'Memory operationId is required');
|
|
252
|
+
this.validator.validateMemoryScope(event.data.scope);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private requireScalarMemoryId(id: string | string[], scope: MemoryScope): string {
|
|
256
|
+
if (Array.isArray(id)) {
|
|
257
|
+
throw new Error(`${scope} memory requires a scalar ID`);
|
|
258
|
+
}
|
|
259
|
+
this.validator.assertIsNonEmptyString(id, `${scope} memory ID is required`);
|
|
260
|
+
return id;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Agent-scoped requests address the requesting agent's own memory. The
|
|
265
|
+
* socket gateway checks this too; the service checks it again so no other
|
|
266
|
+
* caller of the event bridge can read or change another agent's memory by
|
|
267
|
+
* naming it.
|
|
268
|
+
*/
|
|
269
|
+
private requireOwnAgentMemoryId(id: string | string[], requestingAgentId: AgentId): string {
|
|
270
|
+
const agentId = this.requireScalarMemoryId(id, MemoryScope.AGENT);
|
|
271
|
+
if (agentId !== requestingAgentId) {
|
|
272
|
+
throw new Error('Agent memory requests are limited to the requesting agent');
|
|
273
|
+
}
|
|
274
|
+
return agentId;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Channel-scoped requests address the request's own channel: either the
|
|
279
|
+
* whole channel document (id equal to the request channel) or one of its
|
|
280
|
+
* keyed sub-resources (`channel:...:<channelId>`, validated where the key
|
|
281
|
+
* is resolved).
|
|
282
|
+
*/
|
|
283
|
+
private requireOwnChannelMemoryId(id: string | string[], requestChannelId: ChannelId): string {
|
|
284
|
+
const channelMemoryId = this.requireScalarMemoryId(id, MemoryScope.CHANNEL);
|
|
285
|
+
if (!channelMemoryId.startsWith('channel:') && channelMemoryId !== requestChannelId) {
|
|
286
|
+
throw new Error('Channel memory requests are limited to the request channel');
|
|
287
|
+
}
|
|
288
|
+
return channelMemoryId;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Relationship-scoped requests must come from one of the two agents in
|
|
293
|
+
* the relationship, and the channel component must match the request.
|
|
294
|
+
*/
|
|
295
|
+
private requireRelationshipMemoryId(
|
|
296
|
+
id: string | string[],
|
|
297
|
+
channelId: ChannelId,
|
|
298
|
+
requestingAgentId: AgentId
|
|
299
|
+
): [string, string, string] {
|
|
300
|
+
if (!Array.isArray(id) || (id.length !== 2 && id.length !== 3)) {
|
|
301
|
+
throw new Error('Relationship memory requires two agent IDs and an optional channel ID');
|
|
302
|
+
}
|
|
303
|
+
id.forEach((part, index) => {
|
|
304
|
+
this.validator.assertIsNonEmptyString(part, `Relationship memory ID part ${index} is required`);
|
|
305
|
+
});
|
|
306
|
+
if (id.length === 3 && id[2] !== channelId) {
|
|
307
|
+
throw new Error('Relationship memory channel must match the request channel');
|
|
308
|
+
}
|
|
309
|
+
if (id[0] !== requestingAgentId && id[1] !== requestingAgentId) {
|
|
310
|
+
throw new Error('Relationship memory requests are limited to a participant of the relationship');
|
|
311
|
+
}
|
|
312
|
+
return [id[0], id[1], channelId];
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
private ownsPathOrDescendant(value: unknown, reservedPath: string): boolean {
|
|
316
|
+
if (!value || typeof value !== 'object') {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
return Object.keys(value).some(key =>
|
|
320
|
+
key === reservedPath || key.startsWith(`${reservedPath}.`)
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
private getChannelMemoryKey(
|
|
325
|
+
key: string,
|
|
326
|
+
expectedChannelId?: ChannelId
|
|
327
|
+
): { channelId: string; kind: 'messages' | 'context' | 'history' } {
|
|
328
|
+
const prefixes = [
|
|
329
|
+
{ prefix: 'channel:context:history:', kind: 'history' as const },
|
|
330
|
+
{ prefix: 'channel:messages:', kind: 'messages' as const },
|
|
331
|
+
{ prefix: 'channel:context:', kind: 'context' as const }
|
|
332
|
+
];
|
|
333
|
+
const matched = prefixes.find(({ prefix }) => key.startsWith(prefix));
|
|
334
|
+
if (!matched) {
|
|
335
|
+
throw new Error(`Unsupported channel memory key: ${key}`);
|
|
336
|
+
}
|
|
337
|
+
const channelId = key.slice(matched.prefix.length);
|
|
338
|
+
this.validator.assertIsNonEmptyString(channelId, 'Channel memory key channelId is required');
|
|
339
|
+
if (expectedChannelId && channelId !== expectedChannelId) {
|
|
340
|
+
throw new Error('Channel memory key must match the request channel');
|
|
341
|
+
}
|
|
342
|
+
return { channelId, kind: matched.kind };
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private async getKeyedChannelMemory(
|
|
346
|
+
key: string,
|
|
347
|
+
requestChannelId: ChannelId
|
|
348
|
+
): Promise<MemoryGetResultEventData['memory']> {
|
|
349
|
+
const { channelId, kind } = this.getChannelMemoryKey(key, requestChannelId);
|
|
350
|
+
if (!this.persistenceService && this.generalData.has(key)) {
|
|
351
|
+
return this.generalData.get(key) as MemoryGetResultEventData['memory'];
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const channelMemory = this.persistenceService
|
|
355
|
+
? await firstValueFrom(this.persistenceService.getChannelMemory(channelId))
|
|
356
|
+
: await firstValueFrom(this.getChannelMemory(channelId));
|
|
357
|
+
const value = kind === 'messages'
|
|
358
|
+
? channelMemory.conversationHistory
|
|
359
|
+
: kind === 'context'
|
|
360
|
+
? channelMemory.sharedState?.context
|
|
361
|
+
: channelMemory.customData?.contextHistory;
|
|
362
|
+
const cachedMemory = this.channelMemory.get(channelId);
|
|
363
|
+
this.channelMemory.set(channelId, {
|
|
364
|
+
...channelMemory,
|
|
365
|
+
sharedCognitiveInsights: cachedMemory?.sharedCognitiveInsights ?? {
|
|
366
|
+
systemSummaries: [],
|
|
367
|
+
topicExtractions: [],
|
|
368
|
+
collaborativeReflections: []
|
|
235
369
|
}
|
|
236
370
|
});
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
}
|
|
371
|
+
if (value !== undefined) {
|
|
372
|
+
this.generalData.set(key, value);
|
|
373
|
+
} else {
|
|
374
|
+
this.generalData.delete(key);
|
|
375
|
+
}
|
|
376
|
+
return (value as MemoryGetResultEventData['memory']) ?? null;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
private serializeChannelMutation<T>(
|
|
380
|
+
channelId: string,
|
|
381
|
+
operation: () => Promise<T>
|
|
382
|
+
): Promise<T> {
|
|
383
|
+
const previousTail = this.channelMutationTails.get(channelId) ?? Promise.resolve();
|
|
384
|
+
const result = previousTail.then(operation);
|
|
385
|
+
const nextTail = result.then(() => undefined, () => undefined);
|
|
386
|
+
this.channelMutationTails.set(channelId, nextTail);
|
|
387
|
+
|
|
388
|
+
return result.finally(() => {
|
|
389
|
+
if (this.channelMutationTails.get(channelId) === nextTail) {
|
|
390
|
+
this.channelMutationTails.delete(channelId);
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
private serializeAgentMutation<T>(
|
|
396
|
+
agentId: string,
|
|
397
|
+
operation: () => Promise<T>
|
|
398
|
+
): Promise<T> {
|
|
399
|
+
const previousTail = this.agentMutationTails.get(agentId) ?? Promise.resolve();
|
|
400
|
+
const result = previousTail.then(operation);
|
|
401
|
+
const nextTail = result.then(() => undefined, () => undefined);
|
|
402
|
+
this.agentMutationTails.set(agentId, nextTail);
|
|
403
|
+
|
|
404
|
+
return result.finally(() => {
|
|
405
|
+
if (this.agentMutationTails.get(agentId) === nextTail) {
|
|
406
|
+
this.agentMutationTails.delete(agentId);
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
private serializeRelationshipMutation<T>(
|
|
412
|
+
agentId1: string,
|
|
413
|
+
agentId2: string,
|
|
414
|
+
channelId: string,
|
|
415
|
+
operation: () => Promise<T>
|
|
416
|
+
): Promise<T> {
|
|
417
|
+
const relationshipKey = this.getRelationshipKey(agentId1, agentId2, channelId);
|
|
418
|
+
const previousTail = this.relationshipMutationTails.get(relationshipKey) ?? Promise.resolve();
|
|
419
|
+
const result = previousTail.then(operation);
|
|
420
|
+
const nextTail = result.then(() => undefined, () => undefined);
|
|
421
|
+
this.relationshipMutationTails.set(relationshipKey, nextTail);
|
|
422
|
+
|
|
423
|
+
return result.finally(() => {
|
|
424
|
+
if (this.relationshipMutationTails.get(relationshipKey) === nextTail) {
|
|
425
|
+
this.relationshipMutationTails.delete(relationshipKey);
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
private getAtomicMutation(
|
|
431
|
+
kind: 'messages' | 'context' | 'history',
|
|
432
|
+
value: unknown,
|
|
433
|
+
expectedContextUpdatedAt?: number
|
|
434
|
+
): ChannelMemoryAtomicMutation {
|
|
435
|
+
switch (kind) {
|
|
436
|
+
case 'messages':
|
|
437
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
438
|
+
throw new Error('Keyed channel message updates require a non-empty array');
|
|
439
|
+
}
|
|
440
|
+
return { kind: 'append_messages', messages: value };
|
|
441
|
+
case 'context':
|
|
442
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
443
|
+
throw new Error('Keyed channel context updates require an object');
|
|
311
444
|
}
|
|
312
|
-
|
|
313
|
-
|
|
445
|
+
return {
|
|
446
|
+
kind: 'replace_context',
|
|
447
|
+
context: value,
|
|
448
|
+
expectedUpdatedAt: expectedContextUpdatedAt
|
|
449
|
+
};
|
|
450
|
+
case 'history':
|
|
451
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
452
|
+
throw new Error('Keyed channel history updates require a non-empty array');
|
|
453
|
+
}
|
|
454
|
+
return { kind: 'append_context_history', entries: value, retainLast: 100 };
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
private getDeleteMutation(
|
|
459
|
+
kind: 'messages' | 'context' | 'history'
|
|
460
|
+
): ChannelMemoryAtomicMutation {
|
|
461
|
+
switch (kind) {
|
|
462
|
+
case 'messages':
|
|
463
|
+
return { kind: 'delete_messages' };
|
|
464
|
+
case 'context':
|
|
465
|
+
return { kind: 'delete_context' };
|
|
466
|
+
case 'history':
|
|
467
|
+
return { kind: 'delete_context_history' };
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
private async mutateLocalChannelMemory(
|
|
472
|
+
channelId: string,
|
|
473
|
+
mutation: ChannelMemoryAtomicMutation
|
|
474
|
+
): Promise<ChannelMemoryAtomicMutationResult> {
|
|
475
|
+
const deleting = mutation.kind.startsWith('delete_');
|
|
476
|
+
const existingMemory = this.channelMemory.get(channelId);
|
|
477
|
+
if (deleting && !existingMemory) {
|
|
478
|
+
return { found: false, memory: null, value: null };
|
|
479
|
+
}
|
|
480
|
+
const originalMemory = existingMemory ?? await firstValueFrom(this.getChannelMemory(channelId));
|
|
481
|
+
if (mutation.kind === 'replace_context') {
|
|
482
|
+
const existingContext = originalMemory.sharedState?.context as
|
|
483
|
+
| { updatedAt?: unknown }
|
|
484
|
+
| undefined;
|
|
485
|
+
const actualUpdatedAt = existingContext?.updatedAt;
|
|
486
|
+
const versionMatches = mutation.expectedUpdatedAt === undefined
|
|
487
|
+
? existingContext === undefined
|
|
488
|
+
: actualUpdatedAt === mutation.expectedUpdatedAt;
|
|
489
|
+
if (!versionMatches) {
|
|
490
|
+
return { found: false, memory: originalMemory, value: existingContext ?? null };
|
|
314
491
|
}
|
|
492
|
+
}
|
|
493
|
+
const targetExists = mutation.kind === 'delete_messages'
|
|
494
|
+
? originalMemory.conversationHistory !== undefined
|
|
495
|
+
: mutation.kind === 'delete_context'
|
|
496
|
+
? Object.prototype.hasOwnProperty.call(originalMemory.sharedState ?? {}, 'context')
|
|
497
|
+
: mutation.kind === 'delete_context_history'
|
|
498
|
+
? Object.prototype.hasOwnProperty.call(
|
|
499
|
+
originalMemory.customData ?? {},
|
|
500
|
+
'contextHistory'
|
|
501
|
+
)
|
|
502
|
+
: true;
|
|
503
|
+
if (!targetExists) {
|
|
504
|
+
return { found: false, memory: originalMemory, value: null };
|
|
505
|
+
}
|
|
506
|
+
let updatedMemory: IEnhancedChannelMemory;
|
|
507
|
+
let value: unknown;
|
|
508
|
+
|
|
509
|
+
switch (mutation.kind) {
|
|
510
|
+
case 'append_messages':
|
|
511
|
+
value = [...(originalMemory.conversationHistory ?? []), ...mutation.messages];
|
|
512
|
+
updatedMemory = { ...originalMemory, conversationHistory: value as unknown[] };
|
|
513
|
+
break;
|
|
514
|
+
case 'replace_context':
|
|
515
|
+
value = mutation.context;
|
|
516
|
+
updatedMemory = {
|
|
517
|
+
...originalMemory,
|
|
518
|
+
sharedState: { ...originalMemory.sharedState, context: value }
|
|
519
|
+
};
|
|
520
|
+
break;
|
|
521
|
+
case 'append_context_history':
|
|
522
|
+
value = [
|
|
523
|
+
...((originalMemory.customData?.contextHistory as unknown[] | undefined) ?? []),
|
|
524
|
+
...mutation.entries
|
|
525
|
+
].slice(-mutation.retainLast);
|
|
526
|
+
updatedMemory = {
|
|
527
|
+
...originalMemory,
|
|
528
|
+
customData: { ...originalMemory.customData, contextHistory: value }
|
|
529
|
+
};
|
|
530
|
+
break;
|
|
531
|
+
case 'delete_messages':
|
|
532
|
+
value = [];
|
|
533
|
+
updatedMemory = { ...originalMemory, conversationHistory: [] };
|
|
534
|
+
break;
|
|
535
|
+
case 'delete_context': {
|
|
536
|
+
const sharedState = { ...originalMemory.sharedState };
|
|
537
|
+
delete sharedState.context;
|
|
538
|
+
value = null;
|
|
539
|
+
updatedMemory = { ...originalMemory, sharedState };
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
case 'delete_context_history': {
|
|
543
|
+
const customData = { ...originalMemory.customData };
|
|
544
|
+
delete customData.contextHistory;
|
|
545
|
+
value = null;
|
|
546
|
+
updatedMemory = { ...originalMemory, customData };
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
updatedMemory.updatedAt = new Date();
|
|
552
|
+
this.channelMemory.set(channelId, updatedMemory);
|
|
553
|
+
return { found: true, memory: updatedMemory, value };
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
private async executeKeyedChannelMutation(
|
|
557
|
+
key: string,
|
|
558
|
+
requestChannelId: ChannelId | undefined,
|
|
559
|
+
mutation: ChannelMemoryAtomicMutation
|
|
560
|
+
): Promise<ChannelMemoryAtomicMutationResult> {
|
|
561
|
+
const { channelId } = this.getChannelMemoryKey(key, requestChannelId);
|
|
562
|
+
return this.serializeChannelMutation(channelId, async () => {
|
|
563
|
+
const result = this.persistenceService
|
|
564
|
+
? await firstValueFrom(
|
|
565
|
+
this.persistenceService.mutateChannelMemory(channelId, mutation)
|
|
566
|
+
)
|
|
567
|
+
: await this.mutateLocalChannelMemory(channelId, mutation);
|
|
568
|
+
|
|
569
|
+
if (result.memory) {
|
|
570
|
+
const cachedMemory = this.channelMemory.get(channelId);
|
|
571
|
+
this.channelMemory.set(channelId, {
|
|
572
|
+
...result.memory,
|
|
573
|
+
sharedCognitiveInsights: cachedMemory?.sharedCognitiveInsights ?? {
|
|
574
|
+
systemSummaries: [],
|
|
575
|
+
topicExtractions: [],
|
|
576
|
+
collaborativeReflections: []
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
if (result.found) {
|
|
581
|
+
this.generalData.set(key, result.value);
|
|
582
|
+
} else {
|
|
583
|
+
this.generalData.delete(key);
|
|
584
|
+
}
|
|
585
|
+
return result;
|
|
315
586
|
});
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
private async updateKeyedChannelMemory(
|
|
590
|
+
key: string,
|
|
591
|
+
value: unknown,
|
|
592
|
+
requestChannelId: ChannelId,
|
|
593
|
+
expectedContextUpdatedAt?: number
|
|
594
|
+
): Promise<MemoryUpdateResultEventData['memory']> {
|
|
595
|
+
const { kind } = this.getChannelMemoryKey(key, requestChannelId);
|
|
596
|
+
const result = await this.executeKeyedChannelMutation(
|
|
597
|
+
key,
|
|
598
|
+
requestChannelId,
|
|
599
|
+
this.getAtomicMutation(kind, value, expectedContextUpdatedAt)
|
|
600
|
+
);
|
|
601
|
+
if (!result.found) {
|
|
602
|
+
throw new Error(`Channel context changed concurrently while updating ${key}`);
|
|
603
|
+
}
|
|
604
|
+
return result.value as MemoryUpdateResultEventData['memory'];
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
private async deleteKeyedChannelMemory(key: string): Promise<boolean> {
|
|
608
|
+
const { kind } = this.getChannelMemoryKey(key);
|
|
609
|
+
const result = await this.executeKeyedChannelMutation(
|
|
610
|
+
key,
|
|
611
|
+
undefined,
|
|
612
|
+
this.getDeleteMutation(kind)
|
|
613
|
+
);
|
|
614
|
+
if (result.found) {
|
|
615
|
+
this.generalData.delete(key);
|
|
616
|
+
}
|
|
617
|
+
return result.found;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
private async handleMemoryGetRequest(event: MemoryGetEventPayload): Promise<void> {
|
|
621
|
+
let responseId: string | string[] = event.data.id;
|
|
622
|
+
try {
|
|
623
|
+
this.validateMemoryRequestIdentity(event);
|
|
624
|
+
let memory: MemoryGetResultEventData['memory'];
|
|
625
|
+
|
|
626
|
+
switch (event.data.scope) {
|
|
627
|
+
case MemoryScope.AGENT: {
|
|
628
|
+
const agentId = this.requireOwnAgentMemoryId(event.data.id, event.agentId);
|
|
629
|
+
responseId = agentId;
|
|
630
|
+
memory = await firstValueFrom(this.getAgentMemory(agentId));
|
|
631
|
+
break;
|
|
632
|
+
}
|
|
633
|
+
case MemoryScope.CHANNEL: {
|
|
634
|
+
const channelMemoryId = this.requireOwnChannelMemoryId(
|
|
635
|
+
event.data.key ?? event.data.id,
|
|
636
|
+
event.channelId
|
|
637
|
+
);
|
|
638
|
+
responseId = channelMemoryId;
|
|
639
|
+
memory = channelMemoryId.startsWith('channel:')
|
|
640
|
+
? await this.getKeyedChannelMemory(channelMemoryId, event.channelId)
|
|
641
|
+
: await firstValueFrom(this.getChannelMemory(channelMemoryId));
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
case MemoryScope.RELATIONSHIP: {
|
|
645
|
+
const [agentId1, agentId2, channelId] = this.requireRelationshipMemoryId(
|
|
646
|
+
event.data.id,
|
|
647
|
+
event.channelId,
|
|
648
|
+
event.agentId
|
|
649
|
+
);
|
|
650
|
+
responseId = [agentId1, agentId2, channelId];
|
|
651
|
+
memory = await firstValueFrom(
|
|
652
|
+
this.getRelationshipMemory(agentId1, agentId2, channelId)
|
|
653
|
+
);
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
EventBus.server.emit(
|
|
659
|
+
Events.Memory.GET_RESULT,
|
|
660
|
+
createMemoryGetResultEventPayload(
|
|
661
|
+
Events.Memory.GET_RESULT,
|
|
662
|
+
event.agentId,
|
|
663
|
+
event.channelId,
|
|
664
|
+
{
|
|
665
|
+
operationId: event.data.operationId,
|
|
666
|
+
scope: event.data.scope,
|
|
667
|
+
id: responseId,
|
|
668
|
+
memory
|
|
669
|
+
}
|
|
670
|
+
)
|
|
671
|
+
);
|
|
672
|
+
} catch (error) {
|
|
673
|
+
this.emitMemoryGetError(event, responseId, error);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
private async handleMemoryUpdateRequest(event: MemoryUpdateEventPayload): Promise<void> {
|
|
678
|
+
let responseId: string | string[] = event.data.id;
|
|
679
|
+
try {
|
|
680
|
+
this.validateMemoryRequestIdentity(event);
|
|
681
|
+
this.validator.assertIsObject(event.data.data, 'Memory update data is required');
|
|
682
|
+
let memory: MemoryUpdateResultEventData['memory'];
|
|
683
|
+
|
|
684
|
+
switch (event.data.scope) {
|
|
685
|
+
case MemoryScope.AGENT: {
|
|
686
|
+
const agentId = this.requireOwnAgentMemoryId(event.data.id, event.agentId);
|
|
687
|
+
responseId = agentId;
|
|
688
|
+
memory = await firstValueFrom(this.updateAgentMemory(agentId, event.data.data));
|
|
689
|
+
break;
|
|
690
|
+
}
|
|
691
|
+
case MemoryScope.CHANNEL: {
|
|
692
|
+
const channelMemoryId = this.requireOwnChannelMemoryId(
|
|
693
|
+
event.data.id,
|
|
694
|
+
event.channelId
|
|
695
|
+
);
|
|
696
|
+
responseId = channelMemoryId;
|
|
697
|
+
const embeddedMemoryKeys = Object.keys(event.data.data)
|
|
698
|
+
.filter(key => key.startsWith('channel:'));
|
|
699
|
+
const keyedMemoryId = channelMemoryId.startsWith('channel:')
|
|
700
|
+
? channelMemoryId
|
|
701
|
+
: embeddedMemoryKeys.length === 1
|
|
702
|
+
? embeddedMemoryKeys[0]
|
|
703
|
+
: undefined;
|
|
704
|
+
if (keyedMemoryId) {
|
|
705
|
+
responseId = keyedMemoryId;
|
|
706
|
+
const nestedValue = event.data.data[keyedMemoryId];
|
|
707
|
+
const value = nestedValue === undefined ? event.data.data : nestedValue;
|
|
708
|
+
const expectedContextUpdatedAt =
|
|
709
|
+
event.data.metadata?.expectedContextUpdatedAt;
|
|
710
|
+
if (
|
|
711
|
+
expectedContextUpdatedAt !== undefined &&
|
|
712
|
+
(
|
|
713
|
+
typeof expectedContextUpdatedAt !== 'number' ||
|
|
714
|
+
!Number.isFinite(expectedContextUpdatedAt) ||
|
|
715
|
+
expectedContextUpdatedAt < 0
|
|
716
|
+
)
|
|
717
|
+
) {
|
|
718
|
+
throw new Error(
|
|
719
|
+
'Memory update expectedContextUpdatedAt must be a non-negative number'
|
|
357
720
|
);
|
|
358
|
-
|
|
359
|
-
//// this.logger.info(`[CRITICAL] MemoryService emitting GET_RESULT:`, Object.keys(payload));
|
|
360
|
-
EventBus.server.emit(Events.Memory.GET_RESULT, payload);
|
|
361
|
-
} else {
|
|
362
|
-
this.logger.warn(`[DEBUG] No memory key found in GET event data`);
|
|
363
|
-
}
|
|
364
|
-
break;
|
|
365
|
-
|
|
366
|
-
case MemoryScope.AGENT:
|
|
367
|
-
if (typeof memoryEventData.id === 'string') {
|
|
368
|
-
// ;
|
|
369
|
-
memoryObservable = this.getAgentMemory(memoryEventData.id);
|
|
370
|
-
|
|
371
|
-
// Subscribe to the observable and emit result
|
|
372
|
-
memoryObservable.subscribe({
|
|
373
|
-
next: (agentMemory: IEnhancedAgentMemory) => {
|
|
374
|
-
// Create result payload
|
|
375
|
-
const getResultData: MemoryGetResultEventData = {
|
|
376
|
-
operationId: memoryEventData.operationId,
|
|
377
|
-
scope: MemoryScope.AGENT,
|
|
378
|
-
id: memoryEventData.id as string,
|
|
379
|
-
memory: agentMemory || null
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
const payload = createMemoryGetResultEventPayload(
|
|
383
|
-
Events.Memory.GET_RESULT,
|
|
384
|
-
event.agentId,
|
|
385
|
-
event.channelId,
|
|
386
|
-
getResultData
|
|
387
|
-
);
|
|
388
|
-
|
|
389
|
-
EventBus.server.emit(Events.Memory.GET_RESULT, payload);
|
|
390
|
-
},
|
|
391
|
-
error: (error: Error) => {
|
|
392
|
-
this.logger.error(`Error getting agent memory: ${error}`);
|
|
393
|
-
|
|
394
|
-
// Create error result payload
|
|
395
|
-
const getResultData: MemoryGetResultEventData = {
|
|
396
|
-
operationId: memoryEventData.operationId,
|
|
397
|
-
scope: MemoryScope.AGENT,
|
|
398
|
-
id: memoryEventData.id as string,
|
|
399
|
-
memory: null
|
|
400
|
-
};
|
|
401
|
-
|
|
402
|
-
const payload = createMemoryGetResultEventPayload(
|
|
403
|
-
Events.Memory.GET_RESULT,
|
|
404
|
-
event.agentId,
|
|
405
|
-
event.channelId,
|
|
406
|
-
getResultData
|
|
407
|
-
);
|
|
408
|
-
|
|
409
|
-
EventBus.server.emit(Events.Memory.GET_RESULT, payload);
|
|
410
|
-
}
|
|
411
|
-
});
|
|
412
721
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
722
|
+
memory = await this.updateKeyedChannelMemory(
|
|
723
|
+
keyedMemoryId,
|
|
724
|
+
value,
|
|
725
|
+
event.channelId,
|
|
726
|
+
expectedContextUpdatedAt
|
|
727
|
+
);
|
|
728
|
+
} else {
|
|
729
|
+
memory = await firstValueFrom(
|
|
730
|
+
this.updateChannelMemory(channelMemoryId, event.data.data)
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
break;
|
|
734
|
+
}
|
|
735
|
+
case MemoryScope.RELATIONSHIP: {
|
|
736
|
+
const [agentId1, agentId2, channelId] = this.requireRelationshipMemoryId(
|
|
737
|
+
event.data.id,
|
|
738
|
+
event.channelId,
|
|
739
|
+
event.agentId
|
|
740
|
+
);
|
|
741
|
+
responseId = [agentId1, agentId2, channelId];
|
|
742
|
+
memory = await firstValueFrom(
|
|
743
|
+
this.updateRelationshipMemory(agentId1, agentId2, channelId, event.data.data)
|
|
744
|
+
);
|
|
745
|
+
break;
|
|
421
746
|
}
|
|
422
|
-
|
|
423
|
-
} catch (error) {
|
|
424
|
-
this.logger.error('[ERROR] Error processing EventBus Memory.GET:', error);
|
|
425
|
-
|
|
426
|
-
// Log error details for debugging without creating fake event payloads
|
|
427
|
-
const operationId = event.data?.operationId || '[NO_OPERATION_ID]';
|
|
428
|
-
const memoryId = event.data?.id || event.data?.key || '[NO_MEMORY_ID]';
|
|
429
|
-
this.logger.error(`Memory GET operation failed - OperationId: ${operationId}, MemoryId: ${memoryId}, Error: ${(error as Error).message}`);
|
|
430
|
-
|
|
431
|
-
// Cannot emit GET_RESULT event without valid agentId and channelId from original request
|
|
432
|
-
// Original event should have contained these required identifiers
|
|
433
|
-
this.logger.warn('Cannot emit Memory.GET_RESULT event - original event lacked valid agentId/channelId. Memory operation errors should be handled by the requesting component.');
|
|
434
747
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
if (!dataHasChanged) {
|
|
473
|
-
// ;
|
|
474
|
-
return; // Skip update and event emission
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// ;
|
|
478
|
-
this.generalData.set(updateMemoryKey, actualData);
|
|
479
|
-
|
|
480
|
-
// Create success result payload
|
|
481
|
-
const updateResult: MemoryUpdateResultEventData = {
|
|
482
|
-
operationId: memoryEventData.operationId,
|
|
483
|
-
scope: MemoryScope.CHANNEL,
|
|
484
|
-
id: updateMemoryKey, // Use the memory key as the id for proper matching
|
|
485
|
-
memory: actualData
|
|
486
|
-
};
|
|
487
|
-
|
|
488
|
-
const systemAgentId: AgentId = 'SYSTEM_AGENT';
|
|
489
|
-
const noChannelId: ChannelId = 'NO_CHANNEL';
|
|
490
|
-
|
|
491
|
-
const payload = createMemoryUpdateResultEventPayload(
|
|
492
|
-
Events.Memory.UPDATE_RESULT,
|
|
493
|
-
systemAgentId,
|
|
494
|
-
noChannelId,
|
|
495
|
-
updateResult
|
|
496
|
-
);
|
|
497
|
-
|
|
498
|
-
// ;
|
|
499
|
-
EventBus.server.emit(Events.Memory.UPDATE_RESULT, payload);
|
|
500
|
-
} else {
|
|
501
|
-
// Legacy format: Find any channel-related key and data in the data object
|
|
502
|
-
const channelKey = dataKeys.find(key =>
|
|
503
|
-
key.startsWith('channel:messages:') || key.startsWith('channel:context:')
|
|
504
|
-
);
|
|
505
|
-
|
|
506
|
-
if (channelKey && memoryEventData.data[channelKey]) {
|
|
507
|
-
// ;
|
|
508
|
-
|
|
509
|
-
const newData = memoryEventData.data[channelKey];
|
|
510
|
-
|
|
511
|
-
// Check if data has actually changed before updating
|
|
512
|
-
const existingData = this.generalData.get(channelKey);
|
|
513
|
-
const dataHasChanged = !this.isDataEqual(existingData, newData);
|
|
514
|
-
|
|
515
|
-
if (!dataHasChanged) {
|
|
516
|
-
// ;
|
|
517
|
-
return; // Skip update and event emission
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
// Store the data by the key (messages array or context object)
|
|
521
|
-
// ;
|
|
522
|
-
this.generalData.set(channelKey, newData);
|
|
523
|
-
|
|
524
|
-
// Create success result payload
|
|
525
|
-
const updateResult: MemoryUpdateResultEventData = {
|
|
526
|
-
operationId: memoryEventData.operationId,
|
|
527
|
-
scope: MemoryScope.CHANNEL,
|
|
528
|
-
id: channelKey, // Use the memory key as the id for proper matching
|
|
529
|
-
memory: newData
|
|
530
|
-
};
|
|
531
|
-
|
|
532
|
-
const systemAgentId: AgentId = 'SYSTEM_AGENT';
|
|
533
|
-
const noChannelId: ChannelId = 'NO_CHANNEL';
|
|
534
|
-
|
|
535
|
-
const payload = createMemoryUpdateResultEventPayload(
|
|
536
|
-
Events.Memory.UPDATE_RESULT,
|
|
537
|
-
systemAgentId,
|
|
538
|
-
noChannelId,
|
|
539
|
-
updateResult
|
|
540
|
-
);
|
|
541
|
-
|
|
542
|
-
// ;
|
|
543
|
-
EventBus.server.emit(Events.Memory.UPDATE_RESULT, payload);
|
|
544
|
-
} else {
|
|
545
|
-
this.logger.warn(`No recognized channel key found in data keys: ${dataKeys.join(', ')}`);
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
break;
|
|
550
|
-
|
|
551
|
-
case MemoryScope.AGENT:
|
|
552
|
-
// Handle agent memory UPDATE
|
|
553
|
-
if (typeof memoryEventData.id === 'string' && memoryEventData.data) {
|
|
554
|
-
// CRITICAL: Must subscribe to Observable to trigger execution!
|
|
555
|
-
// The request context routes the UPDATE_RESULT back to the
|
|
556
|
-
// requesting agent with its own operationId — without it the
|
|
557
|
-
// SDK's pending save can never observe its result.
|
|
558
|
-
this.updateAgentMemory(memoryEventData.id, memoryEventData.data, {
|
|
559
|
-
operationId: memoryEventData.operationId,
|
|
560
|
-
requesterAgentId: event.agentId,
|
|
561
|
-
requesterChannelId: event.channelId
|
|
562
|
-
}).subscribe({
|
|
563
|
-
next: () => null,
|
|
564
|
-
error: (err) => this.logger.error(`Agent memory update failed for ${memoryEventData.id}: ${err}`)
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
break;
|
|
568
|
-
|
|
569
|
-
case MemoryScope.RELATIONSHIP:
|
|
570
|
-
// Handle relationship memory UPDATE
|
|
571
|
-
break;
|
|
572
|
-
|
|
573
|
-
default:
|
|
574
|
-
this.logger.warn(`Unsupported memory scope: ${memoryEventData.scope}`);
|
|
748
|
+
|
|
749
|
+
EventBus.server.emit(
|
|
750
|
+
Events.Memory.UPDATE_RESULT,
|
|
751
|
+
createMemoryUpdateResultEventPayload(
|
|
752
|
+
Events.Memory.UPDATE_RESULT,
|
|
753
|
+
event.agentId,
|
|
754
|
+
event.channelId,
|
|
755
|
+
{
|
|
756
|
+
operationId: event.data.operationId,
|
|
757
|
+
scope: event.data.scope,
|
|
758
|
+
id: responseId,
|
|
759
|
+
memory
|
|
760
|
+
}
|
|
761
|
+
)
|
|
762
|
+
);
|
|
763
|
+
} catch (error) {
|
|
764
|
+
this.emitMemoryUpdateError(event, responseId, error);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
private async handleMemoryDeleteRequest(event: MemoryDeleteEventPayload): Promise<void> {
|
|
769
|
+
let responseId: string | string[] = event.data.id;
|
|
770
|
+
try {
|
|
771
|
+
this.validateMemoryRequestIdentity(event);
|
|
772
|
+
if (event.data.scope === MemoryScope.RELATIONSHIP) {
|
|
773
|
+
responseId = this.requireRelationshipMemoryId(
|
|
774
|
+
event.data.id,
|
|
775
|
+
event.channelId,
|
|
776
|
+
event.agentId
|
|
777
|
+
);
|
|
778
|
+
} else if (event.data.scope === MemoryScope.AGENT) {
|
|
779
|
+
responseId = this.requireOwnAgentMemoryId(event.data.id, event.agentId);
|
|
780
|
+
} else {
|
|
781
|
+
responseId = this.requireOwnChannelMemoryId(event.data.id, event.channelId);
|
|
782
|
+
if (responseId.startsWith('channel:')) {
|
|
783
|
+
this.getChannelMemoryKey(responseId, event.channelId);
|
|
575
784
|
}
|
|
576
|
-
|
|
577
|
-
} catch (error) {
|
|
578
|
-
this.logger.error('[ERROR] Error processing EventBus Memory.UPDATE:', error);
|
|
579
|
-
|
|
580
|
-
// Log error details for debugging without creating fake event payloads
|
|
581
|
-
const operationId = event.data?.operationId || '[NO_OPERATION_ID]';
|
|
582
|
-
const memoryId = event.data?.id || '[NO_MEMORY_ID]';
|
|
583
|
-
this.logger.error(`Memory UPDATE operation failed - OperationId: ${operationId}, MemoryId: ${memoryId}, Error: ${(error as Error).message}`);
|
|
584
|
-
|
|
585
|
-
// Cannot emit UPDATE_RESULT event without valid agentId and channelId from original request
|
|
586
|
-
// Original event should have contained these required identifiers
|
|
587
|
-
this.logger.warn('Cannot emit Memory.UPDATE_RESULT event - original event lacked valid agentId/channelId. Memory operation errors should be handled by the requesting component.');
|
|
588
785
|
}
|
|
589
|
-
|
|
590
|
-
|
|
786
|
+
|
|
787
|
+
const success = await firstValueFrom(
|
|
788
|
+
this.deleteMemory(event.data.scope, responseId)
|
|
789
|
+
);
|
|
790
|
+
EventBus.server.emit(
|
|
791
|
+
Events.Memory.DELETE_RESULT,
|
|
792
|
+
createMemoryDeleteResultEventPayload(
|
|
793
|
+
Events.Memory.DELETE_RESULT,
|
|
794
|
+
event.agentId,
|
|
795
|
+
event.channelId,
|
|
796
|
+
{
|
|
797
|
+
operationId: event.data.operationId,
|
|
798
|
+
scope: event.data.scope,
|
|
799
|
+
id: responseId,
|
|
800
|
+
success
|
|
801
|
+
}
|
|
802
|
+
)
|
|
803
|
+
);
|
|
804
|
+
} catch (error) {
|
|
805
|
+
this.emitMemoryDeleteError(event, responseId, error);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
private emitMemoryGetError(
|
|
810
|
+
event: MemoryGetEventPayload,
|
|
811
|
+
id: string | string[],
|
|
812
|
+
error: unknown
|
|
813
|
+
): void {
|
|
814
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
815
|
+
this.logger.error(`Memory GET failed: ${message}`);
|
|
816
|
+
EventBus.server.emit(
|
|
817
|
+
Events.Memory.GET_RESULT,
|
|
818
|
+
createMemoryGetResultEventPayload(
|
|
819
|
+
Events.Memory.GET_RESULT,
|
|
820
|
+
event.agentId,
|
|
821
|
+
event.channelId,
|
|
822
|
+
{
|
|
823
|
+
operationId: event.data.operationId,
|
|
824
|
+
scope: event.data.scope,
|
|
825
|
+
id,
|
|
826
|
+
memory: null,
|
|
827
|
+
error: message
|
|
828
|
+
}
|
|
829
|
+
)
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
private emitMemoryUpdateError(
|
|
834
|
+
event: MemoryUpdateEventPayload,
|
|
835
|
+
id: string | string[],
|
|
836
|
+
error: unknown
|
|
837
|
+
): void {
|
|
838
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
839
|
+
this.logger.error(`Memory UPDATE failed: ${message}`);
|
|
840
|
+
EventBus.server.emit(
|
|
841
|
+
Events.Memory.UPDATE_RESULT,
|
|
842
|
+
createMemoryUpdateResultEventPayload(
|
|
843
|
+
Events.Memory.UPDATE_RESULT,
|
|
844
|
+
event.agentId,
|
|
845
|
+
event.channelId,
|
|
846
|
+
{
|
|
847
|
+
operationId: event.data.operationId,
|
|
848
|
+
scope: event.data.scope,
|
|
849
|
+
id,
|
|
850
|
+
memory: null,
|
|
851
|
+
error: message
|
|
852
|
+
}
|
|
853
|
+
)
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
private emitMemoryDeleteError(
|
|
858
|
+
event: MemoryDeleteEventPayload,
|
|
859
|
+
id: string | string[],
|
|
860
|
+
error: unknown
|
|
861
|
+
): void {
|
|
862
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
863
|
+
this.logger.error(`Memory DELETE failed: ${message}`);
|
|
864
|
+
EventBus.server.emit(
|
|
865
|
+
Events.Memory.DELETE_RESULT,
|
|
866
|
+
createMemoryDeleteResultEventPayload(
|
|
867
|
+
Events.Memory.DELETE_RESULT,
|
|
868
|
+
event.agentId,
|
|
869
|
+
event.channelId,
|
|
870
|
+
{
|
|
871
|
+
operationId: event.data.operationId,
|
|
872
|
+
scope: event.data.scope,
|
|
873
|
+
id,
|
|
874
|
+
success: false,
|
|
875
|
+
error: message
|
|
876
|
+
}
|
|
877
|
+
)
|
|
878
|
+
);
|
|
591
879
|
}
|
|
592
880
|
|
|
593
881
|
/**
|
|
@@ -625,11 +913,14 @@ export class MemoryService {
|
|
|
625
913
|
if (persistence) {
|
|
626
914
|
return new Observable<IEnhancedAgentMemory>(observer => {
|
|
627
915
|
persistence.getAgentMemory(agentId).subscribe({
|
|
628
|
-
next: (loadedMemory:
|
|
916
|
+
next: (loadedMemory: IAgentMemory) => {
|
|
629
917
|
// Enhance the loaded memory with cognitive memory structure
|
|
918
|
+
const loadedCognitiveMemory = (
|
|
919
|
+
loadedMemory as Partial<IEnhancedAgentMemory>
|
|
920
|
+
).cognitiveMemory;
|
|
630
921
|
const enhancedMemory: IEnhancedAgentMemory = {
|
|
631
922
|
...loadedMemory,
|
|
632
|
-
cognitiveMemory:
|
|
923
|
+
cognitiveMemory: loadedCognitiveMemory ?? {
|
|
633
924
|
observationIds: [],
|
|
634
925
|
reasoningIds: [],
|
|
635
926
|
planIds: [],
|
|
@@ -644,12 +935,10 @@ export class MemoryService {
|
|
|
644
935
|
observer.next(enhancedMemory);
|
|
645
936
|
observer.complete();
|
|
646
937
|
},
|
|
647
|
-
error: (error:
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
observer.next(newMemory);
|
|
652
|
-
observer.complete();
|
|
938
|
+
error: (error: unknown) => {
|
|
939
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
940
|
+
this.logger.error(`Failed to load agent memory from MongoDB for ${agentId}: ${message}`);
|
|
941
|
+
observer.error(error);
|
|
653
942
|
}
|
|
654
943
|
});
|
|
655
944
|
});
|
|
@@ -685,167 +974,98 @@ export class MemoryService {
|
|
|
685
974
|
|
|
686
975
|
this.agentMemory.set(agentId, newMemory);
|
|
687
976
|
|
|
688
|
-
const operationId_agent_get_new = uuidv4();
|
|
689
|
-
const systemAgentId_agent_get_new: AgentId = 'SYSTEM_AGENT';
|
|
690
|
-
const noChannelId_agent_get_new: ChannelId = 'NO_CHANNEL';
|
|
691
|
-
const updateResultData_agent_get_new: MemoryUpdateResultEventData = {
|
|
692
|
-
operationId: operationId_agent_get_new,
|
|
693
|
-
scope: MemoryScope.AGENT,
|
|
694
|
-
id: agentId,
|
|
695
|
-
memory: newMemory
|
|
696
|
-
};
|
|
697
|
-
EventBus.server.emit(
|
|
698
|
-
Events.Memory.UPDATE_RESULT,
|
|
699
|
-
createMemoryUpdateResultEventPayload(
|
|
700
|
-
Events.Memory.UPDATE_RESULT,
|
|
701
|
-
systemAgentId_agent_get_new,
|
|
702
|
-
noChannelId_agent_get_new,
|
|
703
|
-
updateResultData_agent_get_new
|
|
704
|
-
)
|
|
705
|
-
);
|
|
706
|
-
|
|
707
977
|
return newMemory;
|
|
708
978
|
}
|
|
709
979
|
|
|
710
980
|
/**
|
|
711
981
|
* Update agent memory
|
|
712
982
|
*
|
|
713
|
-
* When the update was requested over the wire (SDK → Events.Memory.UPDATE),
|
|
714
|
-
* requestContext carries the requester's operationId and identity. The
|
|
715
|
-
* UPDATE_RESULT emitted here must echo that operationId and be addressed to
|
|
716
|
-
* the requesting agent: the SDK matches results by operationId, and event
|
|
717
|
-
* forwarding routes them by payload.agentId. Before this parameter existed,
|
|
718
|
-
* agent-scope results were emitted with a freshly generated operationId under
|
|
719
|
-
* SYSTEM_AGENT — no SDK save round-trip could ever observe its own result, so
|
|
720
|
-
* every awaited save hung forever and every fire-and-forget save leaked its
|
|
721
|
-
* result listener.
|
|
722
|
-
*
|
|
723
983
|
* @param pAgentId Agent ID
|
|
724
984
|
* @param updates Memory updates
|
|
725
|
-
* @param requestContext Requester identity for result routing (wire requests only)
|
|
726
985
|
* @returns Observable of updated agent memory
|
|
727
986
|
*/
|
|
728
987
|
public updateAgentMemory(
|
|
729
988
|
pAgentId: string,
|
|
730
|
-
updates: Partial<IEnhancedAgentMemory
|
|
731
|
-
requestContext?: { operationId: string; requesterAgentId: AgentId; requesterChannelId: ChannelId }
|
|
989
|
+
updates: Partial<IEnhancedAgentMemory>
|
|
732
990
|
): Observable<IEnhancedAgentMemory> {
|
|
733
991
|
this.validator.assertIsNonEmptyString(pAgentId, 'Agent ID must be a non-empty string');
|
|
734
992
|
this.validator.assertIsObject(updates, 'Updates must be an object');
|
|
735
|
-
|
|
736
|
-
// Get existing memory or create new one
|
|
993
|
+
|
|
737
994
|
return new Observable<IEnhancedAgentMemory>(observer => {
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
if (updates.conversationHistory !== undefined) {
|
|
768
|
-
updatedMemory.conversationHistory = updates.conversationHistory;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
// Store updated memory in cache
|
|
772
|
-
this.agentMemory.set(pAgentId, updatedMemory);
|
|
773
|
-
|
|
774
|
-
// Persist to MongoDB if persistence service is available (async, non-blocking)
|
|
775
|
-
if (this.persistenceService) {
|
|
776
|
-
this.persistenceService.saveAgentMemory(updatedMemory)
|
|
777
|
-
.subscribe({
|
|
778
|
-
next: () => null,
|
|
779
|
-
error: (err: any) => this.logger.warn(`Failed to persist agent memory to MongoDB for ${pAgentId}: ${err.message}`)
|
|
780
|
-
});
|
|
781
|
-
}
|
|
995
|
+
let cancelled = false;
|
|
996
|
+
void (async (): Promise<void> => {
|
|
997
|
+
try {
|
|
998
|
+
const enhancedStoredMemory = await this.serializeAgentMutation(
|
|
999
|
+
pAgentId,
|
|
1000
|
+
async (): Promise<IEnhancedAgentMemory> => {
|
|
1001
|
+
const originalAgentMemory = await firstValueFrom(
|
|
1002
|
+
this.getAgentMemory(pAgentId)
|
|
1003
|
+
);
|
|
1004
|
+
const updatedMemory: IEnhancedAgentMemory = {
|
|
1005
|
+
...originalAgentMemory,
|
|
1006
|
+
...updates,
|
|
1007
|
+
updatedAt: new Date(),
|
|
1008
|
+
id: originalAgentMemory.id,
|
|
1009
|
+
agentId: originalAgentMemory.agentId,
|
|
1010
|
+
createdAt: originalAgentMemory.createdAt,
|
|
1011
|
+
notes: updates.notes
|
|
1012
|
+
? { ...originalAgentMemory.notes, ...updates.notes }
|
|
1013
|
+
: originalAgentMemory.notes,
|
|
1014
|
+
customData: updates.customData
|
|
1015
|
+
? { ...originalAgentMemory.customData, ...updates.customData }
|
|
1016
|
+
: originalAgentMemory.customData,
|
|
1017
|
+
cognitiveMemory: updates.cognitiveMemory
|
|
1018
|
+
? {
|
|
1019
|
+
...originalAgentMemory.cognitiveMemory,
|
|
1020
|
+
...updates.cognitiveMemory
|
|
1021
|
+
}
|
|
1022
|
+
: originalAgentMemory.cognitiveMemory
|
|
1023
|
+
};
|
|
782
1024
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
.
|
|
1025
|
+
const storedMemory = this.persistenceService
|
|
1026
|
+
? await firstValueFrom(
|
|
1027
|
+
this.persistenceService.saveAgentMemory(updatedMemory)
|
|
1028
|
+
)
|
|
1029
|
+
: updatedMemory;
|
|
1030
|
+
const enhancedMemory: IEnhancedAgentMemory = {
|
|
1031
|
+
...storedMemory,
|
|
1032
|
+
cognitiveMemory: updatedMemory.cognitiveMemory
|
|
1033
|
+
};
|
|
1034
|
+
this.agentMemory.set(pAgentId, enhancedMemory);
|
|
1035
|
+
return enhancedMemory;
|
|
1036
|
+
}
|
|
1037
|
+
);
|
|
1038
|
+
|
|
1039
|
+
if (updates.conversationHistory && updates.conversationHistory.length > 0) {
|
|
1040
|
+
const contentToExtract = updates.conversationHistory
|
|
1041
|
+
.slice(-3)
|
|
1042
|
+
.filter((message): message is typeof message & { content: string } =>
|
|
1043
|
+
typeof message.content === 'string' && message.content.length > 0)
|
|
1044
|
+
.map(message => message.content)
|
|
1045
|
+
.join('\n\n');
|
|
1046
|
+
if (contentToExtract.length > 0) {
|
|
1047
|
+
const channelContext = `agent-memory-${pAgentId}`;
|
|
1048
|
+
const memoryId = `agent-${pAgentId}-${Date.now()}`;
|
|
1049
|
+
this.triggerEntityExtraction(channelContext, memoryId, contentToExtract)
|
|
1050
|
+
.catch(error => this.logger.warn(
|
|
1051
|
+
`Entity extraction failed: ${error instanceof Error ? error.message : String(error)}`
|
|
1052
|
+
));
|
|
1053
|
+
}
|
|
800
1054
|
}
|
|
801
|
-
}
|
|
802
1055
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
const resultChannelId: ChannelId = requestContext?.requesterChannelId ?? 'NO_CHANNEL';
|
|
817
|
-
|
|
818
|
-
const payload = createMemoryUpdateResultEventPayload(
|
|
819
|
-
Events.Memory.UPDATE_RESULT,
|
|
820
|
-
resultAgentId,
|
|
821
|
-
resultChannelId,
|
|
822
|
-
updateResultData
|
|
823
|
-
);
|
|
824
|
-
EventBus.server.emit(Events.Memory.UPDATE_RESULT, payload);
|
|
825
|
-
|
|
826
|
-
observer.next(updatedMemory);
|
|
827
|
-
observer.complete();
|
|
828
|
-
}, error => {
|
|
829
|
-
// Errors must reach the requester too — a save whose failure is
|
|
830
|
-
// only logged server-side leaves the requesting SDK waiting forever.
|
|
831
|
-
const updateResultData_agent_update_error: MemoryUpdateResultEventData = {
|
|
832
|
-
operationId: requestContext?.operationId ?? uuidv4(),
|
|
833
|
-
scope: MemoryScope.AGENT,
|
|
834
|
-
id: pAgentId,
|
|
835
|
-
memory: null,
|
|
836
|
-
error: (error as Error).message
|
|
837
|
-
};
|
|
838
|
-
EventBus.server.emit(
|
|
839
|
-
Events.Memory.UPDATE_RESULT,
|
|
840
|
-
createMemoryUpdateResultEventPayload(
|
|
841
|
-
Events.Memory.UPDATE_RESULT,
|
|
842
|
-
requestContext?.requesterAgentId ?? 'SYSTEM_AGENT',
|
|
843
|
-
requestContext?.requesterChannelId ?? 'NO_CHANNEL',
|
|
844
|
-
updateResultData_agent_update_error
|
|
845
|
-
)
|
|
846
|
-
);
|
|
847
|
-
observer.error(error);
|
|
848
|
-
});
|
|
1056
|
+
if (!cancelled) {
|
|
1057
|
+
observer.next(enhancedStoredMemory);
|
|
1058
|
+
observer.complete();
|
|
1059
|
+
}
|
|
1060
|
+
} catch (error) {
|
|
1061
|
+
if (!cancelled) {
|
|
1062
|
+
observer.error(error);
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
})();
|
|
1066
|
+
return () => {
|
|
1067
|
+
cancelled = true;
|
|
1068
|
+
};
|
|
849
1069
|
});
|
|
850
1070
|
}
|
|
851
1071
|
|
|
@@ -1147,7 +1367,7 @@ export class MemoryService {
|
|
|
1147
1367
|
* @param options Query options
|
|
1148
1368
|
* @returns Observable of cognitive memory entries
|
|
1149
1369
|
*/
|
|
1150
|
-
public queryCognitiveMemory(agentId: AgentId, channelId: ChannelId, options: CognitiveMemoryQueryOptions = {}): Observable<CognitiveMemoryEntry<
|
|
1370
|
+
public queryCognitiveMemory(agentId: AgentId, channelId: ChannelId, options: CognitiveMemoryQueryOptions = {}): Observable<CognitiveMemoryEntry<unknown>[]> {
|
|
1151
1371
|
this.validator.assertIsNonEmptyString(agentId, 'Agent ID must be a non-empty string');
|
|
1152
1372
|
this.validator.assertIsNonEmptyString(channelId, 'Channel ID must be a non-empty string');
|
|
1153
1373
|
|
|
@@ -1201,18 +1421,38 @@ export class MemoryService {
|
|
|
1201
1421
|
* @returns Observable of channel memory
|
|
1202
1422
|
*/
|
|
1203
1423
|
public getChannelMemory(channelId: string): Observable<IEnhancedChannelMemory> {
|
|
1204
|
-
// ;
|
|
1205
1424
|
this.validator.assertIsNonEmptyString(channelId, 'Channel ID must be a non-empty string');
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
if (
|
|
1209
|
-
|
|
1210
|
-
// ;
|
|
1211
|
-
return of(memory);
|
|
1425
|
+
|
|
1426
|
+
const existingMemory = this.channelMemory.get(channelId);
|
|
1427
|
+
if (existingMemory) {
|
|
1428
|
+
return of(existingMemory);
|
|
1212
1429
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1430
|
+
|
|
1431
|
+
const getPersistedChannelMemory = this.persistenceService?.getChannelMemory;
|
|
1432
|
+
if (this.persistenceService && !getPersistedChannelMemory) {
|
|
1433
|
+
return throwError(() => new Error('Channel memory persistence is not available'));
|
|
1434
|
+
}
|
|
1435
|
+
if (getPersistedChannelMemory) {
|
|
1436
|
+
return new Observable<IEnhancedChannelMemory>(observer => {
|
|
1437
|
+
getPersistedChannelMemory.call(this.persistenceService, channelId).subscribe({
|
|
1438
|
+
next: (loadedMemory: IChannelMemory) => {
|
|
1439
|
+
const enhancedMemory: IEnhancedChannelMemory = {
|
|
1440
|
+
...loadedMemory,
|
|
1441
|
+
sharedCognitiveInsights: {
|
|
1442
|
+
systemSummaries: [],
|
|
1443
|
+
topicExtractions: [],
|
|
1444
|
+
collaborativeReflections: []
|
|
1445
|
+
}
|
|
1446
|
+
};
|
|
1447
|
+
this.channelMemory.set(channelId, enhancedMemory);
|
|
1448
|
+
observer.next(enhancedMemory);
|
|
1449
|
+
observer.complete();
|
|
1450
|
+
},
|
|
1451
|
+
error: (error: unknown) => observer.error(error)
|
|
1452
|
+
});
|
|
1453
|
+
});
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1216
1456
|
const newMemory: IEnhancedChannelMemory = {
|
|
1217
1457
|
id: uuidv4(),
|
|
1218
1458
|
channelId,
|
|
@@ -1234,28 +1474,7 @@ export class MemoryService {
|
|
|
1234
1474
|
collaborativeReflections: []
|
|
1235
1475
|
}
|
|
1236
1476
|
};
|
|
1237
|
-
|
|
1238
1477
|
this.channelMemory.set(channelId, newMemory);
|
|
1239
|
-
|
|
1240
|
-
const operationId_channel_get_new = uuidv4();
|
|
1241
|
-
const systemAgentId_channel_get_new: AgentId = 'SYSTEM_AGENT';
|
|
1242
|
-
const noChannelId_channel_get_new: ChannelId = 'NO_CHANNEL';
|
|
1243
|
-
const updateResultData_channel_get_new: MemoryUpdateResultEventData = {
|
|
1244
|
-
operationId: operationId_channel_get_new,
|
|
1245
|
-
scope: MemoryScope.CHANNEL,
|
|
1246
|
-
id: channelId,
|
|
1247
|
-
memory: newMemory
|
|
1248
|
-
};
|
|
1249
|
-
EventBus.server.emit(
|
|
1250
|
-
Events.Memory.UPDATE_RESULT,
|
|
1251
|
-
createMemoryUpdateResultEventPayload(
|
|
1252
|
-
Events.Memory.UPDATE_RESULT,
|
|
1253
|
-
systemAgentId_channel_get_new,
|
|
1254
|
-
noChannelId_channel_get_new,
|
|
1255
|
-
updateResultData_channel_get_new
|
|
1256
|
-
)
|
|
1257
|
-
);
|
|
1258
|
-
|
|
1259
1478
|
return of(newMemory);
|
|
1260
1479
|
}
|
|
1261
1480
|
|
|
@@ -1267,85 +1486,85 @@ export class MemoryService {
|
|
|
1267
1486
|
*/
|
|
1268
1487
|
public updateChannelMemory(channelId: ChannelId, updates: Partial<IEnhancedChannelMemory>): Observable<IEnhancedChannelMemory> {
|
|
1269
1488
|
this.validator.assertIsNonEmptyString(channelId, 'Channel ID must be a non-empty string');
|
|
1489
|
+
this.validator.assertIsObject(updates, 'Channel memory updates must be an object');
|
|
1490
|
+
if (
|
|
1491
|
+
this.ownsPathOrDescendant(updates, 'conversationHistory') ||
|
|
1492
|
+
this.ownsPathOrDescendant(updates, 'sharedState.context') ||
|
|
1493
|
+
this.ownsPathOrDescendant(updates, 'customData.contextHistory') ||
|
|
1494
|
+
this.ownsPathOrDescendant(updates.sharedState, 'context') ||
|
|
1495
|
+
this.ownsPathOrDescendant(updates.customData, 'contextHistory')
|
|
1496
|
+
) {
|
|
1497
|
+
throw new Error(
|
|
1498
|
+
'Reserved channel memory fields must use the atomic keyed-memory operations'
|
|
1499
|
+
);
|
|
1500
|
+
}
|
|
1270
1501
|
|
|
1271
1502
|
return new Observable<IEnhancedChannelMemory>(observer => {
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1503
|
+
let cancelled = false;
|
|
1504
|
+
void (async (): Promise<void> => {
|
|
1505
|
+
try {
|
|
1506
|
+
const enhancedStoredMemory = await this.serializeChannelMutation(
|
|
1507
|
+
channelId,
|
|
1508
|
+
async (): Promise<IEnhancedChannelMemory> => {
|
|
1509
|
+
const originalMemory = await firstValueFrom(this.getChannelMemory(channelId));
|
|
1510
|
+
const updatedMemory: IEnhancedChannelMemory = {
|
|
1511
|
+
...originalMemory,
|
|
1512
|
+
...updates,
|
|
1513
|
+
id: originalMemory.id,
|
|
1514
|
+
channelId,
|
|
1515
|
+
createdAt: originalMemory.createdAt,
|
|
1516
|
+
updatedAt: new Date(),
|
|
1517
|
+
notes: updates.notes
|
|
1518
|
+
? { ...originalMemory.notes, ...updates.notes }
|
|
1519
|
+
: originalMemory.notes,
|
|
1520
|
+
sharedState: updates.sharedState
|
|
1521
|
+
? { ...originalMemory.sharedState, ...updates.sharedState }
|
|
1522
|
+
: originalMemory.sharedState,
|
|
1523
|
+
customData: updates.customData
|
|
1524
|
+
? { ...originalMemory.customData, ...updates.customData }
|
|
1525
|
+
: originalMemory.customData,
|
|
1526
|
+
participants: updates.participants
|
|
1527
|
+
? [...new Set([...(originalMemory.participants ?? []), ...updates.participants])]
|
|
1528
|
+
: originalMemory.participants,
|
|
1529
|
+
topics: updates.topics
|
|
1530
|
+
? [...new Set([...(originalMemory.topics ?? []), ...updates.topics])]
|
|
1531
|
+
: originalMemory.topics,
|
|
1532
|
+
conversationHistory: updates.conversationHistory
|
|
1533
|
+
? [
|
|
1534
|
+
...(originalMemory.conversationHistory ?? []),
|
|
1535
|
+
...updates.conversationHistory
|
|
1536
|
+
]
|
|
1537
|
+
: originalMemory.conversationHistory,
|
|
1538
|
+
sharedCognitiveInsights: {
|
|
1539
|
+
...originalMemory.sharedCognitiveInsights,
|
|
1540
|
+
...updates.sharedCognitiveInsights
|
|
1541
|
+
}
|
|
1542
|
+
};
|
|
1292
1543
|
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1544
|
+
const storedMemory = this.persistenceService
|
|
1545
|
+
? await firstValueFrom(this.persistenceService.saveChannelMemory(updatedMemory))
|
|
1546
|
+
: updatedMemory;
|
|
1547
|
+
const enhancedMemory: IEnhancedChannelMemory = {
|
|
1548
|
+
...storedMemory,
|
|
1549
|
+
sharedCognitiveInsights: updatedMemory.sharedCognitiveInsights
|
|
1550
|
+
};
|
|
1551
|
+
this.channelMemory.set(channelId, enhancedMemory);
|
|
1552
|
+
return enhancedMemory;
|
|
1553
|
+
}
|
|
1554
|
+
);
|
|
1555
|
+
if (!cancelled) {
|
|
1556
|
+
observer.next(enhancedStoredMemory);
|
|
1557
|
+
observer.complete();
|
|
1558
|
+
}
|
|
1559
|
+
} catch (error) {
|
|
1560
|
+
if (!cancelled) {
|
|
1561
|
+
observer.error(error);
|
|
1562
|
+
}
|
|
1299
1563
|
}
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
// Emit update event through EventBus
|
|
1305
|
-
const operationId = uuidv4();
|
|
1306
|
-
const updateResultData: MemoryUpdateResultEventData = {
|
|
1307
|
-
operationId,
|
|
1308
|
-
scope: MemoryScope.CHANNEL,
|
|
1309
|
-
id: channelId,
|
|
1310
|
-
memory: updatedMemory
|
|
1311
|
-
};
|
|
1312
|
-
|
|
1313
|
-
// Define standard agentId and channelId for system-level memory events
|
|
1314
|
-
const systemAgentId: AgentId = 'SYSTEM_AGENT';
|
|
1315
|
-
const systemChannelId: ChannelId = channelId; // Use the actual channel ID for channel operations
|
|
1316
|
-
|
|
1317
|
-
const payload = createMemoryUpdateResultEventPayload(
|
|
1318
|
-
Events.Memory.UPDATE_RESULT,
|
|
1319
|
-
systemAgentId,
|
|
1320
|
-
systemChannelId,
|
|
1321
|
-
updateResultData
|
|
1322
|
-
);
|
|
1323
|
-
EventBus.server.emit(Events.Memory.UPDATE_RESULT, payload);
|
|
1324
|
-
|
|
1325
|
-
observer.next(updatedMemory);
|
|
1326
|
-
observer.complete();
|
|
1327
|
-
}, error => {
|
|
1328
|
-
const operationId_channel_update_error = uuidv4();
|
|
1329
|
-
const updateResultData_channel_update_error: MemoryUpdateResultEventData = {
|
|
1330
|
-
operationId: operationId_channel_update_error,
|
|
1331
|
-
scope: MemoryScope.CHANNEL,
|
|
1332
|
-
id: channelId,
|
|
1333
|
-
memory: null,
|
|
1334
|
-
error: (error as Error).message
|
|
1335
|
-
};
|
|
1336
|
-
const systemAgentId_channel_update_error: AgentId = 'SYSTEM_AGENT';
|
|
1337
|
-
const systemChannelId_channel_update_error: ChannelId = channelId;
|
|
1338
|
-
EventBus.server.emit(
|
|
1339
|
-
Events.Memory.UPDATE_RESULT,
|
|
1340
|
-
createMemoryUpdateResultEventPayload(
|
|
1341
|
-
Events.Memory.UPDATE_RESULT,
|
|
1342
|
-
systemAgentId_channel_update_error,
|
|
1343
|
-
systemChannelId_channel_update_error,
|
|
1344
|
-
updateResultData_channel_update_error
|
|
1345
|
-
)
|
|
1346
|
-
);
|
|
1347
|
-
observer.error(error);
|
|
1348
|
-
});
|
|
1564
|
+
})();
|
|
1565
|
+
return () => {
|
|
1566
|
+
cancelled = true;
|
|
1567
|
+
};
|
|
1349
1568
|
});
|
|
1350
1569
|
}
|
|
1351
1570
|
|
|
@@ -1374,7 +1593,28 @@ export class MemoryService {
|
|
|
1374
1593
|
return of(existingMemory);
|
|
1375
1594
|
}
|
|
1376
1595
|
|
|
1377
|
-
|
|
1596
|
+
const getPersistedRelationshipMemory = this.persistenceService?.getRelationshipMemory;
|
|
1597
|
+
if (this.persistenceService && !getPersistedRelationshipMemory) {
|
|
1598
|
+
return throwError(() => new Error('Relationship memory persistence is not available'));
|
|
1599
|
+
}
|
|
1600
|
+
if (channelId && getPersistedRelationshipMemory) {
|
|
1601
|
+
return new Observable<IRelationshipMemory>(observer => {
|
|
1602
|
+
getPersistedRelationshipMemory.call(
|
|
1603
|
+
this.persistenceService,
|
|
1604
|
+
sortedId1,
|
|
1605
|
+
sortedId2,
|
|
1606
|
+
channelId
|
|
1607
|
+
).subscribe({
|
|
1608
|
+
next: (loadedMemory: IRelationshipMemory) => {
|
|
1609
|
+
this.relationshipMemory.set(relationshipKey, loadedMemory);
|
|
1610
|
+
observer.next(loadedMemory);
|
|
1611
|
+
observer.complete();
|
|
1612
|
+
},
|
|
1613
|
+
error: (error: unknown) => observer.error(error)
|
|
1614
|
+
});
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
|
|
1378
1618
|
const newMemory: IRelationshipMemory = {
|
|
1379
1619
|
id: uuidv4(),
|
|
1380
1620
|
agentId1: sortedId1,
|
|
@@ -1387,28 +1627,7 @@ export class MemoryService {
|
|
|
1387
1627
|
interactionHistory: [],
|
|
1388
1628
|
customData: {}
|
|
1389
1629
|
};
|
|
1390
|
-
|
|
1391
1630
|
this.relationshipMemory.set(relationshipKey, newMemory);
|
|
1392
|
-
|
|
1393
|
-
const operationId_rel_get_new = uuidv4();
|
|
1394
|
-
const systemAgentId_rel_get_new: AgentId = 'SYSTEM_AGENT';
|
|
1395
|
-
const noChannelId_rel_get_new: ChannelId = 'NO_CHANNEL';
|
|
1396
|
-
const updateResultData_rel_get_new: MemoryUpdateResultEventData = {
|
|
1397
|
-
operationId: operationId_rel_get_new,
|
|
1398
|
-
scope: MemoryScope.RELATIONSHIP,
|
|
1399
|
-
id: relationshipKey,
|
|
1400
|
-
memory: newMemory
|
|
1401
|
-
};
|
|
1402
|
-
EventBus.server.emit(
|
|
1403
|
-
Events.Memory.UPDATE_RESULT,
|
|
1404
|
-
createMemoryUpdateResultEventPayload(
|
|
1405
|
-
Events.Memory.UPDATE_RESULT,
|
|
1406
|
-
systemAgentId_rel_get_new,
|
|
1407
|
-
noChannelId_rel_get_new,
|
|
1408
|
-
updateResultData_rel_get_new
|
|
1409
|
-
)
|
|
1410
|
-
);
|
|
1411
|
-
|
|
1412
1631
|
return of(newMemory);
|
|
1413
1632
|
}
|
|
1414
1633
|
|
|
@@ -1428,123 +1647,195 @@ export class MemoryService {
|
|
|
1428
1647
|
|
|
1429
1648
|
const relationshipKey = this.getRelationshipKey(pAgentId1, pAgentId2, pChannelId);
|
|
1430
1649
|
|
|
1431
|
-
// Get existing memory or create new one
|
|
1432
1650
|
return new Observable<IRelationshipMemory>(observer => {
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
};
|
|
1488
|
-
EventBus.server.emit(
|
|
1489
|
-
Events.Memory.UPDATE_RESULT,
|
|
1490
|
-
createMemoryUpdateResultEventPayload(
|
|
1491
|
-
Events.Memory.UPDATE_RESULT,
|
|
1492
|
-
systemAgentId_rel_update_error,
|
|
1493
|
-
noChannelId_rel_update_error,
|
|
1494
|
-
updateResultData_rel_update_error
|
|
1495
|
-
)
|
|
1496
|
-
);
|
|
1497
|
-
observer.error(error);
|
|
1498
|
-
});
|
|
1651
|
+
let cancelled = false;
|
|
1652
|
+
void (async (): Promise<void> => {
|
|
1653
|
+
try {
|
|
1654
|
+
const storedMemory = await this.serializeRelationshipMutation(
|
|
1655
|
+
pAgentId1,
|
|
1656
|
+
pAgentId2,
|
|
1657
|
+
pChannelId,
|
|
1658
|
+
async (): Promise<IRelationshipMemory> => {
|
|
1659
|
+
const originalMemory = await firstValueFrom(
|
|
1660
|
+
this.getRelationshipMemory(pAgentId1, pAgentId2, pChannelId)
|
|
1661
|
+
);
|
|
1662
|
+
const updatedMemory: IRelationshipMemory = {
|
|
1663
|
+
...originalMemory,
|
|
1664
|
+
...updates,
|
|
1665
|
+
id: originalMemory.id,
|
|
1666
|
+
agentId1: originalMemory.agentId1,
|
|
1667
|
+
agentId2: originalMemory.agentId2,
|
|
1668
|
+
channelId: originalMemory.channelId,
|
|
1669
|
+
createdAt: originalMemory.createdAt,
|
|
1670
|
+
updatedAt: new Date(),
|
|
1671
|
+
notes: updates.notes
|
|
1672
|
+
? { ...originalMemory.notes, ...updates.notes }
|
|
1673
|
+
: originalMemory.notes,
|
|
1674
|
+
customData: updates.customData
|
|
1675
|
+
? { ...originalMemory.customData, ...updates.customData }
|
|
1676
|
+
: originalMemory.customData
|
|
1677
|
+
};
|
|
1678
|
+
const saveRelationshipMemory = this.persistenceService?.saveRelationshipMemory;
|
|
1679
|
+
if (this.persistenceService && !saveRelationshipMemory) {
|
|
1680
|
+
throw new Error('Relationship memory persistence is not available');
|
|
1681
|
+
}
|
|
1682
|
+
const persistedMemory = saveRelationshipMemory
|
|
1683
|
+
? await firstValueFrom(saveRelationshipMemory.call(
|
|
1684
|
+
this.persistenceService,
|
|
1685
|
+
updatedMemory
|
|
1686
|
+
))
|
|
1687
|
+
: updatedMemory;
|
|
1688
|
+
this.relationshipMemory.set(relationshipKey, persistedMemory);
|
|
1689
|
+
return persistedMemory;
|
|
1690
|
+
}
|
|
1691
|
+
);
|
|
1692
|
+
if (!cancelled) {
|
|
1693
|
+
observer.next(storedMemory);
|
|
1694
|
+
observer.complete();
|
|
1695
|
+
}
|
|
1696
|
+
} catch (error) {
|
|
1697
|
+
if (!cancelled) {
|
|
1698
|
+
observer.error(error);
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
})();
|
|
1702
|
+
return () => {
|
|
1703
|
+
cancelled = true;
|
|
1704
|
+
};
|
|
1499
1705
|
});
|
|
1500
1706
|
}
|
|
1501
1707
|
|
|
1502
1708
|
/**
|
|
1503
1709
|
* Delete memory by scope and ID
|
|
1504
1710
|
* @param scope Memory scope
|
|
1505
|
-
* @param id Entity ID
|
|
1711
|
+
* @param id Entity ID or relationship composite ID
|
|
1506
1712
|
* @returns Observable of success status
|
|
1507
1713
|
*/
|
|
1508
|
-
public deleteMemory(scope: MemoryScope, id: string): Observable<boolean> {
|
|
1714
|
+
public deleteMemory(scope: MemoryScope, id: string | string[]): Observable<boolean> {
|
|
1509
1715
|
this.validator.validateMemoryScope(scope);
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
case MemoryScope.CHANNEL:
|
|
1520
|
-
success = this.channelMemory.delete(id);
|
|
1521
|
-
break;
|
|
1522
|
-
case MemoryScope.RELATIONSHIP:
|
|
1523
|
-
success = this.relationshipMemory.delete(id);
|
|
1524
|
-
break;
|
|
1716
|
+
if (scope === MemoryScope.RELATIONSHIP) {
|
|
1717
|
+
if (!Array.isArray(id) || id.length !== 3) {
|
|
1718
|
+
throw new Error('Relationship memory deletion requires agentId1, agentId2, and channelId');
|
|
1719
|
+
}
|
|
1720
|
+
id.forEach((part, index) => {
|
|
1721
|
+
this.validator.assertIsNonEmptyString(part, `Relationship delete ID part ${index}`);
|
|
1722
|
+
});
|
|
1723
|
+
} else {
|
|
1724
|
+
this.validator.assertIsNonEmptyString(id, 'Memory ID must be a non-empty string');
|
|
1525
1725
|
}
|
|
1526
|
-
|
|
1527
|
-
// Emit delete event through EventBus
|
|
1528
|
-
const deleteResultData: MemoryDeleteResultEventData = {
|
|
1529
|
-
operationId,
|
|
1530
|
-
scope,
|
|
1531
|
-
id,
|
|
1532
|
-
success
|
|
1533
|
-
};
|
|
1534
1726
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1727
|
+
return new Observable<boolean>(observer => {
|
|
1728
|
+
let cancelled = false;
|
|
1729
|
+
void (async (): Promise<void> => {
|
|
1730
|
+
try {
|
|
1731
|
+
if (
|
|
1732
|
+
scope === MemoryScope.CHANNEL &&
|
|
1733
|
+
typeof id === 'string' &&
|
|
1734
|
+
id.startsWith('channel:')
|
|
1735
|
+
) {
|
|
1736
|
+
const success = await this.deleteKeyedChannelMemory(id);
|
|
1737
|
+
if (!cancelled) {
|
|
1738
|
+
observer.next(success);
|
|
1739
|
+
observer.complete();
|
|
1740
|
+
}
|
|
1741
|
+
return;
|
|
1742
|
+
}
|
|
1743
|
+
const deleteAuthoritatively = async (): Promise<boolean> => {
|
|
1744
|
+
const deletePersistentMemory = this.persistenceService?.deleteMemory;
|
|
1745
|
+
if (this.persistenceService && !deletePersistentMemory) {
|
|
1746
|
+
throw new Error('Memory deletion persistence is not available');
|
|
1747
|
+
}
|
|
1748
|
+
const persisted = deletePersistentMemory
|
|
1749
|
+
? await firstValueFrom(deletePersistentMemory.call(
|
|
1750
|
+
this.persistenceService,
|
|
1751
|
+
scope,
|
|
1752
|
+
id
|
|
1753
|
+
))
|
|
1754
|
+
: false;
|
|
1755
|
+
if (this.persistenceService && !persisted) {
|
|
1756
|
+
return false;
|
|
1757
|
+
}
|
|
1758
|
+
let cached = false;
|
|
1759
|
+
|
|
1760
|
+
switch (scope) {
|
|
1761
|
+
case MemoryScope.AGENT: {
|
|
1762
|
+
const agentId = id as string;
|
|
1763
|
+
cached = this.agentMemory.delete(agentId);
|
|
1764
|
+
for (const [key, memory] of this.relationshipMemory.entries()) {
|
|
1765
|
+
if (memory.agentId1 === agentId || memory.agentId2 === agentId) {
|
|
1766
|
+
cached = this.relationshipMemory.delete(key) || cached;
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
for (const [key, memory] of this.cognitiveMemory.entries()) {
|
|
1770
|
+
if (memory.agentId === agentId) {
|
|
1771
|
+
cached = this.cognitiveMemory.delete(key) || cached;
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
break;
|
|
1775
|
+
}
|
|
1776
|
+
case MemoryScope.CHANNEL: {
|
|
1777
|
+
const channelId = id as string;
|
|
1778
|
+
cached = this.channelMemory.has(channelId);
|
|
1779
|
+
cached = this.channelMemory.delete(channelId) || cached;
|
|
1780
|
+
for (const key of this.generalData.keys()) {
|
|
1781
|
+
if (key.endsWith(`:${channelId}`)) {
|
|
1782
|
+
cached = this.generalData.delete(key) || cached;
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
break;
|
|
1786
|
+
}
|
|
1787
|
+
case MemoryScope.RELATIONSHIP: {
|
|
1788
|
+
const [agentId1, agentId2, channelId] = id as string[];
|
|
1789
|
+
cached = this.relationshipMemory.delete(
|
|
1790
|
+
this.getRelationshipKey(agentId1, agentId2, channelId)
|
|
1791
|
+
);
|
|
1792
|
+
break;
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
return this.persistenceService ? persisted : cached;
|
|
1797
|
+
};
|
|
1538
1798
|
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1799
|
+
let deleted: boolean;
|
|
1800
|
+
switch (scope) {
|
|
1801
|
+
case MemoryScope.AGENT:
|
|
1802
|
+
deleted = await this.serializeAgentMutation(
|
|
1803
|
+
id as string,
|
|
1804
|
+
deleteAuthoritatively
|
|
1805
|
+
);
|
|
1806
|
+
break;
|
|
1807
|
+
case MemoryScope.CHANNEL:
|
|
1808
|
+
deleted = await this.serializeChannelMutation(
|
|
1809
|
+
id as string,
|
|
1810
|
+
deleteAuthoritatively
|
|
1811
|
+
);
|
|
1812
|
+
break;
|
|
1813
|
+
case MemoryScope.RELATIONSHIP: {
|
|
1814
|
+
const [agentId1, agentId2, channelId] = id as string[];
|
|
1815
|
+
deleted = await this.serializeRelationshipMutation(
|
|
1816
|
+
agentId1,
|
|
1817
|
+
agentId2,
|
|
1818
|
+
channelId,
|
|
1819
|
+
deleteAuthoritatively
|
|
1820
|
+
);
|
|
1821
|
+
break;
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
if (!cancelled) {
|
|
1826
|
+
observer.next(deleted);
|
|
1827
|
+
observer.complete();
|
|
1828
|
+
}
|
|
1829
|
+
} catch (error) {
|
|
1830
|
+
if (!cancelled) {
|
|
1831
|
+
observer.error(error);
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
})();
|
|
1835
|
+
return () => {
|
|
1836
|
+
cancelled = true;
|
|
1837
|
+
};
|
|
1838
|
+
});
|
|
1548
1839
|
}
|
|
1549
1840
|
|
|
1550
1841
|
/**
|
|
@@ -1599,15 +1890,15 @@ export class MemoryService {
|
|
|
1599
1890
|
* Get general key-value data
|
|
1600
1891
|
* Used for tool-level key-value storage
|
|
1601
1892
|
*/
|
|
1602
|
-
public getGeneralData(key: string):
|
|
1603
|
-
return this.generalData.get(key);
|
|
1893
|
+
public getGeneralData<T = GeneralDataRecord>(key: string): T | undefined {
|
|
1894
|
+
return this.generalData.get(key) as T | undefined;
|
|
1604
1895
|
}
|
|
1605
1896
|
|
|
1606
1897
|
/**
|
|
1607
1898
|
* Set general key-value data
|
|
1608
1899
|
* Used for tool-level key-value storage
|
|
1609
1900
|
*/
|
|
1610
|
-
public setGeneralData(key: string, value:
|
|
1901
|
+
public setGeneralData(key: string, value: unknown): void {
|
|
1611
1902
|
this.generalData.set(key, value);
|
|
1612
1903
|
}
|
|
1613
1904
|
|
|
@@ -1857,9 +2148,9 @@ export class MemoryService {
|
|
|
1857
2148
|
`${result.relationshipsExtracted} relationships from memory ${memoryId}`
|
|
1858
2149
|
);
|
|
1859
2150
|
}
|
|
1860
|
-
} catch (error:
|
|
2151
|
+
} catch (error: unknown) {
|
|
1861
2152
|
this.logger.warn(
|
|
1862
|
-
`[MemoryService] Entity extraction failed for memory ${memoryId}: ${error.message}`
|
|
2153
|
+
`[MemoryService] Entity extraction failed for memory ${memoryId}: ${error instanceof Error ? error.message : String(error)}`
|
|
1863
2154
|
);
|
|
1864
2155
|
}
|
|
1865
2156
|
}
|
|
@@ -1907,7 +2198,7 @@ export class MemoryService {
|
|
|
1907
2198
|
* Compare two data objects to determine if they are equal
|
|
1908
2199
|
* Uses deep comparison for objects and arrays
|
|
1909
2200
|
*/
|
|
1910
|
-
private isDataEqual(data1:
|
|
2201
|
+
private isDataEqual(data1: unknown, data2: unknown): boolean {
|
|
1911
2202
|
// Handle null/undefined cases
|
|
1912
2203
|
if (data1 === data2) return true;
|
|
1913
2204
|
if (data1 == null || data2 == null) return false;
|
|
@@ -1926,13 +2217,15 @@ export class MemoryService {
|
|
|
1926
2217
|
// Handle objects
|
|
1927
2218
|
if (Array.isArray(data1) || Array.isArray(data2)) return false;
|
|
1928
2219
|
|
|
1929
|
-
const
|
|
1930
|
-
const
|
|
2220
|
+
const record1 = data1 as Record<string, unknown>;
|
|
2221
|
+
const record2 = data2 as Record<string, unknown>;
|
|
2222
|
+
const keys1 = Object.keys(record1);
|
|
2223
|
+
const keys2 = Object.keys(record2);
|
|
1931
2224
|
|
|
1932
2225
|
if (keys1.length !== keys2.length) return false;
|
|
1933
2226
|
|
|
1934
2227
|
return keys1.every(key =>
|
|
1935
|
-
keys2.includes(key) && this.isDataEqual(
|
|
2228
|
+
keys2.includes(key) && this.isDataEqual(record1[key], record2[key])
|
|
1936
2229
|
);
|
|
1937
2230
|
}
|
|
1938
2231
|
}
|