Skip to content

Features/add prompt by channel #591

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ public interface IAgentService
/// <returns></returns>
Task<Agent> LoadAgent(string id);

/// <summary>
/// Inherit from an agent
/// </summary>
/// <param name="agent"></param>
/// <returns></returns>
Task InheritAgent(Agent agent);

string RenderedInstruction(Agent agent);

string RenderedTemplate(Agent agent, string templateName);
Expand Down
38 changes: 21 additions & 17 deletions src/Infrastructure/BotSharp.Abstraction/Agents/Models/Agent.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
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;
Expand All @@ -21,42 +20,43 @@ public class Agent
/// Default LLM settings
/// </summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public AgentLlmConfig LlmConfig { get; set; }
= new AgentLlmConfig();
public AgentLlmConfig LlmConfig { get; set; } = new();

/// <summary>
/// Instruction
/// </summary>
[JsonIgnore]
public string? Instruction { get; set; }

/// <summary>
/// Channel instructions
/// </summary>
[JsonIgnore]
public List<ChannelInstruction> ChannelInstructions { get; set; } = new();

/// <summary>
/// Templates
/// </summary>
[JsonIgnore]
public List<AgentTemplate> Templates { get; set; }
= new List<AgentTemplate>();
public List<AgentTemplate> Templates { get; set; } = new();

/// <summary>
/// Agent tasks
/// </summary>
[JsonIgnore]
public List<AgentTask> Tasks { get; set; }
= new List<AgentTask>();
public List<AgentTask> Tasks { get; set; } = new();

/// <summary>
/// Samples
/// </summary>
[JsonIgnore]
public List<string> Samples { get; set; }
= new List<string>();
public List<string> Samples { get; set; } = new();

/// <summary>
/// Functions
/// </summary>
[JsonIgnore]
public List<FunctionDef> Functions { get; set; }
= new List<FunctionDef>();
public List<FunctionDef> Functions { get; set; } = new();

/// <summary>
/// Responses
Expand Down Expand Up @@ -93,23 +93,20 @@ public class Agent
/// <summary>
/// Agent utilities
/// </summary>
public List<string> Utilities { get; set; }
= new List<string>();
public List<string> Utilities { get; set; } = new();

/// <summary>
/// Inherit from agent
/// </summary>
public string? InheritAgentId { get; set; }

public List<RoutingRule> RoutingRules { get; set; }
= new List<RoutingRule>();
public List<RoutingRule> RoutingRules { get; set; } = new();

/// <summary>
/// For rendering deferral
/// </summary>
[JsonIgnore]
public Dictionary<string, object> TemplateDict { get; set; }
= new Dictionary<string, object>();
public Dictionary<string, object> TemplateDict { get; set; } = new();

public override string ToString()
=> $"{Name} {Id}";
Expand All @@ -124,6 +121,7 @@ public static Agent Clone(Agent agent)
Description = agent.Description,
Type = agent.Type,
Instruction = agent.Instruction,
ChannelInstructions = agent.ChannelInstructions,
Functions = agent.Functions,
Responses = agent.Responses,
Samples = agent.Samples,
Expand All @@ -145,6 +143,12 @@ public Agent SetInstruction(string instruction)
return this;
}

public Agent SetChannelInstructions(List<ChannelInstruction> instructions)
{
ChannelInstructions = instructions ?? new List<ChannelInstruction>();
return this;
}

public Agent SetTemplates(List<AgentTemplate> templates)
{
Templates = templates ?? new List<AgentTemplate>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace BotSharp.Abstraction.Agents.Models;

public class ChannelInstruction
{
public string Channel { get; set; }
public string Instruction { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ public class FunctionDef
[JsonPropertyName("description")]
public string Description { get; set; } = null!;

[JsonPropertyName("channels")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public List<string>? Channels { get; set; }

[JsonPropertyName("visibility_expression")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? VisibilityExpression { get; set; }

[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace BotSharp.Abstraction.Knowledges.Models;

public class KnowledgeSearchResult
{
public IDictionary<string, string> Data { get; set; } = new Dictionary<string, string>();
public Dictionary<string, string> Data { get; set; } = new();
public double Score { get; set; }
public float[]? Vector { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,55 +41,63 @@ public async Task<Agent> CreateAgent(Agent agent)
});

Utilities.ClearCache();

return await Task.FromResult(agentRecord);
}

private Agent FetchAgentFileByName(string agentName, string filePath)
private (string, List<ChannelInstruction>) GetInstructionsFromFile(string fileDir)
{
foreach (var dir in Directory.GetDirectories(filePath))
var defaultInstruction = string.Empty;
var channelInstructions = new List<ChannelInstruction>();

var instructionDir = Path.Combine(fileDir, "instructions");
if (!Directory.Exists(instructionDir))
{
var agentJson = File.ReadAllText(Path.Combine(dir, "agent.json"));
var agent = JsonSerializer.Deserialize<Agent>(agentJson, _options);
if (agent != null && agent.Name.IsEqualTo(agentName))
{
var functions = FetchFunctionsFromFile(dir);
var instruction = FetchInstructionFromFile(dir);
var responses = FetchResponsesFromFile(dir);
var templates = FetchTemplatesFromFile(dir);
var samples = FetchSamplesFromFile(dir);
return agent.SetInstruction(instruction)
.SetTemplates(templates)
.SetFunctions(functions)
.SetResponses(responses)
.SetSamples(samples);
}
return (defaultInstruction, channelInstructions);
}

return null;
}
foreach (var file in Directory.GetFiles(instructionDir))
{
var extension = Path.GetExtension(file).Substring(1);
if (!extension.IsEqualTo(_agentSettings.TemplateFormat))
{
continue;
}

private string FetchInstructionFromFile(string fileDir)
{
var file = Path.Combine(fileDir, $"instruction.{_agentSettings.TemplateFormat}");
if (!File.Exists(file)) return null;
var segments = Path.GetFileName(file).Split(".", StringSplitOptions.RemoveEmptyEntries);
if (segments.IsNullOrEmpty() || !segments[0].IsEqualTo("instruction"))
{
continue;
}

var instruction = File.ReadAllText(file);
return instruction;
if (segments.Length == 2)
{
defaultInstruction = File.ReadAllText(file);
}
else if (segments.Length == 3)
{
var item = new ChannelInstruction
{
Channel = segments[1],
Instruction = File.ReadAllText(file)
};
channelInstructions.Add(item);
}
}
return (defaultInstruction, channelInstructions);
}

private List<AgentTemplate> FetchTemplatesFromFile(string fileDir)
private List<AgentTemplate> GetTemplatesFromFile(string fileDir)
{
var templates = new List<AgentTemplate>();
var templateDir = Path.Combine(fileDir, "templates");
if (!Directory.Exists(templateDir)) return templates;

foreach (var file in Directory.GetFiles(templateDir))
{
var name = Path.GetFileNameWithoutExtension(file);
var extension = Path.GetExtension(file).Substring(1);
if (extension.IsEqualTo(_agentSettings.TemplateFormat))
{
var name = Path.GetFileNameWithoutExtension(file);
var content = File.ReadAllText(file);
templates.Add(new AgentTemplate(name, content));
}
Expand All @@ -98,7 +106,7 @@ private List<AgentTemplate> FetchTemplatesFromFile(string fileDir)
return templates;
}

private List<FunctionDef> FetchFunctionsFromFile(string fileDir)
private List<FunctionDef> GetFunctionsFromFile(string fileDir)
{
var functions = new List<FunctionDef>();
var functionDir = Path.Combine(fileDir, "functions");
Expand All @@ -125,7 +133,7 @@ private List<FunctionDef> FetchFunctionsFromFile(string fileDir)
return functions;
}

private List<AgentResponse> FetchResponsesFromFile(string fileDir)
private List<AgentResponse> GetResponsesFromFile(string fileDir)
{
var responses = new List<AgentResponse>();
var responseDir = Path.Combine(fileDir, "responses");
Expand All @@ -143,7 +151,7 @@ private List<AgentResponse> FetchResponsesFromFile(string fileDir)
return responses;
}

private List<string> FetchSamplesFromFile(string fileDir)
private List<string> GetSamplesFromFile(string fileDir)
{
var file = Path.Combine(fileDir, "samples.txt");
if (!File.Exists(file)) return new List<string>();
Expand All @@ -152,7 +160,7 @@ private List<string> FetchSamplesFromFile(string fileDir)
return samples?.ToList() ?? new List<string>();
}

private List<AgentTask> FetchTasksFromFile(string fileDir)
private List<AgentTask> GetTasksFromFile(string fileDir)
{
var tasks = new List<AgentTask>();
var taskDir = Path.Combine(fileDir, "tasks");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,29 @@ public async Task<Agent> GetAgent(string id)
}

profile.Plugin = GetPlugin(profile.Id);

return profile;
}

public async Task InheritAgent(Agent agent)
{
if (string.IsNullOrWhiteSpace(agent?.InheritAgentId)) return;

var inheritedAgent = await GetAgent(agent.InheritAgentId);
agent.Templates.AddRange(inheritedAgent.Templates
// exclude private template
.Where(x => !x.Name.StartsWith("."))
// exclude duplicate name
.Where(x => !agent.Templates.Exists(t => t.Name == x.Name)));

agent.Functions.AddRange(inheritedAgent.Functions
// exclude private template
.Where(x => !x.Name.StartsWith("."))
// exclude duplicate name
.Where(x => !agent.Functions.Exists(t => t.Name == x.Name)));

if (string.IsNullOrWhiteSpace(agent.Instruction))
{
agent.Instruction = inheritedAgent.Instruction;
}
}
}
Loading