Merge branch 'SciSharp:master' into master
This commit is contained in:
commit
92994da659
|
|
@ -18,6 +18,7 @@ public enum AgentField
|
|||
Sample,
|
||||
LlmConfig,
|
||||
Utility,
|
||||
KnowledgeBase,
|
||||
MaxMessageCount
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public interface IAgentService
|
|||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<Agent> LoadAgent(string id);
|
||||
Task<Agent> LoadAgent(string id, bool loadUtility = true);
|
||||
|
||||
/// <summary>
|
||||
/// Inherit from an agent
|
||||
|
|
|
|||
|
|
@ -99,6 +99,11 @@ public class Agent
|
|||
/// </summary>
|
||||
public List<AgentUtility> Utilities { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Agent knowledge bases
|
||||
/// </summary>
|
||||
public List<AgentKnowledgeBase> KnowledgeBases { get; set; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Inherit from agent
|
||||
/// </summary>
|
||||
|
|
@ -118,6 +123,12 @@ public class Agent
|
|||
[JsonIgnore]
|
||||
public Dictionary<string, object> TemplateDict { get; set; } = new();
|
||||
|
||||
[JsonIgnore]
|
||||
public List<FunctionDef> SecondaryFunctions { get; set; } = [];
|
||||
|
||||
[JsonIgnore]
|
||||
public List<string> SecondaryInstructions { get; set; } = [];
|
||||
|
||||
public override string ToString()
|
||||
=> $"{Name} {Id}";
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
namespace BotSharp.Abstraction.Agents.Models;
|
||||
|
||||
public class AgentKnowledgeBase
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
public AgentKnowledgeBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public AgentKnowledgeBase(string name, bool enabled)
|
||||
{
|
||||
Name = name;
|
||||
Disabled = enabled;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ public class BasicAgentHook : AgentHookBase
|
|||
{
|
||||
public override string SelfId => string.Empty;
|
||||
|
||||
private const string UTIL_PREFIX = "util-";
|
||||
|
||||
public BasicAgentHook(IServiceProvider services, AgentSettings settings)
|
||||
: base(services, settings)
|
||||
{
|
||||
|
|
@ -17,22 +19,23 @@ public class BasicAgentHook : AgentHookBase
|
|||
var isConvMode = conv.IsConversationMode();
|
||||
if (!isConvMode) return;
|
||||
|
||||
agent.Functions ??= [];
|
||||
agent.SecondaryFunctions ??= [];
|
||||
agent.SecondaryInstructions ??= [];
|
||||
agent.Utilities ??= [];
|
||||
|
||||
var (functions, templates) = GetUtilityContent(agent);
|
||||
|
||||
foreach (var fn in functions)
|
||||
{
|
||||
if (!agent.Functions.Any(x => x.Name.Equals(fn.Name, StringComparison.OrdinalIgnoreCase)))
|
||||
if (!agent.SecondaryFunctions.Any(x => x.Name.Equals(fn.Name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
agent.Functions.Add(fn);
|
||||
agent.SecondaryFunctions.Add(fn);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var prompt in templates)
|
||||
{
|
||||
agent.Instruction += $"\r\n\r\n{prompt}\r\n\r\n";
|
||||
agent.SecondaryInstructions.Add(prompt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,14 +70,13 @@ public class BasicAgentHook : AgentHookBase
|
|||
return ([], []);
|
||||
}
|
||||
|
||||
var prefix = "util-";
|
||||
utilities = utilities?.Where(x => !string.IsNullOrEmpty(x.Name) && !x.Disabled)?.ToList() ?? [];
|
||||
var functionNames = utilities.SelectMany(x => x.Functions)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(prefix))
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(UTIL_PREFIX))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
var templateNames = utilities.SelectMany(x => x.Templates)
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(prefix))
|
||||
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(UTIL_PREFIX))
|
||||
.Select(x => x.Name)
|
||||
.Distinct().ToList();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ public partial class AgentService
|
|||
public static ConcurrentDictionary<string, Dictionary<string, string>> AgentParameterTypes = new();
|
||||
|
||||
[MemoryCache(10 * 60, perInstanceCache: true)]
|
||||
public async Task<Agent> LoadAgent(string id)
|
||||
public async Task<Agent> LoadAgent(string id, bool loadUtility = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(id) || id == Guid.Empty.ToString())
|
||||
{
|
||||
|
|
@ -67,7 +67,11 @@ public partial class AgentService
|
|||
hook.OnSamplesLoaded(agent.Samples);
|
||||
}
|
||||
|
||||
hook.OnAgentUtilityLoaded(agent);
|
||||
if (loadUtility)
|
||||
{
|
||||
hook.OnAgentUtilityLoaded(agent);
|
||||
}
|
||||
|
||||
hook.OnAgentLoaded(agent);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,13 +11,18 @@ public partial class AgentService
|
|||
var render = _services.GetRequiredService<ITemplateRender>();
|
||||
var conv = _services.GetRequiredService<IConversationService>();
|
||||
|
||||
// merge instructions
|
||||
var instructions = new List<string> { agent.Instruction };
|
||||
var secondaryInstructions = agent.SecondaryInstructions?.Where(x => !string.IsNullOrWhiteSpace(x)).ToList() ?? [];
|
||||
instructions.AddRange(secondaryInstructions);
|
||||
|
||||
// update states
|
||||
foreach (var t in conv.States.GetStates())
|
||||
{
|
||||
agent.TemplateDict[t.Key] = t.Value;
|
||||
}
|
||||
|
||||
var res = render.Render(agent.Instruction, agent.TemplateDict);
|
||||
var res = render.Render(string.Join("\r\n", instructions), agent.TemplateDict);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public partial class AgentService
|
|||
record.Responses = agent.Responses ?? [];
|
||||
record.Samples = agent.Samples ?? [];
|
||||
record.Utilities = agent.Utilities ?? [];
|
||||
record.KnowledgeBases = agent.KnowledgeBases ?? [];
|
||||
if (agent.LlmConfig != null && !agent.LlmConfig.IsInherit)
|
||||
{
|
||||
record.LlmConfig = agent.LlmConfig;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ namespace BotSharp.Core.Repository
|
|||
case AgentField.Utility:
|
||||
UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities);
|
||||
break;
|
||||
case AgentField.KnowledgeBase:
|
||||
UpdateAgentKnowledgeBases(agent.Id, agent.KnowledgeBases);
|
||||
break;
|
||||
case AgentField.MaxMessageCount:
|
||||
UpdateAgentMaxMessageCount(agent.Id, agent.MaxMessageCount);
|
||||
break;
|
||||
|
|
@ -168,6 +171,19 @@ namespace BotSharp.Core.Repository
|
|||
File.WriteAllText(agentFile, json);
|
||||
}
|
||||
|
||||
private void UpdateAgentKnowledgeBases(string agentId, List<AgentKnowledgeBase> knowledgeBases)
|
||||
{
|
||||
if (knowledgeBases == null) return;
|
||||
|
||||
var (agent, agentFile) = GetAgentFromFile(agentId);
|
||||
if (agent == null) return;
|
||||
|
||||
agent.KnowledgeBases = knowledgeBases;
|
||||
agent.UpdatedDateTime = DateTime.UtcNow;
|
||||
var json = JsonSerializer.Serialize(agent, _options);
|
||||
File.WriteAllText(agentFile, json);
|
||||
}
|
||||
|
||||
private void UpdateAgentRoutingRules(string agentId, List<RoutingRule> rules)
|
||||
{
|
||||
if (rules == null) return;
|
||||
|
|
@ -310,6 +326,7 @@ namespace BotSharp.Core.Repository
|
|||
agent.Type = inputAgent.Type;
|
||||
agent.Profiles = inputAgent.Profiles;
|
||||
agent.Utilities = inputAgent.Utilities;
|
||||
agent.KnowledgeBases = inputAgent.KnowledgeBases;
|
||||
agent.RoutingRules = inputAgent.RoutingRules;
|
||||
agent.LlmConfig = inputAgent.LlmConfig;
|
||||
agent.MaxMessageCount = inputAgent.MaxMessageCount;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
|
|||
type: "boolean",
|
||||
required: true),
|
||||
new ParameterPropertyDef("is_new_task",
|
||||
"whether the user is requesting a new task that is different from the previous topic.",
|
||||
"whether the user is requesting a new task that is different from the previous topic. Set the first round of conversation to false.",
|
||||
type: "boolean")
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@ public class AgentUpdateModel
|
|||
/// </summary>
|
||||
public List<AgentUtility>? Utilities { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// knowledge bases
|
||||
/// </summary>
|
||||
///
|
||||
[JsonPropertyName("knowledge_bases")]
|
||||
public List<AgentKnowledgeBase>? KnowledgeBases { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Functions
|
||||
/// </summary>
|
||||
|
|
@ -90,6 +97,7 @@ public class AgentUpdateModel
|
|||
Functions = Functions ?? new List<FunctionDef>(),
|
||||
Responses = Responses ?? new List<AgentResponse>(),
|
||||
Utilities = Utilities ?? new List<AgentUtility>(),
|
||||
KnowledgeBases = KnowledgeBases ?? [],
|
||||
LlmConfig = LlmConfig
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ public class AgentViewModel
|
|||
public bool MergeUtility { get; set; }
|
||||
public List<AgentUtility> Utilities { get; set; }
|
||||
|
||||
[JsonPropertyName("knowledge_bases")]
|
||||
public List<AgentKnowledgeBase> KnowledgeBases { get; set; }
|
||||
|
||||
[JsonPropertyName("is_public")]
|
||||
public bool IsPublic { get; set; }
|
||||
|
||||
|
|
@ -75,6 +78,7 @@ public class AgentViewModel
|
|||
Responses = agent.Responses,
|
||||
Samples = agent.Samples,
|
||||
Utilities = agent.Utilities,
|
||||
KnowledgeBases = agent.KnowledgeBases,
|
||||
IsPublic= agent.IsPublic,
|
||||
Disabled = agent.Disabled,
|
||||
MergeUtility = agent.MergeUtility,
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
|
||||
if (!string.IsNullOrEmpty(agent.Instruction))
|
||||
if (!string.IsNullOrEmpty(agent.Instruction) || !agent.SecondaryInstructions.IsNullOrEmpty())
|
||||
{
|
||||
instruction += agentService.RenderedInstruction(agent);
|
||||
}
|
||||
|
|
@ -197,7 +197,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
ReferenceHandler = ReferenceHandler.IgnoreCycles,
|
||||
};
|
||||
|
||||
foreach (var fn in agent.Functions)
|
||||
var functions = agent.Functions.Concat(agent.SecondaryFunctions ?? []);
|
||||
foreach (var fn in functions)
|
||||
{
|
||||
/*var inputschema = new InputSchema()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -230,7 +230,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
MaxOutputTokenCount = maxTokens
|
||||
};
|
||||
|
||||
foreach (var function in agent.Functions)
|
||||
var functions = agent.Functions.Concat(agent.SecondaryFunctions ?? []);
|
||||
foreach (var function in functions)
|
||||
{
|
||||
if (!agentService.RenderFunction(agent, function)) continue;
|
||||
|
||||
|
|
@ -242,7 +243,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
functionParameters: BinaryData.FromObjectAsJson(property)));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(agent.Instruction))
|
||||
if (!string.IsNullOrEmpty(agent.Instruction) || !agent.SecondaryInstructions.IsNullOrEmpty())
|
||||
{
|
||||
var instruction = agentService.RenderedInstruction(agent);
|
||||
messages.Add(new SystemChatMessage(instruction));
|
||||
|
|
|
|||
|
|
@ -24,17 +24,20 @@ public class ReadImageFn : IFunctionCallback
|
|||
|
||||
var wholeDialogs = conv.GetDialogHistory();
|
||||
var dialogs = AssembleFiles(conv.ConversationId, args?.ImageUrls, wholeDialogs);
|
||||
var agentId = !string.IsNullOrWhiteSpace(message.CurrentAgentId) ? message.CurrentAgentId : BuiltInAgentId.UtilityAssistant;
|
||||
var agent = await agentService.LoadAgent(agentId);
|
||||
var fileAgent = new Agent
|
||||
var agent = new Agent
|
||||
{
|
||||
Id = agent?.Id ?? Guid.Empty.ToString(),
|
||||
Name = agent?.Name ?? "Unkown",
|
||||
Id = BuiltInAgentId.UtilityAssistant,
|
||||
Name = "Utility Agent",
|
||||
Instruction = !string.IsNullOrWhiteSpace(args?.UserRequest) ? args.UserRequest : "Please describe the image(s).",
|
||||
TemplateDict = new Dictionary<string, object>()
|
||||
};
|
||||
|
||||
var response = await GetChatCompletion(fileAgent, dialogs);
|
||||
if (!string.IsNullOrEmpty(message.CurrentAgentId))
|
||||
{
|
||||
agent = await agentService.LoadAgent(message.CurrentAgentId, loadUtility: false);
|
||||
}
|
||||
|
||||
var response = await GetChatCompletion(agent, dialogs);
|
||||
message.Content = response;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public class GeminiChatCompletionProvider : IChatCompletion
|
|||
|
||||
private string _model;
|
||||
|
||||
public string Provider => "google-gemini";
|
||||
public string Provider => "google-ai";
|
||||
|
||||
public GeminiChatCompletionProvider(
|
||||
IServiceProvider services,
|
||||
|
|
@ -33,7 +33,7 @@ public class GeminiChatCompletionProvider : IChatCompletion
|
|||
await hook.BeforeGenerating(agent, conversations);
|
||||
}
|
||||
|
||||
var client = ProviderHelper.GetGeminiClient(_services);
|
||||
var client = ProviderHelper.GetGeminiClient(Provider, _model, _services);
|
||||
var aiModel = client.GenerativeModel(_model);
|
||||
var (prompt, request) = PrepareOptions(aiModel, agent, conversations);
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ public class GeminiChatCompletionProvider : IChatCompletion
|
|||
var funcDeclarations = new List<FunctionDeclaration>();
|
||||
|
||||
var systemPrompts = new List<string>();
|
||||
if (!string.IsNullOrEmpty(agent.Instruction))
|
||||
if (!string.IsNullOrEmpty(agent.Instruction) || !agent.SecondaryInstructions.IsNullOrEmpty())
|
||||
{
|
||||
var instruction = agentService.RenderedInstruction(agent);
|
||||
contents.Add(new Content(instruction)
|
||||
|
|
@ -119,7 +119,8 @@ public class GeminiChatCompletionProvider : IChatCompletion
|
|||
}
|
||||
|
||||
var funcPrompts = new List<string>();
|
||||
foreach (var function in agent.Functions)
|
||||
var functions = agent.Functions.Concat(agent.SecondaryFunctions ?? []);
|
||||
foreach (var function in functions)
|
||||
{
|
||||
if (!agentService.RenderFunction(agent, function)) continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public class PalmChatCompletionProvider : IChatCompletion
|
|||
|
||||
private string _model;
|
||||
|
||||
public string Provider => "google-ai";
|
||||
public string Provider => "google-palm";
|
||||
|
||||
public PalmChatCompletionProvider(
|
||||
IServiceProvider services,
|
||||
|
|
@ -36,7 +36,7 @@ public class PalmChatCompletionProvider : IChatCompletion
|
|||
await hook.BeforeGenerating(agent, conversations);
|
||||
}
|
||||
|
||||
var client = ProviderHelper.GetPalmClient(_services);
|
||||
var client = ProviderHelper.GetPalmClient(Provider, _model, _services);
|
||||
var (prompt, messages, hasFunctions) = PrepareOptions(agent, conversations);
|
||||
|
||||
RoleDialogModel msg;
|
||||
|
|
@ -99,7 +99,7 @@ public class PalmChatCompletionProvider : IChatCompletion
|
|||
|
||||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
|
||||
if (!string.IsNullOrEmpty(agent.Instruction))
|
||||
if (!string.IsNullOrEmpty(agent.Instruction) || !agent.SecondaryInstructions.IsNullOrEmpty())
|
||||
{
|
||||
prompt += agentService.RenderedInstruction(agent);
|
||||
}
|
||||
|
|
@ -110,10 +110,11 @@ public class PalmChatCompletionProvider : IChatCompletion
|
|||
var messages = conversations.Select(c => new PalmChatMessage(c.Content, c.Role == AgentRole.User ? "user" : "AI"))
|
||||
.ToList();
|
||||
|
||||
if (agent.Functions != null && agent.Functions.Count > 0)
|
||||
var functions = agent.Functions.Concat(agent.SecondaryFunctions ?? []);
|
||||
if (!functions.IsNullOrEmpty())
|
||||
{
|
||||
prompt += "\r\n\r\n[Functions] defined in JSON Schema:\r\n";
|
||||
prompt += JsonSerializer.Serialize(agent.Functions, new JsonSerializerOptions
|
||||
prompt += JsonSerializer.Serialize(functions, new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
WriteIndented = true
|
||||
|
|
|
|||
|
|
@ -5,17 +5,19 @@ namespace BotSharp.Plugin.GoogleAi.Providers;
|
|||
|
||||
public static class ProviderHelper
|
||||
{
|
||||
public static GoogleAI GetGeminiClient(IServiceProvider services)
|
||||
public static GoogleAI GetGeminiClient(string provider, string model, IServiceProvider services)
|
||||
{
|
||||
var settings = services.GetRequiredService<GoogleAiSettings>();
|
||||
var client = new GoogleAI(settings.Gemini.ApiKey);
|
||||
var settingsService = services.GetRequiredService<ILlmProviderService>();
|
||||
var settings = settingsService.GetSetting(provider, model);
|
||||
var client = new GoogleAI(settings.ApiKey);
|
||||
return client;
|
||||
}
|
||||
|
||||
public static GooglePalmClient GetPalmClient(IServiceProvider services)
|
||||
public static GooglePalmClient GetPalmClient(string provider, string model, IServiceProvider services)
|
||||
{
|
||||
var settings = services.GetRequiredService<GoogleAiSettings>();
|
||||
var client = new GooglePalmClient(settings.PaLM.ApiKey);
|
||||
var settingsService = services.GetRequiredService<ILlmProviderService>();
|
||||
var settings = settingsService.GetSetting(provider, model);
|
||||
var client = new GooglePalmClient(settings.ApiKey);
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public class GeminiTextCompletionProvider : ITextCompletion
|
|||
private readonly ITokenStatistics _tokenStatistics;
|
||||
private string _model;
|
||||
|
||||
public string Provider => "google-gemini";
|
||||
public string Provider => "google-ai";
|
||||
|
||||
public GeminiTextCompletionProvider(
|
||||
IServiceProvider services,
|
||||
|
|
@ -45,7 +45,7 @@ public class GeminiTextCompletionProvider : ITextCompletion
|
|||
await hook.BeforeGenerating(agent, new List<RoleDialogModel> { userMessage });
|
||||
}
|
||||
|
||||
var client = ProviderHelper.GetGeminiClient(_services);
|
||||
var client = ProviderHelper.GetGeminiClient(Provider, _model, _services);
|
||||
var aiModel = client.GenerativeModel(_model);
|
||||
PrepareOptions(aiModel);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public class PalmTextCompletionProvider : ITextCompletion
|
|||
|
||||
private string _model;
|
||||
|
||||
public string Provider => "google-ai";
|
||||
public string Provider => "google-palm";
|
||||
|
||||
public PalmTextCompletionProvider(
|
||||
IServiceProvider services,
|
||||
|
|
@ -38,7 +38,7 @@ public class PalmTextCompletionProvider : ITextCompletion
|
|||
await hook.BeforeGenerating(agent, new List<RoleDialogModel> { userMessage });
|
||||
}
|
||||
|
||||
var client = ProviderHelper.GetPalmClient(_services);
|
||||
var client = ProviderHelper.GetPalmClient(Provider, _model, _services);
|
||||
_tokenStatistics.StartTimer();
|
||||
var response = await client.GenerateTextAsync(text, null);
|
||||
_tokenStatistics.StopTimer();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using BotSharp.Abstraction.Utilities;
|
||||
|
||||
namespace BotSharp.Plugin.MetaGLM.Providers;
|
||||
|
||||
public class ChatCompletionProvider : IChatCompletion
|
||||
|
|
@ -86,7 +88,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
List<MessageItem> messages = new List<MessageItem>();
|
||||
List<FunctionTool> toolcalls = new List<FunctionTool>();
|
||||
|
||||
if (!string.IsNullOrEmpty(agent.Instruction))
|
||||
if (!string.IsNullOrEmpty(agent.Instruction) || !agent.SecondaryInstructions.IsNullOrEmpty())
|
||||
{
|
||||
var instruction = agentService.RenderedInstruction(agent);
|
||||
messages.Add(new MessageItem("system", instruction));
|
||||
|
|
@ -105,7 +107,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
new MessageItem("assistant", message.Content));
|
||||
}
|
||||
|
||||
foreach (var function in agent.Functions)
|
||||
var functions = agent.Functions.Concat(agent.SecondaryFunctions ?? []);
|
||||
foreach (var function in functions)
|
||||
{
|
||||
var functionTool = ConvertToFunctionTool(function);
|
||||
toolcalls.Add(functionTool);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ public sealed class MicrosoftExtensionsAIChatCompletionProvider : IChatCompletio
|
|||
|
||||
if (_services.GetService<IAgentService>() is { } agentService)
|
||||
{
|
||||
foreach (var function in agent.Functions)
|
||||
var functions = agent.Functions.Concat(agent.SecondaryFunctions ?? []);
|
||||
foreach (var function in functions)
|
||||
{
|
||||
if (agentService.RenderFunction(agent, function))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public class AgentDocument : MongoBase
|
|||
public List<AgentResponseMongoElement> Responses { get; set; }
|
||||
public List<string> Samples { get; set; }
|
||||
public List<AgentUtilityMongoElement> Utilities { get; set; }
|
||||
public List<AgentKnowledgeBaseMongoElement> KnowledgeBases { get; set; }
|
||||
public List<string> Profiles { get; set; }
|
||||
public List<RoutingRuleMongoElement> RoutingRules { get; set; }
|
||||
public AgentLlmConfigMongoElement? LlmConfig { get; set; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
using BotSharp.Abstraction.Agents.Models;
|
||||
|
||||
namespace BotSharp.Plugin.MongoStorage.Models;
|
||||
|
||||
public class AgentKnowledgeBaseMongoElement
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
public static AgentKnowledgeBaseMongoElement ToMongoElement(AgentKnowledgeBase knowledgeBase)
|
||||
{
|
||||
return new AgentKnowledgeBaseMongoElement
|
||||
{
|
||||
Name = knowledgeBase.Name ?? string.Empty,
|
||||
Disabled = knowledgeBase.Disabled,
|
||||
};
|
||||
}
|
||||
|
||||
public static AgentKnowledgeBase ToDomainElement(AgentKnowledgeBaseMongoElement knowledgeBase)
|
||||
{
|
||||
return new AgentKnowledgeBase
|
||||
{
|
||||
Name = knowledgeBase.Name,
|
||||
Disabled = knowledgeBase.Disabled
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -58,6 +58,9 @@ public partial class MongoRepository
|
|||
case AgentField.Utility:
|
||||
UpdateAgentUtilities(agent.Id, agent.MergeUtility, agent.Utilities);
|
||||
break;
|
||||
case AgentField.KnowledgeBase:
|
||||
UpdateAgentKnowledgeBases(agent.Id, agent.KnowledgeBases);
|
||||
break;
|
||||
case AgentField.MaxMessageCount:
|
||||
UpdateAgentMaxMessageCount(agent.Id, agent.MaxMessageCount);
|
||||
break;
|
||||
|
|
@ -239,6 +242,20 @@ public partial class MongoRepository
|
|||
_dc.Agents.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
private void UpdateAgentKnowledgeBases(string agentId, List<AgentKnowledgeBase> knowledgeBases)
|
||||
{
|
||||
if (knowledgeBases == null) return;
|
||||
|
||||
var elements = knowledgeBases?.Select(x => AgentKnowledgeBaseMongoElement.ToMongoElement(x))?.ToList() ?? [];
|
||||
|
||||
var filter = Builders<AgentDocument>.Filter.Eq(x => x.Id, agentId);
|
||||
var update = Builders<AgentDocument>.Update
|
||||
.Set(x => x.KnowledgeBases, elements)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
||||
_dc.Agents.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
private void UpdateAgentLlmConfig(string agentId, AgentLlmConfig? config)
|
||||
{
|
||||
var llmConfig = AgentLlmConfigMongoElement.ToMongoElement(config);
|
||||
|
|
@ -279,6 +296,7 @@ public partial class MongoRepository
|
|||
.Set(x => x.Responses, agent.Responses.Select(r => AgentResponseMongoElement.ToMongoElement(r)).ToList())
|
||||
.Set(x => x.Samples, agent.Samples)
|
||||
.Set(x => x.Utilities, agent.Utilities.Select(u => AgentUtilityMongoElement.ToMongoElement(u)).ToList())
|
||||
.Set(x => x.KnowledgeBases, agent.KnowledgeBases.Select(u => AgentKnowledgeBaseMongoElement.ToMongoElement(u)).ToList())
|
||||
.Set(x => x.LlmConfig, AgentLlmConfigMongoElement.ToMongoElement(agent.LlmConfig))
|
||||
.Set(x => x.IsPublic, agent.IsPublic)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
using BotSharp.Abstraction.Files.Utilities;
|
||||
using BotSharp.Abstraction.Templating;
|
||||
using OpenAI.Chat;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace BotSharp.Plugin.OpenAI.Providers.Chat;
|
||||
|
||||
|
|
@ -208,7 +210,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
MaxOutputTokenCount = maxTokens
|
||||
};
|
||||
|
||||
foreach (var function in agent.Functions)
|
||||
var functions = agent.Functions.Concat(agent.SecondaryFunctions ?? []);
|
||||
foreach (var function in functions)
|
||||
{
|
||||
if (!agentService.RenderFunction(agent, function)) continue;
|
||||
|
||||
|
|
@ -220,10 +223,10 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
functionParameters: BinaryData.FromObjectAsJson(property)));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(agent.Instruction))
|
||||
if (!string.IsNullOrEmpty(agent.Instruction) || !agent.SecondaryInstructions.IsNullOrEmpty())
|
||||
{
|
||||
var instruction = agentService.RenderedInstruction(agent);
|
||||
messages.Add(new SystemChatMessage(instruction));
|
||||
var text = agentService.RenderedInstruction(agent);
|
||||
messages.Add(new SystemChatMessage(text));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(agent.Knowledges))
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
var agentService = _services.GetRequiredService<IAgentService>();
|
||||
var messages = new List<ChatMessage>();
|
||||
|
||||
if (!string.IsNullOrEmpty(agent.Instruction))
|
||||
if (!string.IsNullOrEmpty(agent.Instruction) || !agent.SecondaryInstructions.IsNullOrEmpty())
|
||||
{
|
||||
var instruction = agentService.RenderedInstruction(agent);
|
||||
messages.Add(ChatMessage.FromSystem(instruction));
|
||||
|
|
@ -193,7 +193,8 @@ public class ChatCompletionProvider : IChatCompletion
|
|||
ChatMessage.FromAssistant(message.Content));
|
||||
}
|
||||
|
||||
foreach (var function in agent.Functions)
|
||||
var agentFuncs = agent.Functions.Concat(agent.SecondaryFunctions ?? []);
|
||||
foreach (var function in agentFuncs)
|
||||
{
|
||||
functions.Add(ConvertToFunctionDef(function));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ public class SqlDriverPlanningHook : IPlanningHook
|
|||
public async Task OnSourceCodeGenerated(string planner, RoleDialogModel msg, string language)
|
||||
{
|
||||
// envoke validate
|
||||
if (language != "sql")
|
||||
{
|
||||
return;
|
||||
if (language != "sql")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var routing = _services.GetRequiredService<IRoutingService>();
|
||||
|
|
@ -42,7 +42,7 @@ public class SqlDriverPlanningHook : IPlanningHook
|
|||
var conversationStateService = _services.GetRequiredService<IConversationStateService>();
|
||||
var conversationId = conversationStateService.GetConversationId();
|
||||
msg.PostbackFunctionName = "execute_sql";
|
||||
msg.RichContent = BuildRunQueryButton(planner, msg.Content);
|
||||
msg.RichContent = BuildRunQueryButton(conversationId, msg.Content);
|
||||
msg.StopCompletion = true;
|
||||
return;
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ public class SqlDriverPlanningHook : IPlanningHook
|
|||
|
||||
public async Task OnPlanningCompleted(string planner, RoleDialogModel msg)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
public async Task<string> GetSummaryAdditionalRequirements(string planner, RoleDialogModel message)
|
||||
|
|
@ -91,8 +91,27 @@ public class SqlDriverPlanningHook : IPlanningHook
|
|||
string pattern = @"```sql\s*([\s\S]*?)\s*```";
|
||||
var sql = Regex.Match(text, pattern).Groups[1].Value;
|
||||
var state = _services.GetRequiredService<IConversationStateService>();
|
||||
var deleteTable = state.GetState("tmp_table");
|
||||
var deleteSql = $"DROP TABLE IF EXISTS {deleteTable};";
|
||||
var tmpTable = state.GetState("tmp_table");
|
||||
|
||||
var elements = new List<ElementButton>() { };
|
||||
elements.Add(new ElementButton
|
||||
{
|
||||
Type = "text",
|
||||
Title = "Execute SQL Statement",
|
||||
Payload = sql,
|
||||
IsPrimary = true
|
||||
});
|
||||
|
||||
if (tmpTable != string.Empty)
|
||||
{
|
||||
var deleteSql = $"DROP TABLE IF EXISTS {tmpTable};";
|
||||
elements.Add(new ElementButton
|
||||
{
|
||||
Type = "text",
|
||||
Title = "Delete Temp Table",
|
||||
Payload = deleteSql
|
||||
});
|
||||
}
|
||||
|
||||
return new RichContent<IRichMessage>
|
||||
{
|
||||
|
|
@ -105,23 +124,9 @@ public class SqlDriverPlanningHook : IPlanningHook
|
|||
Message = new ButtonTemplateMessage
|
||||
{
|
||||
Text = text,
|
||||
Buttons = new List<ElementButton>
|
||||
{
|
||||
new ElementButton
|
||||
{
|
||||
Type = "text",
|
||||
Title = "Execute the SQL Statement",
|
||||
Payload = sql,
|
||||
IsPrimary = true
|
||||
},
|
||||
new ElementButton
|
||||
{
|
||||
Type = "text",
|
||||
Title = "Purge Cache",
|
||||
Payload = deleteSql
|
||||
}
|
||||
}.ToArray()
|
||||
Buttons = elements.ToArray()
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue