diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs index ad79ddcf..36f065fd 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs @@ -29,7 +29,7 @@ public abstract class ConversationHookBase : IConversationHook public virtual Task OnStateLoaded(ConversationState state) => Task.CompletedTask; - public virtual Task OnStateChanged(string name, string preValue, string currentValue) + public virtual Task OnStateChanged(StateChangeModel stateChange) => Task.CompletedTask; public virtual Task OnDialogRecordLoaded(RoleDialogModel dialog) diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs index 4d922d87..b9f0f3b8 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs @@ -43,7 +43,7 @@ public interface IConversationHook Task OnDialogRecordLoaded(RoleDialogModel dialog); Task OnStateLoaded(ConversationState state); - Task OnStateChanged(string name, string preValue, string currentValue); + Task OnStateChanged(StateChangeModel stateChange); Task OnMessageReceived(RoleDialogModel message); Task OnPostbackMessageReceived(RoleDialogModel message, PostbackMessageModel replyMsg); diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateChangeModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateChangeModel.cs new file mode 100644 index 00000000..c342881f --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateChangeModel.cs @@ -0,0 +1,19 @@ +namespace BotSharp.Abstraction.Conversations.Models; + +public class StateChangeModel +{ + [JsonPropertyName("conversation_id")] + public string ConversationId { get; set; } + + [JsonPropertyName("message_id")] + public string MessageId { get; set; } + + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("before_value")] + public string BeforeValue { get; set; } + + [JsonPropertyName("after_value")] + public string AfterValue { get; set; } +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/StateChangeOutputModel.cs b/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/StateChangeOutputModel.cs new file mode 100644 index 00000000..c166bbef --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Loggers/Models/StateChangeOutputModel.cs @@ -0,0 +1,7 @@ +namespace BotSharp.Abstraction.Loggers.Models; + +public class StateChangeOutputModel : StateChangeModel +{ + [JsonPropertyName("created_at")] + public DateTime CreateTime { get; set; } = DateTime.UtcNow; +} diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs index ee2481bf..a52d934e 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs @@ -52,12 +52,20 @@ public class ConversationStateService : IConversationStateService, IDisposable if (!ContainsState(name) || preValue != currentValue) { _logger.LogInformation($"[STATE] {name} = {value}"); + var routingCtx = _services.GetRequiredService(); + foreach (var hook in hooks) { - hook.OnStateChanged(name, preValue, currentValue).Wait(); + hook.OnStateChanged(new StateChangeModel + { + ConversationId = _conversationId, + MessageId = routingCtx.MessageId, + Name = name, + BeforeValue = preValue, + AfterValue = currentValue + }).Wait(); } - - var routingCtx = _services.GetRequiredService(); + var newPair = new StateKeyValue { Key = name, diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs index 1f58faa0..e93026c3 100644 --- a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs +++ b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs @@ -213,6 +213,12 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated", BuildContentLog(input)); } + public override async Task OnStateChanged(StateChangeModel stateChange) + { + if (stateChange == null) return; + + await _chatHub.Clients.User(_user.Id).SendAsync("OnStateChangeGenerated", BuildStateChangeLog(stateChange)); + } #endregion #region IRoutingHook @@ -379,4 +385,19 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR return JsonSerializer.Serialize(log, _options.JsonSerializerOptions); } + + private string BuildStateChangeLog(StateChangeModel stateChange) + { + var log = new StateChangeOutputModel + { + ConversationId = stateChange.ConversationId, + MessageId = stateChange.MessageId, + Name = stateChange.Name, + BeforeValue = stateChange.BeforeValue, + AfterValue = stateChange.AfterValue, + CreateTime = DateTime.UtcNow + }; + + return JsonSerializer.Serialize(log, _options.JsonSerializerOptions); + } }