From fe82939733bf21f269c3049ca7f630571433385f Mon Sep 17 00:00:00 2001 From: Haiping Chen Date: Wed, 23 Apr 2025 23:10:07 -0500 Subject: [PATCH] response_to_user --- Directory.Packages.props | 4 +-- .../Hooks/RealtimeConversationHook.cs | 11 +++++++ .../Services/RealtimeHub.cs | 2 +- .../BotSharp.Core/BotSharp.Core.csproj | 3 ++ .../Routing/Functions/ResponseToUserFn.cs | 29 +++++++++++++++++++ .../functions/response_to_user.json | 15 ++++++++++ .../instructions/instruction.liquid | 2 ++ 7 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/Infrastructure/BotSharp.Core/Routing/Functions/ResponseToUserFn.cs create mode 100644 src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/response_to_user.json diff --git a/Directory.Packages.props b/Directory.Packages.props index b179a20d1..7cdfc1a62 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,8 +6,8 @@ - - + + diff --git a/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs b/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs index 763a3b54b..5e1fcfee1 100644 --- a/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs +++ b/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs @@ -17,6 +17,12 @@ public async Task OnFunctionExecuting(RoleDialogModel message) { return; } + + if (message.FunctionName == "response_to_user") + { + return; + } + // Save states if (message.FunctionArgs != null && message.FunctionArgs.Length > 3) { @@ -51,6 +57,11 @@ public async Task OnFunctionExecuted(RoleDialogModel message) await hub.Completer.UpdateSession(hub.HubConn); await hub.Completer.TriggerModelInference(); } + else if (message.FunctionName == "response_to_user") + { + await hub.Completer.InsertConversationItem(message); + await hub.Completer.TriggerModelInference(); + } else { // Update session for changed states diff --git a/src/Infrastructure/BotSharp.Core.Realtime/Services/RealtimeHub.cs b/src/Infrastructure/BotSharp.Core.Realtime/Services/RealtimeHub.cs index e9f09d162..38a1a7834 100644 --- a/src/Infrastructure/BotSharp.Core.Realtime/Services/RealtimeHub.cs +++ b/src/Infrastructure/BotSharp.Core.Realtime/Services/RealtimeHub.cs @@ -30,7 +30,7 @@ public async Task ConnectToModel(Func? responseToUser = null, Func var routing = _services.GetRequiredService(); var agentService = _services.GetRequiredService(); - var agent = await agentService.LoadAgent(_conn.CurrentAgentId); + var agent = await agentService.GetAgent(_conn.CurrentAgentId); var storage = _services.GetRequiredService(); var dialogs = convService.GetDialogHistory(); diff --git a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj index 0f02e4173..5c27be38c 100644 --- a/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj +++ b/src/Infrastructure/BotSharp.Core/BotSharp.Core.csproj @@ -123,6 +123,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/src/Infrastructure/BotSharp.Core/Routing/Functions/ResponseToUserFn.cs b/src/Infrastructure/BotSharp.Core/Routing/Functions/ResponseToUserFn.cs new file mode 100644 index 000000000..0ee3e5858 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/Routing/Functions/ResponseToUserFn.cs @@ -0,0 +1,29 @@ +using BotSharp.Abstraction.Functions; +using BotSharp.Abstraction.Routing.Models; + +namespace BotSharp.Core.Routing.Functions; + +/// +/// Response to user if router doesn't need to route to agent. +/// +public class ResponseToUserFn : IFunctionCallback +{ + public string Name => "response_to_user"; + private readonly IServiceProvider _services; + private readonly IRoutingContext _context; + + public ResponseToUserFn(IServiceProvider services, IRoutingContext context) + { + _services = services; + _context = context; + } + + public Task Execute(RoleDialogModel message) + { + var args = JsonSerializer.Deserialize(message.FunctionArgs); + message.Content = args.Response; + message.Handled = true; + message.StopCompletion = true; + return Task.FromResult(true); + } +} diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/response_to_user.json b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/response_to_user.json new file mode 100644 index 000000000..a26858101 --- /dev/null +++ b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/functions/response_to_user.json @@ -0,0 +1,15 @@ +{ + "name": "response_to_user", + "description": "Response to user without routing to any other agent", + "visibility_expression": "{% if states.routing_mode == 'lazy' %}visible{% endif %}", + "parameters": { + "type": "object", + "properties": { + "response": { + "type": "string", + "description": "Response content" + } + }, + "required": [ "response" ] + } +} \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid index 7ee8f56e2..99f7a2198 100644 --- a/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid +++ b/src/Infrastructure/BotSharp.Core/data/agents/01fcc3e5-9af7-49e6-ad7a-a760bd12dc4a/instructions/instruction.liquid @@ -7,6 +7,8 @@ Follow these steps to handle user request: 4. You must include all required args for the selected agent, but you must not make up any parameters when there is no exact value provided, those parameters must set value as null if not declared. {% if routing_mode != 'lazy' %} 5. Response must be in JSON format. +{% else %} +5. If user is greeting, you can call function response_to_user with a greeting message. {% endif %} {% if routing_requirements and routing_requirements != empty %}