Skip to content

Add breakpoint feature. #357

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ Task<bool> SendMessage(string agentId,
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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using BotSharp.Abstraction.Repositories;

namespace BotSharp.Core.Conversations.Services;

public partial class ConversationService : IConversationService
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,22 @@ public Task CleanHistory(string agentId)
throw new NotImplementedException();
}

public List<RoleDialogModel> GetDialogHistory(int lastCount = 50)
public List<RoleDialogModel> GetDialogHistory(int lastCount = 50, bool fromBreakpoint = true)
{
if (string.IsNullOrEmpty(_conversationId))
{
throw new ArgumentNullException("ConversationId is null.");
}

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();
Expand Down
63 changes: 20 additions & 43 deletions src/Infrastructure/BotSharp.Core/Repository/BotSharpDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,74 +157,51 @@ public bool DeleteAgentTasks()

#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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,23 @@ public void UpdateConversationTitle(string conversationId, string title)
}
}

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>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ private string GenerateJwtToken(User user)
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())
};

Expand Down
Original file line number Diff line number Diff line change
@@ -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 %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public async Task<IEnumerable<ChatResponseModel>> GetDialogs([FromRoute] string
{
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>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ public void CreateNewConversation(Conversation conversation)
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
Expand Down Expand Up @@ -140,6 +141,18 @@ public void UpdateConversationTitle(string conversationId, string title)
_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();
Expand Down Expand Up @@ -208,7 +221,8 @@ public Conversation GetConversation(string conversationId)
Dialogs = dialogElements,
States = curStates,
CreatedTime = conv.CreatedTime,
UpdatedTime = conv.UpdatedTime
UpdatedTime = conv.UpdatedTime,
Breakpoint = conv.Breakpoint
};
}

Expand Down Expand Up @@ -273,7 +287,8 @@ public PagedItems<Conversation> GetConversations(ConversationFilter filter)
Channel = conv.Channel,
Status = conv.Status,
CreatedTime = conv.CreatedTime,
UpdatedTime = conv.UpdatedTime
UpdatedTime = conv.UpdatedTime,
Breakpoint = conv.Breakpoint
});
}

Expand All @@ -299,7 +314,8 @@ public List<Conversation> GetLastConversations()
Channel = c.Channel,
Status = c.Status,
CreatedTime = c.CreatedTime,
UpdatedTime = c.UpdatedTime
UpdatedTime = c.UpdatedTime,
Breakpoint = c.Breakpoint
}).ToList();
}

Expand Down