Clean code.

This commit is contained in:
Haiping Chen 2023-09-24 11:20:02 -05:00
parent d544527734
commit c46fa843cd
31 changed files with 130 additions and 498 deletions

View file

@ -2,7 +2,7 @@
<PropertyGroup>
<LangVersion>10.0</LangVersion>
<OutputPath>..\..\..\packages</OutputPath>
<BotSharpVersion>0.14.7</BotSharpVersion>
<BotSharpVersion>0.14.8</BotSharpVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
</Project>

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Models;
namespace BotSharp.Abstraction.Routing;
@ -8,7 +9,7 @@ public interface IRoutingHandler
string Description { get; }
bool IsReasoning { get => false; }
bool Enabled { get => true; }
List<string> Parameters { get => new List<string>(); }
List<NameDesc> Parameters { get => new List<NameDesc>(); }
void SetRouter(Agent router) { }

View file

@ -1,8 +1,10 @@
using BotSharp.Abstraction.Models;
namespace BotSharp.Abstraction.Routing.Models;
public class RoutingHandlerDef
{
public string Name { get; set; }
public string Description { get; set; }
public List<string> Parameters { get; set; }
public List<NameDesc> Parameters { get; set; }
}

View file

@ -1,87 +0,0 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Text;
using DotNetToolkit.JwtHelper;
using DotNetToolkit;
using EntityFrameworkCore.BootKit;
using Microsoft.Extensions.Configuration;
using System.Linq;
namespace BotSharp.Core.Accounts
{
/// <summary>
/// The /account endpoint is used to create, retrieve, update, and delete account.
/// </summary>
public class AccountController : CoreController
{
private IConfiguration config;
public AccountController(IConfiguration config)
{
this.config = config;
}
[HttpGet("/account")]
public VmUser GetUser()
{
/*var user = dc.Table<User>().Find(CurrentUserId);
return user.ToObject<VmUser>();*/
return new VmUser
{
Email = "botsharp@ai.com",
FirstName = "Bot",
LastName = "Sharp"
};
}
/// <summary>
/// Get a valid token after login
/// </summary>
/// <param name="username">User Email</param>
/// <param name="password">Password</param>
/// <returns></returns>
[AllowAnonymous]
[HttpPost("/token")]
[ProducesResponseType(typeof(string), 200)]
public IActionResult Token([FromBody] VmUserLogin userModel)
{
if (string.IsNullOrEmpty(userModel.UserName) || string.IsNullOrEmpty(userModel.Password))
{
return new BadRequestObjectResult("Username and password should not be empty.");
}
return Ok(JwtToken.GenerateToken(config, "botsharp"));
// validate from local
var user = (from usr in dc.Table<User>()
join auth in dc.Table<UserAuth>() on usr.Id equals auth.UserId
where usr.UserName == userModel.UserName
select auth).FirstOrDefault();
if (user != null)
{
if (!user.IsActivated)
{
return BadRequest("Account hasn't been activated, please check your email to activate it.");
}
else
{
// validate password
string hash = PasswordHelper.Hash(userModel.Password, user.Salt);
if (user.Password == hash)
{
return Ok(JwtToken.GenerateToken(config, "botsharp"));
}
else
{
return BadRequest("Authorization Failed.");
}
}
}
else
{
return BadRequest("Account doesn't exist");
}
}
}
}

View file

@ -1,64 +0,0 @@
using DotNetToolkit;
using EntityFrameworkCore.BootKit;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BotSharp.Core.Accounts
{
public class AccountCore
{
private Database _dc;
private IConfiguration _config;
public AccountCore(Database dc = null)
{
if (dc == null)
{
dc = new DefaultDataContextLoader().GetDefaultDc();
}
else
{
_dc = dc;
}
_config = (IConfiguration)AppDomain.CurrentDomain.GetData("Configuration");
}
public void CreateUser(User user)
{
user.Authenticaiton.IsActivated = false;
user.Authenticaiton.Salt = PasswordHelper.GetSalt();
user.Authenticaiton.Password = PasswordHelper.Hash(user.Authenticaiton.Password, user.Authenticaiton.Salt);
user.Authenticaiton.ActivationCode = Guid.NewGuid().ToString("N");
_dc.Transaction<IDbRecord>(() =>
{
_dc.Table<User>().Add(user);
});
$"Created user {user.Email}, user id: {user.Id}".Log(LogLevel.INFO);
}
public void Activate(string activationCode)
{
var activation = _dc.Table<UserAuth>().FirstOrDefault(x => x.ActivationCode == activationCode && !x.IsActivated);
if (activation == null)
{
}
else
{
_dc.Transaction<IDbRecord>(() =>
{
activation = _dc.Table<UserAuth>().FirstOrDefault(x => x.ActivationCode == activationCode);
activation.ActivationCode = String.Empty;
activation.IsActivated = true;
activation.UpdatedTime = DateTime.UtcNow;
});
}
}
}
}

View file

@ -1,40 +0,0 @@
using BotSharp.Core.Abstractions;
using CherubNLP.Tokenize;
using EntityFrameworkCore.BootKit;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace BotSharp.Core.Accounts
{
public class AccountDbInitializer : IHookDbInitializer
{
public int Priority => 100;
public void Load(Database dc)
{
ImportAccount(dc);
}
private void ImportAccount(Database dc)
{
var dataPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "DbInitializer", "Accounts");
string json = File.ReadAllText(Path.Combine(dataPath, "users.json"));
var users = JsonConvert.DeserializeObject<List<User>>(json);
users.ForEach(user =>
{
if (!dc.Table<User>().Any(x => x.UserName == user.UserName))
{
var core = new AccountCore(dc);
core.CreateUser(user);
core.Activate(user.Authenticaiton.ActivationCode);
}
});
}
}
}

View file

@ -1,60 +0,0 @@
using EntityFrameworkCore.BootKit;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace BotSharp.Core.Accounts
{
/// <summary>
/// User profile
/// </summary>
[Table("User")]
public class User : DbRecord, IDbRecord
{
[Required]
[StringLength(64)]
public string UserName { get; set; }
[Required]
[StringLength(64)]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[StringLength(32)]
public string FirstName { get; set; }
[StringLength(32)]
public string LastName { get; set; }
[MaxLength(256)]
public string Description { get; set; }
[Required]
[DataType(DataType.DateTime)]
public DateTime SignupDate { get; set; }
[DataType(DataType.Date)]
public DateTime? Birthday { get; set; }
[MaxLength(36)]
public string Nationality { get; set; }
[NotMapped]
public string FullName
{
get
{
return FirstName + (string.IsNullOrEmpty(LastName) ? "" : " " + LastName);
}
}
public UserAuth Authenticaiton { get; set; }
public User()
{
SignupDate = DateTime.UtcNow;
}
}
}

View file

@ -1,36 +0,0 @@
using EntityFrameworkCore.BootKit;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace BotSharp.Core.Accounts
{
/// <summary>
/// User authentication
/// </summary>
[Table("UserAuth")]
public class UserAuth : DbRecord, IDbRecord
{
[StringLength(36)]
public string UserId { get; set; }
[Required]
[StringLength(256)]
[DataType(DataType.Password)]
public string Password { get; set; }
[Required]
[StringLength(64)]
public string Salt { get; set; }
[StringLength(32)]
public string ActivationCode { get; set; }
public bool IsActivated { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
}
}

View file

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Accounts
{
public class VmUser
{
public String FullName
{
get
{
return $"{FirstName} {LastName}";
}
}
public String FirstName { get; set; }
public String LastName { get; set; }
public String Email { get; set; }
public String Avatar { get; set; }
}
}

View file

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Accounts
{
public class VmUserLogin
{
public string UserName { get; set; }
public string Password { get; set; }
}
}

View file

@ -6,28 +6,17 @@
<VersionPrefix>$(BotSharpVersion)</VersionPrefix>
<GeneratePackageOnBuild>$(GeneratePackageOnBuild)</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Label="Globals">
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
<Platforms>AnyCPU;x64</Platforms>
<Configurations>Debug;Release;</Configurations>
</PropertyGroup>
<PropertyGroup>
<Authors>Haiping Chen</Authors>
<Company>SciSharp STACK</Company>
<Product>AI Bot Platform Builder</Product>
<Product>LL Application Framework</Product>
<Description>
Open source AI Bot platform builder which is written in C# runs on .Net Core and is enterprise oriented. Integrated with multiple bot engines besides BotSharp bot engine. Modulized pipeline design make NLP tasks plugin easily. Abstract platform and NLP task, migrate existed chatbot from a platform into another platform perfectly through dump and restore.
If you feel that this project is helpful to you, please Star on the project, we will be very grateful.
Open source LLM application framework to build scalable, flexible and robust AI system.
</Description>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/SciSharp/BotSharp</RepositoryUrl>
<PackageTags>NLU, Chatbot, Bot, AI Bot, Artificial Intelligence</PackageTags>
<PackageTags>Chatbot, Bot, LLM, AI, ChatGPT, OpenAI</PackageTags>
<PackageReleaseNotes>Support dialogue status tracking.</PackageReleaseNotes>
<Copyright>Since 2018 Haiping Chen</Copyright>
<PackageProjectUrl>https://github.com/SciSharp/BotSharp</PackageProjectUrl>
@ -55,29 +44,6 @@
<NoWarn>1701;1702</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Accounts\**" />
<Compile Remove="Functions\**" />
<Compile Remove="Hooks\**" />
<Compile Remove="Repository\Abstraction\**" />
<EmbeddedResource Remove="Accounts\**" />
<EmbeddedResource Remove="Functions\**" />
<EmbeddedResource Remove="Hooks\**" />
<EmbeddedResource Remove="Repository\Abstraction\**" />
<None Remove="Accounts\**" />
<None Remove="Functions\**" />
<None Remove="Hooks\**" />
<None Remove="Repository\Abstraction\**" />
</ItemGroup>
<ItemGroup>
<Compile Remove="CoreController.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="Routing\router_prompt.liquid" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\arts\Icon.png">
<Pack>True</Pack>

View file

@ -9,7 +9,7 @@ using BotSharp.Abstraction.Templating;
using BotSharp.Core.Instructs;
using BotSharp.Abstraction.Instructs;
using BotSharp.Abstraction.Routing;
using BotSharp.Core.Routing.Handlers;
using System.Reflection;
namespace BotSharp.Core;
@ -53,20 +53,7 @@ public static class BotSharpServiceCollectionExtensions
services.AddSingleton((IServiceProvider x) => routingSettings);
services.AddScoped<IAgentRouting, Router>();
// Register function callback
services.AddScoped<IFunctionCallback, RouteToAgentFn>();
// Register routing and handlers
services.AddScoped<IRoutingService, RoutingService>();
services.AddScoped<IRoutingHandler, GetNextInstructionRoutingHandler>();
services.AddScoped<IRoutingHandler, ResponseToUserRoutingHandler>();
services.AddScoped<IRoutingHandler, InterruptTaskExecutionRoutingHandler>();
services.AddScoped<IRoutingHandler, RouteToAgentRoutingHandler>();
services.AddScoped<IRoutingHandler, ContinueExecuteTaskRoutingHandler>();
services.AddScoped<IRoutingHandler, RetrieveDataFromAgentRoutingHandler>();
services.AddScoped<IRoutingHandler, TaskEndRoutingHandler>();
services.AddScoped<IRoutingHandler, ConversationEndRoutingHandler>();
if (myDatabaseSettings.Default == "FileRepository")
{
@ -118,7 +105,30 @@ public static class BotSharpServiceCollectionExtensions
config.Bind("PluginLoader", pluginSettings);
var loader = new PluginLoader(services, config, pluginSettings);
loader.Load();
loader.Load(assembly =>
{
// Register routing handlers
var handlers = assembly.GetTypes()
.Where(x => x.IsClass)
.Where(x => x.GetInterface(nameof(IRoutingHandler)) != null)
.ToArray();
foreach (var handler in handlers)
{
services.AddScoped(typeof(IRoutingHandler), handler);
}
// Register function callback
var functions = assembly.GetTypes()
.Where(x => x.IsClass)
.Where(x => x.GetInterface(nameof(IFunctionCallback)) != null)
.ToArray();
foreach (var function in functions)
{
services.AddScoped(typeof(IFunctionCallback), function);
}
});
services.AddSingleton(loader);
}

View file

@ -1,6 +1,7 @@
using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Settings;
using System.Drawing;
namespace BotSharp.Core.Conversations.Services;
@ -93,9 +94,17 @@ public partial class ConversationService
await hook.AfterCompletion(message);
}
var agent = await _services.GetRequiredService<IAgentService>().GetAgent(message.CurrentAgentId);
var routingSetting = _services.GetRequiredService<RoutingSettings>();
var agentName = routingSetting.RouterId == message.CurrentAgentId ?
routingSetting.RouterName :
(await _services.GetRequiredService<IAgentService>().GetAgent(message.CurrentAgentId)).Name;
_logger.LogInformation($"[{agent?.Name ?? "Router"}] {message.Role}: {message.Content}");
#if DEBUG
Console.WriteLine($"[{agentName}] {message.Role}: {message.Content}", Color.Pink);
#else
_logger.LogInformation($"[{agentName}] {message.Role}: {message.Content}");
#endif
await onMessageReceived(message);

View file

@ -1,43 +0,0 @@
using EntityFrameworkCore.BootKit;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BotSharp.Core
{
[Authorize]
[Produces("application/json")]
[Route("v1/[controller]")]
public class CoreController : ControllerBase
{
protected Database dc { get; set; }
public CoreController()
{
dc = new DefaultDataContextLoader().GetDefaultDc();
}
/*protected string GetConfig(string path)
{
if (string.IsNullOrEmpty(path)) return String.Empty;
return Database.Configuration.GetSection(path).Value;
}
protected List<KeyValuePair<string, string>> GetSection(string path)
{
return Database.Configuration.GetSection(path).AsEnumerable().ToList();
}*/
protected string CurrentUserId
{
get
{
return this.User.Claims.FirstOrDefault(x => x.Type.Equals("UserId")).Value;
}
}
}
}

View file

@ -22,7 +22,7 @@ public class PluginLoader
_settings = settings;
}
public void Load()
public void Load(Action<Assembly> loaded)
{
var executingDir = Directory.GetParent(Assembly.GetEntryAssembly().Location).FullName;
@ -44,6 +44,7 @@ public class PluginLoader
Console.WriteLine($"Loaded plugin {module.GetType().Name} from {assemblyName}.", Color.Green);
}
loaded(assembly);
_modules.AddRange(modules);
}
else

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Models;
using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Settings;
@ -11,11 +12,11 @@ public class ContinueExecuteTaskRoutingHandler : RoutingHandlerBase, IRoutingHan
public string Description => "Continue to execute user's request without further information retrival.";
public List<string> Parameters => new List<string>
public List<NameDesc> Parameters => new List<NameDesc>
{
"agent_name: the name of the agent",
"args: required parameters extracted from question",
"reason: why continue to execute current task"
new NameDesc("agent_name", "the name of the agent"),
new NameDesc("args", "required parameters extracted from question"),
new NameDesc("reason", "why continue to execute current task")
};
public bool IsReasoning => true;

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Models;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Settings;
@ -10,8 +11,9 @@ public class ConversationEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
public string Description => "Call this function when user wants to end this conversation or all tasks have been completed.";
public List<string> Parameters => new List<string>
public List<NameDesc> Parameters => new List<NameDesc>
{
new NameDesc("reason", "why this conversation is end")
};
public bool IsReasoning => false;

View file

@ -10,8 +10,6 @@ public class GetNextInstructionRoutingHandler : RoutingHandlerBase, IRoutingHand
public string Description => "";
public List<string> Parameters => new List<string> { };
public bool IsReasoning => false;
public GetNextInstructionRoutingHandler(IServiceProvider services, ILogger<GetNextInstructionRoutingHandler> logger, RoutingSettings settings)

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Models;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Settings;
@ -10,10 +11,10 @@ public class InterruptTaskExecutionRoutingHandler : RoutingHandlerBase, IRouting
public string Description => "Can't continue user's request becauase the requirements are not met.";
public List<string> Parameters => new List<string>
public List<NameDesc> Parameters => new List<NameDesc>
{
"reason: the reason why the request is interrupted",
"answer: the content response to user"
new NameDesc("reason", "the reason why the request is interrupted"),
new NameDesc("answer", "the content response to user")
};
public bool IsReasoning => true;

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Models;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Settings;
@ -10,10 +11,10 @@ public class ResponseToUserRoutingHandler : RoutingHandlerBase, IRoutingHandler
public string Description => "You know how to response according to the context, don't need to ask specific agent.";
public List<string> Parameters => new List<string>
public List<NameDesc> Parameters => new List<NameDesc>
{
"answer: the content of response",
"reason: why response to user"
new NameDesc("answer", "the content of response"),
new NameDesc("reason", "why response to user")
};
public bool IsReasoning => false;

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Models;
using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Settings;
@ -11,12 +12,12 @@ public class RetrieveDataFromAgentRoutingHandler : RoutingHandlerBase, IRoutingH
public string Description => "Retrieve data from appropriate agent.";
public List<string> Parameters => new List<string>
public List<NameDesc> Parameters => new List<NameDesc>
{
"agent_name: the name of the agent",
"question: the question you will ask the agent to get the necessary data",
"reason: why retrieve data",
"args: required parameters extracted from question and hand over to the next agent"
new NameDesc("agent_name", "the name of the agent"),
new NameDesc("question", "the question you will ask the agent to get the necessary data"),
new NameDesc("reason", "why retrieve data"),
new NameDesc("args", "required parameters extracted from question and hand over to the next agent")
};
public bool IsReasoning => true;

View file

@ -1,5 +1,6 @@
using BotSharp.Abstraction.Functions;
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Models;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Routing.Settings;
@ -12,11 +13,11 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
public string Description => "Route request to appropriate agent.";
public List<string> Parameters => new List<string>
public List<NameDesc> Parameters => new List<NameDesc>
{
"agent_name: the name of the agent from AGENTS",
"reason: why route to this agent",
"args: parameters extracted from context"
new NameDesc("agent_name", "the name of the agent from AGENTS"),
new NameDesc("reason", "why route to this agent"),
new NameDesc("args", "parameters extracted from context")
};
public bool IsReasoning => false;

View file

@ -1,4 +1,5 @@
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Models;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Settings;
@ -10,9 +11,9 @@ public class TaskEndRoutingHandler : RoutingHandlerBase, IRoutingHandler
public string Description => "Call this function when current task is completed.";
public List<string> Parameters => new List<string>
public List<NameDesc> Parameters => new List<NameDesc>
{
"abandoned_arguments: the arguments next task can't reuse"
new NameDesc("abandoned_arguments", "the arguments next task can't reuse")
};
public bool IsReasoning => true;

View file

@ -1,33 +0,0 @@
namespace BotSharp.Core.Routing;
public class PromptConst
{
public const string ROUTER_PROMPT = @"
You're a Router with reasoning. Follow these steps to handle user's request:
1. Read the CONVERSATION context.
2. Select a appropriate function from FUNCTIONS.
3. Determine which agent from AGENTS is suitable for the current task.
FUNCTIONS
{% for fn in routing_handlers %}
* {{ fn.name }}
{{ fn.description }}
{% if fn.parameters != empty -%}
Parameters:
{% for arg in fn.parameters -%}
{{ arg }};
{%- endfor %}
{%- endif %}
{% endfor %}
AGENTS
{% for agent in routing_records %}
* {{ agent.name }}
{{ agent.description }}
{% if agent.required_fields != empty -%}
Required: {% for field in agent.required_fields %}{{ field }},{% endfor %}
{%- endif %}
{% endfor %}
CONVERSATION";
}

View file

@ -5,7 +5,6 @@ using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Routing.Settings;
using BotSharp.Abstraction.Templating;
namespace BotSharp.Core.Routing;
public class RoutingService : IRoutingService
@ -113,8 +112,38 @@ public class RoutingService : IRoutingService
};
var agents = db.Agents.Where(x => !x.Disabled && x.AllowRouting).ToArray();
var dict = new Dictionary<string, object>();
dict["routing_records"] = agents.Select(x => new RoutingItem
// Assemble prompt
var prompt = @"You're a Router with reasoning. Follow these steps to handle user's request:
1. Read the CONVERSATION context.
2. Select a appropriate function from FUNCTIONS.
3. Determine which agent from AGENTS is suitable for the current task.";
// Append function
prompt += "\r\n";
prompt += "\r\nFUNCTIONS";
GetHandlers().Select((handler, i) =>
{
prompt += "\r\n";
prompt += $"\r\n{i + 1}. {handler.Name}";
prompt += $"\r\n{handler.Description}";
// Append parameters
if (handler.Parameters.Any())
{
prompt += "\r\nParameters:";
handler.Parameters.Select((p, i) =>
{
prompt += $"\r\n{i + 1}. {p.Name}: {p.Description}";
return p;
}).ToList();
}
return handler;
}).ToList();
prompt += "\r\n";
prompt += "\r\nAGENTS";
agents.Select(x => new RoutingItem
{
AgentId = x.Id,
Description = x.Description,
@ -122,12 +151,23 @@ public class RoutingService : IRoutingService
RequiredFields = x.RoutingRules.Where(x => x.Required)
.Select(x => x.Field)
.ToArray()
}).ToArray();
}).Select((agent, i) =>
{
prompt += "\r\n";
prompt += $"\r\n{i + 1}. {agent.Name}";
prompt += $"\r\n{agent.Description}";
dict["routing_handlers"] = GetHandlers();
// Append parameters
if (agent.RequiredFields.Any())
{
prompt += $"\r\nRequired: {string.Join(',', agent.RequiredFields)}.";
}
return agent;
}).ToList();
var render = _services.GetRequiredService<ITemplateRender>();
router.Instruction = render.Render(PromptConst.ROUTER_PROMPT, dict);
prompt += "\r\n";
prompt += "\r\nCONVERSATION";
router.Instruction = prompt;
return router;
}

View file

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

View file

@ -39,10 +39,10 @@ public class ChatCompletionProvider : IChatCompletion
var api = _services.GetRequiredService<IInferenceApi>();
if (_settings.Model.Contains('/'))
if (_model.Contains('/'))
{
var space = _settings.Model.Split('/')[0];
var model = _settings.Model.Split("/")[1];
var space = _model.Split('/')[0];
var model = _model.Split("/")[1];
var response = await api.Post(space, model, new InferenceInput
{

View file

@ -10,7 +10,7 @@
<ItemGroup>
<PackageReference Include="PdfPig" Version="0.1.9-alpha-20230827-ee756" />
<PackageReference Include="TensorFlow.Keras" Version="0.11.2" />
<PackageReference Include="TensorFlow.Keras" Version="0.11.4" />
</ItemGroup>
<ItemGroup>

View file

@ -21,7 +21,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Infrastructure\BotSharp.Abstraction\BotSharp.Abstraction.csproj" />
<ProjectReference Include="..\..\Infrastructure\BotSharp.Core\BotSharp.Core.csproj" />
</ItemGroup>

View file

@ -6,18 +6,12 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Senparc.CO2NET.AspNet;
using Senparc.CO2NET;
using Senparc.Weixin.RegisterServices;
using System;
using System.Collections.Generic;
using System.Text;
using Senparc.Weixin;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.MessageHandlers.Middleware;
using Senparc.Weixin.Entities;
using Senparc.CO2NET.RegisterServices;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using BotSharp.Abstraction.Users;
using BotSharp.Plugin.WeChat.Users;
namespace BotSharp.Plugin.WeChat

View file

@ -18,6 +18,7 @@
"RouterName": "PizzaBot",
"Description": "Pizza restaurant AI Bot",
"EnableReasoning": false,
"Provider": "azure-openai",
"Model": "gpt-3.5"
},