Skip to content

Commit a02bbcd

Browse files
authored
Merge pull request #1283 from yileicn/master
optimize IAgentHook use async method
2 parents 99af76f + 7c63258 commit a02bbcd

10 files changed

Lines changed: 74 additions & 55 deletions

File tree

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

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,44 +24,45 @@ public void SetAgent(Agent agent)
2424
_agent = agent;
2525
}
2626

27-
public virtual bool OnAgentLoading(ref string id)
27+
public virtual Task<string?> OnAgentLoading(string id)
2828
{
29-
return true;
29+
return Task.FromResult<string?>(id);
3030
}
3131

32-
public virtual bool OnInstructionLoaded(string template, IDictionary<string, object> dict)
32+
public virtual Task<bool> OnInstructionLoaded(string template, IDictionary<string, object> dict)
3333
{
3434
dict["current_date"] = $"{DateTime.Now:MMM dd, yyyy}";
3535
dict["current_time"] = $"{DateTime.Now:hh:mm tt}";
3636
dict["current_weekday"] = $"{DateTime.Now:dddd}";
3737
dict["current_utc_datetime"] = $"{DateTime.UtcNow}";
3838

39-
return true;
39+
return Task.FromResult(true);
4040
}
4141

42-
public virtual bool OnFunctionsLoaded(List<FunctionDef> functions)
42+
public virtual Task<bool> OnFunctionsLoaded(List<FunctionDef> functions)
4343
{
4444
_agent.Functions = functions;
45-
return true;
45+
return Task.FromResult(true);
4646
}
4747

48-
public virtual bool OnSamplesLoaded(List<string> samples)
48+
public virtual Task<bool> OnSamplesLoaded(List<string> samples)
4949
{
5050
_agent.Samples = samples;
51-
return true;
51+
return Task.FromResult(true);
5252
}
5353

54-
public virtual void OnAgentLoaded(Agent agent)
54+
public virtual Task OnAgentLoaded(Agent agent)
5555
{
56+
return Task.CompletedTask;
5657
}
5758

58-
public virtual void OnAgentUtilityLoaded(Agent agent)
59+
public virtual Task OnAgentUtilityLoaded(Agent agent)
5960
{
60-
61+
return Task.CompletedTask;
6162
}
6263

63-
public virtual void OnAgentMcpToolLoaded(Agent agent)
64+
public virtual Task OnAgentMcpToolLoaded(Agent agent)
6465
{
65-
66+
return Task.CompletedTask;
6667
}
6768
}

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,26 @@ public interface IAgentHook : IHookBase
1010

1111
/// <summary>
1212
/// Triggered when agent is loading.
13-
/// Return different agent for redirection purpose.
13+
/// Return different agent id for redirection purpose.
1414
/// </summary>
1515
/// <param name="id">Agent Id</param>
16-
/// <returns></returns>
17-
bool OnAgentLoading(ref string id);
16+
/// <returns>New agent id if redirection is needed, null otherwise</returns>
17+
Task<string?> OnAgentLoading(string id);
1818

19-
bool OnInstructionLoaded(string template, IDictionary<string, object> dict);
19+
Task<bool> OnInstructionLoaded(string template, IDictionary<string, object> dict);
2020

21-
bool OnFunctionsLoaded(List<FunctionDef> functions);
21+
Task<bool> OnFunctionsLoaded(List<FunctionDef> functions);
2222

23-
bool OnSamplesLoaded(List<string> samples);
23+
Task<bool> OnSamplesLoaded(List<string> samples);
2424

25-
void OnAgentUtilityLoaded(Agent agent);
25+
Task OnAgentUtilityLoaded(Agent agent);
2626

27-
void OnAgentMcpToolLoaded(Agent agent);
27+
Task OnAgentMcpToolLoaded(Agent agent);
2828

2929
/// <summary>
3030
/// Triggered when agent is loaded completely.
3131
/// </summary>
3232
/// <param name="agent"></param>
3333
/// <returns></returns>
34-
void OnAgentLoaded(Agent agent);
34+
Task OnAgentLoaded(Agent agent);
3535
}

src/Infrastructure/BotSharp.Core.A2A/Hooks/A2AAgentHook.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,29 @@ public A2AAgentHook(IServiceProvider services, IA2AService a2aService, A2ASettin
2323
_a2aSettings = a2aSettings;
2424
}
2525

26-
public override bool OnAgentLoading(ref string id)
26+
public override async Task<string?> OnAgentLoading(string id)
2727
{
28-
var agentId = id;
29-
var remoteConfig = _a2aSettings.Agents?.FirstOrDefault(x => x.Id == agentId);
28+
var remoteConfig = _a2aSettings.Agents?.FirstOrDefault(x => x.Id == id);
3029
if (remoteConfig != null)
3130
{
32-
return true;
31+
return id; // No redirection needed, continue with current id
3332
}
34-
return base.OnAgentLoading(ref id);
33+
return await base.OnAgentLoading(id);
3534
}
3635

37-
public override void OnAgentLoaded(Agent agent)
36+
public override async Task OnAgentLoaded(Agent agent)
3837
{
3938
// Check if this is an A2A remote agent
4039
if (agent.Type != AgentType.A2ARemote)
4140
{
41+
await base.OnAgentLoaded(agent);
4242
return;
4343
}
4444

4545
var remoteConfig = _a2aSettings.Agents?.FirstOrDefault(x => x.Id == agent.Id);
4646
if (remoteConfig != null)
4747
{
48-
var agentCard = _a2aService.GetCapabilitiesAsync(remoteConfig.Endpoint).GetAwaiter().GetResult();
48+
var agentCard = await _a2aService.GetCapabilitiesAsync(remoteConfig.Endpoint);
4949
if (agentCard != null)
5050
{
5151
agent.Name = agentCard.Name;
@@ -83,6 +83,6 @@ public override void OnAgentLoaded(Agent agent)
8383
});
8484
}
8585
}
86-
base.OnAgentLoaded(agent);
86+
await base.OnAgentLoaded(agent);
8787
}
8888
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ public BasicAgentHook(IServiceProvider services, AgentSettings settings)
1111
{
1212
}
1313

14-
public override void OnAgentUtilityLoaded(Agent agent)
14+
public override Task OnAgentUtilityLoaded(Agent agent)
1515
{
1616
var conv = _services.GetRequiredService<IConversationService>();
1717
var isConvMode = conv.IsConversationMode();
18-
if (!isConvMode) return;
18+
if (!isConvMode) return Task.CompletedTask;
1919

2020
agent.Utilities ??= [];
2121
agent.SecondaryFunctions ??= [];
@@ -26,6 +26,8 @@ public override void OnAgentUtilityLoaded(Agent agent)
2626
agent.SecondaryFunctions = agent.SecondaryFunctions.Concat(functions).DistinctBy(x => x.Name, StringComparer.OrdinalIgnoreCase).ToList();
2727
var contents = templates.Select(x => x.Content);
2828
agent.SecondaryInstructions = agent.SecondaryInstructions.Concat(contents).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
29+
30+
return Task.CompletedTask;
2931
}
3032

3133

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using BotSharp.Abstraction.Hooks;
12
using BotSharp.Abstraction.Routing.Models;
23
using System.Collections.Concurrent;
34

@@ -15,7 +16,16 @@ public async Task<Agent> LoadAgent(string id, bool loadUtility = true)
1516
return null;
1617
}
1718

18-
HookEmitter.Emit<IAgentHook>(_services, hook => hook.OnAgentLoading(ref id), id);
19+
var hooks = _services.GetHooks<IAgentHook>(id);
20+
foreach (var hook in hooks)
21+
{
22+
var newId = await hook.OnAgentLoading(id);
23+
if (!string.IsNullOrEmpty(newId) && newId != id)
24+
{
25+
id = newId;
26+
break; // Only the first hook that redirects takes effect
27+
}
28+
}
1929

2030
var agent = await GetAgent(id);
2131
if (agent == null)
@@ -35,35 +45,35 @@ public async Task<Agent> LoadAgent(string id, bool loadUtility = true)
3545
PopulateState(agent);
3646

3747
// After agent is loaded
38-
HookEmitter.Emit<IAgentHook>(_services, hook => {
48+
await HookEmitter.Emit<IAgentHook>(_services, async hook => {
3949
hook.SetAgent(agent);
4050

4151
if (!string.IsNullOrEmpty(agent.Instruction))
4252
{
43-
hook.OnInstructionLoaded(agent.Instruction, agent.TemplateDict);
53+
await hook.OnInstructionLoaded(agent.Instruction, agent.TemplateDict);
4454
}
4555

4656
if (agent.Functions != null)
4757
{
48-
hook.OnFunctionsLoaded(agent.Functions);
58+
await hook.OnFunctionsLoaded(agent.Functions);
4959
}
5060

5161
if (agent.Samples != null)
5262
{
53-
hook.OnSamplesLoaded(agent.Samples);
63+
await hook.OnSamplesLoaded(agent.Samples);
5464
}
5565

5666
if (loadUtility && !agent.Utilities.IsNullOrEmpty())
5767
{
58-
hook.OnAgentUtilityLoaded(agent);
68+
await hook.OnAgentUtilityLoaded(agent);
5969
}
6070

6171
if (!agent.McpTools.IsNullOrEmpty())
6272
{
63-
hook.OnAgentMcpToolLoaded(agent);
73+
await hook.OnAgentMcpToolLoaded(agent);
6474
}
6575

66-
hook.OnAgentLoaded(agent);
76+
await hook.OnAgentLoaded(agent);
6777

6878
}, id);
6979

src/Infrastructure/BotSharp.Core/MCP/Hooks/MCPToolAgentHook.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public McpToolAgentHook(IServiceProvider services, AgentSettings settings)
1414
{
1515
}
1616

17-
public override void OnAgentMcpToolLoaded(Agent agent)
17+
public override async Task OnAgentMcpToolLoaded(Agent agent)
1818
{
1919
if (agent.Type == AgentType.Routing)
2020
{
@@ -27,7 +27,7 @@ public override void OnAgentMcpToolLoaded(Agent agent)
2727

2828
agent.SecondaryFunctions ??= [];
2929

30-
var functions = GetMcpContent(agent).ConfigureAwait(false).GetAwaiter().GetResult();
30+
var functions = await GetMcpContent(agent);
3131
agent.SecondaryFunctions = agent.SecondaryFunctions.Concat(functions).DistinctBy(x => x.Name, StringComparer.OrdinalIgnoreCase).ToList();
3232
}
3333

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ public RoutingAgentHook(IServiceProvider services, AgentSettings settings, Routi
1313
_routingSetting = routingSetting;
1414
}
1515

16-
public override bool OnInstructionLoaded(string template, IDictionary<string, object> dict)
16+
public override async Task<bool> OnInstructionLoaded(string template, IDictionary<string, object> dict)
1717
{
1818
if (_agent.Type != AgentType.Routing)
1919
{
20-
return base.OnInstructionLoaded(template, dict);
20+
return await base.OnInstructionLoaded(template, dict);
2121
}
2222
dict["router"] = _agent;
2323

@@ -59,10 +59,10 @@ public override bool OnInstructionLoaded(string template, IDictionary<string, ob
5959

6060
dict["routing_agents"] = agents;
6161

62-
return base.OnInstructionLoaded(template, dict);
62+
return await base.OnInstructionLoaded(template, dict);
6363
}
6464

65-
public override bool OnFunctionsLoaded(List<FunctionDef> functions)
65+
public override async Task<bool> OnFunctionsLoaded(List<FunctionDef> functions)
6666
{
6767
if (_agent.Type == AgentType.Task)
6868
{
@@ -73,7 +73,7 @@ public override bool OnFunctionsLoaded(List<FunctionDef> functions)
7373
if (rule != null)
7474
{
7575
var agentService = _services.GetRequiredService<IAgentService>();
76-
var redirectAgent = agentService.GetAgent(rule.RedirectTo).ConfigureAwait(false).GetAwaiter().GetResult();
76+
var redirectAgent = await agentService.GetAgent(rule.RedirectTo);
7777

7878
var json = JsonSerializer.Serialize(new
7979
{
@@ -111,6 +111,6 @@ public override bool OnFunctionsLoaded(List<FunctionDef> functions)
111111
}
112112
}
113113

114-
return base.OnFunctionsLoaded(functions);
114+
return await base.OnFunctionsLoaded(functions);
115115
}
116116
}

src/Plugins/BotSharp.Plugin.Planner/SqlGeneration/Hooks/SqlPlannerAgentHook.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
using BotSharp.Abstraction.Agents;
2+
using BotSharp.Abstraction.Agents.Settings;
3+
using BotSharp.Abstraction.Knowledges;
4+
using BotSharp.Abstraction.MLTasks;
5+
using BotSharp.Plugin.Planner.Enums;
6+
17
namespace BotSharp.Plugin.Planner.SqlGeneration.Hooks;
28

39
public class SqlPlannerAgentHook : AgentHookBase
@@ -9,18 +15,18 @@ public SqlPlannerAgentHook(IServiceProvider services, AgentSettings settings)
915
{
1016
}
1117

12-
public override bool OnInstructionLoaded(string template, IDictionary<string, object> dict)
18+
public override async Task<bool> OnInstructionLoaded(string template, IDictionary<string, object> dict)
1319
{
1420
var knowledgeHooks = _services.GetServices<IKnowledgeHook>();
1521

1622
// Get global knowledges
1723
var knowledges = new List<string>();
1824
foreach (var hook in knowledgeHooks)
1925
{
20-
var k = hook.GetGlobalKnowledges(new RoleDialogModel(AgentRole.User, template)
26+
var k = await hook.GetGlobalKnowledges(new RoleDialogModel(AgentRole.User, template)
2127
{
2228
CurrentAgentId = PlannerAgentId.SqlPlanner
23-
}).ConfigureAwait(false).GetAwaiter().GetResult();
29+
});
2430
knowledges.AddRange(k);
2531
}
2632
dict["global_knowledges"] = knowledges;

tests/BotSharp.Plugin.PizzaBot/Hooks/CommonAgentHook.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ public CommonAgentHook(IServiceProvider services, AgentSettings settings)
1111
{
1212
}
1313

14-
public override bool OnInstructionLoaded(string template, IDictionary<string, object> dict)
14+
public override async Task<bool> OnInstructionLoaded(string template, IDictionary<string, object> dict)
1515
{
1616
dict["current_date"] = DateTime.Now.ToString("MM/dd/yyyy");
1717
dict["current_time"] = DateTime.Now.ToString("hh:mm tt");
1818
dict["current_weekday"] = DateTime.Now.DayOfWeek;
19-
return base.OnInstructionLoaded(template, dict);
19+
return await base.OnInstructionLoaded(template, dict);
2020
}
2121
}

tests/BotSharp.Plugin.PizzaBot/Hooks/PizzaBotAgentHook.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ public PizzaBotAgentHook(IServiceProvider services, AgentSettings settings)
1212
{
1313
}
1414

15-
public override bool OnInstructionLoaded(string template, IDictionary<string, object> dict)
15+
public override async Task<bool> OnInstructionLoaded(string template, IDictionary<string, object> dict)
1616
{
17-
return base.OnInstructionLoaded(template, dict);
17+
return await base.OnInstructionLoaded(template, dict);
1818
}
1919
}

0 commit comments

Comments
 (0)