refine message states

This commit is contained in:
Jicheng Lu 2025-07-14 12:40:59 -05:00
parent ea54988ec4
commit a453009394
5 changed files with 38 additions and 26 deletions

View file

@ -8,20 +8,24 @@ public class MessageState
[JsonPropertyName("active_rounds")]
public int ActiveRounds { get; set; } = -1;
[JsonPropertyName("global")]
public bool Global { get; set; }
public MessageState()
{
}
public MessageState(string key, object value, int activeRounds = -1)
public MessageState(string key, object value, int activeRounds = -1, bool global = false)
{
Key = key;
Value = value;
ActiveRounds = activeRounds;
Global = global;
}
public override string ToString()
{
return $"Key: {Key} => Value: {Value}, ActiveRounds: {ActiveRounds}";
return $"Key: {Key} => Value: {Value}, ActiveRounds: {ActiveRounds}, Global: {Global}";
}
}

View file

@ -178,7 +178,7 @@ public partial class ConversationService : IConversationService
{
_conversationId = conversationId;
_state.Load(_conversationId, isReadOnly);
states.ForEach(x => _state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, source: StateSource.External));
states.ForEach(x => _state.SetState(x.Key, x.Value, activeRounds: x.ActiveRounds, isNeedVersion: !x.Global, source: StateSource.External));
}
public async Task<Conversation> GetConversationRecordOrCreateNew(string agentId)

View file

@ -1,9 +1,6 @@
using BotSharp.Abstraction.Agents.Enums;
using BotSharp.Abstraction.Conversations.Enums;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Statistics.Enums;
using BotSharp.Abstraction.Statistics.Models;
using BotSharp.Abstraction.Statistics.Services;
using BotSharp.Abstraction.Users;
namespace BotSharp.Logger.Hooks;

View file

@ -166,16 +166,16 @@ public class TwilioInboundController : TwilioController
var states = new List<MessageState>
{
new("channel", ConversationChannel.Phone),
new("calling_phone", request.From),
new("phone_direction", request.Direction),
new("twilio_call_sid", request.CallSid),
new("channel", ConversationChannel.Phone, global: true),
new("calling_phone", request.From, global: true),
new("phone_direction", request.Direction, global: true),
new("twilio_call_sid", request.CallSid, global: true),
};
if (request.Direction == "inbound")
{
states.Add(new MessageState("calling_phone_from", request.From));
states.Add(new MessageState("calling_phone_to", request.To));
states.Add(new MessageState("calling_phone_from", request.From, global: true));
states.Add(new MessageState("calling_phone_to", request.To, global: true));
}
var requestStates = ParseStates(request.States);

View file

@ -9,6 +9,7 @@ using BotSharp.Plugin.Twilio.Interfaces;
using BotSharp.Plugin.Twilio.Models;
using BotSharp.Plugin.Twilio.OutboundPhoneCallHandler.LlmContexts;
using Twilio.Rest.Api.V2010.Account;
using Twilio.TwiML.Messaging;
using Twilio.Types;
using Conversation = BotSharp.Abstraction.Conversations.Models.Conversation;
using Task = System.Threading.Tasks.Task;
@ -176,7 +177,7 @@ public class OutboundPhoneCallFn : IFunctionCallback
});
var utcNow = DateTime.UtcNow;
var excludStates = new List<string>
var excludeStates = new List<string>
{
"provider",
"model",
@ -185,22 +186,34 @@ public class OutboundPhoneCallFn : IFunctionCallback
"llm_total_cost"
};
var curStates = state.GetStates().Select(x => new MessageState(x.Key, x.Value)).ToList();
var curConvStates = state.GetStates().Select(x => new MessageState(x.Key, x.Value)).ToList();
var subConvStates = new List<MessageState>
{
new(StateConst.ORIGIN_CONVERSATION_ID, originConversationId),
new("channel", "phone"),
new("phone_from", call.From),
new("phone_direction", call.Direction),
new("phone_number", call.To),
new("twilio_call_sid", call.Sid)
new(StateConst.ORIGIN_CONVERSATION_ID, originConversationId, global: true),
new("channel", "phone", global: true),
new("phone_from", call.From, global: true),
new("phone_direction", call.Direction, global: true),
new("phone_number", call.To, global: true),
new("twilio_call_sid", call.Sid, global: true)
};
var subStateKeys = subConvStates.Select(x => x.Key).ToList();
var included = curStates.Where(x => !subStateKeys.Contains(x.Key) && !excludStates.Contains(x.Key));
var newStates = subConvStates.Concat(included).Select(x => new StateKeyValue
var included = curConvStates.Where(x => !subStateKeys.Contains(x.Key) && !excludeStates.Contains(x.Key));
var mappedCurConvStates = MapStates(included, messageId, utcNow);
var mappedSubConvStates = MapStates(subConvStates, messageId, utcNow);
var totalStates = mappedCurConvStates.Concat(mappedSubConvStates).ToList();
db.UpdateConversationStates(newConversationId, totalStates);
}
private IEnumerable<StateKeyValue> MapStates(IEnumerable<MessageState> states, string messageId, DateTime updateTime)
{
if (states.IsNullOrEmpty()) return [];
return states.Select(x => new StateKeyValue
{
Key = x.Key,
Versioning = true,
Versioning = !x.Global,
Values = [
new StateValue
{
@ -209,11 +222,9 @@ public class OutboundPhoneCallFn : IFunctionCallback
Active = true,
ActiveRounds = x.ActiveRounds,
Source = StateSource.Application,
UpdateTime = utcNow
UpdateTime = updateTime
}
]
}).ToList();
db.UpdateConversationStates(newConversationId, newStates);
}
}