diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs index 5f0489ac..ad79ddcf 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs @@ -73,4 +73,7 @@ public abstract class ConversationHookBase : IConversationHook public virtual Task OnMessageDeleted(string conversationId, string messageId) => Task.CompletedTask; + + public virtual Task OnBreakpointUpdated(string conversationId, bool resetStates) + => Task.CompletedTask; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs index 7d943754..4d922d87 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs @@ -93,4 +93,11 @@ public interface IConversationHook /// /// Task OnMessageDeleted(string conversationId, string messageId); + + /// + /// Brakpoint updated + /// + /// + /// + Task OnBreakpointUpdated(string conversationId, bool resetStates); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs index 0fb164c6..7091f042 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationService.cs @@ -41,6 +41,7 @@ public interface IConversationService /// /// Use this feature when you want to hide some context from LLM. /// + /// Whether to reset all states /// - Task UpdateBreakpoint(); + Task UpdateBreakpoint(bool resetStates = false); } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs index d4e88991..61c9d6c8 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs @@ -14,6 +14,6 @@ public interface IConversationStateService Dictionary GetStates(); IConversationStateService SetState(string name, T value, bool isNeedVersion = true); void SaveStateByArgs(JsonDocument args); - void CleanState(); + void CleanStates(); void Save(); } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.UpdateBreakpoint.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.UpdateBreakpoint.cs index b4a4671c..6aa2f86f 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.UpdateBreakpoint.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.UpdateBreakpoint.cs @@ -2,9 +2,26 @@ namespace BotSharp.Core.Conversations.Services; public partial class ConversationService : IConversationService { - public async Task UpdateBreakpoint() + public async Task UpdateBreakpoint(bool resetStates = false) { var db = _services.GetRequiredService(); db.UpdateConversationBreakpoint(_conversationId, DateTime.UtcNow); + + // Reset states + if (resetStates) + { + var states = _services.GetRequiredService(); + states.CleanStates(); + } + + var hooks = _services.GetServices() + .OrderBy(x => x.Priority) + .ToList(); + + // Before executing functions + foreach (var hook in hooks) + { + await hook.OnBreakpointUpdated(_conversationId, resetStates); + } } } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs index 069d3598..995b8fae 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs @@ -119,7 +119,7 @@ public class ConversationStateService : IConversationStateService, IDisposable _logger.LogInformation($"Saved states of conversation {_conversationId}"); } - public void CleanState() + public void CleanStates() { _states.Clear(); } diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs index 757b31a3..6d342e98 100644 --- a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs +++ b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs @@ -187,6 +187,27 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated", BuildContentLog(input)); } + public override async Task OnBreakpointUpdated(string conversationId, bool resetStates) + { + var log = $"Conversation breakpoint is updated"; + if (resetStates) + { + log += ", states are reset"; + } + var routing = _services.GetRequiredService(); + var agentId = routing.Context.ConversationId; + var agent = await _agentService.LoadAgent(agentId); + + var input = new ContentLogInputModel() + { + Name = agent.Name, + ConversationId = conversationId, + Source = ContentLogSource.FunctionCall, + Log = log + }; + await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated", BuildContentLog(input)); + } + #endregion #region IRoutingHook