From 6308bdea5fa712f12f56e09d0d51343a25835d8a Mon Sep 17 00:00:00 2001
From: Jicheng Lu <103353@smsassist.com>
Date: Mon, 4 Aug 2025 14:21:11 -0500
Subject: [PATCH] change to options
---
.../Conversations/ConversationHookBase.cs | 4 +--
.../Conversations/IConversationHook.cs | 4 +--
.../Routing/IRoutingService.cs | 4 +--
.../Routing/Models/InvokeOptions.cs | 31 +++++++++++++++++++
.../Hooks/RealtimeConversationHook.cs | 6 ++--
.../Services/RealtimeHub.cs | 2 +-
.../Evaluations/EvaluationConversationHook.cs | 5 +--
.../Routing/Reasoning/InstructExecutor.cs | 14 +++++----
.../Routing/RoutingService.InvokeAgent.cs | 17 +++++-----
.../Routing/RoutingService.InvokeFunction.cs | 8 +++--
.../BotSharp.Core/Routing/RoutingService.cs | 11 ++++---
.../Controllers/RealtimeController.cs | 2 +-
.../Hooks/ChatHubConversationHook.cs | 5 +--
.../Hooks/StreamingLogHook.cs | 5 +--
.../Hooks/TwilioConversationHook.cs | 3 +-
15 files changed, 81 insertions(+), 40 deletions(-)
create mode 100644 src/Infrastructure/BotSharp.Abstraction/Routing/Models/InvokeOptions.cs
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs
index 0a5244f8..855bd79e 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/ConversationHookBase.cs
@@ -49,10 +49,10 @@ public abstract class ConversationHookBase : IConversationHook
public virtual Task OnHumanInterventionNeeded(RoleDialogModel message)
=> Task.CompletedTask;
- public virtual Task OnFunctionExecuting(RoleDialogModel message, string from = InvokeSource.Manual)
+ public virtual Task OnFunctionExecuting(RoleDialogModel message, InvokeFunctionOptions? options = null)
=> Task.CompletedTask;
- public virtual Task OnFunctionExecuted(RoleDialogModel message, string from = InvokeSource.Manual)
+ public virtual Task OnFunctionExecuted(RoleDialogModel message, InvokeFunctionOptions? options = null)
=> Task.CompletedTask;
public virtual Task OnMessageReceived(RoleDialogModel message)
diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs
index d1b6f83c..5a1d8aa2 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/IConversationHook.cs
@@ -61,7 +61,7 @@ public interface IConversationHook : IHookBase
///
///
///
- Task OnFunctionExecuting(RoleDialogModel message, string from = InvokeSource.Manual);
+ Task OnFunctionExecuting(RoleDialogModel message, InvokeFunctionOptions? options = null);
///
/// Triggered when the function calling completed.
@@ -69,7 +69,7 @@ public interface IConversationHook : IHookBase
///
///
///
- Task OnFunctionExecuted(RoleDialogModel message, string from = InvokeSource.Manual);
+ Task OnFunctionExecuted(RoleDialogModel message, InvokeFunctionOptions? options = null);
Task OnResponseGenerated(RoleDialogModel message);
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs
index 56c98a82..d387fab1 100644
--- a/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/IRoutingService.cs
@@ -26,8 +26,8 @@ public interface IRoutingService
///
RoutingRule[] GetRulesByAgentId(string id);
- Task InvokeAgent(string agentId, List dialogs, string from = InvokeSource.Manual, bool useStream = false);
- Task InvokeFunction(string name, RoleDialogModel messages, string from = InvokeSource.Manual);
+ Task InvokeAgent(string agentId, List dialogs, InvokeAgentOptions? options = null);
+ Task InvokeFunction(string name, RoleDialogModel messages, InvokeFunctionOptions? options = null);
Task InstructLoop(Agent agent, RoleDialogModel message, List dialogs);
///
diff --git a/src/Infrastructure/BotSharp.Abstraction/Routing/Models/InvokeOptions.cs b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/InvokeOptions.cs
new file mode 100644
index 00000000..5e031787
--- /dev/null
+++ b/src/Infrastructure/BotSharp.Abstraction/Routing/Models/InvokeOptions.cs
@@ -0,0 +1,31 @@
+namespace BotSharp.Abstraction.Routing.Models;
+
+public abstract class InvokeOptions
+{
+ public string From { get; set; }
+}
+
+public class InvokeAgentOptions : InvokeOptions
+{
+ public bool UseStream { get; set; }
+
+ public static InvokeAgentOptions Default()
+ {
+ return new()
+ {
+ From = InvokeSource.Manual,
+ UseStream = false
+ };
+ }
+}
+
+public class InvokeFunctionOptions : InvokeOptions
+{
+ public static InvokeFunctionOptions Default()
+ {
+ return new()
+ {
+ From = InvokeSource.Manual
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs b/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs
index 095ff2b8..07b8646c 100644
--- a/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs
+++ b/src/Infrastructure/BotSharp.Core.Realtime/Hooks/RealtimeConversationHook.cs
@@ -11,7 +11,7 @@ public class RealtimeConversationHook : ConversationHookBase, IConversationHook
_services = services;
}
- public async Task OnFunctionExecuting(RoleDialogModel message, string from = InvokeSource.Manual)
+ public async Task OnFunctionExecuting(RoleDialogModel message, InvokeFunctionOptions? options = null)
{
var hub = _services.GetRequiredService();
if (hub.HubConn == null)
@@ -32,10 +32,10 @@ public class RealtimeConversationHook : ConversationHookBase, IConversationHook
}
}
- public async Task OnFunctionExecuted(RoleDialogModel message, string from = InvokeSource.Manual)
+ public async Task OnFunctionExecuted(RoleDialogModel message, InvokeFunctionOptions? options = null)
{
var hub = _services.GetRequiredService();
- if (from != InvokeSource.Llm || hub.HubConn == null)
+ if (options?.From != InvokeSource.Llm || hub.HubConn == null)
{
return;
}
diff --git a/src/Infrastructure/BotSharp.Core.Realtime/Services/RealtimeHub.cs b/src/Infrastructure/BotSharp.Core.Realtime/Services/RealtimeHub.cs
index fe544b4d..0ff601e1 100644
--- a/src/Infrastructure/BotSharp.Core.Realtime/Services/RealtimeHub.cs
+++ b/src/Infrastructure/BotSharp.Core.Realtime/Services/RealtimeHub.cs
@@ -99,7 +99,7 @@ public class RealtimeHub : IRealtimeHub
agent.Id);
}
- await routing.InvokeFunction(message.FunctionName, message, from: InvokeSource.Llm);
+ await routing.InvokeFunction(message.FunctionName, message, options: new() { From = InvokeSource.Llm });
}
else
{
diff --git a/src/Infrastructure/BotSharp.Core/Evaluations/EvaluationConversationHook.cs b/src/Infrastructure/BotSharp.Core/Evaluations/EvaluationConversationHook.cs
index b1b4541e..80757219 100644
--- a/src/Infrastructure/BotSharp.Core/Evaluations/EvaluationConversationHook.cs
+++ b/src/Infrastructure/BotSharp.Core/Evaluations/EvaluationConversationHook.cs
@@ -1,4 +1,5 @@
using BotSharp.Abstraction.Evaluations;
+using BotSharp.Abstraction.Routing.Models;
namespace BotSharp.Core.Evaluations;
@@ -22,13 +23,13 @@ public class EvaluationConversationHook : ConversationHookBase
return base.OnMessageReceived(message);
}
- public override Task OnFunctionExecuted(RoleDialogModel message, string from = InvokeSource.Manual)
+ public override Task OnFunctionExecuted(RoleDialogModel message, InvokeFunctionOptions? options = null)
{
if (Conversation != null && _convSettings.EnableExecutionLog)
{
_logger.Append(Conversation.Id, $"[{DateTime.Now}] {message.Role}: {message.FunctionName}({message.FunctionArgs}) => {message.Content}");
}
- return base.OnFunctionExecuted(message, from: from);
+ return base.OnFunctionExecuted(message, options);
}
public override Task OnResponseGenerated(RoleDialogModel message)
diff --git a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs
index e0ac69a2..9dd19c09 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/Reasoning/InstructExecutor.cs
@@ -1,5 +1,6 @@
using BotSharp.Abstraction.Infrastructures.Enums;
using BotSharp.Abstraction.Planning;
+using BotSharp.Abstraction.Routing.Models;
namespace BotSharp.Core.Routing.Reasoning;
@@ -33,7 +34,7 @@ public class InstructExecutor : IExecutor
if (message.FunctionName != null)
{
var msg = RoleDialogModel.From(message, role: AgentRole.Function);
- await routing.InvokeFunction(message.FunctionName, msg, from: InvokeSource.Llm);
+ await routing.InvokeFunction(message.FunctionName, msg, options: new() { From = InvokeSource.Routing });
}
var agentId = routing.Context.GetCurrentAgentId();
@@ -59,11 +60,12 @@ public class InstructExecutor : IExecutor
{
var state = _services.GetRequiredService();
var useStreamMsg = state.GetState("use_stream_message");
- var ret = await routing.InvokeAgent(
- agentId,
- dialogs,
- from: InvokeSource.Routing,
- useStream: bool.TryParse(useStreamMsg, out var useStream) && useStream);
+ var options = new InvokeAgentOptions()
+ {
+ From = InvokeSource.Routing,
+ UseStream = bool.TryParse(useStreamMsg, out var useStream) && useStream
+ };
+ var ret = await routing.InvokeAgent(agentId, dialogs, options);
}
var response = dialogs.Last();
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs
index 6d2813d9..6acb58b2 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs
@@ -1,3 +1,4 @@
+using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.Templating;
namespace BotSharp.Core.Routing;
@@ -7,9 +8,9 @@ public partial class RoutingService
public async Task InvokeAgent(
string agentId,
List dialogs,
- string from = InvokeSource.Manual,
- bool useStream = false)
+ InvokeAgentOptions? options = null)
{
+ options ??= InvokeAgentOptions.Default();
var agentService = _services.GetRequiredService();
var agent = await agentService.LoadAgent(agentId);
@@ -36,7 +37,7 @@ public partial class RoutingService
RoleDialogModel response;
var message = dialogs.Last();
- if (useStream)
+ if (options?.UseStream == true)
{
response = await chatCompletion.GetChatCompletionsStreamingAsync(agent, dialogs);
}
@@ -59,7 +60,7 @@ public partial class RoutingService
message.CurrentAgentId = agent.Id;
message.IsStreaming = response.IsStreaming;
- await InvokeFunction(message, dialogs, from: from, useStream: useStream);
+ await InvokeFunction(message, dialogs, options);
}
else
{
@@ -83,8 +84,7 @@ public partial class RoutingService
private async Task InvokeFunction(
RoleDialogModel message,
List dialogs,
- string from,
- bool useStream)
+ InvokeAgentOptions? options = null)
{
// execute function
// Save states
@@ -93,7 +93,8 @@ public partial class RoutingService
var routing = _services.GetRequiredService();
// Call functions
- await routing.InvokeFunction(message.FunctionName, message, from: from);
+ var funcOptions = options != null ? new InvokeFunctionOptions() { From = options.From } : null;
+ await routing.InvokeFunction(message.FunctionName, message, options: funcOptions);
// Pass execution result to LLM to get response
if (!message.StopCompletion)
@@ -120,7 +121,7 @@ public partial class RoutingService
// Send to Next LLM
var curAgentId = routing.Context.GetCurrentAgentId();
- await InvokeAgent(curAgentId, dialogs, from, useStream);
+ await InvokeAgent(curAgentId, dialogs, options);
}
}
else
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeFunction.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeFunction.cs
index 694ab2d3..dea0947d 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeFunction.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeFunction.cs
@@ -1,3 +1,4 @@
+using BotSharp.Abstraction.Routing.Models;
using BotSharp.Core.MessageHub;
using BotSharp.Core.Routing.Executor;
@@ -5,8 +6,9 @@ namespace BotSharp.Core.Routing;
public partial class RoutingService
{
- public async Task InvokeFunction(string name, RoleDialogModel message, string from = InvokeSource.Manual)
+ public async Task InvokeFunction(string name, RoleDialogModel message, InvokeFunctionOptions? options = null)
{
+ options ??= InvokeFunctionOptions.Default();
var currentAgentId = message.CurrentAgentId;
var agentService = _services.GetRequiredService();
var agent = await agentService.GetAgent(currentAgentId);
@@ -38,7 +40,7 @@ public partial class RoutingService
foreach (var hook in hooks)
{
hook.SetAgent(agent);
- await hook.OnFunctionExecuting(clonedMessage, from: from);
+ await hook.OnFunctionExecuting(clonedMessage, options);
}
bool result = false;
@@ -50,7 +52,7 @@ public partial class RoutingService
// After functions have been executed
foreach (var hook in hooks)
{
- await hook.OnFunctionExecuted(clonedMessage, from: from);
+ await hook.OnFunctionExecuted(clonedMessage, options);
}
// Set result to original message
diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
index c66ef4b2..4e43cbd5 100644
--- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
+++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.cs
@@ -53,11 +53,12 @@ public partial class RoutingService : IRoutingService
{
var state = _services.GetRequiredService();
var useStreamMsg = state.GetState("use_stream_message");
- var ret = await routing.InvokeAgent(
- agentId,
- dialogs,
- from: InvokeSource.Routing,
- useStream: bool.TryParse(useStreamMsg, out var useStream) && useStream);
+ var options = new InvokeAgentOptions()
+ {
+ From = InvokeSource.Routing,
+ UseStream = bool.TryParse(useStreamMsg, out var useStream) && useStream
+ };
+ var ret = await routing.InvokeAgent(agentId, dialogs, options);
}
var response = dialogs.Last();
diff --git a/src/Infrastructure/BotSharp.OpenAPI/Controllers/RealtimeController.cs b/src/Infrastructure/BotSharp.OpenAPI/Controllers/RealtimeController.cs
index 61ae77a7..ff3aca46 100644
--- a/src/Infrastructure/BotSharp.OpenAPI/Controllers/RealtimeController.cs
+++ b/src/Infrastructure/BotSharp.OpenAPI/Controllers/RealtimeController.cs
@@ -26,7 +26,7 @@ public class RealtimeController : ControllerBase
FunctionName = functionName,
FunctionArgs = JsonSerializer.Serialize(args)
};
- await routing.InvokeFunction(functionName, message, from: InvokeSource.Llm);
+ await routing.InvokeFunction(functionName, message, options: new() { From = InvokeSource.Llm });
return message.Content;
}
}
diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubConversationHook.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubConversationHook.cs
index bd590276..e07f94d4 100644
--- a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubConversationHook.cs
+++ b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/ChatHubConversationHook.cs
@@ -1,6 +1,7 @@
using BotSharp.Abstraction.Conversations.Dtos;
using BotSharp.Abstraction.Conversations.Enums;
using BotSharp.Abstraction.Routing.Enums;
+using BotSharp.Abstraction.Routing.Models;
using BotSharp.Abstraction.SideCar;
using BotSharp.Abstraction.Users.Dtos;
using Microsoft.AspNetCore.SignalR;
@@ -78,9 +79,9 @@ public class ChatHubConversationHook : ConversationHookBase
await base.OnMessageReceived(message);
}
- public override async Task OnFunctionExecuting(RoleDialogModel message, string from = InvokeSource.Manual)
+ public override async Task OnFunctionExecuting(RoleDialogModel message, InvokeFunctionOptions? options = null)
{
- await base.OnFunctionExecuting(message, from: from);
+ await base.OnFunctionExecuting(message, options);
}
public override async Task OnPostbackMessageReceived(RoleDialogModel message, PostbackMessageModel replyMsg)
diff --git a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs
index 73365115..86adaf2c 100644
--- a/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs
+++ b/src/Plugins/BotSharp.Plugin.ChatHub/Hooks/StreamingLogHook.cs
@@ -1,5 +1,6 @@
using BotSharp.Abstraction.Conversations.Enums;
using BotSharp.Abstraction.Routing.Enums;
+using BotSharp.Abstraction.Routing.Models;
using Microsoft.AspNetCore.SignalR;
using System.Runtime.CompilerServices;
using System.Text.Encodings.Web;
@@ -141,7 +142,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
if (!_convSettings.ShowVerboseLog) return;
}
- public override async Task OnFunctionExecuting(RoleDialogModel message, string from = InvokeSource.Manual)
+ public override async Task OnFunctionExecuting(RoleDialogModel message, InvokeFunctionOptions? options = null)
{
var conversationId = _state.GetConversationId();
if (string.IsNullOrEmpty(conversationId)) return;
@@ -165,7 +166,7 @@ public class StreamingLogHook : ConversationHookBase, IContentGeneratingHook, IR
await SendEvent(ChatEvent.OnConversationContentLogGenerated, conversationId, BuildContentLog(input));
}
- public override async Task OnFunctionExecuted(RoleDialogModel message, string from = InvokeSource.Manual)
+ public override async Task OnFunctionExecuted(RoleDialogModel message, InvokeFunctionOptions? options = null)
{
var conversationId = _state.GetConversationId();
if (string.IsNullOrEmpty(conversationId)) return;
diff --git a/src/Plugins/BotSharp.Plugin.Twilio/Hooks/TwilioConversationHook.cs b/src/Plugins/BotSharp.Plugin.Twilio/Hooks/TwilioConversationHook.cs
index 11bd8d36..bf856ee4 100644
--- a/src/Plugins/BotSharp.Plugin.Twilio/Hooks/TwilioConversationHook.cs
+++ b/src/Plugins/BotSharp.Plugin.Twilio/Hooks/TwilioConversationHook.cs
@@ -1,6 +1,7 @@
using BotSharp.Abstraction.Hooks;
using BotSharp.Abstraction.Routing;
using BotSharp.Abstraction.Routing.Enums;
+using BotSharp.Abstraction.Routing.Models;
using BotSharp.Plugin.Twilio.Interfaces;
using BotSharp.Plugin.Twilio.Models;
using Twilio.Rest.Api.V2010.Account;
@@ -23,7 +24,7 @@ public class TwilioConversationHook : ConversationHookBase, IConversationHook
_logger = logger;
}
- public override async Task OnFunctionExecuted(RoleDialogModel message, string from = InvokeSource.Manual)
+ public override async Task OnFunctionExecuted(RoleDialogModel message, InvokeFunctionOptions? options = null)
{
var hooks = _services.GetHooks(message.CurrentAgentId);