diff --git a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj index bbade11e..65424adb 100644 --- a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj +++ b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj @@ -22,6 +22,7 @@ + diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/StateDataType.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/StateDataType.cs new file mode 100644 index 00000000..20d635f4 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/StateDataType.cs @@ -0,0 +1,10 @@ +namespace BotSharp.Abstraction.Conversations.Enums; + +public class StateDataType +{ + public const string String = "string"; + public const string Boolean = "boolean"; + public const string Number = "number"; + public const string Currency = "currency"; + public const string Date = "date"; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/StateSource.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/StateSource.cs new file mode 100644 index 00000000..31f32e16 --- /dev/null +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Enums/StateSource.cs @@ -0,0 +1,8 @@ +namespace BotSharp.Abstraction.Conversations.Enums; + +public class StateSource +{ + public const string External = "external"; + public const string Application = "application"; + public const string User = "user"; +} diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs index 07eab6c1..4b28c1d3 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationStateService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Conversations.Enums; using System.Text.Json; namespace BotSharp.Abstraction.Conversations; @@ -12,7 +13,8 @@ public interface IConversationStateService string GetState(string name, string defaultValue = ""); bool ContainsState(string name); Dictionary GetStates(); - IConversationStateService SetState(string name, T value, bool isNeedVersion = true, int activeRounds = -1); + IConversationStateService SetState(string name, T value, bool isNeedVersion = true, + int activeRounds = -1, string valueType = StateDataType.String, string source = StateSource.User, bool readOnly = false); void SaveStateByArgs(JsonDocument args); void CleanStates(); void Save(); diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateChangeModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateChangeModel.cs index f98a896d..26c10a71 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateChangeModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateChangeModel.cs @@ -22,4 +22,13 @@ public class StateChangeModel [JsonPropertyName("after_active_rounds")] public int? AfterActiveRounds { get; set; } + + [JsonPropertyName("data_type")] + public string DataType { get; set; } + + [JsonPropertyName("source")] + public string Source { get; set; } + + [JsonPropertyName("readonly")] + public bool Readonly { get; set; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateKeyValue.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateKeyValue.cs index 53618242..4afea9da 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateKeyValue.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/StateKeyValue.cs @@ -1,9 +1,12 @@ +using BotSharp.Abstraction.Conversations.Enums; + namespace BotSharp.Abstraction.Conversations.Models; public class StateKeyValue { public string Key { get; set; } public bool Versioning { get; set; } + public bool Readonly { get; set; } public List Values { get; set; } = new List(); public StateKeyValue() @@ -16,6 +19,12 @@ public class StateKeyValue Key = key; Values = values; } + + public override string ToString() + { + var lastValue = Values.LastOrDefault(); + return $"{Key} => ({lastValue?.ToString()})"; + } } public class StateValue @@ -30,6 +39,12 @@ public class StateValue [JsonPropertyName("active_rounds")] public int ActiveRounds { get; set; } + [JsonPropertyName("data_type")] + public string DataType { get; set; } = StateDataType.String; + + [JsonPropertyName("source")] + public string Source { get; set; } + [JsonPropertyName("update_time")] public DateTime UpdateTime { get; set; } @@ -37,4 +52,11 @@ public class StateValue { } + + public override string ToString() + { + var isActive = Active ? "Yes" : "No"; + var activeRounds = ActiveRounds <= 0 ? "infinity" : ActiveRounds.ToString(); + return $"Data: {Data}, Active: {isActive}, Active rounds: {activeRounds}, Source: {Source}"; + } } \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/MessageParser.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/BotSharpMessageParser.cs similarity index 55% rename from src/Infrastructure/BotSharp.Abstraction/Messaging/MessageParser.cs rename to src/Infrastructure/BotSharp.Abstraction/Messaging/BotSharpMessageParser.cs index b739709c..e22150e9 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Messaging/MessageParser.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/BotSharpMessageParser.cs @@ -1,17 +1,19 @@ -using BotSharp.Abstraction.Messaging; using BotSharp.Abstraction.Messaging.Enums; using BotSharp.Abstraction.Messaging.Models.RichContent.Template; using BotSharp.Abstraction.Messaging.Models.RichContent; using System.Text.Json; +using System.Reflection; +using Newtonsoft.Json; -namespace BotSharp.Core.Messaging; +namespace BotSharp.Abstraction.Messaging; -public static class MessageParser +public static class BotSharpMessageParser { - public static IRichMessage? ParseRichMessage(JsonElement root, JsonSerializerOptions options) + public static IRichMessage? ParseRichMessage(JsonElement root) { IRichMessage? res = null; + Type? targetType = null; JsonElement element; var jsonText = root.GetRawText(); @@ -20,47 +22,52 @@ public static class MessageParser var richType = element.GetString(); if (richType == RichTypeEnum.ButtonTemplate) { - res = JsonSerializer.Deserialize(jsonText, options); + targetType = typeof(ButtonTemplateMessage); } else if (richType == RichTypeEnum.MultiSelectTemplate) { - res = JsonSerializer.Deserialize(jsonText, options); + targetType = typeof(MultiSelectTemplateMessage); } else if (richType == RichTypeEnum.QuickReply) { - res = JsonSerializer.Deserialize(jsonText, options); + targetType = typeof(QuickReplyMessage); } else if (richType == RichTypeEnum.CouponTemplate) { - res = JsonSerializer.Deserialize(jsonText, options); + targetType = typeof(CouponTemplateMessage); } else if (richType == RichTypeEnum.Text) { - res = JsonSerializer.Deserialize(jsonText, options); + targetType = typeof(TextMessage); } else if (richType == RichTypeEnum.GenericTemplate) { if (root.TryGetProperty("element_type", out element)) { var elementType = element.GetString(); - if (elementType == typeof(GenericElement).Name) + var wrapperType = typeof(GenericTemplateMessage<>); + var genericType = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(x => x.Name == elementType); + + if (wrapperType != null && genericType != null) { - res = JsonSerializer.Deserialize>(jsonText, options); - } - else if (elementType == typeof(ButtonElement).Name) - { - res = JsonSerializer.Deserialize>(jsonText, options); + targetType = wrapperType.MakeGenericType(genericType); } } } } + if (targetType != null) + { + res = JsonConvert.DeserializeObject(jsonText, targetType) as IRichMessage; + } + return res; } - public static ITemplateMessage? ParseTemplateMessage(JsonElement root, JsonSerializerOptions options) + public static ITemplateMessage? ParseTemplateMessage(JsonElement root) { ITemplateMessage? res = null; + Type? targetType = null; JsonElement element; var jsonText = root.GetRawText(); @@ -69,37 +76,42 @@ public static class MessageParser var templateType = element.GetString(); if (templateType == TemplateTypeEnum.Button) { - res = JsonSerializer.Deserialize(jsonText, options); + targetType = typeof(ButtonTemplateMessage); } else if (templateType == TemplateTypeEnum.MultiSelect) { - res = JsonSerializer.Deserialize(jsonText, options); + targetType = typeof(MultiSelectTemplateMessage); } else if (templateType == TemplateTypeEnum.Coupon) { - res = JsonSerializer.Deserialize(jsonText, options); + targetType = typeof(CouponTemplateMessage); } else if (templateType == TemplateTypeEnum.Product) { - res = JsonSerializer.Deserialize(jsonText, options); + targetType = typeof(ProductTemplateMessage); } else if (templateType == TemplateTypeEnum.Generic) { if (root.TryGetProperty("element_type", out element)) { var elementType = element.GetString(); - if (elementType == typeof(GenericElement).Name) + var wrapperType = typeof(GenericTemplateMessage<>); + var genericType = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(x => x.Name == elementType); + + if (wrapperType != null && genericType != null) { - res = JsonSerializer.Deserialize>(jsonText, options); - } - else if (elementType == typeof(ButtonElement).Name) - { - res = JsonSerializer.Deserialize>(jsonText, options); + targetType = wrapperType.MakeGenericType(genericType); + res = JsonConvert.DeserializeObject(jsonText, targetType) as ITemplateMessage; } } } } + if (targetType != null) + { + res = JsonConvert.DeserializeObject(jsonText, targetType) as ITemplateMessage; + } + return res; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/JsonConverters/RichContentJsonConverter .cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/JsonConverters/RichContentJsonConverter .cs index 502b0785..1748eb5a 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Messaging/JsonConverters/RichContentJsonConverter .cs +++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/JsonConverters/RichContentJsonConverter .cs @@ -1,4 +1,3 @@ -using BotSharp.Core.Messaging; using System.Text.Json; namespace BotSharp.Abstraction.Messaging.JsonConverters; @@ -9,8 +8,7 @@ public class RichContentJsonConverter : JsonConverter { using var jsonDoc = JsonDocument.ParseValue(ref reader); var root = jsonDoc.RootElement; - var jsonText = root.GetRawText(); - var res = MessageParser.ParseRichMessage(root, options); + var res = BotSharpMessageParser.ParseRichMessage(root); return res; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/JsonConverters/TemplateMessageJsonConverter.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/JsonConverters/TemplateMessageJsonConverter.cs index f0f14730..ce42c489 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Messaging/JsonConverters/TemplateMessageJsonConverter.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/JsonConverters/TemplateMessageJsonConverter.cs @@ -1,4 +1,3 @@ -using BotSharp.Core.Messaging; using System.Text.Json; namespace BotSharp.Abstraction.Messaging.JsonConverters; @@ -9,8 +8,7 @@ public class TemplateMessageJsonConverter : JsonConverter { using var jsonDoc = JsonDocument.ParseValue(ref reader); var root = jsonDoc.RootElement; - var jsonText = root.GetRawText(); - var res = MessageParser.ParseTemplateMessage(root, options); + var res = BotSharpMessageParser.ParseTemplateMessage(root); return res; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/ElementButton.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/ElementButton.cs index b3642194..bc13660a 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/ElementButton.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/ElementButton.cs @@ -5,13 +5,19 @@ namespace BotSharp.Abstraction.Messaging.Models.RichContent; /// public class ElementButton { - public string Type { get; set; } + public string Type { get; set; } = "web_url"; [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string Url { get; set; } - public string Title { get; set; } + public string Title { get; set; } = string.Empty; [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string Payload { get; set; } + + [JsonPropertyName("is_primary")] + public bool IsPrimary { get; set; } + + [JsonPropertyName("is_secondary")] + public bool IsSecondary { get; set; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplateMessage.cs b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplateMessage.cs index 4c92a3fb..32ad73e2 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplateMessage.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Messaging/Models/RichContent/Template/ButtonTemplateMessage.cs @@ -17,27 +17,8 @@ public class ButtonTemplateMessage : IRichMessage, ITemplateMessage public string TemplateType => TemplateTypeEnum.Button; [JsonPropertyName("buttons")] - public ButtonElement[] Buttons { get; set; } = new ButtonElement[0]; + public ElementButton[] Buttons { get; set; } = new ElementButton[0]; [JsonPropertyName("is_horizontal")] public bool IsHorizontal { get; set; } } - -public class ButtonElement -{ - /// - /// web_url, postback, phone_number - /// - public string Type { get; set; } = "web_url"; - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Url { get; set; } - - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? Payload { get; set; } - - public string Title { get; set; } = string.Empty; - - [JsonPropertyName("is_primary")] - public bool IsPrimary { get; set; } -} diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs index 8b3bb0fc..188715d4 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Models; namespace BotSharp.Core.Conversations.Services; @@ -126,6 +127,6 @@ public partial class ConversationService : IConversationService { _conversationId = conversationId; _state.Load(_conversationId); - states.ForEach(x => _state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds)); + states.ForEach(x => _state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External)); } } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs index 9356e2f5..b87a8fd7 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStateService.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.Users.Enums; namespace BotSharp.Core.Conversations.Services; @@ -33,7 +34,8 @@ public class ConversationStateService : IConversationStateService, IDisposable /// /// whether the state is related to message or not /// - public IConversationStateService SetState(string name, T value, bool isNeedVersion = true, int activeRounds = -1) + public IConversationStateService SetState(string name, T value, bool isNeedVersion = true, + int activeRounds = -1, string valueType = StateDataType.String, string source = StateSource.User, bool readOnly = false) { if (value == null) { @@ -56,24 +58,31 @@ public class ConversationStateService : IConversationStateService, IDisposable _logger.LogInformation($"[STATE] {name} = {value}"); var routingCtx = _services.GetRequiredService(); - foreach (var hook in hooks) + if (!ContainsState(name) || preValue != currentValue || preActiveRounds != curActiveRounds) { - hook.OnStateChanged(new StateChangeModel + foreach (var hook in hooks) { - ConversationId = _conversationId, - MessageId = routingCtx.MessageId, - Name = name, - BeforeValue = preValue, - BeforeActiveRounds = preActiveRounds, - AfterValue = currentValue, - AfterActiveRounds = curActiveRounds - }).Wait(); + hook.OnStateChanged(new StateChangeModel + { + ConversationId = _conversationId, + MessageId = routingCtx.MessageId, + Name = name, + BeforeValue = preValue, + BeforeActiveRounds = preActiveRounds, + AfterValue = currentValue, + AfterActiveRounds = curActiveRounds, + DataType = valueType, + Source = source, + Readonly = readOnly + }).Wait(); + } } var newPair = new StateKeyValue { Key = name, - Versioning = isNeedVersion + Versioning = isNeedVersion, + Readonly = readOnly }; var newValue = new StateValue @@ -82,6 +91,8 @@ public class ConversationStateService : IConversationStateService, IDisposable MessageId = routingCtx.MessageId, Active = true, ActiveRounds = curActiveRounds, + DataType = valueType, + Source = source, UpdateTime = DateTime.UtcNow, }; @@ -132,6 +143,8 @@ public class ConversationStateService : IConversationStateService, IDisposable MessageId = curMsgId, Active = false, ActiveRounds = value.ActiveRounds, + DataType = value.DataType, + Source = value.Source, UpdateTime = DateTime.UtcNow }); continue; @@ -192,6 +205,8 @@ public class ConversationStateService : IConversationStateService, IDisposable MessageId = curMsgId, Active = false, ActiveRounds = lastValue.ActiveRounds, + DataType = lastValue.DataType, + Source = lastValue.Source, UpdateTime = utcNow }); } @@ -246,7 +261,7 @@ public class ConversationStateService : IConversationStateService, IDisposable { if (!string.IsNullOrEmpty(property.Value.ToString())) { - SetState(property.Name, property.Value); + SetState(property.Name, property.Value, source: StateSource.Application); } } } diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs index 1ee38e2e..ca230ff3 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/TokenStatistics.cs @@ -1,3 +1,4 @@ +using BotSharp.Abstraction.Conversations.Enums; using BotSharp.Abstraction.MLTasks; using System.Diagnostics; using System.Drawing; @@ -47,14 +48,14 @@ public class TokenStatistics : ITokenStatistics // Accumulated Token var stat = _services.GetRequiredService(); var inputCount = int.Parse(stat.GetState("prompt_total", "0")); - stat.SetState("prompt_total", stats.PromptCount + inputCount, false); + stat.SetState("prompt_total", stats.PromptCount + inputCount, isNeedVersion: false, source: StateSource.Application); var outputCount = int.Parse(stat.GetState("completion_total", "0")); - stat.SetState("completion_total", stats.CompletionCount + outputCount, false); + stat.SetState("completion_total", stats.CompletionCount + outputCount, isNeedVersion: false, source: StateSource.Application); // Total cost var total_cost = float.Parse(stat.GetState("llm_total_cost", "0")); total_cost += Cost; - stat.SetState("llm_total_cost", total_cost, false); + stat.SetState("llm_total_cost", total_cost, isNeedVersion: false, source: StateSource.Application); } public void PrintStatistics() diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs index daf2b116..e01a0f46 100644 --- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs +++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/ConversationController.cs @@ -1,5 +1,4 @@ using BotSharp.Abstraction.Routing; -using BotSharp.Abstraction.Users.Models; namespace BotSharp.OpenAPI.Controllers; @@ -166,11 +165,11 @@ public class ConversationController : ControllerBase routing.Context.SetMessageId(conversationId, inputMsg.MessageId); conv.SetConversationId(conversationId, input.States); - conv.States.SetState("channel", input.Channel) - .SetState("provider", input.Provider) - .SetState("model", input.Model) - .SetState("temperature", input.Temperature) - .SetState("sampling_factor", input.SamplingFactor); + conv.States.SetState("channel", input.Channel, source: StateSource.External) + .SetState("provider", input.Provider, source: StateSource.External) + .SetState("model", input.Model, source: StateSource.External) + .SetState("temperature", input.Temperature, source: StateSource.External) + .SetState("sampling_factor", input.SamplingFactor, source: StateSource.External); var response = new ChatResponseModel(); diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs index 2162bcb9..2e2ed3d6 100644 --- a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs +++ b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs @@ -436,6 +436,9 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR BeforeActiveRounds = stateChange.BeforeActiveRounds, AfterValue = stateChange.AfterValue, AfterActiveRounds = stateChange.AfterActiveRounds, + DataType = stateChange.DataType, + Source = stateChange.Source, + Readonly = stateChange.Readonly, CreateTime = DateTime.UtcNow }; diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/StateMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/StateMongoElement.cs index b56483e1..a939f59c 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/StateMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/StateMongoElement.cs @@ -6,6 +6,7 @@ public class StateMongoElement { public string Key { get; set; } public bool Versioning { get; set; } + public bool Readonly { get; set; } public List Values { get; set; } public static StateMongoElement ToMongoElement(StateKeyValue state) @@ -14,6 +15,7 @@ public class StateMongoElement { Key = state.Key, Versioning = state.Versioning, + Readonly = state.Readonly, Values = state.Values?.Select(x => StateValueMongoElement.ToMongoElement(x))?.ToList() ?? new List() }; } @@ -24,6 +26,7 @@ public class StateMongoElement { Key = state.Key, Versioning = state.Versioning, + Readonly = state.Readonly, Values = state.Values?.Select(x => StateValueMongoElement.ToDomainElement(x))?.ToList() ?? new List() }; } @@ -35,6 +38,9 @@ public class StateValueMongoElement public string? MessageId { get; set; } public bool Active { get; set; } public int ActiveRounds { get; set; } + public string DataType { get; set; } + public string Source { get; set; } + public DateTime UpdateTime { get; set; } public static StateValueMongoElement ToMongoElement(StateValue element) @@ -45,6 +51,8 @@ public class StateValueMongoElement MessageId = element.MessageId, Active = element.Active, ActiveRounds = element.ActiveRounds, + DataType = element.DataType, + Source = element.Source, UpdateTime = element.UpdateTime }; } @@ -57,6 +65,8 @@ public class StateValueMongoElement MessageId = element.MessageId, Active = element.Active, ActiveRounds = element.ActiveRounds, + DataType= element.DataType, + Source = element.Source, UpdateTime = element.UpdateTime }; }