Skip to content

Commit 565f289

Browse files
authored
Merge pull request #1066 from iceljc/features/add-utility-visibility
add utility visibility expression
2 parents 854e6bf + e2f2d0a commit 565f289

File tree

32 files changed

+314
-166
lines changed

32 files changed

+314
-166
lines changed

src/Infrastructure/BotSharp.Abstraction/Agents/IAgentService.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public interface IAgentService
3636

3737
FunctionParametersDef? RenderFunctionProperty(Agent agent, FunctionDef def);
3838

39+
bool RenderVisibility(string? visibilityExpression, Dictionary<string, object> dict);
40+
3941
/// <summary>
4042
/// Get agent detail without trigger any hook.
4143
/// </summary>

src/Infrastructure/BotSharp.Abstraction/Agents/Models/AgentUtility.cs

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,38 @@ namespace BotSharp.Abstraction.Agents.Models;
22

33
public class AgentUtility
44
{
5+
public string Category { get; set; }
56
public string Name { get; set; }
67
public bool Disabled { get; set; }
7-
public IEnumerable<UtilityFunction> Functions { get; set; } = [];
8-
public IEnumerable<UtilityTemplate> Templates { get; set; } = [];
98

10-
public AgentUtility()
11-
{
12-
13-
}
14-
15-
public AgentUtility(
16-
string name,
17-
IEnumerable<UtilityFunction>? functions = null,
18-
IEnumerable<UtilityTemplate>? templates = null)
19-
{
20-
Name = name;
21-
Functions = functions ?? [];
22-
Templates = templates ?? [];
23-
}
24-
25-
public override string ToString()
26-
{
27-
return Name;
28-
}
29-
}
9+
[JsonPropertyName("visibility_expression")]
10+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
11+
public string? VisibilityExpression { get; set; }
3012

13+
public IEnumerable<UtilityItem> Items { get; set; } = [];
3114

32-
public class UtilityFunction : UtilityBase
33-
{
34-
public UtilityFunction()
15+
public AgentUtility()
3516
{
3617

3718
}
3819

39-
public UtilityFunction(string name)
20+
public override string ToString()
4021
{
41-
Name = name;
22+
return $"{Category}-{Name}";
4223
}
4324
}
4425

45-
public class UtilityTemplate : UtilityBase
26+
public class UtilityItem
4627
{
47-
public UtilityTemplate()
48-
{
49-
50-
}
28+
[JsonPropertyName("function_name")]
29+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
30+
public string? FunctionName { get; set; }
5131

52-
public UtilityTemplate(string name)
53-
{
54-
Name = name;
55-
}
56-
}
32+
[JsonPropertyName("template_name")]
33+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
34+
public string? TemplateName { get; set; }
5735

58-
public class UtilityBase
59-
{
60-
public string Name { get; set; }
36+
[JsonPropertyName("visibility_expression")]
37+
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
38+
public string? VisibilityExpression { get; set; }
6139
}

src/Infrastructure/BotSharp.Core.Crontab/Enum/UtilityName.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ namespace BotSharp.Core.Crontab.Enum;
22

33
public class UtilityName
44
{
5-
public const string ScheduleTask = "crontab.schedule-task";
5+
public const string ScheduleTask = "schedule-task";
66
}

src/Infrastructure/BotSharp.Core.Crontab/Hooks/CrontabUtilityHook.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,19 @@ public void AddUtilities(List<AgentUtility> utilities)
1515
{
1616
new AgentUtility
1717
{
18+
Category = "crontab",
1819
Name = UtilityName.ScheduleTask,
19-
Functions = [new(SCHEDULE_TASK_FN), new(TASK_WAIT_FN)],
20-
Templates = [new($"{SCHEDULE_TASK_FN}.fn")]
20+
Items = [
21+
new UtilityItem
22+
{
23+
FunctionName = SCHEDULE_TASK_FN,
24+
TemplateName = $"{SCHEDULE_TASK_FN}.fn"
25+
},
26+
new UtilityItem
27+
{
28+
FunctionName = TASK_WAIT_FN
29+
},
30+
]
2131
}
2232
};
2333

src/Infrastructure/BotSharp.Core/Agents/Hooks/BasicAgentHook.cs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ public override void OnAgentUtilityLoaded(Agent agent)
1919
var isConvMode = conv.IsConversationMode();
2020
if (!isConvMode) return;
2121

22+
agent.Utilities ??= [];
2223
agent.SecondaryFunctions ??= [];
2324
agent.SecondaryInstructions ??= [];
24-
agent.Utilities ??= [];
2525

2626
var (functions, templates) = GetUtilityContent(agent);
2727

@@ -34,7 +34,7 @@ public override void OnAgentUtilityLoaded(Agent agent)
3434
private (IEnumerable<FunctionDef>, IEnumerable<AgentTemplate>) GetUtilityContent(Agent agent)
3535
{
3636
var db = _services.GetRequiredService<IBotSharpRepository>();
37-
var (functionNames, templateNames) = GetUniqueContent(agent.Utilities);
37+
var (functionNames, templateNames) = FilterUtilityContent(agent.Utilities, agent);
3838

3939
if (agent.MergeUtility)
4040
{
@@ -43,7 +43,7 @@ public override void OnAgentUtilityLoaded(Agent agent)
4343
if (!string.IsNullOrEmpty(entryAgentId))
4444
{
4545
var entryAgent = db.GetAgent(entryAgentId, basicsOnly: true);
46-
var (fns, tps) = GetUniqueContent(entryAgent?.Utilities);
46+
var (fns, tps) = FilterUtilityContent(entryAgent?.Utilities, agent);
4747
functionNames = functionNames.Concat(fns).Distinct().ToList();
4848
templateNames = templateNames.Concat(tps).Distinct().ToList();
4949
}
@@ -55,23 +55,41 @@ public override void OnAgentUtilityLoaded(Agent agent)
5555
return (functions, templates);
5656
}
5757

58-
private (IEnumerable<string>, IEnumerable<string>) GetUniqueContent(IEnumerable<AgentUtility>? utilities)
58+
private (IEnumerable<string>, IEnumerable<string>) FilterUtilityContent(IEnumerable<AgentUtility>? utilities, Agent agent)
5959
{
6060
if (utilities.IsNullOrEmpty())
6161
{
6262
return ([], []);
6363
}
6464

65-
utilities = utilities?.Where(x => !string.IsNullOrEmpty(x.Name) && !x.Disabled)?.ToList() ?? [];
66-
var functionNames = utilities.SelectMany(x => x.Functions)
67-
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(UTIL_PREFIX))
68-
.Select(x => x.Name)
69-
.Distinct().ToList();
70-
var templateNames = utilities.SelectMany(x => x.Templates)
71-
.Where(x => !string.IsNullOrEmpty(x.Name) && x.Name.StartsWith(UTIL_PREFIX))
72-
.Select(x => x.Name)
73-
.Distinct().ToList();
74-
75-
return (functionNames, templateNames);
65+
var agentService = _services.GetRequiredService<IAgentService>();
66+
var innerUtilities = utilities!.Where(x => !string.IsNullOrEmpty(x.Name) && !x.Disabled).ToList();
67+
68+
var functionNames = new List<string>();
69+
var templateNames = new List<string>();
70+
71+
foreach (var utility in innerUtilities)
72+
{
73+
var isVisible = agentService.RenderVisibility(utility.VisibilityExpression, agent.TemplateDict);
74+
if (!isVisible || utility.Items.IsNullOrEmpty()) continue;
75+
76+
foreach (var item in utility.Items)
77+
{
78+
isVisible = agentService.RenderVisibility(item.VisibilityExpression, agent.TemplateDict);
79+
if (!isVisible) continue;
80+
81+
if (item.FunctionName?.StartsWith(UTIL_PREFIX) == true)
82+
{
83+
functionNames.Add(item.FunctionName);
84+
}
85+
86+
if (item.TemplateName?.StartsWith(UTIL_PREFIX) == true)
87+
{
88+
templateNames.Add(item.TemplateName);
89+
}
90+
}
91+
}
92+
93+
return (functionNames.Distinct(), templateNames.Distinct());
7694
}
7795
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using BotSharp.Abstraction.Infrastructures;
21
using BotSharp.Abstraction.Routing.Models;
32
using System.Collections.Concurrent;
43

@@ -18,12 +17,15 @@ public async Task<Agent> LoadAgent(string id, bool loadUtility = true)
1817
var agent = await GetAgent(id);
1918
if (agent == null) return null;
2019

20+
agent.TemplateDict = [];
21+
agent.SecondaryInstructions = [];
22+
agent.SecondaryFunctions = [];
23+
2124
await InheritAgent(agent);
2225
OverrideInstructionByChannel(agent);
2326
AddOrUpdateParameters(agent);
2427

2528
// Populate state into dictionary
26-
agent.TemplateDict = new Dictionary<string, object>();
2729
PopulateState(agent.TemplateDict);
2830

2931
// After agent is loaded

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,7 @@ public bool RenderFunction(Agent agent, FunctionDef def)
4646

4747
if (!string.IsNullOrWhiteSpace(def.VisibilityExpression))
4848
{
49-
var render = _services.GetRequiredService<ITemplateRender>();
50-
var result = render.Render(def.VisibilityExpression, new Dictionary<string, object>
51-
{
52-
{ "states", agent.TemplateDict }
53-
});
54-
isRender = isRender && result == "visible";
49+
isRender = RenderVisibility(def.VisibilityExpression, agent.TemplateDict);
5550
}
5651

5752
return isRender;
@@ -76,12 +71,7 @@ public bool RenderFunction(Agent agent, FunctionDef def)
7671
if (node.TryGetProperty(visibleExpress, out var element))
7772
{
7873
var expression = element.GetString();
79-
var render = _services.GetRequiredService<ITemplateRender>();
80-
var result = render.Render(expression, new Dictionary<string, object>
81-
{
82-
{ "states", agent.TemplateDict }
83-
});
84-
matched = result == "visible";
74+
matched = RenderVisibility(expression, agent.TemplateDict);
8575
}
8676

8777
if (matched)
@@ -137,4 +127,20 @@ public string RenderedTemplate(Agent agent, string templateName)
137127

138128
return content;
139129
}
130+
131+
public bool RenderVisibility(string? visibilityExpression, Dictionary<string, object> dict)
132+
{
133+
if (string.IsNullOrWhiteSpace(visibilityExpression))
134+
{
135+
return true;
136+
}
137+
138+
var render = _services.GetRequiredService<ITemplateRender>();
139+
var result = render.Render(visibilityExpression, new Dictionary<string, object>
140+
{
141+
{ "states", dict ?? [] }
142+
});
143+
144+
return result.IsEqualTo("visible");
145+
}
140146
}

src/Infrastructure/BotSharp.Core/Instructs/Hooks/InstructUtilityHook.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ public void AddUtilities(List<AgentUtility> utilities)
99
{
1010
utilities.Add(new AgentUtility
1111
{
12-
Name = "instruct.template",
13-
Functions = [new($"{EXECUTE_TEMPLATE}")],
14-
Templates = [new($"{EXECUTE_TEMPLATE}.fn")]
12+
Category = "instruct",
13+
Name = "template",
14+
Items = [
15+
new UtilityItem {
16+
FunctionName = $"{EXECUTE_TEMPLATE}",
17+
TemplateName = $"{EXECUTE_TEMPLATE}.fn"
18+
}
19+
]
1520
});
1621
}
1722
}

src/Infrastructure/BotSharp.Core/Routing/Hooks/RoutingUtilityHook.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,20 @@ public void AddUtilities(List<AgentUtility> utilities)
1010
{
1111
utilities.Add(new AgentUtility
1212
{
13+
Category = "routing",
1314
Name = "routing.tools",
14-
Functions = [new($"{REDIRECT_TO_AGENT}"), new($"{FALLBACK_TO_ROUTER}")],
15-
Templates = [new($"{REDIRECT_TO_AGENT}.fn"), new($"{FALLBACK_TO_ROUTER}.fn")]
15+
Items = [
16+
new UtilityItem
17+
{
18+
FunctionName = $"{REDIRECT_TO_AGENT}",
19+
TemplateName = $"{REDIRECT_TO_AGENT}.fn"
20+
},
21+
new UtilityItem
22+
{
23+
FunctionName = $"{FALLBACK_TO_ROUTER}",
24+
TemplateName = $"{FALLBACK_TO_ROUTER}.fn"
25+
}
26+
]
1627
});
1728
}
1829
}

src/Infrastructure/BotSharp.OpenAPI/Controllers/AgentController.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,9 @@ public IEnumerable<AgentUtility> GetAgentUtilityOptions()
167167
{
168168
hook.AddUtilities(utilities);
169169
}
170-
return utilities.Where(x => !string.IsNullOrWhiteSpace(x.Name)).OrderBy(x => x.Name).ToList();
170+
return utilities.Where(x => !string.IsNullOrWhiteSpace(x.Category)
171+
&& !string.IsNullOrWhiteSpace(x.Name)
172+
&& !x.Items.IsNullOrEmpty()).ToList();
171173
}
172174

173175
[HttpGet("/agent/labels")]

src/Plugins/BotSharp.Plugin.AudioHandler/Enums/UtilityName.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ namespace BotSharp.Plugin.AudioHandler.Enums;
22

33
public class UtilityName
44
{
5-
public const string AudioHandler = "audio.audio-handler";
5+
public const string AudioHandler = "audio-handler";
66
}

src/Plugins/BotSharp.Plugin.AudioHandler/Hooks/AudioHandlerUtilityHook.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,15 @@ public void AddUtilities(List<AgentUtility> utilities)
99
{
1010
var utility = new AgentUtility
1111
{
12+
Category = "audio",
1213
Name = UtilityName.AudioHandler,
13-
Functions = [new(HANDLER_AUDIO)],
14-
Templates = [new($"{HANDLER_AUDIO}.fn")]
14+
Items = [
15+
new UtilityItem
16+
{
17+
FunctionName = HANDLER_AUDIO,
18+
TemplateName = $"{HANDLER_AUDIO}.fn"
19+
}
20+
]
1521
};
1622

1723
utilities.Add(utility);

src/Plugins/BotSharp.Plugin.EmailHandler/Enums/UtilityName.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ namespace BotSharp.Plugin.EmailHandler.Enums;
22

33
public class UtilityName
44
{
5-
public const string EmailHandler = "email.email-handler";
5+
public const string EmailHandler = "email-handler";
66
}

src/Plugins/BotSharp.Plugin.EmailHandler/Hooks/EmailHandlerUtilityHook.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,20 @@ public void AddUtilities(List<AgentUtility> utilities)
1313
{
1414
var utility = new AgentUtility
1515
{
16+
Category = "email",
1617
Name = UtilityName.EmailHandler,
17-
Functions = [new(EMAIL_READER_FN), new(EMAIL_SENDER_FN)],
18-
Templates = [new($"{EMAIL_READER_FN}.fn"), new($"{EMAIL_SENDER_FN}.fn")]
18+
Items = [
19+
new UtilityItem
20+
{
21+
FunctionName = EMAIL_READER_FN,
22+
TemplateName = $"{EMAIL_READER_FN}.fn"
23+
},
24+
new UtilityItem
25+
{
26+
FunctionName = EMAIL_SENDER_FN,
27+
TemplateName = $"{EMAIL_SENDER_FN}.fn"
28+
}
29+
]
1930
};
2031

2132
utilities.Add(utility);

src/Plugins/BotSharp.Plugin.ExcelHandler/Enums/UtilityName.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ namespace BotSharp.Plugin.ExcelHandler.Enums;
22

33
public class UtilityName
44
{
5-
public const string ExcelHandler = "excel.excel-handler";
5+
public const string ExcelHandler = "excel-handler";
66
}

0 commit comments

Comments
 (0)