BotSharp/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.Log.cs

273 lines
9.4 KiB
C#
Raw Normal View History

2024-02-15 20:43:36 +00:00
using BotSharp.Abstraction.Loggers.Models;
2025-03-05 23:22:46 +00:00
using BotSharp.Abstraction.Repositories.Filters;
2025-03-04 23:25:35 +00:00
using System.Text.Json;
2024-01-13 02:13:38 +00:00
namespace BotSharp.Plugin.MongoStorage.Repository;
public partial class MongoRepository
{
#region LLM Completion Log
public void SaveLlmCompletionLog(LlmCompletionLog log)
{
if (log == null) return;
var conversationId = log.ConversationId.IfNullOrEmptyAs(Guid.NewGuid().ToString());
var messageId = log.MessageId.IfNullOrEmptyAs(Guid.NewGuid().ToString());
2025-02-20 18:17:21 +00:00
var data = new LlmCompletionLogDocument
2024-01-13 02:13:38 +00:00
{
2025-02-20 18:17:21 +00:00
Id = Guid.NewGuid().ToString(),
ConversationId = conversationId,
2024-01-13 02:13:38 +00:00
MessageId = messageId,
AgentId = log.AgentId,
Prompt = log.Prompt,
Response = log.Response,
2025-02-20 18:17:21 +00:00
CreatedTime = log.CreatedTime
2024-01-13 02:13:38 +00:00
};
2025-02-20 18:17:21 +00:00
_dc.LlmCompletionLogs.InsertOne(data);
2024-01-13 02:13:38 +00:00
}
#endregion
2024-02-15 20:43:36 +00:00
#region Conversation Content Log
2024-03-01 02:50:39 +00:00
public void SaveConversationContentLog(ContentLogOutputModel log)
2024-02-15 20:43:36 +00:00
{
if (log == null) return;
2024-03-26 21:57:13 +00:00
var found = _dc.Conversations.AsQueryable().FirstOrDefault(x => x.Id == log.ConversationId);
if (found == null) return;
2024-02-15 20:43:36 +00:00
var logDoc = new ConversationContentLogDocument
{
2024-03-26 21:57:13 +00:00
ConversationId = log.ConversationId,
MessageId = log.MessageId,
2024-02-15 20:43:36 +00:00
Name = log.Name,
2024-03-01 02:50:39 +00:00
AgentId = log.AgentId,
2024-02-15 20:43:36 +00:00
Role = log.Role,
2024-02-22 17:25:13 +00:00
Source = log.Source,
2024-02-15 20:43:36 +00:00
Content = log.Content,
CreatedTime = log.CreatedTime
2024-02-15 20:43:36 +00:00
};
_dc.ContentLogs.InsertOne(logDoc);
}
2024-03-01 02:50:39 +00:00
public List<ContentLogOutputModel> GetConversationContentLogs(string conversationId)
2024-02-15 20:43:36 +00:00
{
var logs = _dc.ContentLogs
.AsQueryable()
.Where(x => x.ConversationId == conversationId)
2024-03-01 02:50:39 +00:00
.Select(x => new ContentLogOutputModel
2024-02-15 20:43:36 +00:00
{
ConversationId = x.ConversationId,
MessageId = x.MessageId,
Name = x.Name,
2024-03-01 02:50:39 +00:00
AgentId = x.AgentId,
2024-02-15 20:43:36 +00:00
Role = x.Role,
2024-02-22 17:25:13 +00:00
Source = x.Source,
2024-02-15 20:43:36 +00:00
Content = x.Content,
CreatedTime = x.CreatedTime
2024-02-15 20:43:36 +00:00
})
.OrderBy(x => x.CreatedTime)
2024-02-15 20:43:36 +00:00
.ToList();
return logs;
}
#endregion
#region Conversation State Log
public void SaveConversationStateLog(ConversationStateLogModel log)
{
if (log == null) return;
2024-03-26 21:57:13 +00:00
var found = _dc.Conversations.AsQueryable().FirstOrDefault(x => x.Id == log.ConversationId);
if (found == null) return;
2024-02-15 20:43:36 +00:00
var logDoc = new ConversationStateLogDocument
{
2024-03-26 21:57:13 +00:00
ConversationId = log.ConversationId,
2025-01-29 22:21:19 +00:00
AgentId= log.AgentId,
2024-03-26 21:57:13 +00:00
MessageId = log.MessageId,
2024-02-15 20:43:36 +00:00
States = log.States,
CreatedTime = log.CreatedTime
2024-02-15 20:43:36 +00:00
};
_dc.StateLogs.InsertOne(logDoc);
}
public List<ConversationStateLogModel> GetConversationStateLogs(string conversationId)
{
var logs = _dc.StateLogs
.AsQueryable()
.Where(x => x.ConversationId == conversationId)
.Select(x => new ConversationStateLogModel
{
ConversationId = x.ConversationId,
2025-01-29 22:21:19 +00:00
AgentId = x.AgentId,
2024-02-15 20:43:36 +00:00
MessageId = x.MessageId,
States = x.States,
CreatedTime = x.CreatedTime
2024-02-15 20:43:36 +00:00
})
.OrderBy(x => x.CreatedTime)
2024-02-15 20:43:36 +00:00
.ToList();
return logs;
}
#endregion
2025-03-04 23:25:35 +00:00
#region Instruction Log
public bool SaveInstructionLogs(IEnumerable<InstructionLogModel> logs)
{
if (logs.IsNullOrEmpty()) return false;
2025-03-06 23:44:49 +00:00
var docs = new List<InstructionLogDocument>();
2025-03-04 23:25:35 +00:00
foreach (var log in logs)
{
2025-03-06 23:44:49 +00:00
var doc = InstructionLogDocument.ToMongoModel(log);
2025-03-04 23:25:35 +00:00
foreach (var pair in log.States)
{
try
{
var jsonStr = JsonSerializer.Serialize(new { Data = JsonDocument.Parse(pair.Value) }, _botSharpOptions.JsonSerializerOptions);
var json = BsonDocument.Parse(jsonStr);
doc.States[pair.Key] = json;
}
catch
{
var jsonStr = JsonSerializer.Serialize(new { Data = pair.Value }, _botSharpOptions.JsonSerializerOptions);
var json = BsonDocument.Parse(jsonStr);
doc.States[pair.Key] = json;
}
}
docs.Add(doc);
}
_dc.InstructionLogs.InsertMany(docs);
return true;
}
public PagedItems<InstructionLogModel> GetInstructionLogs(InstructLogFilter filter)
{
if (filter == null)
{
filter = InstructLogFilter.Empty();
}
var logBuilder = Builders<InstructionLogDocument>.Filter;
var logFilters = new List<FilterDefinition<InstructionLogDocument>>() { logBuilder.Empty };
2025-03-04 23:25:35 +00:00
// Filter logs
if (!filter.AgentIds.IsNullOrEmpty())
{
logFilters.Add(logBuilder.In(x => x.AgentId, filter.AgentIds));
2025-03-04 23:25:35 +00:00
}
if (!filter.Providers.IsNullOrEmpty())
{
logFilters.Add(logBuilder.In(x => x.Provider, filter.Providers));
2025-03-04 23:25:35 +00:00
}
if (!filter.Models.IsNullOrEmpty())
{
logFilters.Add(logBuilder.In(x => x.Model, filter.Models));
2025-03-04 23:25:35 +00:00
}
2025-03-05 23:22:46 +00:00
if (!filter.TemplateNames.IsNullOrEmpty())
2025-03-04 23:25:35 +00:00
{
logFilters.Add(logBuilder.In(x => x.TemplateName, filter.TemplateNames));
2025-03-04 23:25:35 +00:00
}
// Filter states
if (filter != null && !filter.States.IsNullOrEmpty())
{
foreach (var pair in filter.States)
{
if (string.IsNullOrWhiteSpace(pair.Key)) continue;
// Format key
var keys = pair.Key.Split(".").ToList();
keys.Insert(1, "data");
keys.Insert(0, "States");
var formattedKey = string.Join(".", keys);
if (string.IsNullOrWhiteSpace(pair.Value))
{
logFilters.Add(logBuilder.Exists(formattedKey));
}
else if (bool.TryParse(pair.Value, out var boolValue))
{
logFilters.Add(logBuilder.Eq(formattedKey, boolValue));
}
else if (int.TryParse(pair.Value, out var intValue))
{
logFilters.Add(logBuilder.Eq(formattedKey, intValue));
}
else if (decimal.TryParse(pair.Value, out var decimalValue))
{
logFilters.Add(logBuilder.Eq(formattedKey, decimalValue));
}
else if (float.TryParse(pair.Value, out var floatValue))
{
logFilters.Add(logBuilder.Eq(formattedKey, floatValue));
}
else if (double.TryParse(pair.Value, out var doubleValue))
{
logFilters.Add(logBuilder.Eq(formattedKey, doubleValue));
}
else
{
logFilters.Add(logBuilder.Eq(formattedKey, pair.Value));
}
}
}
var filterDef = logBuilder.And(logFilters);
2025-03-06 23:44:49 +00:00
var sortDef = Builders<InstructionLogDocument>.Sort.Descending(x => x.CreatedTime);
2025-03-04 23:25:35 +00:00
var docs = _dc.InstructionLogs.Find(filterDef).Sort(sortDef).Skip(filter.Offset).Limit(filter.Size).ToList();
var count = _dc.InstructionLogs.CountDocuments(filterDef);
var logs = docs.Select(x =>
{
2025-03-06 23:44:49 +00:00
var log = InstructionLogDocument.ToDomainModel(x);
2025-03-05 23:22:46 +00:00
log.States = x.States.ToDictionary(p => p.Key, p =>
{
var jsonStr = p.Value.ToJson();
var jsonDoc = JsonDocument.Parse(jsonStr);
var data = jsonDoc.RootElement.GetProperty("data");
return data.ValueKind != JsonValueKind.Null ? data.ToString() : null;
});
2025-03-04 23:25:35 +00:00
return log;
}).ToList();
return new PagedItems<InstructionLogModel>
{
Items = logs,
Count = (int)count
};
}
2025-03-10 17:14:44 +00:00
public List<string> GetInstructionLogSearchKeys(InstructLogKeysFilter filter)
{
var builder = Builders<InstructionLogDocument>.Filter;
var sortDef = Builders<InstructionLogDocument>.Sort.Descending(x => x.CreatedTime);
var filters = new List<FilterDefinition<InstructionLogDocument>>()
{
builder.Exists(x => x.States),
builder.Ne(x => x.States, [])
};
if (!filter.AgentIds.IsNullOrEmpty())
{
filters.Add(builder.In(x => x.AgentId, filter.AgentIds));
}
if (!filter.UserIds.IsNullOrEmpty())
{
filters.Add(builder.In(x => x.UserId, filter.UserIds));
}
var convDocs = _dc.InstructionLogs.Find(builder.And(filters))
.Sort(sortDef)
.Limit(filter.LogLimit)
.ToList();
var keys = convDocs.SelectMany(x => x.States.Select(x => x.Key)).Distinct().ToList();
return keys;
}
2025-03-04 23:25:35 +00:00
#endregion
2024-01-13 02:13:38 +00:00
}