add agent utility description

This commit is contained in:
Jicheng Lu 2025-06-04 22:15:07 -05:00
parent 49201c41f1
commit ef5f196927
6 changed files with 116 additions and 14 deletions

View file

@ -13,6 +13,7 @@ public interface IAgentService
Task<string> RefreshAgents();
Task<PagedItems<Agent>> GetAgents(AgentFilter filter);
Task<List<IdName>> GetAgentOptions(List<string>? agentIds = null, bool byName = false);
Task<IEnumerable<AgentUtility>> GetAgentUtilityOptions();
/// <summary>
/// Load agent configurations and trigger hooks

View file

@ -26,8 +26,7 @@ public class AgentUtility
public class UtilityItem
{
[JsonPropertyName("function_name")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? FunctionName { get; set; }
public string FunctionName { get; set; } = null!;
[JsonPropertyName("template_name")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@ -36,4 +35,8 @@ public class UtilityItem
[JsonPropertyName("visibility_expression")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? VisibilityExpression { get; set; }
[JsonPropertyName("description")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Description { get; set; }
}

View file

@ -0,0 +1,101 @@
using BotSharp.Abstraction.Repositories.Settings;
using System.IO;
namespace BotSharp.Core.Agents.Services;
public partial class AgentService
{
public async Task<IEnumerable<AgentUtility>> GetAgentUtilityOptions()
{
var utilities = new List<AgentUtility>();
var hooks = _services.GetServices<IAgentUtilityHook>();
foreach (var hook in hooks)
{
hook.AddUtilities(utilities);
}
utilities = utilities.Where(x => !string.IsNullOrWhiteSpace(x.Category)
&& !string.IsNullOrWhiteSpace(x.Name)
&& !x.Items.IsNullOrEmpty()).ToList();
var allItems = utilities.SelectMany(x => x.Items).ToList();
var functionNames = allItems.Select(x => x.FunctionName).Distinct().ToList();
var mapper = await GetAgentDocs(functionNames);
allItems.ForEach(x =>
{
if (mapper.ContainsKey(x.FunctionName))
{
x.Description = mapper[x.FunctionName];
}
});
return utilities;
}
#region Private methods
private async ValueTask<IDictionary<string, string>> GetAgentDocs(IEnumerable<string> names)
{
var mapper = new Dictionary<string, string>();
if (names.IsNullOrEmpty())
{
return mapper;
}
var dir = GetAgentDocDir(BuiltInAgentId.UtilityAssistant);
if (string.IsNullOrEmpty(dir))
{
return mapper;
}
var matchDocs = Directory.GetFiles(dir, "*.md")
.Where(x => names.Contains(Path.GetFileNameWithoutExtension(x)))
.ToList();
if (matchDocs.IsNullOrEmpty())
{
return mapper;
}
await foreach (var item in GetUtilityDescriptions(matchDocs))
{
mapper[item.Key] = item.Value;
}
return mapper;
}
private string GetAgentDocDir(string agentId)
{
var dbSettings = _services.GetRequiredService<BotSharpDatabaseSettings>();
var agentSettings = _services.GetRequiredService<AgentSettings>();
var dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dbSettings.FileRepository, agentSettings.DataDir, agentId, "docs");
if (!Directory.Exists(dir))
{
dir = string.Empty;
}
return dir;
}
private async IAsyncEnumerable<KeyValuePair<string, string>> GetUtilityDescriptions(IEnumerable<string> docs)
{
foreach (var doc in docs)
{
var content = string.Empty;
try
{
content = await File.ReadAllTextAsync(doc);
}
catch { }
if (string.IsNullOrWhiteSpace(content))
{
continue;
}
var fileName = Path.GetFileNameWithoutExtension(doc);
yield return new KeyValuePair<string, string>(fileName, content);
}
}
#endregion
}

View file

@ -159,17 +159,10 @@ public class AgentController : ControllerBase
}
[HttpGet("/agent/utility/options")]
public IEnumerable<AgentUtility> GetAgentUtilityOptions()
public async Task<IEnumerable<AgentUtility>> GetAgentUtilityOptions()
{
var utilities = new List<AgentUtility>();
var hooks = _services.GetServices<IAgentUtilityHook>();
foreach (var hook in hooks)
{
hook.AddUtilities(utilities);
}
return utilities.Where(x => !string.IsNullOrWhiteSpace(x.Category)
&& !string.IsNullOrWhiteSpace(x.Name)
&& !x.Items.IsNullOrEmpty()).ToList();
var agentService = _services.GetRequiredService<IAgentService>();
return await agentService.GetAgentUtilityOptions();
}
[HttpGet("/agent/labels")]

View file

@ -48,7 +48,7 @@ public class AgentUtilityMongoElement
public class AgentUtilityItemMongoElement
{
public string? FunctionName { get; set; }
public string FunctionName { get; set; }
public string? TemplateName { get; set; }
public string? VisibilityExpression { get; set; }
}

View file

@ -6,7 +6,6 @@ using BotSharp.Abstraction.Models;
using BotSharp.Abstraction.Plugins.Models;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Utilities;
using NetTopologySuite.Algorithm;
namespace BotSharp.Plugin.Google.Core
{
@ -111,5 +110,10 @@ namespace BotSharp.Plugin.Google.Core
{
return new PluginDef();
}
public Task<IEnumerable<AgentUtility>> GetAgentUtilityOptions()
{
return Task.FromResult(Enumerable.Empty<AgentUtility>());
}
}
}