Skip to content
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 @@ -2,7 +2,6 @@ namespace BotSharp.Abstraction.Conversations.Models;

public class LlmCompletionLog
{
public string Id { get; set; } = string.Empty;
public string ConversationId { get; set; } = string.Empty;
public string MessageId { get; set; } = string.Empty;
public string AgentId { get; set; } = string.Empty;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Repositories.Models;
using BotSharp.Abstraction.Users.Models;

namespace BotSharp.Abstraction.Repositories;
Expand Down Expand Up @@ -30,6 +31,7 @@ public interface IBotSharpRepository
void CreateNewConversation(Conversation conversation);
bool DeleteConversation(string conversationId);
List<DialogElement> GetConversationDialogs(string conversationId);
void UpdateConversationDialogElements(string conversationId, List<DialogContentUpdateModel> updateElements);
void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs);
List<StateKeyValue> GetConversationStates(string conversationId);
void UpdateConversationStates(string conversationId, List<StateKeyValue> states);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace BotSharp.Abstraction.Repositories.Models
{
public class DialogContentUpdateModel
{
public int Index { get; set; }
public string UpdateContent { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ public static string RemoveNewLine(this string input)
return input.Replace("\r", " ").Replace("\n", " ").Trim();
}

public static bool IsEqualTo(this string str1, string str2, StringComparison option = StringComparison.OrdinalIgnoreCase)
public static bool IsEqualTo(this string? str1, string? str2, StringComparison option = StringComparison.OrdinalIgnoreCase)
{
if (str1 == null) return str2 == null;

return str1.Equals(str2, option);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Repositories.Models;
using BotSharp.Abstraction.Users.Models;
using Microsoft.EntityFrameworkCore.Infrastructure;

Expand Down Expand Up @@ -146,6 +147,11 @@ public List<DialogElement> GetConversationDialogs(string conversationId)
throw new NotImplementedException();
}

public void UpdateConversationDialogElements(string conversationId, List<DialogContentUpdateModel> updateElements)
{
throw new NotImplementedException();
}

public List<StateKeyValue> GetConversationStates(string conversationId)
{
throw new NotImplementedException();
Expand Down
42 changes: 39 additions & 3 deletions src/Infrastructure/BotSharp.Core/Repository/FileRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
using MongoDB.Driver;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Utilities;
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Repositories.Models;

namespace BotSharp.Core.Repository;

Expand Down Expand Up @@ -650,6 +653,33 @@ public List<DialogElement> GetConversationDialogs(string conversationId)
return dialogs;
}

public void UpdateConversationDialogElements(string conversationId, List<DialogContentUpdateModel> updateElements)
{
var dialogElements = GetConversationDialogs(conversationId);
if (dialogElements.IsNullOrEmpty() || updateElements.IsNullOrEmpty()) return;

var convDir = FindConversationDirectory(conversationId);
if (!string.IsNullOrEmpty(convDir))
{
var dialogDir = Path.Combine(convDir, "dialogs.txt");
if (File.Exists(dialogDir))
{
var updated = dialogElements.Select((x, idx) =>
{
var found = updateElements.FirstOrDefault(e => e.Index == idx);
if (found != null)
{
x.Content = found.UpdateContent;
}
return x;
}).ToList();

var texts = ParseDialogElements(updated);
File.WriteAllLines(dialogDir, texts);
}
}
}

public void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs)
{
var convDir = FindConversationDirectory(conversationId);
Expand Down Expand Up @@ -860,18 +890,24 @@ public List<string> GetExecutionLogs(string conversationId)
#region LLM Completion Log
public void SaveLlmCompletionLog(LlmCompletionLog log)
{
if (log == null || string.IsNullOrEmpty(log.ConversationId)) return;
if (log == null) return;

log.ConversationId = log.ConversationId.IfNullOrEmptyAs(Guid.NewGuid().ToString());
log.MessageId = log.MessageId.IfNullOrEmptyAs(Guid.NewGuid().ToString());

var convDir = FindConversationDirectory(log.ConversationId);
if (string.IsNullOrEmpty(convDir)) return;
if (string.IsNullOrEmpty(convDir))
{
convDir = Path.Combine(_dbSettings.FileRepository, _conversationSettings.DataDir, log.ConversationId);
Directory.CreateDirectory(convDir);
}

var logDir = Path.Combine(convDir, "llm_prompt_log");
if (!Directory.Exists(logDir))
{
Directory.CreateDirectory(logDir);
}

log.Id = Guid.NewGuid().ToString();
var index = GetNextLlmCompletionLogIndex(logDir, log.MessageId);
var file = Path.Combine(logDir, $"{log.MessageId}.{index}.log");
File.WriteAllText(file, JsonSerializer.Serialize(log, _options));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using BotSharp.Plugin.MongoStorage.Models;

namespace BotSharp.Plugin.MongoStorage.Collections;

public class LlmCompletionLogDocument : MongoBase
{
public string ConversationId { get; set; }
public string MessageId { get; set; }
public string AgentId { get; set; }
public string Prompt { get; set; }
public string? Response { get; set; }
public DateTime CreateDateTime { get; set; }
public List<PromptLogElement> Logs { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace BotSharp.Plugin.MongoStorage.Models;

public class PromptLogElement
{
public string MessageId { get; set; }
public string AgentId { get; set; }
public string Prompt { get; set; }
public string? Response { get; set; }
public DateTime CreateDateTime { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Repositories.Models;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Users.Models;
using BotSharp.Plugin.MongoStorage.Collections;
Expand Down Expand Up @@ -635,7 +636,8 @@ public bool DeleteConversation(string conversationId)
var promptLogDeleted = _dc.LlmCompletionLogs.DeleteMany(filterPromptLog);
var dialogDeleted = _dc.ConversationDialogs.DeleteMany(filterDialog);
var convDeleted = _dc.Conversations.DeleteMany(filterConv);
return convDeleted.DeletedCount > 0 || dialogDeleted.DeletedCount > 0;
return convDeleted.DeletedCount > 0 || dialogDeleted.DeletedCount > 0
|| exeLogDeleted.DeletedCount > 0 || promptLogDeleted.DeletedCount > 0;
}

public List<DialogElement> GetConversationDialogs(string conversationId)
Expand All @@ -651,6 +653,27 @@ public List<DialogElement> GetConversationDialogs(string conversationId)
return formattedDialog ?? new List<DialogElement>();
}

public void UpdateConversationDialogElements(string conversationId, List<DialogContentUpdateModel> updateElements)
{
if (string.IsNullOrEmpty(conversationId) || updateElements.IsNullOrEmpty()) return;

var filterDialog = Builders<ConversationDialogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
var foundDialog = _dc.ConversationDialogs.Find(filterDialog).FirstOrDefault();
if (foundDialog == null || foundDialog.Dialogs.IsNullOrEmpty()) return;

foundDialog.Dialogs = foundDialog.Dialogs.Select((x, idx) =>
{
var found = updateElements.FirstOrDefault(e => e.Index == idx);
if (found != null)
{
x.Content = found.UpdateContent;
}
return x;
}).ToList();

_dc.ConversationDialogs.ReplaceOne(filterDialog, foundDialog);
}

public void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs)
{
if (string.IsNullOrEmpty(conversationId)) return;
Expand Down Expand Up @@ -892,20 +915,26 @@ public List<string> GetExecutionLogs(string conversationId)
#region LLM Completion Log
public void SaveLlmCompletionLog(LlmCompletionLog log)
{
if (log == null || string.IsNullOrEmpty(log.ConversationId)) return;
if (log == null) return;

var conversationId = log.ConversationId.IfNullOrEmptyAs(Guid.NewGuid().ToString());
var messageId = log.MessageId.IfNullOrEmptyAs(Guid.NewGuid().ToString());

var completiongLog = new LlmCompletionLogDocument
var logElement = new PromptLogElement
{
Id = string.IsNullOrEmpty(log.Id) ? Guid.NewGuid().ToString() : log.Id,
ConversationId = log.ConversationId,
MessageId = log.MessageId,
MessageId = messageId,
AgentId = log.AgentId,
Prompt = log.Prompt,
Response = log.Response,
CreateDateTime = log.CreateDateTime
};

_dc.LlmCompletionLogs.InsertOne(completiongLog);
var filter = Builders<LlmCompletionLogDocument>.Filter.Eq(x => x.ConversationId, conversationId);
var update = Builders<LlmCompletionLogDocument>.Update
.SetOnInsert(x => x.Id, Guid.NewGuid().ToString())
.Push(x => x.Logs, logElement);

_dc.LlmCompletionLogs.UpdateOne(filter, update, _options);
}
#endregion
}