refine agent response

This commit is contained in:
Jicheng Lu 2023-09-09 16:44:25 -05:00
parent 0955cf5b4e
commit f5e006edd7
18 changed files with 81 additions and 71 deletions

View file

@ -26,7 +26,7 @@ public class Agent
/// <summary>
/// Responses
/// </summary>
public List<string> Responses { get; set; }
public List<AgentResponse> Responses { get; set; }
/// <summary>
/// Domain knowledges
@ -69,9 +69,9 @@ public class Agent
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;
}

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;
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)
{
@ -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.Users.Models;
@ -32,8 +31,8 @@ public interface IBotSharpRepository
string GetConversationDialog(string conversationId);
void UpdateConversationDialog(string conversationId, string dialogs);
List<KeyValueModel> GetConversationStates(string conversationId);
void UpdateConversationStates(string conversationId, List<KeyValueModel> states);
List<StateKeyValue> GetConversationStates(string conversationId);
void UpdateConversationStates(string conversationId, List<StateKeyValue> states);
Conversation GetConversation(string conversationId);
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;
namespace BotSharp.Abstraction.Repositories.Records;
@ -20,7 +19,7 @@ public class ConversationRecord : RecordBase
public string Dialog { get; set; }
[JsonIgnore]
public List<KeyValueModel> States { get; set; }
public List<StateKeyValue> States { get; set; }
[Required]
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;

View file

@ -108,15 +108,20 @@ public partial class AgentService
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");
if (!Directory.Exists(responseDir)) return responses;
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;
}

View file

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

View file

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

View file

@ -1,5 +1,4 @@
using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Repositories.Models;
using System.IO;
using FunctionDef = BotSharp.Abstraction.Functions.Models.FunctionDef;
using BotSharp.Abstraction.Users.Models;
@ -454,9 +453,9 @@ public class FileRepository : IBotSharpRepository
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);
if (!string.IsNullOrEmpty(convDir))
{
@ -467,7 +466,7 @@ public class FileRepository : IBotSharpRepository
foreach (var line in dict)
{
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;
}
public void UpdateConversationStates(string conversationId, List<KeyValueModel> states)
public void UpdateConversationStates(string conversationId, List<StateKeyValue> states)
{
var localStates = new List<string>();
var convDir = FindConversationDirectory(conversationId);
@ -532,7 +531,7 @@ public class FileRepository : IBotSharpRepository
if (record != null && File.Exists(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;

View file

@ -19,12 +19,6 @@ public class ResponseTemplateService : IResponseTemplateService
public async Task<string> RenderFunctionResponse(string agentId, RoleDialogModel message)
{
// 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 responses = db.GetAgentResponses(agentId, "func", message.FunctionName);
@ -34,7 +28,6 @@ public class ResponseTemplateService : IResponseTemplateService
}
var randomIndex = new Random().Next(0, responses.Count);
//var template = File.ReadAllText(responses[randomIndex]);
var template = responses[randomIndex];
var render = _services.GetRequiredService<ITemplateRender>();

View file

@ -8,7 +8,7 @@ public class AgentCreationModel
public string Description { get; set; }
public string Instruction { 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 Agent ToAgent()

View file

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

View file

@ -9,7 +9,7 @@ public class AgentViewModel
public string Description { get; set; }
public string Instruction { 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 DateTime UpdatedDateTime { get; set; }

View file

@ -1,3 +1,5 @@
using BotSharp.Abstraction.Agents.Models;
namespace BotSharp.Plugin.MongoStorage.Collections;
public class AgentCollection : MongoBase
@ -6,7 +8,7 @@ public class AgentCollection : MongoBase
public string Description { get; set; }
public string Instruction { 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 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;
@ -7,7 +7,7 @@ public class ConversationCollection : MongoBase
public Guid AgentId { get; set; }
public Guid UserId { 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 UpdatedTime { get; set; }
}

View file

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