Merge branch 'SciSharp:master' into master

This commit is contained in:
Deep Blue 2023-12-20 20:22:55 -06:00 committed by GitHub
commit 59217016db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 107 additions and 17 deletions

View file

@ -2,7 +2,6 @@ namespace BotSharp.Abstraction.Conversations.Models;
public class LlmCompletionLog public class LlmCompletionLog
{ {
public string Id { get; set; } = string.Empty;
public string ConversationId { get; set; } = string.Empty; public string ConversationId { get; set; } = string.Empty;
public string MessageId { get; set; } = string.Empty; public string MessageId { get; set; } = string.Empty;
public string AgentId { get; set; } = string.Empty; public string AgentId { get; set; } = string.Empty;

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Repositories.Models;
using BotSharp.Abstraction.Users.Models; using BotSharp.Abstraction.Users.Models;
namespace BotSharp.Abstraction.Repositories; namespace BotSharp.Abstraction.Repositories;
@ -30,6 +31,7 @@ public interface IBotSharpRepository
void CreateNewConversation(Conversation conversation); void CreateNewConversation(Conversation conversation);
bool DeleteConversation(string conversationId); bool DeleteConversation(string conversationId);
List<DialogElement> GetConversationDialogs(string conversationId); List<DialogElement> GetConversationDialogs(string conversationId);
void UpdateConversationDialogElements(string conversationId, List<DialogContentUpdateModel> updateElements);
void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs); void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs);
List<StateKeyValue> GetConversationStates(string conversationId); List<StateKeyValue> GetConversationStates(string conversationId);
void UpdateConversationStates(string conversationId, List<StateKeyValue> states); void UpdateConversationStates(string conversationId, List<StateKeyValue> states);

View file

@ -0,0 +1,8 @@
namespace BotSharp.Abstraction.Repositories.Models
{
public class DialogContentUpdateModel
{
public int Index { get; set; }
public string UpdateContent { get; set; }
}
}

View file

@ -37,8 +37,10 @@ public static class StringExtensions
return input.Replace("\r", " ").Replace("\n", " ").Trim(); 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); return str1.Equals(str2, option);
} }

View file

@ -1,6 +1,7 @@
using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Repositories; using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Repositories.Models;
using BotSharp.Abstraction.Users.Models; using BotSharp.Abstraction.Users.Models;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
@ -146,6 +147,11 @@ public class BotSharpDbContext : Database, IBotSharpRepository
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void UpdateConversationDialogElements(string conversationId, List<DialogContentUpdateModel> updateElements)
{
throw new NotImplementedException();
}
public List<StateKeyValue> GetConversationStates(string conversationId) public List<StateKeyValue> GetConversationStates(string conversationId)
{ {
throw new NotImplementedException(); throw new NotImplementedException();

View file

@ -6,6 +6,9 @@ using BotSharp.Abstraction.Agents.Models;
using MongoDB.Driver; using MongoDB.Driver;
using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Utilities;
using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Repositories.Models;
namespace BotSharp.Core.Repository; namespace BotSharp.Core.Repository;
@ -650,6 +653,33 @@ public class FileRepository : IBotSharpRepository
return dialogs; 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) public void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs)
{ {
var convDir = FindConversationDirectory(conversationId); var convDir = FindConversationDirectory(conversationId);
@ -860,10 +890,17 @@ public class FileRepository : IBotSharpRepository
#region LLM Completion Log #region LLM Completion Log
public void SaveLlmCompletionLog(LlmCompletionLog 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); 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"); var logDir = Path.Combine(convDir, "llm_prompt_log");
if (!Directory.Exists(logDir)) if (!Directory.Exists(logDir))
@ -871,7 +908,6 @@ public class FileRepository : IBotSharpRepository
Directory.CreateDirectory(logDir); Directory.CreateDirectory(logDir);
} }
log.Id = Guid.NewGuid().ToString();
var index = GetNextLlmCompletionLogIndex(logDir, log.MessageId); var index = GetNextLlmCompletionLogIndex(logDir, log.MessageId);
var file = Path.Combine(logDir, $"{log.MessageId}.{index}.log"); var file = Path.Combine(logDir, $"{log.MessageId}.{index}.log");
File.WriteAllText(file, JsonSerializer.Serialize(log, _options)); File.WriteAllText(file, JsonSerializer.Serialize(log, _options));

View file

@ -1,11 +1,9 @@
using BotSharp.Plugin.MongoStorage.Models;
namespace BotSharp.Plugin.MongoStorage.Collections; namespace BotSharp.Plugin.MongoStorage.Collections;
public class LlmCompletionLogDocument : MongoBase public class LlmCompletionLogDocument : MongoBase
{ {
public string ConversationId { get; set; } public string ConversationId { get; set; }
public string MessageId { get; set; } public List<PromptLogElement> Logs { get; set; }
public string AgentId { get; set; }
public string Prompt { get; set; }
public string? Response { get; set; }
public DateTime CreateDateTime { get; set; }
} }

View file

@ -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; }
}

View file

@ -2,6 +2,7 @@ using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations.Models;
using BotSharp.Abstraction.Functions.Models; using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Repositories.Filters; using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Repositories.Models;
using BotSharp.Abstraction.Routing.Models; using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Users.Models; using BotSharp.Abstraction.Users.Models;
using BotSharp.Plugin.MongoStorage.Collections; using BotSharp.Plugin.MongoStorage.Collections;
@ -635,7 +636,8 @@ public class MongoRepository : IBotSharpRepository
var promptLogDeleted = _dc.LlmCompletionLogs.DeleteMany(filterPromptLog); var promptLogDeleted = _dc.LlmCompletionLogs.DeleteMany(filterPromptLog);
var dialogDeleted = _dc.ConversationDialogs.DeleteMany(filterDialog); var dialogDeleted = _dc.ConversationDialogs.DeleteMany(filterDialog);
var convDeleted = _dc.Conversations.DeleteMany(filterConv); 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) public List<DialogElement> GetConversationDialogs(string conversationId)
@ -651,6 +653,27 @@ public class MongoRepository : IBotSharpRepository
return formattedDialog ?? new List<DialogElement>(); 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) public void AppendConversationDialogs(string conversationId, List<DialogElement> dialogs)
{ {
if (string.IsNullOrEmpty(conversationId)) return; if (string.IsNullOrEmpty(conversationId)) return;
@ -892,20 +915,26 @@ public class MongoRepository : IBotSharpRepository
#region LLM Completion Log #region LLM Completion Log
public void SaveLlmCompletionLog(LlmCompletionLog log) public void SaveLlmCompletionLog(LlmCompletionLog log)
{ {
if (log == null || string.IsNullOrEmpty(log.ConversationId)) return; if (log == null) return;
var completiongLog = new LlmCompletionLogDocument var conversationId = log.ConversationId.IfNullOrEmptyAs(Guid.NewGuid().ToString());
var messageId = log.MessageId.IfNullOrEmptyAs(Guid.NewGuid().ToString());
var logElement = new PromptLogElement
{ {
Id = string.IsNullOrEmpty(log.Id) ? Guid.NewGuid().ToString() : log.Id, MessageId = messageId,
ConversationId = log.ConversationId,
MessageId = log.MessageId,
AgentId = log.AgentId, AgentId = log.AgentId,
Prompt = log.Prompt, Prompt = log.Prompt,
Response = log.Response, Response = log.Response,
CreateDateTime = log.CreateDateTime 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 #endregion
} }