using BotSharp.Abstraction.Utilities; namespace BotSharp.Core.Realtime.Hooks; public class RealtimeConversationHook : ConversationHookBase, IConversationHook { private readonly IServiceProvider _services; public RealtimeConversationHook(IServiceProvider services) { _services = services; } public async Task OnFunctionExecuting(RoleDialogModel message) { var hub = _services.GetRequiredService(); if (hub.HubConn == null) { return; } // Save states if (message.FunctionArgs != null && message.FunctionArgs.Length > 3) { var states = _services.GetRequiredService(); states.SaveStateByArgs(message.FunctionArgs?.JsonContent()); } } public async Task OnFunctionExecuted(RoleDialogModel message) { var hub = _services.GetRequiredService(); if (hub.HubConn == null) { return; } var routing = _services.GetRequiredService(); message.Role = AgentRole.Function; if (message.FunctionName == "route_to_agent") { hub.HubConn.CurrentAgentId = routing.Context.GetCurrentAgentId(); await hub.Completer.UpdateSession(hub.HubConn); await hub.Completer.TriggerModelInference(); } else if (message.FunctionName == "util-routing-fallback_to_router") { hub.HubConn.CurrentAgentId = routing.Context.GetCurrentAgentId(); await hub.Completer.UpdateSession(hub.HubConn); await hub.Completer.TriggerModelInference(); } else { // Update session for changed states var instruction = await hub.Completer.UpdateSession(hub.HubConn); await hub.Completer.InsertConversationItem(message); if (message.StopCompletion) { await hub.Completer.TriggerModelInference($"Say to user: \"{message.Content}\""); } else { await hub.Completer.TriggerModelInference($"{instruction}\r\n\r\nResponse user based on function result"); } } } }