Merge pull request #405 from iceljc/features/refine-agent-refresh

refine agent refresh
This commit is contained in:
C. Oceania 2024-04-11 05:30:13 -05:00 committed by GitHub
commit 5380ecba7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 148 additions and 113 deletions

View file

@ -10,7 +10,7 @@ namespace BotSharp.Abstraction.Agents;
public interface IAgentService
{
Task<Agent> CreateAgent(Agent agent);
Task RefreshAgents();
Task<string> RefreshAgents();
Task<PagedItems<Agent>> GetAgents(AgentFilter filter);
/// <summary>
@ -37,7 +37,7 @@ public interface IAgentService
Task<bool> DeleteAgent(string id);
Task UpdateAgent(Agent agent, AgentField updateField);
Task UpdateAgentFromFile(string id);
Task<string> UpdateAgentFromFile(string id);
string GetDataDir();
string GetAgentDataDir(string agentId);

View file

@ -32,6 +32,7 @@ public interface IBotSharpRepository
void BulkInsertAgents(List<Agent> agents);
void BulkInsertUserAgents(List<UserAgent> userAgents);
bool DeleteAgents();
bool DeleteAgent(string agentId);
List<string> GetAgentResponses(string agentId, string prefix, string intent);
string GetAgentTemplate(string agentId, string templateName);
#endregion
@ -42,7 +43,7 @@ public interface IBotSharpRepository
void InsertAgentTask(AgentTask task);
void BulkInsertAgentTasks(List<AgentTask> tasks);
void UpdateAgentTask(AgentTask task, AgentTaskField field);
bool DeleteAgentTask(string agentId, string taskId);
bool DeleteAgentTask(string agentId, List<string> taskIds);
bool DeleteAgentTasks();
#endregion

View file

@ -1,55 +1,79 @@
using BotSharp.Abstraction.Tasks.Models;
using System.IO;
namespace BotSharp.Core.Agents.Services;
public partial class AgentService
{
public async Task RefreshAgents()
public async Task<string> RefreshAgents()
{
var isAgentDeleted = _db.DeleteAgents();
var isTaskDeleted = _db.DeleteAgentTasks();
if (!isAgentDeleted) return;
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
var agentDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
dbSettings.FileRepository,
_agentSettings.DataDir);
string refreshResult;
if (!Directory.Exists(agentDir))
{
refreshResult = $"Cannot find the directory: {agentDir}";
return refreshResult;
}
var user = _db.GetUserById(_user.Id);
var agents = new List<Agent>();
var userAgents = new List<UserAgent>();
var agentTasks = new List<AgentTask>();
var refreshedAgents = new List<string>();
foreach (var dir in Directory.GetDirectories(agentDir))
{
var agentJson = File.ReadAllText(Path.Combine(dir, "agent.json"));
var agent = JsonSerializer.Deserialize<Agent>(agentJson, _options);
if (agent == null) continue;
try
{
var agentJson = File.ReadAllText(Path.Combine(dir, "agent.json"));
var agent = JsonSerializer.Deserialize<Agent>(agentJson, _options);
if (agent == null)
{
_logger.LogError($"Cannot find agent in file directory: {dir}");
continue;
}
var functions = FetchFunctionsFromFile(dir);
var instruction = FetchInstructionFromFile(dir);
var responses = FetchResponsesFromFile(dir);
var templates = FetchTemplatesFromFile(dir);
var samples = FetchSamplesFromFile(dir);
agent.SetInstruction(instruction)
.SetTemplates(templates)
.SetFunctions(functions)
.SetResponses(responses)
.SetSamples(samples);
agents.Add(agent);
var functions = FetchFunctionsFromFile(dir);
var instruction = FetchInstructionFromFile(dir);
var responses = FetchResponsesFromFile(dir);
var templates = FetchTemplatesFromFile(dir);
var samples = FetchSamplesFromFile(dir);
agent.SetInstruction(instruction)
.SetTemplates(templates)
.SetFunctions(functions)
.SetResponses(responses)
.SetSamples(samples);
var userAgent = BuildUserAgent(agent.Id, user.Id);
userAgents.Add(userAgent);
var userAgent = BuildUserAgent(agent.Id, user.Id);
var tasks = FetchTasksFromFile(dir);
var tasks = FetchTasksFromFile(dir);
agentTasks.AddRange(tasks);
var isAgentDeleted = _db.DeleteAgent(agent.Id);
if (isAgentDeleted)
{
_db.BulkInsertAgents(new List<Agent> { agent });
_db.BulkInsertUserAgents(new List<UserAgent> { userAgent });
_db.BulkInsertAgentTasks(tasks);
refreshedAgents.Add(agent.Name);
}
}
catch (Exception ex)
{
_logger.LogError($"Failed to migrate agent in file directory: {dir}\r\nError: {ex.Message}");
}
}
_db.BulkInsertAgents(agents);
_db.BulkInsertUserAgents(userAgents);
_db.BulkInsertAgentTasks(agentTasks);
if (!refreshedAgents.IsNullOrEmpty())
{
Utilities.ClearCache();
refreshResult = $"Agents are migrated! {string.Join("\r\n", refreshedAgents)}";
}
else
{
refreshResult = "No agent gets refreshed!";
}
Utilities.ClearCache();
_logger.LogInformation(refreshResult);
return refreshResult;
}
}

View file

@ -39,11 +39,13 @@ public partial class AgentService
await Task.CompletedTask;
}
public async Task UpdateAgentFromFile(string id)
public async Task<string> UpdateAgentFromFile(string id)
{
var agent = _db.GetAgent(id);
if (agent == null) return;
if (agent == null)
{
return $"Cannot find agent ${id}";
}
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
var agentSettings = _services.GetRequiredService<AgentSettings>();
@ -53,7 +55,12 @@ public partial class AgentService
var clonedAgent = Agent.Clone(agent);
var foundAgent = FetchAgentFileById(agent.Id, filePath);
if (foundAgent != null)
if (foundAgent == null)
{
return $"Cannot find agent {agent.Name} in file directory: {filePath}";
}
try
{
clonedAgent.SetId(foundAgent.Id)
.SetName(foundAgent.Name)
@ -71,15 +78,19 @@ public partial class AgentService
.SetLlmConfig(foundAgent.LlmConfig);
_db.UpdateAgent(clonedAgent, AgentField.All);
Utilities.ClearCache();
return $"Agent {agent.Name} has been migrated!";
}
catch (Exception ex)
{
return $"Failed to migrate agent {agent.Name} in file directory {filePath}.\r\nError: {ex.Message}";
}
await Task.CompletedTask;
}
private Agent FetchAgentFileById(string agentId, string filePath)
private Agent? FetchAgentFileById(string agentId, string filePath)
{
if (!Directory.Exists(filePath)) return null;
foreach (var dir in Directory.GetDirectories(filePath))
{
var agentJson = File.ReadAllText(Path.Combine(dir, "agent.json"));

View file

@ -73,86 +73,57 @@ public class BotSharpDbContext : Database, IBotSharpRepository
#region Agent
public Agent GetAgent(string agentId)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public List<Agent> GetAgents(AgentFilter filter)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public List<Agent> GetAgentsByUser(string userId)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public void UpdateAgent(Agent agent, AgentField field)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public string GetAgentTemplate(string agentId, string templateName)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public List<string> GetAgentResponses(string agentId, string prefix, string intent)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public void BulkInsertAgents(List<Agent> agents)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public void BulkInsertUserAgents(List<UserAgent> userAgents)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public bool DeleteAgents()
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public bool DeleteAgent(string agentId)
=> throw new NotImplementedException();
#endregion
#region Agent Task
public PagedItems<AgentTask> GetAgentTasks(AgentTaskFilter filter)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public AgentTask? GetAgentTask(string agentId, string taskId)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public void InsertAgentTask(AgentTask task)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public void BulkInsertAgentTasks(List<AgentTask> tasks)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public void UpdateAgentTask(AgentTask task, AgentTaskField field)
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
public bool DeleteAgentTask(string agentId, string taskId)
{
throw new NotImplementedException();
}
public bool DeleteAgentTask(string agentId, List<string> taskIds)
=> throw new NotImplementedException();
public bool DeleteAgentTasks()
{
throw new NotImplementedException();
}
=> throw new NotImplementedException();
#endregion
#region Conversation

View file

@ -1,9 +1,4 @@
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Tasks.Models;
using Microsoft.Extensions.Logging;
using System.IO;
namespace BotSharp.Core.Repository
@ -419,5 +414,10 @@ namespace BotSharp.Core.Repository
{
return false;
}
public bool DeleteAgent(string agentId)
{
return false;
}
}
}

View file

@ -1,7 +1,5 @@
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Tasks.Models;
using System.IO;
using System.Threading.Tasks;
namespace BotSharp.Core.Repository;
@ -192,19 +190,25 @@ public partial class FileRepository
File.WriteAllText(taskFile, fileContent);
}
public bool DeleteAgentTask(string agentId, string taskId)
public bool DeleteAgentTask(string agentId, List<string> taskIds)
{
var agentDir = Path.Combine(_dbSettings.FileRepository, _agentSettings.DataDir, agentId);
if (!Directory.Exists(agentDir)) return false;
if (!Directory.Exists(agentDir) || taskIds.IsNullOrEmpty()) return false;
var taskDir = Path.Combine(agentDir, "tasks");
if (!Directory.Exists(taskDir)) return false;
var taskFile = FindTaskFileById(taskDir, taskId);
if (string.IsNullOrWhiteSpace(taskFile)) return false;
var deletedTasks = new List<string>();
foreach (var taskId in taskIds)
{
var taskFile = FindTaskFileById(taskDir, taskId);
if (string.IsNullOrWhiteSpace(taskFile)) continue;
File.Delete(taskFile);
return true;
File.Delete(taskFile);
deletedTasks.Add(taskId);
}
return deletedTasks.Any();
}
public bool DeleteAgentTasks()

View file

@ -72,7 +72,7 @@ public class AgentTaskService : IAgentTaskService
public async Task<bool> DeleteTask(string agentId, string taskId)
{
var db = _services.GetRequiredService<IBotSharpRepository>();
var isDeleted = db.DeleteAgentTask(agentId, taskId);
var isDeleted = db.DeleteAgentTask(agentId, new List<string> { taskId });
return await Task.FromResult(isDeleted);
}
}

View file

@ -84,15 +84,15 @@ public class AgentController : ControllerBase
}
[HttpPost("/refresh-agents")]
public async Task RefreshAgents()
public async Task<string> RefreshAgents()
{
await _agentService.RefreshAgents();
return await _agentService.RefreshAgents();
}
[HttpPut("/agent/file/{agentId}")]
public async Task UpdateAgentFromFile([FromRoute] string agentId)
public async Task<string> UpdateAgentFromFile([FromRoute] string agentId)
{
await _agentService.UpdateAgentFromFile(agentId);
return await _agentService.UpdateAgentFromFile(agentId);
}
[HttpPut("/agent/{agentId}")]

View file

@ -398,7 +398,27 @@ public partial class MongoRepository
{
return false;
}
}
public bool DeleteAgent(string agentId)
{
try
{
if (string.IsNullOrEmpty(agentId)) return false;
var agentFilter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
var agentUserFilter = Builders<UserAgentDocument>.Filter.Eq(x => x.AgentId, agentId);
var agentTaskFilter = Builders<AgentTaskDocument>.Filter.Eq(x => x.AgentId, agentId);
_dc.Agents.DeleteOne(agentFilter);
_dc.UserAgents.DeleteMany(agentUserFilter);
_dc.AgentTasks.DeleteMany(agentTaskFilter);
return true;
}
catch
{
return false;
}
}
private Agent TransformAgentDocument(AgentDocument? agentDoc)

View file

@ -155,12 +155,16 @@ public partial class MongoRepository
_dc.AgentTasks.ReplaceOne(filter, taskDoc);
}
public bool DeleteAgentTask(string agentId, string taskId)
public bool DeleteAgentTask(string agentId, List<string> taskIds)
{
if (string.IsNullOrEmpty(taskId)) return false;
if (taskIds.IsNullOrEmpty()) return false;
var filter = Builders<AgentTaskDocument>.Filter.Eq(x => x.Id, taskId);
var taskDeleted = _dc.AgentTasks.DeleteOne(filter);
var builder = Builders<AgentTaskDocument>.Filter;
var filters = new List<FilterDefinition<AgentTaskDocument>>
{
builder.In(x => x.Id, taskIds)
};
var taskDeleted = _dc.AgentTasks.DeleteMany(builder.And(filters));
return taskDeleted.DeletedCount > 0;
}