add conversation collection
This commit is contained in:
parent
c897209fda
commit
4cc74e596a
|
|
@ -6,6 +6,7 @@ public class Conversation
|
|||
public string AgentId { get; set; } = string.Empty;
|
||||
public string UserId { get; set; } = string.Empty;
|
||||
public string Title { get; set; } = string.Empty;
|
||||
public string Dialog { get; set; }
|
||||
|
||||
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
|
||||
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,19 @@
|
|||
using BotSharp.Abstraction.Repositories.Models;
|
||||
|
||||
namespace BotSharp.Abstraction.Conversations.Models;
|
||||
|
||||
public class ConversationState : Dictionary<string, string>
|
||||
{
|
||||
public ConversationState()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ConversationState(List<KeyValueModel> pairs)
|
||||
{
|
||||
foreach (var pair in pairs)
|
||||
{
|
||||
this[pair.Key] = pair.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using BotSharp.Abstraction.Repositories.Models;
|
||||
using BotSharp.Abstraction.Repositories.Records;
|
||||
using BotSharp.Abstraction.Routing.Models;
|
||||
using System.Linq;
|
||||
|
|
@ -27,4 +28,14 @@ public interface IBotSharpRepository
|
|||
|
||||
AgentRecord GetAgent(string agentId);
|
||||
List<string> GetAgentResponses(string agentId);
|
||||
|
||||
void CreateNewConversation(ConversationRecord conversation);
|
||||
string GetConversationDialog(string conversationId);
|
||||
void UpdateConversationDialog(string conversationId, string dialogs);
|
||||
|
||||
List<KeyValueModel> GetConversationState(string conversationId);
|
||||
void UpdateConversationState(string conversationId, List<KeyValueModel> state);
|
||||
|
||||
ConversationRecord GetConversation(string conversationId);
|
||||
List<ConversationRecord> GetConversations(string userId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
namespace BotSharp.Abstraction.Repositories.Models;
|
||||
|
||||
public class KeyValueModel
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string Value { get; set; }
|
||||
|
||||
public KeyValueModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public KeyValueModel(string key, string value)
|
||||
{
|
||||
Key = key;
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Repositories.Models;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace BotSharp.Abstraction.Repositories.Records;
|
||||
|
||||
|
|
@ -15,6 +17,12 @@ public class ConversationRecord : RecordBase
|
|||
[MaxLength(64)]
|
||||
public string Title { get; set; } = string.Empty;
|
||||
|
||||
[JsonIgnore]
|
||||
public string Dialog { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public List<KeyValueModel> State { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
|
||||
|
||||
|
|
@ -29,6 +37,8 @@ public class ConversationRecord : RecordBase
|
|||
UserId = conv.UserId,
|
||||
Id = conv.Id,
|
||||
Title = conv.Title,
|
||||
Dialog = conv.Dialog,
|
||||
State = conv.State?.Select(x => new KeyValueModel(x.Key, x.Value))?.ToList() ?? new List<KeyValueModel>(),
|
||||
CreatedTime = conv.CreatedTime,
|
||||
UpdatedTime = conv.UpdatedTime
|
||||
};
|
||||
|
|
@ -42,6 +52,8 @@ public class ConversationRecord : RecordBase
|
|||
Title = Title,
|
||||
UserId = UserId,
|
||||
AgentId = AgentId,
|
||||
Dialog = Dialog,
|
||||
State = new ConversationState(State),
|
||||
CreatedTime = CreatedTime,
|
||||
UpdatedTime = UpdatedTime
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,13 +20,7 @@ public partial class AgentService
|
|||
public async Task<Agent> GetAgent(string id)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
//var query = from agent in db.Agent
|
||||
// where agent.Id == id
|
||||
// select agent.ToAgent();
|
||||
|
||||
//var profile = query.FirstOrDefault();
|
||||
var profile = db.GetAgent(id)?.ToAgent();
|
||||
//var dir = GetAgentDataDir(id);
|
||||
|
||||
var instructionFile = profile?.Instruction;
|
||||
if (instructionFile != null)
|
||||
|
|
|
|||
|
|
@ -36,21 +36,26 @@ public partial class ConversationService : IConversationService
|
|||
public async Task<Conversation> GetConversation(string id)
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var query = from sess in db.Conversation
|
||||
where sess.Id == id
|
||||
orderby sess.CreatedTime descending
|
||||
select sess.ToConversation();
|
||||
return query.FirstOrDefault();
|
||||
//var query = from sess in db.Conversation
|
||||
// where sess.Id == id
|
||||
// orderby sess.CreatedTime descending
|
||||
// select sess.ToConversation();
|
||||
|
||||
var conversation = db.GetConversation(id);
|
||||
return conversation?.ToConversation();
|
||||
}
|
||||
|
||||
public async Task<List<Conversation>> GetConversations()
|
||||
{
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var query = from sess in db.Conversation
|
||||
where sess.UserId == _user.Id
|
||||
orderby sess.CreatedTime descending
|
||||
select sess.ToConversation();
|
||||
return query.ToList();
|
||||
//var query = from sess in db.Conversation
|
||||
// where sess.UserId == _user.Id
|
||||
// orderby sess.CreatedTime descending
|
||||
// select sess.ToConversation();
|
||||
|
||||
var user = db.User.FirstOrDefault(x => x.ExternalId == _user.Id);
|
||||
var conversations = db.GetConversations(user?.Id);
|
||||
return conversations.Select(x => x.ToConversation()).OrderByDescending(x => x.CreatedTime).ToList();
|
||||
}
|
||||
|
||||
public async Task<Conversation> NewConversation(Conversation sess)
|
||||
|
|
@ -66,26 +71,7 @@ public partial class ConversationService : IConversationService
|
|||
record.UserId = sess.UserId.IfNullOrEmptyAs(foundUserId);
|
||||
record.Title = "New Conversation";
|
||||
|
||||
//db.Transaction<IBotSharpTable>(delegate
|
||||
//{
|
||||
// db.Add<IBotSharpTable>(record);
|
||||
//});
|
||||
|
||||
var dir = Path.Combine(dbSettings.FileRepository, conversationSettings.DataDir, record.Id);
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
var path = Path.Combine(dir, "conversation.json");
|
||||
File.WriteAllText(path, JsonSerializer.Serialize(record, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
}));
|
||||
|
||||
_storage.InitStorage(record.Id);
|
||||
|
||||
db.CreateNewConversation(record);
|
||||
return record.ToConversation();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Repositories.Models;
|
||||
using BotSharp.Abstraction.Repositories.Records;
|
||||
using MongoDB.Bson;
|
||||
using System.IO;
|
||||
|
|
@ -20,6 +21,7 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
|||
private BotSharpDatabaseSettings _dbSettings;
|
||||
private string _conversationId;
|
||||
private string _file;
|
||||
private List<KeyValueModel> _savedStates;
|
||||
|
||||
public ConversationStateService(ILogger<ConversationStateService> logger,
|
||||
IServiceProvider services,
|
||||
|
|
@ -65,18 +67,13 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
|||
}
|
||||
|
||||
_state = new ConversationState();
|
||||
_savedStates = _db.GetConversationState(_conversationId);
|
||||
|
||||
_file = GetStorageFile(_conversationId);
|
||||
//_file = GetConversationState(_conversationId);
|
||||
|
||||
if (_file != null)
|
||||
if (_savedStates != null)
|
||||
{
|
||||
var dict = File.ReadAllLines(_file);
|
||||
//var dict = _file.SplitByNewLine();
|
||||
|
||||
foreach (var line in dict)
|
||||
foreach (var data in _savedStates)
|
||||
{
|
||||
_state[line.Split('=')[0]] = line.Split('=')[1];
|
||||
_state[data.Key] = data.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -92,32 +89,20 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
|||
|
||||
public void Save()
|
||||
{
|
||||
//var states = new StringBuilder();
|
||||
//var conversation = _db.Conversation.FirstOrDefault(x => x.Id == _conversationId);
|
||||
|
||||
var states = new List<string>();
|
||||
var states = new List<KeyValueModel>();
|
||||
|
||||
foreach (var dic in _state)
|
||||
{
|
||||
states.Add($"{dic.Key}={dic.Value}");
|
||||
//states.AppendLine($"{dic.Key}={dic.Value}");
|
||||
states.Add(new KeyValueModel(dic.Key, dic.Value));
|
||||
}
|
||||
File.WriteAllLines(_file, states);
|
||||
_logger.LogInformation($"Saved state {_conversationId}");
|
||||
|
||||
//if (conversation != null)
|
||||
//{
|
||||
// conversation.State = states.ToString();
|
||||
// _db.Transaction<IBotSharpTable>(delegate
|
||||
// {
|
||||
// _db.Add<IBotSharpTable>(conversation);
|
||||
// });
|
||||
//}
|
||||
_db.UpdateConversationState(_conversationId, states);
|
||||
_logger.LogInformation($"Saved state {_conversationId}");
|
||||
}
|
||||
|
||||
public void CleanState()
|
||||
{
|
||||
File.Delete(_file);
|
||||
//File.Delete(_file);
|
||||
}
|
||||
|
||||
private string GetStorageFile(string conversationId)
|
||||
|
|
@ -136,33 +121,6 @@ public class ConversationStateService : IConversationStateService, IDisposable
|
|||
return stateFile;
|
||||
}
|
||||
|
||||
//private string GetConversationState(string conversationId)
|
||||
//{
|
||||
// var conversation = _db.Conversation.FirstOrDefault(x => x.Id == conversationId);
|
||||
// if (conversation == null)
|
||||
// {
|
||||
// var user = _db.User.FirstOrDefault(x => x.ExternalId == _user.Id);
|
||||
// var record = new ConversationRecord()
|
||||
// {
|
||||
// Id = ObjectId.GenerateNewId().ToString(),
|
||||
// //AgentId = _agentSettings.RouterId,
|
||||
// UserId = user?.Id ?? ObjectId.GenerateNewId().ToString(),
|
||||
// Title = "New Conversation",
|
||||
// Dialog = string.Empty,
|
||||
// State = string.Empty
|
||||
// };
|
||||
|
||||
// _db.Transaction<IBotSharpTable>(delegate
|
||||
// {
|
||||
// _db.Add<IBotSharpTable>(record);
|
||||
// });
|
||||
|
||||
// conversation = _db.Conversation.FirstOrDefault(x => x.Id == record.Id);
|
||||
// }
|
||||
|
||||
// return conversation.State ?? string.Empty;
|
||||
//}
|
||||
|
||||
public string GetState(string name)
|
||||
{
|
||||
if (!_state.ContainsKey(name))
|
||||
|
|
|
|||
|
|
@ -1,11 +1,6 @@
|
|||
using BotSharp.Abstraction.Agents.Enums;
|
||||
using BotSharp.Abstraction.Agents.Settings;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Repositories.Records;
|
||||
using MongoDB.Bson;
|
||||
using System.IO;
|
||||
using Tensorflow;
|
||||
|
||||
namespace BotSharp.Core.Conversations.Services;
|
||||
|
||||
|
|
@ -29,12 +24,9 @@ public class ConversationStorage : IConversationStorage
|
|||
|
||||
public void Append(string conversationId, string agentId, RoleDialogModel dialog)
|
||||
{
|
||||
//var dialogs = GetConversationDialogs(conversationId);
|
||||
//var sb = new StringBuilder(dialogs);
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
|
||||
var conversationFile = GetStorageFile(conversationId);
|
||||
var sb = new StringBuilder();
|
||||
var dialogText = db.GetConversationDialog(conversationId);
|
||||
var sb = new StringBuilder(dialogText);
|
||||
|
||||
if (dialog.Role == AgentRole.Function)
|
||||
{
|
||||
|
|
@ -63,24 +55,15 @@ public class ConversationStorage : IConversationStorage
|
|||
}
|
||||
|
||||
var updatedDialogs = sb.ToString();
|
||||
File.AppendAllText(conversationFile, updatedDialogs);
|
||||
|
||||
//var conversation = db.Conversation.FirstOrDefault(x => x.Id == conversationId);
|
||||
//conversation.AgentId = agentId;
|
||||
//conversation.Dialog = updatedDialogs;
|
||||
//db.Transaction<IBotSharpTable>(delegate
|
||||
//{
|
||||
// db.Add<IBotSharpTable>(conversation);
|
||||
//});
|
||||
//File.AppendAllText(conversationFile, updatedDialogs);
|
||||
db.UpdateConversationDialog(conversationId, updatedDialogs);
|
||||
}
|
||||
|
||||
public List<RoleDialogModel> GetDialogs(string conversationId)
|
||||
{
|
||||
var conversationFile = GetStorageFile(conversationId);
|
||||
var dialogs = File.ReadAllLines(conversationFile);
|
||||
|
||||
//var conversationFile = GetConversationDialogs(conversationId);
|
||||
//var dialogs = conversationFile.SplitByNewLine();
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var dialogText = db.GetConversationDialog(conversationId);
|
||||
var dialogs = dialogText.SplitByNewLine();
|
||||
|
||||
var results = new List<RoleDialogModel>();
|
||||
for (int i = 0; i < dialogs.Length; i += 2)
|
||||
|
|
@ -113,8 +96,6 @@ public class ConversationStorage : IConversationStorage
|
|||
{
|
||||
File.WriteAllLines(file, new string[0]);
|
||||
}
|
||||
|
||||
//GetConversationDialogs(conversationId);
|
||||
}
|
||||
|
||||
private string GetStorageFile(string conversationId)
|
||||
|
|
@ -126,30 +107,4 @@ public class ConversationStorage : IConversationStorage
|
|||
}
|
||||
return Path.Combine(dir, "dialogs.txt");
|
||||
}
|
||||
|
||||
//private string GetConversationDialogs(string conversationId)
|
||||
//{
|
||||
// var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
// var conversation = db.Conversation.FirstOrDefault(x => x.Id == conversationId);
|
||||
// if (conversation == null)
|
||||
// {
|
||||
// var user = db.User.FirstOrDefault(x => x.ExternalId == _user.Id);
|
||||
// var record = new ConversationRecord()
|
||||
// {
|
||||
// Id = ObjectId.GenerateNewId().ToString(),
|
||||
// //AgentId = _agentSettings.RouterId,
|
||||
// UserId = user?.Id ?? ObjectId.GenerateNewId().ToString(),
|
||||
// Title = "New Conversation"
|
||||
// };
|
||||
|
||||
// db.Transaction<IBotSharpTable>(delegate
|
||||
// {
|
||||
// db.Add<IBotSharpTable>(record);
|
||||
// });
|
||||
|
||||
// conversation = db.Conversation.FirstOrDefault(x => x.Id == record.Id);
|
||||
// }
|
||||
|
||||
// return conversation.Dialog ?? string.Empty;
|
||||
//}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Repositories.Models;
|
||||
using BotSharp.Abstraction.Repositories.Records;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
|
||||
|
|
@ -106,4 +107,39 @@ public class BotSharpDbContext : Database, IBotSharpRepository
|
|||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void CreateNewConversation(ConversationRecord conversation)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetConversationDialog(string conversationId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void UpdateConversationDialog(string conversationId, string dialogs)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<KeyValueModel> GetConversationState(string conversationId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void UpdateConversationState(string conversationId, List<KeyValueModel> state)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public ConversationRecord GetConversation(string conversationId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public List<ConversationRecord> GetConversations(string userId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Conversations.Settings;
|
||||
using BotSharp.Abstraction.Functions.Models;
|
||||
using BotSharp.Abstraction.Repositories;
|
||||
using BotSharp.Abstraction.Repositories.Models;
|
||||
using BotSharp.Abstraction.Repositories.Records;
|
||||
using MongoDB.Driver.Core.Operations;
|
||||
using System.IO;
|
||||
using static Tensorflow.TensorShapeProto.Types;
|
||||
using Tensorflow;
|
||||
using FunctionDef = BotSharp.Abstraction.Functions.Models.FunctionDef;
|
||||
|
||||
namespace BotSharp.Core.Repository;
|
||||
|
||||
|
|
@ -401,4 +408,181 @@ public class FileRepository : IBotSharpRepository
|
|||
var functions = functionDefs.Select(x => JsonSerializer.Serialize(x, _options)).ToList();
|
||||
return functions;
|
||||
}
|
||||
|
||||
public void CreateNewConversation(ConversationRecord conversation)
|
||||
{
|
||||
var dir = Path.Combine(_dbSettings.FileRepository, _conversationSetting.DataDir, conversation.Id);
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
var convDir = Path.Combine(dir, "conversation.json");
|
||||
if (!File.Exists(convDir))
|
||||
{
|
||||
File.WriteAllText(convDir, JsonSerializer.Serialize(conversation, _options));
|
||||
}
|
||||
|
||||
var dialogDir = Path.Combine(dir, "dialogs.txt");
|
||||
if (!File.Exists(dialogDir))
|
||||
{
|
||||
File.WriteAllText(dialogDir, string.Empty);
|
||||
}
|
||||
|
||||
var stateDir = Path.Combine(dir, "state.dict");
|
||||
if (!File.Exists(stateDir))
|
||||
{
|
||||
File.WriteAllText(stateDir, string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetConversationDialog(string conversationId)
|
||||
{
|
||||
var convDir = FindConversationDirectory(conversationId);
|
||||
if (!string.IsNullOrEmpty(convDir))
|
||||
{
|
||||
var dialogDir = Path.Combine(convDir, "dialogs.txt");
|
||||
if (File.Exists(dialogDir))
|
||||
{
|
||||
return File.ReadAllText(dialogDir);
|
||||
}
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public void UpdateConversationDialog(string conversationId, string dialogs)
|
||||
{
|
||||
var convDir = FindConversationDirectory(conversationId);
|
||||
if (!string.IsNullOrEmpty(convDir))
|
||||
{
|
||||
var dialogDir = Path.Combine(convDir, "dialogs.txt");
|
||||
if (File.Exists(dialogDir))
|
||||
{
|
||||
File.WriteAllText(dialogDir, dialogs);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public List<KeyValueModel> GetConversationState(string conversationId)
|
||||
{
|
||||
var curStates = new List<KeyValueModel>();
|
||||
var convDir = FindConversationDirectory(conversationId);
|
||||
if (!string.IsNullOrEmpty(convDir))
|
||||
{
|
||||
var stateDir = Path.Combine(convDir, "state.dict");
|
||||
if (File.Exists(stateDir))
|
||||
{
|
||||
var dict = File.ReadAllLines(stateDir);
|
||||
foreach (var line in dict)
|
||||
{
|
||||
var data = line.Split('=');
|
||||
curStates.Add(new KeyValueModel(data[0], data[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return curStates;
|
||||
}
|
||||
|
||||
private string? FindConversationDirectory(string conversationId)
|
||||
{
|
||||
var dir = Path.Combine(_dbSettings.FileRepository, _conversationSetting.DataDir);
|
||||
|
||||
foreach (var d in Directory.GetDirectories(dir))
|
||||
{
|
||||
var path = Path.Combine(d, "conversation.json");
|
||||
if (!File.Exists(path)) continue;
|
||||
|
||||
var json = File.ReadAllText(path);
|
||||
var conv = JsonSerializer.Deserialize<ConversationRecord>(json, _options);
|
||||
if (conv != null && conv.Id == conversationId)
|
||||
{
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void UpdateConversationState(string conversationId, List<KeyValueModel> state)
|
||||
{
|
||||
var localStates = new List<string>();
|
||||
var convDir = FindConversationDirectory(conversationId);
|
||||
if (!string.IsNullOrEmpty(convDir))
|
||||
{
|
||||
var stateDir = Path.Combine(convDir, "state.dict");
|
||||
if (File.Exists(stateDir))
|
||||
{
|
||||
foreach (var data in state)
|
||||
{
|
||||
localStates.Add($"{data.Key}={data.Value}");
|
||||
}
|
||||
File.WriteAllLines(stateDir, localStates);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ConversationRecord GetConversation(string conversationId)
|
||||
{
|
||||
var convDir = FindConversationDirectory(conversationId);
|
||||
if (!string.IsNullOrEmpty(convDir))
|
||||
{
|
||||
var convFile = Path.Combine(convDir, "conversation.json");
|
||||
var record = JsonSerializer.Deserialize<ConversationRecord>(convFile);
|
||||
|
||||
var dialogFile = Path.Combine(convDir, "dialogs.txt");
|
||||
if (record != null && File.Exists(dialogFile))
|
||||
{
|
||||
record.Dialog = File.ReadAllText(dialogFile);
|
||||
}
|
||||
|
||||
var stateFile = Path.Combine(convDir, "state.dict");
|
||||
if (record != null && File.Exists(stateFile))
|
||||
{
|
||||
var states = File.ReadLines(stateFile);
|
||||
record.State = states.Select(x => new KeyValueModel(x.Split('=')[0], x.Split('=')[1])).ToList();
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<ConversationRecord> GetConversations(string userId)
|
||||
{
|
||||
var records = new List<ConversationRecord>();
|
||||
var dir = Path.Combine(_dbSettings.FileRepository, _conversationSetting.DataDir);
|
||||
|
||||
foreach (var d in Directory.GetDirectories(dir))
|
||||
{
|
||||
var path = Path.Combine(d, "conversation.json");
|
||||
if (!File.Exists(path)) continue;
|
||||
|
||||
var json = File.ReadAllText(path);
|
||||
var record = JsonSerializer.Deserialize<ConversationRecord>(json, _options);
|
||||
if (record != null && record.UserId == userId)
|
||||
{
|
||||
var dialogFile = Path.Combine(d, "dialogs.txt");
|
||||
if (File.Exists(dialogFile))
|
||||
{
|
||||
record.Dialog = File.ReadAllText(dialogFile);
|
||||
}
|
||||
|
||||
var stateFile = Path.Combine(d, "state.dict");
|
||||
if (File.Exists(stateFile))
|
||||
{
|
||||
var states = File.ReadLines(stateFile);
|
||||
record.State = states.Select(x => new KeyValueModel(x.Split('=')[0], x.Split('=')[1])).ToList();
|
||||
}
|
||||
|
||||
records.Add(record);
|
||||
}
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,24 +31,15 @@ public class Router : IAgentRouting
|
|||
|
||||
public RoutingItem[] GetRoutingRecords()
|
||||
{
|
||||
var agentSettings = _services.GetRequiredService<AgentSettings>();
|
||||
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
//var filePath = Path.Combine(dbSettings.FileRepository, agentSettings.DataDir, "route.json");
|
||||
//var records = JsonSerializer.Deserialize<RoutingItem[]>(File.ReadAllText(filePath));
|
||||
|
||||
var records = db.RoutingItem.Select(x => x.ToRoutingItem()).ToArray();
|
||||
|
||||
// check if routing profile is specified
|
||||
//filePath = Path.Combine(dbSettings.FileRepository, agentSettings.DataDir, "routing-profile.json");
|
||||
|
||||
var profiles = db.RoutingProfile.ToList();
|
||||
|
||||
if (profiles != null && profiles.Any())
|
||||
{
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
var name = state.GetState("channel");
|
||||
//var profiles = JsonSerializer.Deserialize<RoutingProfile[]>(File.ReadAllText(filePath));
|
||||
var specifiedProfile = profiles.FirstOrDefault(x => x.Name == name);
|
||||
if (specifiedProfile != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -96,11 +96,9 @@ public class UserService : IUserService
|
|||
|
||||
public async Task<User> GetMyProfile()
|
||||
{
|
||||
var userId = _user.Id;
|
||||
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var user = (from u in db.User
|
||||
where u.Id == userId
|
||||
where u.ExternalId == _user.Id
|
||||
select new User
|
||||
{
|
||||
Id = u.Id,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using BotSharp.Abstraction.Repositories.Models;
|
||||
|
||||
namespace BotSharp.Plugin.MongoStorage.Collections;
|
||||
|
||||
public class ConversationCollection : MongoBase
|
||||
|
|
@ -5,6 +7,8 @@ public class ConversationCollection : MongoBase
|
|||
public Guid AgentId { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Dialog { get; set; }
|
||||
public List<KeyValueModel> State { get; set; }
|
||||
|
||||
public DateTime CreatedTime { get; set; }
|
||||
public DateTime UpdatedTime { get; set; }
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
using BotSharp.Abstraction.Conversations.Models;
|
||||
using BotSharp.Abstraction.Repositories.Models;
|
||||
using BotSharp.Plugin.MongoStorage.Collections;
|
||||
|
||||
namespace BotSharp.Plugin.MongoStorage.Repository;
|
||||
|
|
@ -210,6 +213,8 @@ public class MongoRepository : IBotSharpRepository
|
|||
AgentId = Guid.Parse(x.AgentId),
|
||||
UserId = Guid.Parse(x.UserId),
|
||||
Title = x.Title,
|
||||
Dialog = x.Dialog,
|
||||
State = x.State,
|
||||
CreatedTime = x.CreatedTime,
|
||||
UpdatedTime = x.UpdatedTime
|
||||
}).ToList();
|
||||
|
|
@ -221,6 +226,8 @@ public class MongoRepository : IBotSharpRepository
|
|||
.Set(x => x.AgentId, conversation.AgentId)
|
||||
.Set(x => x.UserId, conversation.UserId)
|
||||
.Set(x => x.Title, conversation.Title)
|
||||
.Set(x => x.Dialog, conversation.Dialog)
|
||||
.Set(x => x.State, conversation.State)
|
||||
.Set(x => x.CreatedTime, conversation.CreatedTime)
|
||||
.Set(x => x.UpdatedTime, conversation.UpdatedTime);
|
||||
_dc.Conversations.UpdateOne(filter, update, _options);
|
||||
|
|
@ -444,4 +451,116 @@ public class MongoRepository : IBotSharpRepository
|
|||
var foundAgent = Agent.FirstOrDefault(x => x.Id == agentId);
|
||||
return foundAgent;
|
||||
}
|
||||
|
||||
public void CreateNewConversation(ConversationRecord conversation)
|
||||
{
|
||||
if (conversation == null) return;
|
||||
|
||||
var collection = new ConversationCollection
|
||||
{
|
||||
Id = Guid.Parse(conversation.Id),
|
||||
AgentId = Guid.Parse(conversation.AgentId),
|
||||
UserId = Guid.Parse(conversation.UserId),
|
||||
Title = conversation.Title,
|
||||
Dialog = string.Empty,
|
||||
State = new List<KeyValueModel>(),
|
||||
CreatedTime = DateTime.UtcNow,
|
||||
UpdatedTime = DateTime.UtcNow,
|
||||
};
|
||||
|
||||
_dc.Conversations.InsertOne(collection);
|
||||
}
|
||||
|
||||
public string GetConversationDialog(string conversationId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(conversationId)) return string.Empty;
|
||||
|
||||
var filterById = Builders<ConversationCollection>.Filter.Eq(x => x.Id, Guid.Parse(conversationId));
|
||||
var foundConversation = _dc.Conversations.Find(filterById).FirstOrDefault();
|
||||
if (foundConversation == null) return string.Empty;
|
||||
|
||||
return foundConversation.Dialog;
|
||||
}
|
||||
|
||||
public void UpdateConversationDialog(string conversationId, string dialogs)
|
||||
{
|
||||
if (string.IsNullOrEmpty(conversationId)) return;
|
||||
|
||||
var filterById = Builders<ConversationCollection>.Filter.Eq(x => x.Id, Guid.Parse(conversationId));
|
||||
var foundConversation = _dc.Conversations.Find(filterById).FirstOrDefault();
|
||||
if (foundConversation == null) return;
|
||||
|
||||
var update = Builders<ConversationCollection>.Update
|
||||
.Set(x => x.Dialog, dialogs)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
||||
_dc.Conversations.UpdateOne(filterById, update);
|
||||
}
|
||||
|
||||
public List<KeyValueModel> GetConversationState(string conversationId)
|
||||
{
|
||||
var states = new List<KeyValueModel>();
|
||||
if (string.IsNullOrEmpty(conversationId)) return states;
|
||||
|
||||
var filterById = Builders<ConversationCollection>.Filter.Eq(x => x.Id, Guid.Parse(conversationId));
|
||||
var foundConversation = _dc.Conversations.Find(filterById).FirstOrDefault();
|
||||
if (foundConversation == null) return states;
|
||||
|
||||
var savedStates = foundConversation.State ?? new List<KeyValueModel>();
|
||||
return savedStates;
|
||||
}
|
||||
|
||||
public void UpdateConversationState(string conversationId, List<KeyValueModel> state)
|
||||
{
|
||||
if (string.IsNullOrEmpty(conversationId)) return;
|
||||
|
||||
var filterById = Builders<ConversationCollection>.Filter.Eq(x => x.Id, Guid.Parse(conversationId));
|
||||
var foundConversation = _dc.Conversations.Find(filterById).FirstOrDefault();
|
||||
if (foundConversation == null) return;
|
||||
|
||||
var update = Builders<ConversationCollection>.Update
|
||||
.Set(x => x.State, state)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
||||
_dc.Conversations.UpdateOne(filterById, update);
|
||||
}
|
||||
|
||||
public ConversationRecord GetConversation(string conversationId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(conversationId)) return null;
|
||||
|
||||
var filterById = Builders<ConversationCollection>.Filter.Eq(x => x.Id, Guid.Parse(conversationId));
|
||||
var found = _dc.Conversations.Find(filterById).FirstOrDefault();
|
||||
|
||||
return found != null ? new ConversationRecord
|
||||
{
|
||||
Id = found.Id.ToString(),
|
||||
AgentId = found.AgentId.ToString(),
|
||||
UserId = found.UserId.ToString(),
|
||||
Title = found.Title,
|
||||
Dialog = found.Dialog,
|
||||
State = found.State,
|
||||
CreatedTime = found.CreatedTime,
|
||||
UpdatedTime = found.UpdatedTime
|
||||
}: null;
|
||||
}
|
||||
|
||||
public List<ConversationRecord> GetConversations(string userId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(userId)) return new List<ConversationRecord>();
|
||||
|
||||
var filterByUserId = Builders<ConversationCollection>.Filter.Eq(x => x.UserId, Guid.Parse(userId));
|
||||
var conversations = _dc.Conversations.Find(filterByUserId).ToList();
|
||||
return conversations.Select(x => new ConversationRecord
|
||||
{
|
||||
Id = x.Id.ToString(),
|
||||
AgentId = x.AgentId.ToString(),
|
||||
UserId = x.UserId.ToString(),
|
||||
Title = x.Title,
|
||||
Dialog = x.Dialog,
|
||||
State = x.State,
|
||||
CreatedTime = x.CreatedTime,
|
||||
UpdatedTime = x.UpdatedTime
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue