Merge pull request #357 from hchen2020/master

Add breakpoint feature.
This commit is contained in:
C. Oceania 2024-03-23 20:37:14 -05:00 committed by GitHub
commit 52eb65ffd3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 97 additions and 57 deletions

View file

@ -35,6 +35,12 @@ public interface IConversationService
Func<RoleDialogModel, Task> onFunctionExecuting,
Func<RoleDialogModel, Task> onFunctionExecuted);
List<RoleDialogModel> GetDialogHistory(int lastCount = 50);
List<RoleDialogModel> GetDialogHistory(int lastCount = 50, bool fromBreakpoint = true);
Task CleanHistory(string agentId);
/// <summary>
/// Use this feature when you want to hide some context from LLM.
/// </summary>
/// <returns></returns>
Task UpdateBreakpoint();
}

View file

@ -26,6 +26,12 @@ public class Conversation
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
/// <summary>
/// The default value will be same as CreatedTime
/// It used to insert a breakpoint in the conversation to hide the previous dialogs.
/// </summary>
public DateTime Breakpoint { get; set; } = DateTime.UtcNow.AddMilliseconds(-100);
}
public class DialogElement

View file

@ -58,6 +58,7 @@ public interface IBotSharpRepository
Conversation GetConversation(string conversationId);
PagedItems<Conversation> GetConversations(ConversationFilter filter);
void UpdateConversationTitle(string conversationId, string title);
void UpdateConversationBreakpoint(string conversationId, DateTime breakpoint);
List<Conversation> GetLastConversations();
List<string> GetIdleConversations(int batchSize, int messageLimit, int bufferHours);
bool TruncateConversation(string conversationId, string messageId, bool cleanLog = false);

View file

@ -1,5 +1,3 @@
using BotSharp.Abstraction.Repositories;
namespace BotSharp.Core.Conversations.Services;
public partial class ConversationService : IConversationService

View file

@ -0,0 +1,10 @@
namespace BotSharp.Core.Conversations.Services;
public partial class ConversationService : IConversationService
{
public async Task UpdateBreakpoint()
{
var db = _services.GetRequiredService<IBotSharpRepository>();
db.UpdateConversationBreakpoint(_conversationId, DateTime.UtcNow);
}
}

View file

@ -99,7 +99,7 @@ public partial class ConversationService : IConversationService
throw new NotImplementedException();
}
public List<RoleDialogModel> GetDialogHistory(int lastCount = 50)
public List<RoleDialogModel> GetDialogHistory(int lastCount = 50, bool fromBreakpoint = true)
{
if (string.IsNullOrEmpty(_conversationId))
{
@ -107,6 +107,14 @@ public partial class ConversationService : IConversationService
}
var dialogs = _storage.GetDialogs(_conversationId);
if (fromBreakpoint)
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var conversation = db.GetConversation(_conversationId);
dialogs = dialogs.Where(x => x.CreatedAt >= conversation.Breakpoint).ToList();
}
return dialogs
.TakeLast(lastCount)
.ToList();

View file

@ -157,74 +157,51 @@ public class BotSharpDbContext : Database, IBotSharpRepository
#region Conversation
public void CreateNewConversation(Conversation conversation)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public bool DeleteConversations(IEnumerable<string> conversationIds)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public Conversation GetConversation(string conversationId)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public PagedItems<Conversation> GetConversations(ConversationFilter filter)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public List<Conversation> GetLastConversations()
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public List<string> GetIdleConversations(int batchSize, int messageLimit, int bufferHours)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public List<DialogElement> GetConversationDialogs(string conversationId)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public void UpdateConversationDialogElements(string conversationId, List<DialogContentUpdateModel> updateElements)
{
throw new NotImplementedException();
}
=> new NotImplementedException();
public ConversationState GetConversationStates(string conversationId)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs)
{
throw new NotImplementedException();
}
=> new NotImplementedException();
public void UpdateConversationTitle(string conversationId, string title)
{
throw new NotImplementedException();
}
=> new NotImplementedException();
public void UpdateConversationBreakpoint(string conversationId, DateTime breakpoint)
=> new NotImplementedException();
public void UpdateConversationStates(string conversationId, List<StateKeyValue> states)
{
throw new NotImplementedException();
}
=> new NotImplementedException();
public void UpdateConversationStatus(string conversationId, string status)
{
throw new NotImplementedException();
}
=> new NotImplementedException();
public bool TruncateConversation(string conversationId, string messageId, bool cleanLog = false)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
#endregion
#region User
public User? GetUserByEmail(string email)
=> throw new NotImplementedException();

View file

@ -141,6 +141,23 @@ namespace BotSharp.Core.Repository
}
}
public void UpdateConversationBreakpoint(string conversationId, DateTime breakpoint)
{
var convDir = FindConversationDirectory(conversationId);
if (!string.IsNullOrEmpty(convDir))
{
var convFile = Path.Combine(convDir, CONVERSATION_FILE);
var content = File.ReadAllText(convFile);
var record = JsonSerializer.Deserialize<Conversation>(content, _options);
if (record != null)
{
record.UpdatedTime = DateTime.UtcNow;
record.Breakpoint = breakpoint;
File.WriteAllText(convFile, JsonSerializer.Serialize(record, _options));
}
}
}
public ConversationState GetConversationStates(string conversationId)
{
var states = new List<StateKeyValue>();

View file

@ -146,10 +146,10 @@ public class UserService : IUserService
new Claim(JwtRegisteredClaimNames.NameId, user.Id),
new Claim(JwtRegisteredClaimNames.UniqueName, user.UserName),
new Claim(JwtRegisteredClaimNames.Email, user.Email),
new Claim(JwtRegisteredClaimNames.GivenName, user.FirstName),
new Claim(JwtRegisteredClaimNames.FamilyName, user.LastName),
new Claim(JwtRegisteredClaimNames.GivenName, user?.FirstName ?? string.Empty),
new Claim(JwtRegisteredClaimNames.FamilyName, user?.LastName ?? string.Empty),
new Claim("source", user.Source),
new Claim("external_id", user.ExternalId??string.Empty),
new Claim("external_id", user.ExternalId ?? string.Empty),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};

View file

@ -1,5 +1,5 @@
What is the next step based on the CONVERSATION?
Route to the appropriate agent last handled agent based on the context.
Route to the last handling agent in priority.
{% if expected_next_action_agent != empty -%}
Expected next action agent is {{ expected_next_action_agent }}.
{%- endif %}

View file

@ -66,7 +66,7 @@ public class ConversationController : ControllerBase
{
var conv = _services.GetRequiredService<IConversationService>();
conv.SetConversationId(conversationId, new List<string>());
var history = conv.GetDialogHistory();
var history = conv.GetDialogHistory(fromBreakpoint: false);
var userService = _services.GetRequiredService<IUserService>();
var agentService = _services.GetRequiredService<IAgentService>();

View file

@ -10,4 +10,5 @@ public class ConversationDocument : MongoBase
public string Status { get; set; }
public DateTime CreatedTime { get; set; }
public DateTime UpdatedTime { get; set; }
public DateTime Breakpoint { get; set; }
}

View file

@ -22,8 +22,9 @@ public partial class MongoRepository
Channel = conversation.Channel,
TaskId = conversation.TaskId,
Status = conversation.Status,
CreatedTime = DateTime.UtcNow,
UpdatedTime = DateTime.UtcNow,
CreatedTime = conversation.CreatedTime,
UpdatedTime = conversation.UpdatedTime,
Breakpoint = conversation.Breakpoint,
};
var dialogDoc = new ConversationDialogDocument
@ -140,6 +141,18 @@ public partial class MongoRepository
_dc.Conversations.UpdateOne(filterConv, updateConv);
}
public void UpdateConversationBreakpoint(string conversationId, DateTime breakpoint)
{
if (string.IsNullOrEmpty(conversationId)) return;
var filterConv = Builders<ConversationDocument>.Filter.Eq(x => x.Id, conversationId);
var updateConv = Builders<ConversationDocument>.Update
.Set(x => x.UpdatedTime, DateTime.UtcNow)
.Set(x => x.Breakpoint, breakpoint);
_dc.Conversations.UpdateOne(filterConv, updateConv);
}
public ConversationState GetConversationStates(string conversationId)
{
var states = new ConversationState();
@ -208,7 +221,8 @@ public partial class MongoRepository
Dialogs = dialogElements,
States = curStates,
CreatedTime = conv.CreatedTime,
UpdatedTime = conv.UpdatedTime
UpdatedTime = conv.UpdatedTime,
Breakpoint = conv.Breakpoint
};
}
@ -273,7 +287,8 @@ public partial class MongoRepository
Channel = conv.Channel,
Status = conv.Status,
CreatedTime = conv.CreatedTime,
UpdatedTime = conv.UpdatedTime
UpdatedTime = conv.UpdatedTime,
Breakpoint = conv.Breakpoint
});
}
@ -299,7 +314,8 @@ public partial class MongoRepository
Channel = c.Channel,
Status = c.Status,
CreatedTime = c.CreatedTime,
UpdatedTime = c.UpdatedTime
UpdatedTime = c.UpdatedTime,
Breakpoint = c.Breakpoint
}).ToList();
}