From fa16c83674518b4f4ffa007efbe7b00ea90354f1 Mon Sep 17 00:00:00 2001 From: Jicheng Lu Date: Wed, 17 Dec 2025 22:53:18 -0600 Subject: [PATCH 1/6] add thought signature --- .../Conversations/Models/Conversation.cs | 4 ++ .../Conversations/Models/RoleDialogModel.cs | 6 +- .../Services/ConversationStorage.cs | 3 + .../Routing/RoutingService.InvokeAgent.cs | 2 + .../Models/Chat/ChatThoughtModel.cs | 9 +++ .../Providers/Chat/ChatCompletionProvider.cs | 57 +++++++++++++------ .../Realtime/RealTimeCompletionProvider.cs | 2 + src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs | 1 + .../Models/DialogMongoElement.cs | 3 + .../Providers/Chat/ChatCompletionProvider.cs | 11 ++-- 10 files changed, 74 insertions(+), 24 deletions(-) create mode 100644 src/Plugins/BotSharp.Plugin.GoogleAI/Models/Chat/ChatThoughtModel.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs index 675c0885a..126010212 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs @@ -114,6 +114,10 @@ public class DialogMetaData [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? ToolCallId { get; set; } + [JsonPropertyName("thought_signature")] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ThoughtSignature { get; set; } + [JsonPropertyName("sender_id")] public string? SenderId { get; set; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs index 90cc44889..d475c9a1c 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs @@ -71,6 +71,9 @@ public class RoleDialogModel : ITrackableMessage [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? FunctionArgs { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? ThoughtSignature { get; set; } + /// /// Set this flag is in OnFunctionExecuting, if true, it won't be executed by InvokeFunction. /// @@ -200,7 +203,8 @@ public static RoleDialogModel From(RoleDialogModel source, Instruction = source.Instruction, Data = source.Data, IsStreaming = source.IsStreaming, - Annotations = source.Annotations + Annotations = source.Annotations, + ThoughtSignature = source.ThoughtSignature }; } } \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs index a673ea64f..da1ec7eb8 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs @@ -76,6 +76,7 @@ public List GetDialogs(string conversationId) FunctionName = meta?.FunctionName, FunctionArgs = meta?.FunctionArgs, ToolCallId = meta?.ToolCallId, + ThoughtSignature = meta?.ThoughtSignature, RichContent = richContent, SecondaryContent = secondaryContent, SecondaryRichContent = secondaryRichContent, @@ -113,6 +114,7 @@ public List GetDialogs(string conversationId) FunctionName = dialog.FunctionName, FunctionArgs = dialog.FunctionArgs, ToolCallId = dialog.ToolCallId, + ThoughtSignature = dialog.ThoughtSignature, CreatedTime = dialog.CreatedAt }; @@ -139,6 +141,7 @@ public List GetDialogs(string conversationId) MessageLabel = dialog.MessageLabel, SenderId = dialog.SenderId, FunctionName = dialog.FunctionName, + ThoughtSignature = dialog.ThoughtSignature, CreatedTime = dialog.CreatedAt }; diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs index e0175a70d..ecdc2d948 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs @@ -56,6 +56,7 @@ public async Task InvokeAgent( message.ToolCallId = response.ToolCallId; message.FunctionName = response.FunctionName; message.FunctionArgs = response.FunctionArgs; + message.ThoughtSignature = response.ThoughtSignature; message.Indication = response.Indication; message.CurrentAgentId = agent.Id; message.IsStreaming = response.IsStreaming; @@ -74,6 +75,7 @@ public async Task InvokeAgent( message = RoleDialogModel.From(message, role: AgentRole.Assistant, content: response.Content); message.CurrentAgentId = agent.Id; + message.ThoughtSignature = response.ThoughtSignature; message.IsStreaming = response.IsStreaming; message.MessageLabel = response.MessageLabel; dialogs.Add(message); diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Models/Chat/ChatThoughtModel.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Models/Chat/ChatThoughtModel.cs new file mode 100644 index 000000000..e00b7d922 --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Models/Chat/ChatThoughtModel.cs @@ -0,0 +1,9 @@ +using GenerativeAI.Types; + +namespace BotSharp.Plugin.GoogleAI.Models.Chat; + +internal class ChatThoughtModel +{ + internal FunctionCall? ToolCall { get; set; } + internal string? ThoughtSignature { get; set; } +} diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs index 54089050d..64c062f08 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs @@ -1,4 +1,3 @@ -using Azure; using BotSharp.Abstraction.Files; using BotSharp.Abstraction.Files.Models; using BotSharp.Abstraction.Files.Utilities; @@ -6,7 +5,6 @@ using BotSharp.Abstraction.MessageHub.Models; using BotSharp.Core.Infrastructures.Streams; using BotSharp.Core.MessageHub; -using Fluid; using GenerativeAI; using GenerativeAI.Core; using GenerativeAI.Types; @@ -26,6 +24,7 @@ public class ChatCompletionProvider : IChatCompletion public string Model => _model; private GoogleAiSettings _settings; + public ChatCompletionProvider( IServiceProvider services, GoogleAiSettings googleSettings, @@ -58,13 +57,15 @@ public async Task GetChatCompletions(Agent agent, List GetChatCompletions(Agent agent, List GetChatCompletionsAsync(Agent agent, List GetChatCompletionsAsync(Agent agent, List GetChatCompletionsStreamingAsync(Agent agent, }); using var textStream = new RealtimeTextStream(); + ChatThoughtModel? thoughtModel = null; UsageMetadata? tokenUsage = null; var responseMessage = new RoleDialogModel(AgentRole.Assistant, string.Empty) @@ -212,36 +217,44 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, } var part = candidate?.Content?.Parts?.FirstOrDefault(); + thoughtModel = part?.FunctionCall != null + ? new() { ToolCall = part.FunctionCall, ThoughtSignature = part.ThoughtSignature } + : thoughtModel; + if (!string.IsNullOrEmpty(part?.Text)) { var text = part.Text; textStream.Collect(text); - var content = new RoleDialogModel(AgentRole.Assistant, text) - { - CurrentAgentId = agent.Id, - MessageId = messageId - }; hub.Push(new() { EventName = ChatEvent.OnReceiveLlmStreamMessage, RefId = conv.ConversationId, - Data = content + Data = new RoleDialogModel(AgentRole.Assistant, text) + { + CurrentAgentId = agent.Id, + MessageId = messageId + } }); } - if (candidate.FinishReason == FinishReason.STOP) + if (candidate!.FinishReason == FinishReason.STOP) { - if (part?.FunctionCall != null) + var thought = part?.FunctionCall != null + ? new() { ToolCall = part.FunctionCall, ThoughtSignature = part.ThoughtSignature } + : thoughtModel; + var functionCall = thought?.ToolCall; + + if (functionCall != null) { - var functionCall = part.FunctionCall; responseMessage = new RoleDialogModel(AgentRole.Function, string.Empty) { CurrentAgentId = agent.Id, MessageId = messageId, ToolCallId = functionCall.Id, FunctionName = functionCall.Name, - FunctionArgs = functionCall.Args?.ToString() ?? string.Empty + FunctionArgs = functionCall.Args?.ToJsonString(), + ThoughtSignature = thought?.ThoughtSignature }; #if DEBUG @@ -259,6 +272,7 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, { CurrentAgentId = agent.Id, MessageId = messageId, + ThoughtSignature = part?.ThoughtSignature, IsStreaming = true }; } @@ -272,6 +286,7 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, { CurrentAgentId = agent.Id, MessageId = messageId, + ThoughtSignature = part?.ThoughtSignature, IsStreaming = true }; @@ -381,6 +396,7 @@ public void SetModelName(string model) contents.Add(new Content([ new Part() { + ThoughtSignature = message.ThoughtSignature, FunctionCall = new FunctionCall { Id = message.ToolCallId, @@ -393,6 +409,7 @@ public void SetModelName(string model) contents.Add(new Content([ new Part() { + ThoughtSignature = message.ThoughtSignature, FunctionResponse = new FunctionResponse { Id = message.ToolCallId, @@ -410,7 +427,10 @@ public void SetModelName(string model) else if (message.Role == AgentRole.User) { var text = message.LlmContent; - var contentParts = new List { new() { Text = text } }; + var contentParts = new List + { + new() { Text = text, ThoughtSignature = message.ThoughtSignature } + }; if (allowMultiModal && !message.Files.IsNullOrEmpty()) { @@ -422,7 +442,10 @@ public void SetModelName(string model) else if (message.Role == AgentRole.Assistant) { var text = message.LlmContent; - var contentParts = new List { new() { Text = text } }; + var contentParts = new List + { + new() { Text = text, ThoughtSignature = message.ThoughtSignature } + }; if (allowMultiModal && !message.Files.IsNullOrEmpty()) { diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs index 51d2232fb..8db7c25ff 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs @@ -551,6 +551,7 @@ await hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, text) contents.Add(new Content([ new Part() { + ThoughtSignature = message.ThoughtSignature, FunctionCall = new FunctionCall { Id = message.ToolCallId, @@ -563,6 +564,7 @@ await hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, text) contents.Add(new Content([ new Part() { + ThoughtSignature = message.ThoughtSignature, FunctionResponse = new FunctionResponse { Id = message.ToolCallId, diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs index daff1e0b0..ea457dbbb 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs @@ -26,5 +26,6 @@ global using BotSharp.Abstraction.Functions.Models; global using BotSharp.Abstraction.Loggers; +global using BotSharp.Plugin.GoogleAI.Models.Chat; global using BotSharp.Plugin.GoogleAi.Settings; global using BotSharp.Plugin.GoogleAi.Providers.Chat; \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs index 7dd7ece77..d4e431188 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs @@ -50,6 +50,7 @@ public class DialogMetaDataMongoElement public string? FunctionName { get; set; } public string? FunctionArgs { get; set; } public string? ToolCallId { get; set; } + public string? ThoughtSignature { get; set; } public string? SenderId { get; set; } public DateTime CreateTime { get; set; } @@ -65,6 +66,7 @@ public static DialogMetaData ToDomainElement(DialogMetaDataMongoElement meta) FunctionName = meta.FunctionName, FunctionArgs = meta.FunctionArgs, ToolCallId = meta.ToolCallId, + ThoughtSignature = meta.ThoughtSignature, SenderId = meta.SenderId, CreatedTime = meta.CreateTime, }; @@ -82,6 +84,7 @@ public static DialogMetaDataMongoElement ToMongoElement(DialogMetaData meta) FunctionName = meta.FunctionName, FunctionArgs = meta.FunctionArgs, ToolCallId = meta.ToolCallId, + ThoughtSignature = meta.ThoughtSignature, SenderId = meta.SenderId, CreateTime = meta.CreatedTime, }; diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs index cffe6e6b0..195a1e803 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs @@ -260,16 +260,15 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, _logger.LogDebug($"Stream Content update: {text}"); #endif - var content = new RoleDialogModel(AgentRole.Assistant, text) - { - CurrentAgentId = agent.Id, - MessageId = messageId - }; hub.Push(new() { EventName = ChatEvent.OnReceiveLlmStreamMessage, RefId = conv.ConversationId, - Data = content + Data = new RoleDialogModel(AgentRole.Assistant, text) + { + CurrentAgentId = agent.Id, + MessageId = messageId + } }); } From 8e90ae28fd1949720d4b544e51e531f2fef6889c Mon Sep 17 00:00:00 2001 From: Jicheng Lu Date: Wed, 17 Dec 2025 23:21:53 -0600 Subject: [PATCH 2/6] change to function meta data --- .../Conversations/Models/Conversation.cs | 4 +- .../Conversations/Models/RoleDialogModel.cs | 16 +++--- .../Services/ConversationStorage.cs | 11 ++-- .../Routing/RoutingService.InvokeAgent.cs | 4 +- .../Constants/Constants.cs | 6 ++ .../Providers/Chat/ChatCompletionProvider.cs | 55 ++++++++++++++----- .../Realtime/RealTimeCompletionProvider.cs | 2 - src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs | 1 + .../Models/DialogMongoElement.cs | 16 +++--- 9 files changed, 74 insertions(+), 41 deletions(-) create mode 100644 src/Plugins/BotSharp.Plugin.GoogleAI/Constants/Constants.cs diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs index 126010212..367fec7f8 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs @@ -114,9 +114,9 @@ public class DialogMetaData [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? ToolCallId { get; set; } - [JsonPropertyName("thought_signature")] + [JsonPropertyName("function_data")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? ThoughtSignature { get; set; } + public Dictionary? FunctionMetaData { get; set; } [JsonPropertyName("sender_id")] public string? SenderId { get; set; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs index d475c9a1c..1915fb54b 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs @@ -62,9 +62,6 @@ public class RoleDialogModel : ITrackableMessage [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? FunctionName { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? ToolCallId { get; set; } - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? PostbackFunctionName { get; set; } @@ -72,7 +69,10 @@ public class RoleDialogModel : ITrackableMessage public string? FunctionArgs { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public string? ThoughtSignature { get; set; } + public string? ToolCallId { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public Dictionary? FunctionMetaData { get; set; } /// /// Set this flag is in OnFunctionExecuting, if true, it won't be executed by InvokeFunction. @@ -192,9 +192,10 @@ public static RoleDialogModel From(RoleDialogModel source, MessageId = source.MessageId, MessageType = source.MessageType, MessageLabel = source.MessageLabel, - FunctionArgs = source.FunctionArgs, - FunctionName = source.FunctionName, ToolCallId = source.ToolCallId, + FunctionName = source.FunctionName, + FunctionArgs = source.FunctionArgs, + FunctionMetaData = source.FunctionMetaData != null ? new(source.FunctionMetaData) : null, Indication = source.Indication, PostbackFunctionName = source.PostbackFunctionName, RichContent = source.RichContent, @@ -203,8 +204,7 @@ public static RoleDialogModel From(RoleDialogModel source, Instruction = source.Instruction, Data = source.Data, IsStreaming = source.IsStreaming, - Annotations = source.Annotations, - ThoughtSignature = source.ThoughtSignature + Annotations = source.Annotations }; } } \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs index da1ec7eb8..de500bd3f 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs @@ -73,10 +73,10 @@ public List GetDialogs(string conversationId) MessageLabel = meta?.MessageLabel, CreatedAt = meta?.CreatedTime ?? default, SenderId = senderId, + ToolCallId = meta?.ToolCallId, FunctionName = meta?.FunctionName, FunctionArgs = meta?.FunctionArgs, - ToolCallId = meta?.ToolCallId, - ThoughtSignature = meta?.ThoughtSignature, + FunctionMetaData = meta?.FunctionMetaData, RichContent = richContent, SecondaryContent = secondaryContent, SecondaryRichContent = secondaryRichContent, @@ -111,10 +111,9 @@ public List GetDialogs(string conversationId) MessageId = dialog.MessageId, MessageType = dialog.MessageType, MessageLabel = dialog.MessageLabel, - FunctionName = dialog.FunctionName, - FunctionArgs = dialog.FunctionArgs, ToolCallId = dialog.ToolCallId, - ThoughtSignature = dialog.ThoughtSignature, + FunctionName = dialog.FunctionName, + FunctionMetaData = dialog.FunctionMetaData, CreatedTime = dialog.CreatedAt }; @@ -141,7 +140,7 @@ public List GetDialogs(string conversationId) MessageLabel = dialog.MessageLabel, SenderId = dialog.SenderId, FunctionName = dialog.FunctionName, - ThoughtSignature = dialog.ThoughtSignature, + FunctionMetaData = dialog.FunctionMetaData, CreatedTime = dialog.CreatedAt }; diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs index ecdc2d948..900ca3dd6 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs @@ -56,7 +56,7 @@ public async Task InvokeAgent( message.ToolCallId = response.ToolCallId; message.FunctionName = response.FunctionName; message.FunctionArgs = response.FunctionArgs; - message.ThoughtSignature = response.ThoughtSignature; + message.FunctionMetaData = response.FunctionMetaData; message.Indication = response.Indication; message.CurrentAgentId = agent.Id; message.IsStreaming = response.IsStreaming; @@ -75,7 +75,7 @@ public async Task InvokeAgent( message = RoleDialogModel.From(message, role: AgentRole.Assistant, content: response.Content); message.CurrentAgentId = agent.Id; - message.ThoughtSignature = response.ThoughtSignature; + message.FunctionMetaData = response.FunctionMetaData; message.IsStreaming = response.IsStreaming; message.MessageLabel = response.MessageLabel; dialogs.Add(message); diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Constants/Constants.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Constants/Constants.cs new file mode 100644 index 000000000..e0aa12b6c --- /dev/null +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Constants/Constants.cs @@ -0,0 +1,6 @@ +namespace BotSharp.Plugin.GoogleAI.Constants; + +internal static class Constants +{ + internal const string ThoughtSignature = "thought_signature"; +} diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs index 64c062f08..319c39d7e 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs @@ -65,7 +65,10 @@ public async Task GetChatCompletions(Agent agent, List + { + [Constants.ThoughtSignature] = part?.ThoughtSignature + }, RenderedInstruction = string.Join("\r\n", renderedInstructions) }; } @@ -75,7 +78,10 @@ public async Task GetChatCompletions(Agent agent, List + { + [Constants.ThoughtSignature] = part?.ThoughtSignature + }, RenderedInstruction = string.Join("\r\n", renderedInstructions) }; } @@ -119,7 +125,10 @@ public async Task GetChatCompletionsAsync(Agent agent, List + { + [Constants.ThoughtSignature] = part?.ThoughtSignature + }, RenderedInstruction = string.Join("\r\n", renderedInstructions) }; @@ -148,7 +157,10 @@ public async Task GetChatCompletionsAsync(Agent agent, List + { + [Constants.ThoughtSignature] = part?.ThoughtSignature + }, RenderedInstruction = string.Join("\r\n", renderedInstructions) }; @@ -254,7 +266,10 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, ToolCallId = functionCall.Id, FunctionName = functionCall.Name, FunctionArgs = functionCall.Args?.ToJsonString(), - ThoughtSignature = thought?.ThoughtSignature + FunctionMetaData = new Dictionary + { + [Constants.ThoughtSignature] = thought?.ThoughtSignature + } }; #if DEBUG @@ -272,8 +287,11 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, { CurrentAgentId = agent.Id, MessageId = messageId, - ThoughtSignature = part?.ThoughtSignature, - IsStreaming = true + IsStreaming = true, + FunctionMetaData = new Dictionary + { + [Constants.ThoughtSignature] = part?.ThoughtSignature + } }; } @@ -286,8 +304,11 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, { CurrentAgentId = agent.Id, MessageId = messageId, - ThoughtSignature = part?.ThoughtSignature, - IsStreaming = true + IsStreaming = true, + FunctionMetaData = new Dictionary + { + [Constants.ThoughtSignature] = part?.ThoughtSignature + } }; tokenUsage = response?.UsageMetadata; @@ -396,7 +417,7 @@ public void SetModelName(string model) contents.Add(new Content([ new Part() { - ThoughtSignature = message.ThoughtSignature, + ThoughtSignature = message.FunctionMetaData?.GetValueOrDefault(Constants.ThoughtSignature, null), FunctionCall = new FunctionCall { Id = message.ToolCallId, @@ -409,7 +430,7 @@ public void SetModelName(string model) contents.Add(new Content([ new Part() { - ThoughtSignature = message.ThoughtSignature, + ThoughtSignature = message.FunctionMetaData?.GetValueOrDefault(Constants.ThoughtSignature, null), FunctionResponse = new FunctionResponse { Id = message.ToolCallId, @@ -429,7 +450,11 @@ public void SetModelName(string model) var text = message.LlmContent; var contentParts = new List { - new() { Text = text, ThoughtSignature = message.ThoughtSignature } + new() + { + Text = text, + ThoughtSignature = message.FunctionMetaData?.GetValueOrDefault(Constants.ThoughtSignature, null) + } }; if (allowMultiModal && !message.Files.IsNullOrEmpty()) @@ -444,7 +469,11 @@ public void SetModelName(string model) var text = message.LlmContent; var contentParts = new List { - new() { Text = text, ThoughtSignature = message.ThoughtSignature } + new() + { + Text = text, + ThoughtSignature = message.FunctionMetaData?.GetValueOrDefault(Constants.ThoughtSignature, null) + } }; if (allowMultiModal && !message.Files.IsNullOrEmpty()) diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs index 8db7c25ff..51d2232fb 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Realtime/RealTimeCompletionProvider.cs @@ -551,7 +551,6 @@ await hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, text) contents.Add(new Content([ new Part() { - ThoughtSignature = message.ThoughtSignature, FunctionCall = new FunctionCall { Id = message.ToolCallId, @@ -564,7 +563,6 @@ await hook.AfterGenerated(new RoleDialogModel(AgentRole.Assistant, text) contents.Add(new Content([ new Part() { - ThoughtSignature = message.ThoughtSignature, FunctionResponse = new FunctionResponse { Id = message.ToolCallId, diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs index ea457dbbb..c69582963 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Using.cs @@ -26,6 +26,7 @@ global using BotSharp.Abstraction.Functions.Models; global using BotSharp.Abstraction.Loggers; +global using BotSharp.Plugin.GoogleAI.Constants; global using BotSharp.Plugin.GoogleAI.Models.Chat; global using BotSharp.Plugin.GoogleAi.Settings; global using BotSharp.Plugin.GoogleAi.Providers.Chat; \ No newline at end of file diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs index d4e431188..3c68c8a2b 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs @@ -47,10 +47,10 @@ public class DialogMetaDataMongoElement public string MessageId { get; set; } = default!; public string MessageType { get; set; } = default!; public string? MessageLabel { get; set; } + public string? ToolCallId { get; set; } public string? FunctionName { get; set; } public string? FunctionArgs { get; set; } - public string? ToolCallId { get; set; } - public string? ThoughtSignature { get; set; } + public Dictionary? FunctionMetaData { get; set; } public string? SenderId { get; set; } public DateTime CreateTime { get; set; } @@ -63,12 +63,12 @@ public static DialogMetaData ToDomainElement(DialogMetaDataMongoElement meta) MessageId = meta.MessageId, MessageType = meta.MessageType, MessageLabel = meta.MessageLabel, + ToolCallId = meta.ToolCallId, FunctionName = meta.FunctionName, FunctionArgs = meta.FunctionArgs, - ToolCallId = meta.ToolCallId, - ThoughtSignature = meta.ThoughtSignature, + FunctionMetaData = meta.FunctionMetaData, SenderId = meta.SenderId, - CreatedTime = meta.CreateTime, + CreatedTime = meta.CreateTime }; } @@ -81,12 +81,12 @@ public static DialogMetaDataMongoElement ToMongoElement(DialogMetaData meta) MessageId = meta.MessageId, MessageType = meta.MessageType, MessageLabel = meta.MessageLabel, + ToolCallId = meta.ToolCallId, FunctionName = meta.FunctionName, FunctionArgs = meta.FunctionArgs, - ToolCallId = meta.ToolCallId, - ThoughtSignature = meta.ThoughtSignature, + FunctionMetaData = meta.FunctionMetaData, SenderId = meta.SenderId, - CreateTime = meta.CreatedTime, + CreateTime = meta.CreatedTime }; } } From 5938742cf0a134d8737741933b43c41e506ef090 Mon Sep 17 00:00:00 2001 From: Jicheng Lu Date: Wed, 17 Dec 2025 23:26:05 -0600 Subject: [PATCH 3/6] minor change --- .../BotSharp.Core/Conversations/Services/ConversationStorage.cs | 1 + .../BotSharp.Core/Routing/RoutingService.InvokeAgent.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs index de500bd3f..037ef4206 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs @@ -113,6 +113,7 @@ public List GetDialogs(string conversationId) MessageLabel = dialog.MessageLabel, ToolCallId = dialog.ToolCallId, FunctionName = dialog.FunctionName, + FunctionArgs = dialog.FunctionArgs, FunctionMetaData = dialog.FunctionMetaData, CreatedTime = dialog.CreatedAt }; diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs index 900ca3dd6..34b2b197b 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs @@ -56,7 +56,7 @@ public async Task InvokeAgent( message.ToolCallId = response.ToolCallId; message.FunctionName = response.FunctionName; message.FunctionArgs = response.FunctionArgs; - message.FunctionMetaData = response.FunctionMetaData; + message.FunctionMetaData = response.FunctionMetaData != null ? new(response.FunctionMetaData) : null; message.Indication = response.Indication; message.CurrentAgentId = agent.Id; message.IsStreaming = response.IsStreaming; From 68ea4f2ed087baaf48c7153f822422b0d516f179 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Thu, 18 Dec 2025 10:09:38 -0600 Subject: [PATCH 4/6] avoid null --- .../BotSharp.Core/Plugins/PluginLoader.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs b/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs index 96c703121..583f8b69a 100644 --- a/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs +++ b/src/Infrastructure/BotSharp.Core/Plugins/PluginLoader.cs @@ -160,6 +160,11 @@ public PluginDef UpdatePluginStatus(IServiceProvider services, string id, bool e foreach (var agentId in dependentAgentIds) { var agent = agentService.LoadAgent(agentId).ConfigureAwait(false).GetAwaiter().GetResult(); + if (agent == null) + { + continue; + } + agent.Disabled = false; agentService.UpdateAgent(agent, AgentField.Disabled); @@ -184,11 +189,13 @@ public PluginDef UpdatePluginStatus(IServiceProvider services, string id, bool e foreach (var agentId in plugin.AgentIds) { var agent = agentService.LoadAgent(agentId).ConfigureAwait(false).GetAwaiter().GetResult(); - if (agent != null) + if (agent == null) { - agent.Disabled = true; - agentService.UpdateAgent(agent, AgentField.Disabled); + continue; } + + agent.Disabled = true; + agentService.UpdateAgent(agent, AgentField.Disabled); } } return plugin; From 03732666bcd9acdc70b55ddce9ec17dcc3a23d69 Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Thu, 18 Dec 2025 10:17:37 -0600 Subject: [PATCH 5/6] rename --- .../Conversations/Models/Conversation.cs | 4 ++-- .../Conversations/Models/RoleDialogModel.cs | 6 ++--- .../Services/ConversationStorage.cs | 6 ++--- .../Routing/RoutingService.InvokeAgent.cs | 4 ++-- .../Providers/Chat/ChatCompletionProvider.cs | 22 +++++++++---------- .../Models/DialogMongoElement.cs | 6 ++--- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs index 367fec7f8..c4235a965 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/Conversation.cs @@ -114,9 +114,9 @@ public class DialogMetaData [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? ToolCallId { get; set; } - [JsonPropertyName("function_data")] + [JsonPropertyName("meta_data")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public Dictionary? FunctionMetaData { get; set; } + public Dictionary? MetaData { get; set; } [JsonPropertyName("sender_id")] public string? SenderId { get; set; } diff --git a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs index 1915fb54b..796ee93d7 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Conversations/Models/RoleDialogModel.cs @@ -72,7 +72,7 @@ public class RoleDialogModel : ITrackableMessage public string? ToolCallId { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public Dictionary? FunctionMetaData { get; set; } + public Dictionary? MetaData { get; set; } /// /// Set this flag is in OnFunctionExecuting, if true, it won't be executed by InvokeFunction. @@ -195,7 +195,6 @@ public static RoleDialogModel From(RoleDialogModel source, ToolCallId = source.ToolCallId, FunctionName = source.FunctionName, FunctionArgs = source.FunctionArgs, - FunctionMetaData = source.FunctionMetaData != null ? new(source.FunctionMetaData) : null, Indication = source.Indication, PostbackFunctionName = source.PostbackFunctionName, RichContent = source.RichContent, @@ -204,7 +203,8 @@ public static RoleDialogModel From(RoleDialogModel source, Instruction = source.Instruction, Data = source.Data, IsStreaming = source.IsStreaming, - Annotations = source.Annotations + Annotations = source.Annotations, + MetaData = source.MetaData != null ? new(source.MetaData) : null }; } } \ No newline at end of file diff --git a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs index 037ef4206..3a8b3cdca 100644 --- a/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs +++ b/src/Infrastructure/BotSharp.Core/Conversations/Services/ConversationStorage.cs @@ -76,7 +76,7 @@ public List GetDialogs(string conversationId) ToolCallId = meta?.ToolCallId, FunctionName = meta?.FunctionName, FunctionArgs = meta?.FunctionArgs, - FunctionMetaData = meta?.FunctionMetaData, + MetaData = meta?.MetaData, RichContent = richContent, SecondaryContent = secondaryContent, SecondaryRichContent = secondaryRichContent, @@ -114,7 +114,7 @@ public List GetDialogs(string conversationId) ToolCallId = dialog.ToolCallId, FunctionName = dialog.FunctionName, FunctionArgs = dialog.FunctionArgs, - FunctionMetaData = dialog.FunctionMetaData, + MetaData = dialog.MetaData, CreatedTime = dialog.CreatedAt }; @@ -141,7 +141,7 @@ public List GetDialogs(string conversationId) MessageLabel = dialog.MessageLabel, SenderId = dialog.SenderId, FunctionName = dialog.FunctionName, - FunctionMetaData = dialog.FunctionMetaData, + MetaData = dialog.MetaData, CreatedTime = dialog.CreatedAt }; diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs index 34b2b197b..29266ea17 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs @@ -56,7 +56,7 @@ public async Task InvokeAgent( message.ToolCallId = response.ToolCallId; message.FunctionName = response.FunctionName; message.FunctionArgs = response.FunctionArgs; - message.FunctionMetaData = response.FunctionMetaData != null ? new(response.FunctionMetaData) : null; + message.MetaData = response.MetaData != null ? new(response.MetaData) : null; message.Indication = response.Indication; message.CurrentAgentId = agent.Id; message.IsStreaming = response.IsStreaming; @@ -75,7 +75,7 @@ public async Task InvokeAgent( message = RoleDialogModel.From(message, role: AgentRole.Assistant, content: response.Content); message.CurrentAgentId = agent.Id; - message.FunctionMetaData = response.FunctionMetaData; + message.MetaData = response.MetaData; message.IsStreaming = response.IsStreaming; message.MessageLabel = response.MessageLabel; dialogs.Add(message); diff --git a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs index 319c39d7e..085f5e590 100644 --- a/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.GoogleAI/Providers/Chat/ChatCompletionProvider.cs @@ -65,7 +65,7 @@ public async Task GetChatCompletions(Agent agent, List + MetaData = new Dictionary { [Constants.ThoughtSignature] = part?.ThoughtSignature }, @@ -78,7 +78,7 @@ public async Task GetChatCompletions(Agent agent, List + MetaData = new Dictionary { [Constants.ThoughtSignature] = part?.ThoughtSignature }, @@ -125,7 +125,7 @@ public async Task GetChatCompletionsAsync(Agent agent, List + MetaData = new Dictionary { [Constants.ThoughtSignature] = part?.ThoughtSignature }, @@ -157,7 +157,7 @@ public async Task GetChatCompletionsAsync(Agent agent, List + MetaData = new Dictionary { [Constants.ThoughtSignature] = part?.ThoughtSignature }, @@ -266,7 +266,7 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, ToolCallId = functionCall.Id, FunctionName = functionCall.Name, FunctionArgs = functionCall.Args?.ToJsonString(), - FunctionMetaData = new Dictionary + MetaData = new Dictionary { [Constants.ThoughtSignature] = thought?.ThoughtSignature } @@ -288,7 +288,7 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, CurrentAgentId = agent.Id, MessageId = messageId, IsStreaming = true, - FunctionMetaData = new Dictionary + MetaData = new Dictionary { [Constants.ThoughtSignature] = part?.ThoughtSignature } @@ -305,7 +305,7 @@ public async Task GetChatCompletionsStreamingAsync(Agent agent, CurrentAgentId = agent.Id, MessageId = messageId, IsStreaming = true, - FunctionMetaData = new Dictionary + MetaData = new Dictionary { [Constants.ThoughtSignature] = part?.ThoughtSignature } @@ -417,7 +417,7 @@ public void SetModelName(string model) contents.Add(new Content([ new Part() { - ThoughtSignature = message.FunctionMetaData?.GetValueOrDefault(Constants.ThoughtSignature, null), + ThoughtSignature = message.MetaData?.GetValueOrDefault(Constants.ThoughtSignature, null), FunctionCall = new FunctionCall { Id = message.ToolCallId, @@ -430,7 +430,7 @@ public void SetModelName(string model) contents.Add(new Content([ new Part() { - ThoughtSignature = message.FunctionMetaData?.GetValueOrDefault(Constants.ThoughtSignature, null), + ThoughtSignature = message.MetaData?.GetValueOrDefault(Constants.ThoughtSignature, null), FunctionResponse = new FunctionResponse { Id = message.ToolCallId, @@ -453,7 +453,7 @@ public void SetModelName(string model) new() { Text = text, - ThoughtSignature = message.FunctionMetaData?.GetValueOrDefault(Constants.ThoughtSignature, null) + ThoughtSignature = message.MetaData?.GetValueOrDefault(Constants.ThoughtSignature, null) } }; @@ -472,7 +472,7 @@ public void SetModelName(string model) new() { Text = text, - ThoughtSignature = message.FunctionMetaData?.GetValueOrDefault(Constants.ThoughtSignature, null) + ThoughtSignature = message.MetaData?.GetValueOrDefault(Constants.ThoughtSignature, null) } }; diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs index 3c68c8a2b..ff70bdab8 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Models/DialogMongoElement.cs @@ -50,7 +50,7 @@ public class DialogMetaDataMongoElement public string? ToolCallId { get; set; } public string? FunctionName { get; set; } public string? FunctionArgs { get; set; } - public Dictionary? FunctionMetaData { get; set; } + public Dictionary? MetaData { get; set; } public string? SenderId { get; set; } public DateTime CreateTime { get; set; } @@ -66,7 +66,7 @@ public static DialogMetaData ToDomainElement(DialogMetaDataMongoElement meta) ToolCallId = meta.ToolCallId, FunctionName = meta.FunctionName, FunctionArgs = meta.FunctionArgs, - FunctionMetaData = meta.FunctionMetaData, + MetaData = meta.MetaData, SenderId = meta.SenderId, CreatedTime = meta.CreateTime }; @@ -84,7 +84,7 @@ public static DialogMetaDataMongoElement ToMongoElement(DialogMetaData meta) ToolCallId = meta.ToolCallId, FunctionName = meta.FunctionName, FunctionArgs = meta.FunctionArgs, - FunctionMetaData = meta.FunctionMetaData, + MetaData = meta.MetaData, SenderId = meta.SenderId, CreateTime = meta.CreatedTime }; From cd09ada3221b4a270353ebc51972eca73afe6ddf Mon Sep 17 00:00:00 2001 From: Jicheng Lu <103353@smsassist.com> Date: Thu, 18 Dec 2025 10:21:30 -0600 Subject: [PATCH 6/6] minor change --- .../BotSharp.Core/Routing/RoutingService.InvokeAgent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs index 29266ea17..fdaddc85e 100644 --- a/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs +++ b/src/Infrastructure/BotSharp.Core/Routing/RoutingService.InvokeAgent.cs @@ -75,7 +75,7 @@ public async Task InvokeAgent( message = RoleDialogModel.From(message, role: AgentRole.Assistant, content: response.Content); message.CurrentAgentId = agent.Id; - message.MetaData = response.MetaData; + message.MetaData = response.MetaData != null ? new(response.MetaData) : null; message.IsStreaming = response.IsStreaming; message.MessageLabel = response.MessageLabel; dialogs.Add(message);