AgentTask

This commit is contained in:
Haiping Chen 2024-02-02 16:36:05 -06:00
parent b29b074d0a
commit a8c2b49d6f
27 changed files with 314 additions and 24 deletions

View file

@ -102,6 +102,7 @@ BotSharp uses component design, the kernel is kept to a minimum, and business fu
- BotSharp.Plugin.PaddleSharp
#### Tools
- BotSharp.Plugin.Dashboard
- BotSharp.Plugin.RoutingSpeeder
- BotSharp.Plugin.WebDriver
- BotSharp.Plugin.PizzaBot

View file

@ -56,7 +56,7 @@ master_doc = 'index'
# General information about the project.
project = 'BotSharp'
copyright = 'Since 2018, Haiping Chen'
copyright = 'Since 2018, SciSharp STACK'
author = 'Haiping Chen'
# The version info for the project you're documenting, acts as replacement for
@ -64,9 +64,9 @@ author = 'Haiping Chen'
# built documents.
#
# The short X.Y version.
version = '0.21'
version = '0.23'
# The full version, including alpha/beta/rc tags.
release = '0.21.0'
release = '0.23.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View file

@ -1,6 +1,7 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Plugins.Models;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Tasks.Models;
namespace BotSharp.Abstraction.Agents.Models;
@ -36,6 +37,13 @@ public class Agent
public List<AgentTemplate> Templates { get; set; }
= new List<AgentTemplate>();
/// <summary>
/// Agent tasks
/// </summary>
[JsonIgnore]
public List<AgentTask> Tasks { get; set; }
= new List<AgentTask>();
/// <summary>
/// Samples
/// </summary>
@ -136,6 +144,12 @@ public class Agent
return this;
}
public Agent SetTasks(List<AgentTask> tasks)
{
Tasks = tasks ?? new List<AgentTask>();
return this;
}
public Agent SetFunctions(List<FunctionDef> functions)
{
Functions = functions ?? new List<FunctionDef>();

View file

@ -6,5 +6,6 @@ public interface ILlmProviderService
{
LlmModelSetting GetSetting(string provider, string model);
List<string> GetProviders();
LlmModelSetting GetProviderModel(string provider, string id);
List<LlmModelSetting> GetProviderModels(string provider);
}

View file

@ -0,0 +1,7 @@
namespace BotSharp.Abstraction.Repositories.Filters;
public class AgentTaskFilter
{
public Pagination Pager { get; set; } = new Pagination();
public string? AgentId { get; set; }
}

View file

@ -0,0 +1,7 @@
public class TaskExecutionStatus
{
public const string New = "new";
public const string Running = "running";
public const string Success = "success";
public const string Failed = "failed";
}

View file

@ -0,0 +1,9 @@
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Tasks.Models;
namespace BotSharp.Abstraction.Tasks;
public interface IAgentTaskService
{
Task<PagedItems<AgentTask>> GetTasks(AgentTaskFilter filter);
}

View file

@ -0,0 +1,22 @@
namespace BotSharp.Abstraction.Tasks.Models;
public class AgentTask
{
public string Id { get; set; }
public string Name { get; set; }
public string? Description { get; set; }
public string Content { get; set; }
public bool Enabled { get; set; }
public DateTime CreatedDateTime { get; set; }
public DateTime UpdatedDateTime { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.Always)]
public Agent Agent { get; set; }
public AgentTask(string id, string name, string? description = null)
{
Id = id;
Name = name;
Description = description;
}
}

View file

@ -38,6 +38,18 @@ public class LlmProviderService : ILlmProviderService
?.Models ?? new List<LlmModelSetting>();
}
public LlmModelSetting GetProviderModel(string provider, string id)
{
var models = GetProviderModels(provider)
.Where(x => x.Id == id)
.ToList();
var random = new Random();
var index = random.Next(0, models.Count());
var modelSetting = models.ElementAt(index);
return modelSetting;
}
public LlmModelSetting? GetSetting(string provider, string model)
{
var settings = _services.GetRequiredService<List<LlmProviderSetting>>();

View file

@ -326,6 +326,7 @@ namespace BotSharp.Core.Repository
var functions = FetchFunctions(dir);
var samples = FetchSamples(dir);
var templates = FetchTemplates(dir);
var tasks = FetchTasks(dir);
var responses = FetchResponses(dir);
return record.SetInstruction(instruction)
.SetFunctions(functions)

View file

@ -7,6 +7,8 @@ using MongoDB.Driver;
using System.Text.Encodings.Web;
using BotSharp.Abstraction.Plugins.Models;
using BotSharp.Abstraction.Statistics.Settings;
using BotSharp.Abstraction.Tasks.Models;
using System.Text.RegularExpressions;
namespace BotSharp.Core.Repository;
@ -115,6 +117,7 @@ public partial class FileRepository : IBotSharpRepository
{
agent = agent.SetInstruction(FetchInstruction(d))
.SetTemplates(FetchTemplates(d))
.SetTasks(FetchTasks(d))
.SetFunctions(FetchFunctions(d))
.SetResponses(FetchResponses(d))
.SetSamples(FetchSamples(d));
@ -225,6 +228,32 @@ public partial class FileRepository : IBotSharpRepository
return templates;
}
private List<AgentTask> FetchTasks(string fileDir)
{
var tasks = new List<AgentTask>();
var taskDir = Path.Combine(fileDir, "tasks");
if (!Directory.Exists(taskDir)) return tasks;
foreach (var file in Directory.GetFiles(taskDir))
{
var fileName = file.Split(Path.DirectorySeparatorChar).Last();
var id = fileName.Split('.').First();
var data = File.ReadAllText(file);
var metadata = Regex.Match(data, @"#metadata.+/metadata", RegexOptions.Singleline);
if (metadata.Success)
{
var task = metadata.Value.JsonContent<AgentTask>();
task.Id = id;
var content = Regex.Match(data, @"/metadata.+", RegexOptions.Singleline).Value;
task.Content = content.Substring(9).Trim();
tasks.Add(task);
}
}
return tasks;
}
private List<AgentResponse> FetchResponses(string fileDir)
{
var responses = new List<AgentResponse>();

View file

@ -1,5 +1,6 @@
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.MLTasks;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Routing.Planning;
@ -138,9 +139,13 @@ public class SequentialPlanner : IPlaner
var inst = new DecomposedStep();
var llmProviderService = _services.GetRequiredService<ILlmProviderService>();
var model = llmProviderService.GetProviderModel("azure-openai", "gpt-4");
// chat completion
var completion = CompletionProvider.GetChatCompletion(_services,
model: "llm-gpt4");
provider: "azure-openai",
model: model.Name);
int retryCount = 0;
while (retryCount < 2)
@ -182,4 +187,9 @@ public class SequentialPlanner : IPlaner
{
});
}
public Task<FunctionCallFromLlm> GetNextInstruction(Agent router, string messageId)
{
throw new NotImplementedException();
}
}

View file

@ -0,0 +1,36 @@
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Tasks;
using BotSharp.Abstraction.Tasks.Models;
namespace BotSharp.Core.Tasks.Services;
public class AgentTaskService : IAgentTaskService
{
private readonly IServiceProvider _services;
public AgentTaskService(IServiceProvider services)
{
_services = services;
}
public async Task<PagedItems<AgentTask>> GetTasks(AgentTaskFilter filter)
{
var agentService = _services.GetRequiredService<IAgentService>();
var agents = await agentService.GetAgents(new AgentFilter());
var tasks = new List<AgentTask>();
foreach (var agent in agents.Items)
{
if (filter.AgentId != null && filter.AgentId != agent.Id)
{
continue;
}
agent.Tasks.ForEach(x => x.Agent = agent);
tasks.AddRange(agent.Tasks);
}
return new PagedItems<AgentTask>
{
Items = tasks.Skip(filter.Pager.Offset).Take(filter.Pager.Size),
Count = tasks.Count,
};
}
}

View file

@ -0,0 +1,26 @@
using BotSharp.Abstraction.Plugins.Models;
using BotSharp.Abstraction.Tasks;
using BotSharp.Core.Tasks.Services;
using Microsoft.Extensions.Configuration;
namespace BotSharp.Core.Tasks;
public class TaskPlugin : IBotSharpPlugin
{
public string Id => "e1fb196a-8be9-4c3b-91ba-adfab5a359ef";
public string Name => "Agent Task";
public string Description => "Define some specific task templates and execute them. It can been used for the fixed business scenarios.";
public void RegisterDI(IServiceCollection services, IConfiguration config)
{
services.AddScoped<IAgentTaskService, AgentTaskService>();
}
public bool AttachMenu(List<PluginMenuDef> menu)
{
var section = menu.First(x => x.Label == "Apps");
menu.Add(new PluginMenuDef("Task", link: "page/task", icon: "bx bx-task", weight: section.Weight + 8));
return true;
}
}

View file

@ -0,0 +1,37 @@
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Tasks;
using BotSharp.Abstraction.Tasks.Models;
namespace BotSharp.OpenAPI.Controllers;
[Authorize]
[ApiController]
public class AgentTaskController : ControllerBase
{
private readonly IAgentService _agentService;
private readonly IServiceProvider _services;
public AgentTaskController(IAgentService agentService, IServiceProvider services)
{
_agentService = agentService;
_services = services;
}
[HttpGet("/agent/task/{id}")]
public async Task<AgentViewModel> GetAgentTask([FromRoute] string id)
{
throw new NotImplementedException("");
}
[HttpGet("/agent/tasks")]
public async Task<PagedItems<AgentTaskViewModel>> GetAgents([FromQuery] AgentTaskFilter filter)
{
var taskService = _services.GetRequiredService<IAgentTaskService>();
var tasks = await taskService.GetTasks(filter);
return new PagedItems<AgentTaskViewModel>
{
Items = tasks.Items.Select(x => AgentTaskViewModel.From(x)),
Count = tasks.Count
};
}
}

View file

@ -0,0 +1,37 @@
using BotSharp.Abstraction.Tasks.Models;
using System.Text.Json.Serialization;
namespace BotSharp.OpenAPI.ViewModels.Agents;
public class AgentTaskViewModel
{
public string Id { get; set; }
public string Name { get; set; }
public string? Description { get; set; }
public string Content { get; set; }
public bool Enabled { get; set; }
[JsonPropertyName("created_datetime")]
public DateTime CreatedDateTime { get; set; }
[JsonPropertyName("updated_datetime")]
public DateTime UpdatedDateTime { get; set; }
[JsonPropertyName("agent_id")]
public string AgentId { get; set; }
[JsonPropertyName("agent_name")]
public string AgentName { get; set; }
public static AgentTaskViewModel From(AgentTask task)
{
return new AgentTaskViewModel
{
Id = task.Id,
Name = task.Name,
Description = task.Description,
Content = task.Content,
Enabled = task.Enabled,
AgentId = task.Agent.Id,
AgentName = task.Agent.Name,
CreatedDateTime = task.CreatedDateTime,
UpdatedDateTime = task.UpdatedDateTime
};
}
}

View file

@ -11,7 +11,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.AI.OpenAI" Version="1.0.0-beta.12" />
<PackageReference Include="Azure.AI.OpenAI" Version="1.0.0-beta.13" />
</ItemGroup>
<ItemGroup>

View file

@ -10,6 +10,24 @@
<OutputPath>$(SolutionDir)packages</OutputPath>
</PropertyGroup>
<ItemGroup>
<None Remove="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\agent.json" />
<None Remove="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\functions.json" />
<None Remove="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\instruction.liquid" />
</ItemGroup>
<ItemGroup>
<Content Include="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\agent.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\functions.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\87c458fc-ec5f-40ae-8ed6-05dda8a07523\instruction.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Infrastructure\BotSharp.Core\BotSharp.Core.csproj" />
</ItemGroup>

View file

@ -1,9 +0,0 @@
{
"name": "HTTP Handler",
"description": "Use Web API to interact with other systems to obtain or update data.",
"createdDateTime": "2024-01-06T00:00:00Z",
"updatedDateTime": "2024-01-06T00:00:00Z",
"id": "87c458fc-ec5f-40ae-8ed6-05dda8a07523",
"allowRouting": true,
"isPublic": true
}

View file

@ -0,0 +1,14 @@
{
"id": "87c458fc-ec5f-40ae-8ed6-05dda8a07523",
"name": "HTTP Handler",
"description": "Use Web Open API to interact with 3rd system.",
"type": "task",
"createdDateTime": "2024-01-06T00:00:00Z",
"updatedDateTime": "2024-01-06T00:00:00Z",
"disabled": false,
"isPublic": true,
"profiles": [ "tool", "webapi" ],
"llmConfig": {
"max_recursion_depth": 1
}
}

View file

@ -10,6 +10,24 @@
<OutputPath>$(SolutionDir)packages</OutputPath>
</PropertyGroup>
<ItemGroup>
<None Remove="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\agent.json" />
<None Remove="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\functions.json" />
<None Remove="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\instruction.liquid" />
</ItemGroup>
<ItemGroup>
<Content Include="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\agent.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\functions.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="data\agents\beda4c12-e1ec-4b4b-b328-3df4a6687c4f\instruction.liquid">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.28" />
<PackageReference Include="MySqlConnector" Version="2.3.5" />

View file

@ -2,8 +2,13 @@
"id": "beda4c12-e1ec-4b4b-b328-3df4a6687c4f",
"name": "SQL Driver",
"description": "Convert the requirements into corresponding SQL statements according to the table structure and execute them if needed.",
"type": "task",
"createdDateTime": "2023-11-15T13:49:00Z",
"updatedDateTime": "2023-11-15T13:49:00Z",
"disabled": false,
"isPublic": false,
"allowRouting": true
"profiles": [ "tool", "sql" ],
"llmConfig": {
"max_recursion_depth": 1
}
}

View file

@ -1,8 +1 @@
You are a SQL Driver who knows how to convert business requirements to SQL expressions.
Follow these steps:
1: Look at the table DDL defintions especially for the CONSTRAINT and FOREIGN KEY REFERENCES.
2: Translate user requirements into SQL statements step by step.
3: Double check, don't miss any requirements, all the parameters must have values.
4: Confirm with the user whether to execute the sql statement.
If user confirms to run the query, call function execute_sql to execute it.
You are a SQL Driver who knows how to convert human language to SQL statements.

View file

@ -7,7 +7,7 @@
"updatedDateTime": "2024-01-02T00:00:00Z",
"disabled": false,
"isPublic": true,
"profiles": [ "web-driver" ],
"profiles": [ "tool", "browser" ],
"llmConfig": {
"max_recursion_depth": 1
}

View file

@ -82,9 +82,11 @@
"EnableLlmCompletionLog": false,
"EnableExecutionLog": true
},
"Statistics": {
"DataDir": "stats"
},
"LlamaSharp": {
"Interactive": true,
"ModelDir": "C:/Users/haipi/Downloads",