BotSharp/src/Infrastructure/BotSharp.Core/Agents/Services/AgentService.Rendering.cs

162 lines
5.2 KiB
C#
Raw Normal View History

2024-03-31 19:28:16 +00:00
using BotSharp.Abstraction.Loggers;
using BotSharp.Abstraction.Templating;
2024-04-09 20:52:21 +00:00
using Newtonsoft.Json.Linq;
2024-03-31 19:28:16 +00:00
namespace BotSharp.Core.Agents.Services;
public partial class AgentService
{
public string RenderedInstruction(Agent agent)
{
var render = _services.GetRequiredService<ITemplateRender>();
var conv = _services.GetRequiredService<IConversationService>();
2024-11-25 22:13:40 +00:00
2024-12-22 22:36:18 +00:00
// merge instructions
2024-12-26 06:18:02 +00:00
var instructions = new List<string> { agent.Instruction };
var secondaryInstructions = agent.SecondaryInstructions?.Where(x => !string.IsNullOrWhiteSpace(x)).ToList() ?? [];
instructions.AddRange(secondaryInstructions);
2024-12-22 22:36:18 +00:00
2024-11-25 22:13:40 +00:00
// update states
2024-03-31 19:28:16 +00:00
foreach (var t in conv.States.GetStates())
{
agent.TemplateDict[t.Key] = t.Value;
}
2024-11-25 22:13:40 +00:00
2025-04-28 19:53:32 +00:00
RenderAgentLinks(agent, agent.TemplateDict);
2024-12-26 06:18:02 +00:00
var res = render.Render(string.Join("\r\n", instructions), agent.TemplateDict);
2024-11-25 22:13:40 +00:00
return res;
2024-03-31 19:28:16 +00:00
}
public bool RenderFunction(Agent agent, FunctionDef def)
{
2024-08-13 22:37:47 +00:00
var isRender = true;
var channels = def.Channels;
if (channels != null)
{
var state = _services.GetRequiredService<IConversationStateService>();
var channel = state.GetState("channel");
if (!string.IsNullOrWhiteSpace(channel))
{
isRender = isRender && channels.Contains(channel);
}
}
if (!isRender) return false;
if (!string.IsNullOrWhiteSpace(def.VisibilityExpression))
2024-03-31 19:28:16 +00:00
{
var render = _services.GetRequiredService<ITemplateRender>();
var result = render.Render(def.VisibilityExpression, new Dictionary<string, object>
{
{ "states", agent.TemplateDict }
});
2024-08-13 22:37:47 +00:00
isRender = isRender && result == "visible";
2024-03-31 19:28:16 +00:00
}
2024-08-13 22:37:47 +00:00
return isRender;
2024-03-31 19:28:16 +00:00
}
2024-04-09 20:52:21 +00:00
public FunctionParametersDef? RenderFunctionProperty(Agent agent, FunctionDef def)
{
var parameterDef = def?.Parameters;
var propertyDef = parameterDef?.Properties;
if (propertyDef == null) return null;
var visibleExpress = "visibility_expression";
var root = propertyDef.RootElement;
var iterator = root.EnumerateObject();
2024-04-09 21:00:53 +00:00
var visibleProps = new List<string>();
2024-04-09 20:52:21 +00:00
while (iterator.MoveNext())
{
var prop = iterator.Current;
var name = prop.Name;
var node = prop.Value;
var matched = true;
if (node.TryGetProperty(visibleExpress, out var element))
{
var expression = element.GetString();
var render = _services.GetRequiredService<ITemplateRender>();
var result = render.Render(expression, new Dictionary<string, object>
{
{ "states", agent.TemplateDict }
});
matched = result == "visible";
}
if (matched)
{
2024-04-09 21:00:53 +00:00
visibleProps.Add(name);
2024-04-09 20:52:21 +00:00
}
}
var rootObject = JObject.Parse(root.GetRawText());
var clonedRoot = rootObject.DeepClone() as JObject;
var required = parameterDef?.Required ?? new List<string>();
foreach (var property in rootObject.Properties())
{
2024-04-09 21:00:53 +00:00
if (visibleProps.Contains(property.Name))
2024-04-09 20:52:21 +00:00
{
var value = clonedRoot.GetValue(property.Name) as JObject;
if (value != null && value.ContainsKey(visibleExpress))
{
value.Remove(visibleExpress);
}
}
else
{
clonedRoot.Remove(property.Name);
required.Remove(property.Name);
}
}
parameterDef.Properties = JsonSerializer.Deserialize<JsonDocument>(clonedRoot.ToString());
parameterDef.Required = required;
2025-01-09 22:30:25 +00:00
return parameterDef;
2024-04-09 20:52:21 +00:00
}
2024-03-31 19:28:16 +00:00
public string RenderedTemplate(Agent agent, string templateName)
{
2024-11-25 22:13:40 +00:00
var conv = _services.GetRequiredService<IConversationService>();
2024-03-31 19:28:16 +00:00
var render = _services.GetRequiredService<ITemplateRender>();
2024-11-25 22:13:40 +00:00
2025-03-31 20:16:46 +00:00
var template = agent.Templates.FirstOrDefault(x => x.Name == templateName)?.Content ?? string.Empty;
2024-11-25 22:13:40 +00:00
2024-03-31 19:28:16 +00:00
// update states
foreach (var t in conv.States.GetStates())
{
agent.TemplateDict[t.Key] = t.Value;
}
2024-11-25 22:13:40 +00:00
// render liquid template
2024-03-31 19:28:16 +00:00
var content = render.Render(template, agent.TemplateDict);
HookEmitter.Emit<IContentGeneratingHook>(_services, async hook =>
await hook.OnRenderingTemplate(agent, templateName, content)
).Wait();
return content;
}
2025-04-28 19:53:32 +00:00
private void RenderAgentLinks(Agent agent, Dictionary<string, object> dict)
{
var render = _services.GetRequiredService<ITemplateRender>();
var links = new Dictionary<string, string>();
agent.Links ??= [];
foreach (var link in agent.Links)
{
if (string.IsNullOrWhiteSpace(link.Name)
|| string.IsNullOrWhiteSpace(link.Content))
{
continue;
}
links[link.Name] = link.Content;
}
render.RegisterTag("link", links, dict);
return;
}
2024-11-25 22:13:40 +00:00
}