Merge pull request #138 from iceljc/features/add-mongo-implementation

refine agent response
This commit is contained in:
Haiping 2023-09-10 21:54:48 -05:00 committed by GitHub
commit 54afdfef3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 81 additions and 71 deletions

View file

@ -26,7 +26,7 @@ public class Agent
/// <summary> /// <summary>
/// Responses /// Responses
/// </summary> /// </summary>
public List<string> Responses { get; set; } public List<AgentResponse> Responses { get; set; }
/// <summary> /// <summary>
/// Domain knowledges /// Domain knowledges
@ -69,9 +69,9 @@ public class Agent
return this; return this;
} }
public Agent SetResponses(List<string> responses) public Agent SetResponses(List<AgentResponse> responses)
{ {
Responses = responses ?? new List<string>(); ; Responses = responses ?? new List<AgentResponse>(); ;
return this; return this;
} }

View file

@ -0,0 +1,20 @@
namespace BotSharp.Abstraction.Agents.Models;
public class AgentResponse
{
public string Prefix { get; set; }
public string Intent { get; set; }
public string Content { get; set; }
public AgentResponse()
{
}
public AgentResponse(string prefix, string intent, string content)
{
Prefix = prefix;
Intent = intent;
Content = content;
}
}

View file

@ -1,5 +1,3 @@
using BotSharp.Abstraction.Repositories.Models;
namespace BotSharp.Abstraction.Conversations.Models; namespace BotSharp.Abstraction.Conversations.Models;
public class ConversationState : Dictionary<string, string> public class ConversationState : Dictionary<string, string>
@ -9,7 +7,7 @@ public class ConversationState : Dictionary<string, string>
} }
public ConversationState(List<KeyValueModel> pairs) public ConversationState(List<StateKeyValue> pairs)
{ {
foreach (var pair in pairs) foreach (var pair in pairs)
{ {
@ -17,8 +15,8 @@ public class ConversationState : Dictionary<string, string>
} }
} }
public List<KeyValueModel> ToKeyValueList() public List<StateKeyValue> ToKeyValueList()
{ {
return this.Select(x => new KeyValueModel(x.Key, x.Value)).ToList(); return this.Select(x => new StateKeyValue(x.Key, x.Value)).ToList();
} }
} }

View file

@ -0,0 +1,18 @@
namespace BotSharp.Abstraction.Conversations.Models;
public class StateKeyValue
{
public string Key { get; set; }
public string Value { get; set; }
public StateKeyValue()
{
}
public StateKeyValue(string key, string value)
{
Key = key;
Value = value;
}
}

View file

@ -1,4 +1,3 @@
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;
@ -32,8 +31,8 @@ public interface IBotSharpRepository
string GetConversationDialog(string conversationId); string GetConversationDialog(string conversationId);
void UpdateConversationDialog(string conversationId, string dialogs); void UpdateConversationDialog(string conversationId, string dialogs);
List<KeyValueModel> GetConversationStates(string conversationId); List<StateKeyValue> GetConversationStates(string conversationId);
void UpdateConversationStates(string conversationId, List<KeyValueModel> states); void UpdateConversationStates(string conversationId, List<StateKeyValue> states);
Conversation GetConversation(string conversationId); Conversation GetConversation(string conversationId);
List<Conversation> GetConversations(string userId); List<Conversation> GetConversations(string userId);

View file

@ -1,19 +0,0 @@
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;
}
}

View file

@ -1,4 +1,3 @@
using BotSharp.Abstraction.Repositories.Models;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace BotSharp.Abstraction.Repositories.Records; namespace BotSharp.Abstraction.Repositories.Records;
@ -20,7 +19,7 @@ public class ConversationRecord : RecordBase
public string Dialog { get; set; } public string Dialog { get; set; }
[JsonIgnore] [JsonIgnore]
public List<KeyValueModel> States { get; set; } public List<StateKeyValue> States { get; set; }
[Required] [Required]
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow; public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;

View file

@ -108,15 +108,20 @@ public partial class AgentService
return functions; return functions;
} }
private List<string> FetchResponsesFromFile(string fileDir) private List<AgentResponse> FetchResponsesFromFile(string fileDir)
{ {
var responses = new List<string>(); var responses = new List<AgentResponse>();
var responseDir = Path.Combine(fileDir, "responses"); var responseDir = Path.Combine(fileDir, "responses");
if (!Directory.Exists(responseDir)) return responses; if (!Directory.Exists(responseDir)) return responses;
foreach (var file in Directory.GetFiles(responseDir)) foreach (var file in Directory.GetFiles(responseDir))
{ {
responses.Add(File.ReadAllText(file)); var fileName = file.Split(Path.DirectorySeparatorChar).Last();
var splits = fileName.Split('.');
var prefix = splits[0];
var intent = splits[1];
var content = File.ReadAllText(file);
responses.Add(new AgentResponse(prefix, intent, content));
} }
return responses; return responses;
} }

View file

@ -1,5 +1,4 @@
using BotSharp.Abstraction.Repositories; using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Repositories.Models;
using System.IO; using System.IO;
namespace BotSharp.Core.Conversations.Services; namespace BotSharp.Core.Conversations.Services;
@ -16,7 +15,7 @@ public class ConversationStateService : IConversationStateService, IDisposable
private string _conversationId; private string _conversationId;
private string _file; private string _file;
private readonly IBotSharpRepository _db; private readonly IBotSharpRepository _db;
private List<KeyValueModel> _savedStates; private List<StateKeyValue> _savedStates;
public ConversationStateService(ILogger<ConversationStateService> logger, public ConversationStateService(ILogger<ConversationStateService> logger,
IServiceProvider services, IServiceProvider services,
@ -78,11 +77,11 @@ public class ConversationStateService : IConversationStateService, IDisposable
return; return;
} }
var states = new List<KeyValueModel>(); var states = new List<StateKeyValue>();
foreach (var dic in _states) foreach (var dic in _states)
{ {
states.Add(new KeyValueModel(dic.Key, dic.Value)); states.Add(new StateKeyValue(dic.Key, dic.Value));
} }
_db.UpdateConversationStates(_conversationId, states); _db.UpdateConversationStates(_conversationId, states);

View file

@ -1,6 +1,5 @@
using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Repositories; using BotSharp.Abstraction.Repositories;
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 Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
@ -128,7 +127,7 @@ public class BotSharpDbContext : Database, IBotSharpRepository
throw new NotImplementedException(); throw new NotImplementedException();
} }
public List<KeyValueModel> GetConversationStates(string conversationId) public List<StateKeyValue> GetConversationStates(string conversationId)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -148,7 +147,7 @@ public class BotSharpDbContext : Database, IBotSharpRepository
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void UpdateConversationStates(string conversationId, List<KeyValueModel> states) public void UpdateConversationStates(string conversationId, List<StateKeyValue> states)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View file

@ -1,5 +1,4 @@
using BotSharp.Abstraction.Repositories; using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Repositories.Models;
using System.IO; using System.IO;
using FunctionDef = BotSharp.Abstraction.Functions.Models.FunctionDef; using FunctionDef = BotSharp.Abstraction.Functions.Models.FunctionDef;
using BotSharp.Abstraction.Users.Models; using BotSharp.Abstraction.Users.Models;
@ -454,9 +453,9 @@ public class FileRepository : IBotSharpRepository
return; return;
} }
public List<KeyValueModel> GetConversationStates(string conversationId) public List<StateKeyValue> GetConversationStates(string conversationId)
{ {
var curStates = new List<KeyValueModel>(); var curStates = new List<StateKeyValue>();
var convDir = FindConversationDirectory(conversationId); var convDir = FindConversationDirectory(conversationId);
if (!string.IsNullOrEmpty(convDir)) if (!string.IsNullOrEmpty(convDir))
{ {
@ -467,7 +466,7 @@ public class FileRepository : IBotSharpRepository
foreach (var line in dict) foreach (var line in dict)
{ {
var data = line.Split('='); var data = line.Split('=');
curStates.Add(new KeyValueModel(data[0], data[1])); curStates.Add(new StateKeyValue(data[0], data[1]));
} }
} }
} }
@ -495,7 +494,7 @@ public class FileRepository : IBotSharpRepository
return null; return null;
} }
public void UpdateConversationStates(string conversationId, List<KeyValueModel> states) public void UpdateConversationStates(string conversationId, List<StateKeyValue> states)
{ {
var localStates = new List<string>(); var localStates = new List<string>();
var convDir = FindConversationDirectory(conversationId); var convDir = FindConversationDirectory(conversationId);
@ -532,7 +531,7 @@ public class FileRepository : IBotSharpRepository
if (record != null && File.Exists(stateFile)) if (record != null && File.Exists(stateFile))
{ {
var states = File.ReadLines(stateFile); var states = File.ReadLines(stateFile);
record.States = new ConversationState(states.Select(x => new KeyValueModel(x.Split('=')[0], x.Split('=')[1])).ToList()); record.States = new ConversationState(states.Select(x => new StateKeyValue(x.Split('=')[0], x.Split('=')[1])).ToList());
} }
return record; return record;

View file

@ -19,12 +19,6 @@ public class ResponseTemplateService : IResponseTemplateService
public async Task<string> RenderFunctionResponse(string agentId, RoleDialogModel message) public async Task<string> RenderFunctionResponse(string agentId, RoleDialogModel message)
{ {
// Find response template // Find response template
//var agentService = _services.GetRequiredService<IAgentService>();
//var dir = Path.Combine(agentService.GetAgentDataDir(agentId), "responses");
//var responses = Directory.GetFiles(dir)
// .Where(f => f.Split(Path.DirectorySeparatorChar).Last().Split('.')[1] == message.FunctionName)
// .ToList();
var db = _services.GetRequiredService<IBotSharpRepository>(); var db = _services.GetRequiredService<IBotSharpRepository>();
var responses = db.GetAgentResponses(agentId, "func", message.FunctionName); var responses = db.GetAgentResponses(agentId, "func", message.FunctionName);
@ -34,7 +28,6 @@ public class ResponseTemplateService : IResponseTemplateService
} }
var randomIndex = new Random().Next(0, responses.Count); var randomIndex = new Random().Next(0, responses.Count);
//var template = File.ReadAllText(responses[randomIndex]);
var template = responses[randomIndex]; var template = responses[randomIndex];
var render = _services.GetRequiredService<ITemplateRender>(); var render = _services.GetRequiredService<ITemplateRender>();

View file

@ -8,7 +8,7 @@ public class AgentCreationModel
public string Description { get; set; } public string Description { get; set; }
public string Instruction { get; set; } public string Instruction { get; set; }
public List<string> Functions { get; set; } public List<string> Functions { get; set; }
public List<string> Responses { get; set; } public List<AgentResponse> Responses { get; set; }
public bool IsPublic { get; set; } public bool IsPublic { get; set; }
public Agent ToAgent() public Agent ToAgent()

View file

@ -25,7 +25,7 @@ public class AgentUpdateModel
/// <summary> /// <summary>
/// Routes /// Routes
/// </summary> /// </summary>
public List<string> Responses { get; set; } public List<AgentResponse> Responses { get; set; }
public Agent ToAgent() public Agent ToAgent()
{ {

View file

@ -9,7 +9,7 @@ public class AgentViewModel
public string Description { get; set; } public string Description { get; set; }
public string Instruction { get; set; } public string Instruction { get; set; }
public List<string> Functions { get; set; } public List<string> Functions { get; set; }
public List<string> Responses { get; set; } public List<AgentResponse> Responses { get; set; }
public bool IsPublic { get; set; } public bool IsPublic { get; set; }
public DateTime UpdatedDateTime { get; set; } public DateTime UpdatedDateTime { get; set; }

View file

@ -1,3 +1,5 @@
using BotSharp.Abstraction.Agents.Models;
namespace BotSharp.Plugin.MongoStorage.Collections; namespace BotSharp.Plugin.MongoStorage.Collections;
public class AgentCollection : MongoBase public class AgentCollection : MongoBase
@ -6,7 +8,7 @@ public class AgentCollection : MongoBase
public string Description { get; set; } public string Description { get; set; }
public string Instruction { get; set; } public string Instruction { get; set; }
public List<string> Functions { get; set; } public List<string> Functions { get; set; }
public List<string> Responses { get; set; } public List<AgentResponse> Responses { get; set; }
public bool IsPublic { get; set; } public bool IsPublic { get; set; }
public DateTime CreatedTime { get; set; } public DateTime CreatedTime { get; set; }

View file

@ -1,4 +1,4 @@
using BotSharp.Abstraction.Repositories.Models; using BotSharp.Abstraction.Conversations.Models;
namespace BotSharp.Plugin.MongoStorage.Collections; namespace BotSharp.Plugin.MongoStorage.Collections;
@ -7,7 +7,7 @@ public class ConversationCollection : MongoBase
public Guid AgentId { get; set; } public Guid AgentId { get; set; }
public Guid UserId { get; set; } public Guid UserId { get; set; }
public string Title { get; set; } public string Title { get; set; }
public List<KeyValueModel> States { get; set; } public List<StateKeyValue> States { get; set; }
public DateTime CreatedTime { get; set; } public DateTime CreatedTime { get; set; }
public DateTime UpdatedTime { get; set; } public DateTime UpdatedTime { get; set; }
} }

View file

@ -1,6 +1,5 @@
using BotSharp.Abstraction.Agents.Models; using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Conversations.Models; using BotSharp.Abstraction.Conversations.Models;
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;
@ -225,7 +224,7 @@ public class MongoRepository : IBotSharpRepository
AgentId = Guid.Parse(x.AgentId), AgentId = Guid.Parse(x.AgentId),
UserId = Guid.Parse(x.UserId), UserId = Guid.Parse(x.UserId),
Title = x.Title, Title = x.Title,
States = x.States?.ToKeyValueList() ?? new List<KeyValueModel>(), States = x.States?.ToKeyValueList() ?? new List<StateKeyValue>(),
CreatedTime = x.CreatedTime, CreatedTime = x.CreatedTime,
UpdatedTime = x.UpdatedTime UpdatedTime = x.UpdatedTime
}).ToList(); }).ToList();
@ -457,8 +456,7 @@ public class MongoRepository : IBotSharpRepository
var agent = Agents.FirstOrDefault(x => x.Id == agentId); var agent = Agents.FirstOrDefault(x => x.Id == agentId);
if (agent == null) return responses; if (agent == null) return responses;
// Should use name to filter by prefix return agent.Responses.Where(x => x.Prefix == prefix && x.Intent == intent).Select(x => x.Content).ToList();
return agent.Responses.Where(x => x.StartsWith(prefix + "." + intent)).ToList();
} }
public Agent GetAgent(string agentId) public Agent GetAgent(string agentId)
@ -477,7 +475,7 @@ public class MongoRepository : IBotSharpRepository
AgentId = Guid.Parse(conversation.AgentId), AgentId = Guid.Parse(conversation.AgentId),
UserId = Guid.Parse(conversation.UserId), UserId = Guid.Parse(conversation.UserId),
Title = conversation.Title, Title = conversation.Title,
States = conversation.States?.ToKeyValueList() ?? new List<KeyValueModel>(), States = conversation.States?.ToKeyValueList() ?? new List<StateKeyValue>(),
CreatedTime = DateTime.UtcNow, CreatedTime = DateTime.UtcNow,
UpdatedTime = DateTime.UtcNow, UpdatedTime = DateTime.UtcNow,
}; };
@ -523,18 +521,18 @@ public class MongoRepository : IBotSharpRepository
_dc.Conversations.UpdateOne(filterConv, updateConv); _dc.Conversations.UpdateOne(filterConv, updateConv);
} }
public List<KeyValueModel> GetConversationStates(string conversationId) public List<StateKeyValue> GetConversationStates(string conversationId)
{ {
var states = new List<KeyValueModel>(); var states = new List<StateKeyValue>();
if (string.IsNullOrEmpty(conversationId)) return states; if (string.IsNullOrEmpty(conversationId)) return states;
var filter = Builders<ConversationCollection>.Filter.Eq(x => x.Id, Guid.Parse(conversationId)); var filter = Builders<ConversationCollection>.Filter.Eq(x => x.Id, Guid.Parse(conversationId));
var foundConversation = _dc.Conversations.Find(filter).FirstOrDefault(); var foundConversation = _dc.Conversations.Find(filter).FirstOrDefault();
var savedStates = foundConversation?.States ?? new List<KeyValueModel>(); var savedStates = foundConversation?.States ?? new List<StateKeyValue>();
return savedStates; return savedStates;
} }
public void UpdateConversationStates(string conversationId, List<KeyValueModel> states) public void UpdateConversationStates(string conversationId, List<StateKeyValue> states)
{ {
if (string.IsNullOrEmpty(conversationId)) return; if (string.IsNullOrEmpty(conversationId)) return;
@ -568,7 +566,7 @@ public class MongoRepository : IBotSharpRepository
UserId = conv.UserId.ToString(), UserId = conv.UserId.ToString(),
Title = conv.Title, Title = conv.Title,
Dialog = dialog?.Dialog ?? string.Empty, Dialog = dialog?.Dialog ?? string.Empty,
States = new ConversationState(conv.States ?? new List<KeyValueModel>()), States = new ConversationState(conv.States ?? new List<StateKeyValue>()),
CreatedTime = conv.CreatedTime, CreatedTime = conv.CreatedTime,
UpdatedTime = conv.UpdatedTime UpdatedTime = conv.UpdatedTime
}; };