diff --git a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj
index 285cb0b8..bbade11e 100644
--- a/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj
+++ b/src/Infrastructure/BotSharp.Abstraction/BotSharp.Abstraction.csproj
@@ -10,12 +10,6 @@
$(SolutionDir)packages
-
-
-
-
-
-
True
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs
index 569ac4e1..ea6a03d8 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs
@@ -69,10 +69,4 @@ public abstract class ConversationHookBase : IConversationHook
public virtual Task OnUserAgentConnectedInitially(Conversation conversation)
=> Task.CompletedTask;
-
- public virtual Task OnConversationRedirected(string toAgentId, RoleDialogModel message)
- => Task.CompletedTask;
-
- public virtual Task OnConversationRouting(FunctionCallFromLlm instruct, RoleDialogModel message)
- => Task.CompletedTask;
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs
index 68360bed..95afaab4 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs
@@ -84,20 +84,4 @@ public interface IConversationHook
///
///
Task OnHumanInterventionNeeded(RoleDialogModel message);
-
- ///
- /// Conversation is redirected to another agent
- ///
- ///
- ///
- ///
- Task OnConversationRedirected(string toAgentId, RoleDialogModel message);
-
- ///
- /// Routing instruction is received from Router
- ///
- /// routing instruction
- /// message
- ///
- Task OnConversationRouting(FunctionCallFromLlm instruct, RoleDialogModel message);
}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Infrastructures/HookEmittedResult.cs b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/HookEmittedResult.cs
new file mode 100644
index 00000000..5084b412
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Infrastructures/HookEmittedResult.cs
@@ -0,0 +1,5 @@
+namespace BotSharp.Abstraction.Infrastructures;
+
+public class HookEmittedResult
+{
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingContext.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingContext.cs
new file mode 100644
index 00000000..01da8e31
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingContext.cs
@@ -0,0 +1,13 @@
+namespace BotSharp.Abstraction.Routing;
+
+public interface IRoutingContext
+{
+ string GetCurrentAgentId();
+ string OriginAgentId { get; }
+ bool IsEmpty { get; }
+ string IntentName { get; set; }
+ void Push(string agentId);
+ void Pop();
+ void Replace(string agentId);
+ void Empty();
+}
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHook.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHook.cs
new file mode 100644
index 00000000..34a07162
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingHook.cs
@@ -0,0 +1,30 @@
+using BotSharp.Abstraction.Functions.Models;
+
+namespace BotSharp.Abstraction.Routing;
+
+public interface IRoutingHook
+{
+ ///
+ /// Conversation is redirected to another agent
+ ///
+ ///
+ ///
+ ///
+ Task OnConversationRedirected(string toAgentId, RoleDialogModel message);
+
+ ///
+ /// Routing instruction is received from Router
+ ///
+ /// routing instruction
+ /// message
+ ///
+ Task OnConversationRouting(FunctionCallFromLlm instruct, RoleDialogModel message);
+
+ Task OnAgentEnqueued(string agentId, string preAgentId);
+
+ Task OnAgentDequeued(string agentId, string currentAgentId);
+
+ Task OnAgentReplaced(string fromAgentId, string toAgentId);
+
+ Task OnAgentQueueEmptied(string agentId);
+}
diff --git a/src/Infrastructure/BotSharp.Core/Infrastructures/HookEmitter.cs b/src/Infrastructure/BotSharp.Core/Infrastructures/HookEmitter.cs
new file mode 100644
index 00000000..988863ac
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Core/Infrastructures/HookEmitter.cs
@@ -0,0 +1,27 @@
+using BotSharp.Abstraction.Infrastructures;
+
+namespace BotSharp.Core.Infrastructures;
+
+public static class HookEmitter
+{
+ public static async Task Emit(IServiceProvider services, Action action)
+ {
+ var logger = services.GetRequiredService>();
+ var result = new HookEmittedResult();
+ var hooks = services.GetServices();
+
+ foreach (var hook in hooks)
+ {
+ try
+ {
+ action(hook);
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex.ToString());
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Functions/FallbackToRouterFn.cs b/src/Infrastructure/BotSharp.Core/Routing/Functions/FallbackToRouterFn.cs
index d6fb3dcb..4d51113f 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Functions/FallbackToRouterFn.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Functions/FallbackToRouterFn.cs
@@ -29,7 +29,7 @@ public class FallbackToRouterFn : IFunctionCallback
return false;
}
- var routing = _services.GetRequiredService();
+ var routing = _services.GetRequiredService();
routing.Replace(targetAgent.Id);
var router = _services.GetRequiredService();
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs b/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs
index ee78fd1b..c8085cf3 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Functions/RouteToAgentFn.cs
@@ -14,9 +14,9 @@ public class RouteToAgentFn : IFunctionCallback
{
public string Name => "route_to_agent";
private readonly IServiceProvider _services;
- private readonly RoutingContext _context;
+ private readonly IRoutingContext _context;
- public RouteToAgentFn(IServiceProvider services, RoutingContext context)
+ public RouteToAgentFn(IServiceProvider services, IRoutingContext context)
{
_services = services;
_context = context;
@@ -153,11 +153,9 @@ public class RouteToAgentFn : IFunctionCallback
#else
logger.LogInformation($"*** Routing redirect to {record.Name.ToUpper()} ***");
#endif
- var hooks = _services.GetServices();
- foreach (var hook in hooks)
- {
- hook.OnConversationRedirected(routingRule.RedirectTo, message).Wait();
- }
+ HookEmitter.Emit(_services, async hook =>
+ await hook.OnConversationRedirected(routingRule.RedirectTo, message)
+ ).Wait();
}
else
{
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs
index 54f3e66c..24a048ae 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RetrieveDataFromAgentRoutingHandler.cs
@@ -39,7 +39,7 @@ public class RetrieveDataFromAgentRoutingHandler : RoutingHandlerBase, IRoutingH
public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
- var context = _services.GetRequiredService();
+ var context = _services.GetRequiredService();
var agentId = context.GetCurrentAgentId();
var dialogs = new List
{
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs
index 2404e896..4aae20db 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Handlers/RouteToAgentRoutingHandler.cs
@@ -39,7 +39,7 @@ public class RouteToAgentRoutingHandler : RoutingHandlerBase, IRoutingHandler
public async Task Handle(IRoutingService routing, FunctionCallFromLlm inst, RoleDialogModel message)
{
- var context = _services.GetRequiredService();
+ var context = _services.GetRequiredService();
var function = _services.GetServices().FirstOrDefault(x => x.Name == inst.Function);
message.FunctionArgs = JsonSerializer.Serialize(inst);
var ret = await function.Execute(message);
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Planning/HFPlanner.cs b/src/Infrastructure/BotSharp.Core/Routing/Planning/HFPlanner.cs
index ccb4f274..6f49c933 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Planning/HFPlanner.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Planning/HFPlanner.cs
@@ -2,7 +2,7 @@ using BotSharp.Abstraction.Agents.Models;
using BotSharp.Abstraction.Functions.Models;
using BotSharp.Abstraction.Repositories;
using BotSharp.Abstraction.Repositories.Filters;
-using BotSharp.Abstraction.Routing.Models;
+using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Planning;
using BotSharp.Abstraction.Templating;
@@ -75,7 +75,7 @@ public class HFPlanner : IPlaner
var filter = new AgentFilter { AgentName = inst.AgentName };
var agent = db.GetAgents(filter).FirstOrDefault();
- var context = _services.GetRequiredService();
+ var context = _services.GetRequiredService();
context.Push(agent.Id);
}
@@ -84,7 +84,7 @@ public class HFPlanner : IPlaner
public async Task AgentExecuted(Agent router, FunctionCallFromLlm inst, RoleDialogModel message, List dialogs)
{
- var context = _services.GetRequiredService();
+ var context = _services.GetRequiredService();
context.Empty();
return true;
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Planning/NaivePlanner.cs b/src/Infrastructure/BotSharp.Core/Routing/Planning/NaivePlanner.cs
index 91f35801..684c947c 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Planning/NaivePlanner.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Planning/NaivePlanner.cs
@@ -87,7 +87,7 @@ public class NaivePlanner : IPlaner
public async Task AgentExecuted(Agent router, FunctionCallFromLlm inst, RoleDialogModel message, List dialogs)
{
- var context = _services.GetRequiredService();
+ var context = _services.GetRequiredService();
if (inst.UnmatchedAgent)
{
var unmatchedAgentId = context.GetCurrentAgentId();
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Planning/SequentialPlanner.cs b/src/Infrastructure/BotSharp.Core/Routing/Planning/SequentialPlanner.cs
index 84246d40..24cc2aa7 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Planning/SequentialPlanner.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Planning/SequentialPlanner.cs
@@ -140,7 +140,7 @@ public class SequentialPlanner : IPlaner
public async Task AgentExecuted(Agent router, FunctionCallFromLlm inst, RoleDialogModel message, List dialogs)
{
- var context = _services.GetRequiredService();
+ var context = _services.GetRequiredService();
if (message.StopCompletion)
{
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Planning/TwoStagePlanner/TwoStagePlanner.cs b/src/Infrastructure/BotSharp.Core/Routing/Planning/TwoStagePlanner/TwoStagePlanner.cs
index 5688fce4..8dfa2f69 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Planning/TwoStagePlanner/TwoStagePlanner.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Planning/TwoStagePlanner/TwoStagePlanner.cs
@@ -155,7 +155,7 @@ public partial class TwoStagePlanner : IPlaner
public async Task AgentExecuted(Agent router, FunctionCallFromLlm inst, RoleDialogModel message, List dialogs)
{
- var context = _services.GetRequiredService();
+ var context = _services.GetRequiredService();
if (message.StopCompletion || _isTaskCompleted)
{
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingContext.cs
similarity index 63%
rename from src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs
rename to src/Infrastructure/BotSharp.Core/Routing/RoutingContext.cs
index d09658d8..6b39978e 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/RoutingContext.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingContext.cs
@@ -1,11 +1,9 @@
-using BotSharp.Abstraction.Agents;
using BotSharp.Abstraction.Repositories.Filters;
using BotSharp.Abstraction.Routing.Settings;
-using Microsoft.Extensions.DependencyInjection;
-namespace BotSharp.Abstraction.Routing.Models;
+namespace BotSharp.Core.Routing;
-public class RoutingContext
+public class RoutingContext : IRoutingContext
{
private readonly IServiceProvider _services;
private readonly RoutingSettings _setting;
@@ -56,7 +54,12 @@ public class RoutingContext
{
if (_stack.Count == 0 || _stack.Peek() != agentId)
{
+ var preAgentId = _stack.Count == 0 ? agentId : _stack.Peek();
_stack.Push(agentId);
+
+ HookEmitter.Emit(_services, async hook =>
+ await hook.OnAgentEnqueued(agentId, preAgentId)
+ ).Wait();
}
}
@@ -65,24 +68,50 @@ public class RoutingContext
///
public void Pop()
{
- _stack.Pop();
+ if (_stack.Count == 0)
+ {
+ return;
+ }
+
+ var agentId = _stack.Pop();
+
+ HookEmitter.Emit(_services, async hook =>
+ await hook.OnAgentDequeued(agentId, _stack.Peek())
+ ).Wait();
}
public void Replace(string agentId)
{
+ var fromAgent = agentId;
+ var toAgent = agentId;
+
if (_stack.Count == 0)
{
_stack.Push(agentId);
}
else if (_stack.Peek() != agentId)
{
+ fromAgent = _stack.Peek();
_stack.Pop();
_stack.Push(agentId);
+
+ HookEmitter.Emit(_services, async hook =>
+ await hook.OnAgentReplaced(fromAgent, toAgent)
+ ).Wait();
}
}
public void Empty()
{
+ if (_stack.Count == 0)
+ {
+ return;
+ }
+
+ var agentId = GetCurrentAgentId();
_stack.Clear();
+ HookEmitter.Emit(_services, async hook =>
+ await hook.OnAgentQueueEmptied(agentId)
+ ).Wait();
}
}
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingPlugin.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingPlugin.cs
index 410070d1..1ee1d732 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingPlugin.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingPlugin.cs
@@ -23,7 +23,7 @@ public class RoutingPlugin : IBotSharpPlugin
public void RegisterDI(IServiceCollection services, IConfiguration config)
{
- services.AddScoped();
+ services.AddScoped();
// Register router
services.AddScoped(provider =>
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs
index 9ea133fa..ede6ee42 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs
@@ -64,7 +64,7 @@ public partial class RoutingService
// Pass execution result to LLM to get response
if (!message.StopCompletion)
{
- var routing = _services.GetRequiredService();
+ var routing = _services.GetRequiredService();
// Find response template
var templateService = _services.GetRequiredService();
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
index d9c4e21b..8d93b420 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
@@ -80,7 +80,7 @@ public partial class RoutingService : IRoutingService
var conv = _services.GetRequiredService();
var dialogs = conv.GetDialogHistory();
- var context = _services.GetRequiredService();
+ var context = _services.GetRequiredService();
var executor = _services.GetRequiredService();
var planner = GetPlanner(_router);
@@ -98,11 +98,9 @@ public partial class RoutingService : IRoutingService
// Get instruction from Planner
var inst = await planner.GetNextInstruction(_router, message.MessageId, dialogs);
- var hooks = _services.GetServices();
- foreach (var hook in hooks)
- {
- await hook.OnConversationRouting(inst, message);
- }
+ await HookEmitter.Emit(_services, async hook =>
+ await hook.OnConversationRouting(inst, message)
+ );
// Save states
states.SaveStateByArgs(inst.Arguments);
diff --git a/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs b/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs
index 6bde9ce6..5119bc91 100644
--- a/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs
+++ b/src/Infrastructure/BotSharp.Core/Templating/ResponseTemplateService.cs
@@ -68,8 +68,8 @@ public class ResponseTemplateService : IResponseTemplateService
// .ToList();
var db = _services.GetRequiredService();
- var context = _services.GetRequiredService();
- var responses = db.GetAgentResponses(agentId, "intent", context.IntentName);
+ var routing = _services.GetRequiredService();
+ var responses = db.GetAgentResponses(agentId, "intent", routing.IntentName);
if (responses.Count == 0)
{
diff --git a/src/Infrastructure/BotSharp.Core/Using.cs b/src/Infrastructure/BotSharp.Core/Using.cs
index 4571da54..c55585e5 100644
--- a/src/Infrastructure/BotSharp.Core/Using.cs
+++ b/src/Infrastructure/BotSharp.Core/Using.cs
@@ -7,6 +7,7 @@ global using System.Text.Json;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.Logging;
global using EntityFrameworkCore.BootKit;
+global using BotSharp.Abstraction.Routing;
global using BotSharp.Abstraction.Plugins;
global using BotSharp.Abstraction.Agents;
global using BotSharp.Abstraction.Conversations;
@@ -18,6 +19,7 @@ global using BotSharp.Abstraction.Agents.Settings;
global using BotSharp.Abstraction.Conversations.Settings;
global using BotSharp.Abstraction.Agents.Enums;
global using BotSharp.Core.Repository;
+global using BotSharp.Core.Routing;
global using BotSharp.Core.Agents.Services;
global using BotSharp.Core.Conversations.Services;
global using BotSharp.Core.Infrastructures;
diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/ChatHubPlugin.cs b/src/Plugins/BotSharp.Plugin.ChatHub/ChatHubPlugin.cs
index bec0a01a..7825f0f1 100644
--- a/src/Plugins/BotSharp.Plugin.ChatHub/ChatHubPlugin.cs
+++ b/src/Plugins/BotSharp.Plugin.ChatHub/ChatHubPlugin.cs
@@ -1,4 +1,5 @@
using BotSharp.Abstraction.Loggers;
+using BotSharp.Abstraction.Routing;
using BotSharp.Plugin.ChatHub.Hooks;
using Microsoft.Extensions.Configuration;
@@ -20,5 +21,6 @@ public class ChatHubPlugin : IBotSharpPlugin
services.AddScoped();
services.AddScoped();
services.AddScoped();
+ services.AddScoped();
}
}
diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs
index 90fbcefa..5b7f65fc 100644
--- a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs
+++ b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs
@@ -4,11 +4,12 @@ using BotSharp.Abstraction.Loggers;
using BotSharp.Abstraction.Loggers.Enums;
using BotSharp.Abstraction.Loggers.Models;
using BotSharp.Abstraction.Repositories;
+using BotSharp.Abstraction.Routing;
using Microsoft.AspNetCore.SignalR;
namespace BotSharp.Plugin.ChatHub.Hooks;
-public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook
+public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IRoutingHook
{
private readonly ConversationSetting _convSettings;
private readonly JsonSerializerOptions _serializerOptions;
@@ -17,6 +18,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook
private readonly IConversationStateService _state;
private readonly IUserIdentity _user;
private readonly IAgentService _agentService;
+ private string _messageId;
public StreamingLogHook(
ConversationSetting convSettings,
@@ -43,32 +45,13 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook
public override async Task OnMessageReceived(RoleDialogModel message)
{
+ _messageId = message.MessageId;
var conversationId = _state.GetConversationId();
- var log = $"{message.Role}: {message.Content}";
+ var log = $"{message.Content}";
await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated",
BuildContentLog(conversationId, _user.UserName, log, ContentLogSource.UserInput, message));
}
- public override async Task OnConversationRouting(FunctionCallFromLlm instruct, RoleDialogModel message)
- {
- var conversationId = _state.GetConversationId();
- var agent = await _agentService.LoadAgent(message.CurrentAgentId);
- var log = JsonSerializer.Serialize(instruct, _serializerOptions);
- await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated",
- BuildContentLog(conversationId, agent?.Name, log, ContentLogSource.AgentResponse, message));
- }
-
- public override async Task OnConversationRedirected(string toAgentId, RoleDialogModel message)
- {
- var conversationId = _state.GetConversationId();
- var fromAgent = await _agentService.LoadAgent(message.CurrentAgentId);
- var toAgent = await _agentService.LoadAgent(toAgentId);
-
- var log = $"{message.Content}\r\n=====\r\nREDIRECTED TO {toAgent.Name}";
- await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated",
- BuildContentLog(conversationId, fromAgent.Name, log, ContentLogSource.HardRule, message));
- }
-
public async Task BeforeGenerating(Agent agent, List conversations)
{
if (!_convSettings.ShowVerboseLog) return;
@@ -147,6 +130,8 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook
CreateTime = DateTime.UtcNow
};
+ var json = JsonSerializer.Serialize(log, _serializerOptions);
+
var convSettings = _services.GetRequiredService();
if (convSettings.EnableContentLog)
{
@@ -154,7 +139,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook
db.SaveConversationContentLog(log);
}
- return JsonSerializer.Serialize(log, _serializerOptions);
+ return json;
}
private string BuildStateLog(string conversationId, Dictionary states, RoleDialogModel message)
@@ -176,4 +161,81 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook
return JsonSerializer.Serialize(log, _serializerOptions);
}
+
+ #region IRoutingHook
+ public async Task OnAgentEnqueued(string agentId, string preAgentId)
+ {
+ var conversationId = _state.GetConversationId();
+ var agent = await _agentService.LoadAgent(agentId);
+ var preAgent = await _agentService.LoadAgent(preAgentId);
+
+ var log = $"{agent.Name} is enqueued";
+ await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated",
+ BuildContentLog(conversationId, preAgent.Name, log, ContentLogSource.HardRule, new RoleDialogModel(AgentRole.System, log)
+ {
+ MessageId = _messageId
+ }));
+ }
+
+ public async Task OnAgentDequeued(string agentId, string currentAgentId)
+ {
+ var conversationId = _state.GetConversationId();
+ var agent = await _agentService.LoadAgent(agentId);
+ var currentAgent = await _agentService.LoadAgent(currentAgentId);
+
+ var log = $"{agent.Name} is dequeued";
+ await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated",
+ BuildContentLog(conversationId, currentAgent.Name, log, ContentLogSource.HardRule, new RoleDialogModel(AgentRole.System, log)
+ {
+ MessageId = _messageId
+ }));
+ }
+
+ public async Task OnAgentReplaced(string fromAgentId, string toAgentId)
+ {
+ var conversationId = _state.GetConversationId();
+ var fromAgent = await _agentService.LoadAgent(fromAgentId);
+ var toAgent = await _agentService.LoadAgent(toAgentId);
+
+ var log = $"{fromAgent.Name} is replaced to {toAgent.Name}";
+ await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated",
+ BuildContentLog(conversationId, toAgent.Name, log, ContentLogSource.HardRule, new RoleDialogModel(AgentRole.System, log)
+ {
+ MessageId = _messageId
+ }));
+ }
+
+ public async Task OnAgentQueueEmptied(string agentId)
+ {
+ var conversationId = _state.GetConversationId();
+ var agent = await _agentService.LoadAgent(agentId);
+
+ var log = $"Agent queue is cleared.";
+ await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated",
+ BuildContentLog(conversationId, agent.Name, log, ContentLogSource.HardRule, new RoleDialogModel(AgentRole.System, log)
+ {
+ MessageId = _messageId
+ }));
+ }
+
+ public async Task OnConversationRouting(FunctionCallFromLlm instruct, RoleDialogModel message)
+ {
+ var conversationId = _state.GetConversationId();
+ var agent = await _agentService.LoadAgent(message.CurrentAgentId);
+ var log = JsonSerializer.Serialize(instruct, _serializerOptions);
+ await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated",
+ BuildContentLog(conversationId, agent?.Name, log, ContentLogSource.AgentResponse, message));
+ }
+
+ public async Task OnConversationRedirected(string toAgentId, RoleDialogModel message)
+ {
+ var conversationId = _state.GetConversationId();
+ var fromAgent = await _agentService.LoadAgent(message.CurrentAgentId);
+ var toAgent = await _agentService.LoadAgent(toAgentId);
+
+ var log = $"{message.Content}\r\n=====\r\nREDIRECTED TO {toAgent.Name}";
+ await _chatHub.Clients.User(_user.Id).SendAsync("OnConversationContentLogGenerated",
+ BuildContentLog(conversationId, fromAgent.Name, log, ContentLogSource.HardRule, message));
+ }
+ #endregion
}
diff --git a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs
index 8c6d826e..b7fab29e 100644
--- a/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs
+++ b/src/Plugins/BotSharp.Plugin.RoutingSpeeder/RoutingConversationHook.cs
@@ -12,6 +12,7 @@ using BotSharp.Abstraction.Agents;
using System.IO;
using BotSharp.Abstraction.Routing.Settings;
using BotSharp.Abstraction.Routing.Models;
+using BotSharp.Abstraction.Routing;
namespace BotSharp.Plugin.RoutingSpeeder;
@@ -31,7 +32,7 @@ public class RoutingConversationHook: ConversationHookBase
// intentClassifier.Train();
// Utilize local discriminative model to predict intent
- var context = _services.GetRequiredService();
+ var context = _services.GetRequiredService();
context.IntentName = intentClassifier.Predict(vector);
if (string.IsNullOrEmpty(context.IntentName))
diff --git a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json
index 80f66ba9..4f19d591 100644
--- a/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json
+++ b/src/Plugins/BotSharp.Plugin.SqlDriver/data/agents/beda4c12-e1ec-4b4b-b328-3df4a6687c4f/agent.json
@@ -9,6 +9,8 @@
"isPublic": true,
"profiles": [ "tool", "sql" ],
"llmConfig": {
+ "model": "gpt-4-0125",
+ "model3": "gpt-35-turbo-1106",
"max_recursion_depth": 10
}
}
\ No newline at end of file