diff --git a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs index 11a91207..54cdfc51 100644 --- a/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.DeepSeekAI/Providers/Chat/ChatCompletionProvider.cs @@ -210,19 +210,23 @@ public class ChatCompletionProvider : IChatCompletion { var client = ProviderHelper.GetClient(Provider, _model, _services); var chatClient = client.GetChatClient(_model); - var (prompt, messages, options) = PrepareOptions(agent, conversations); var hub = _services.GetRequiredService>>(); var conv = _services.GetRequiredService(); var messageId = conversations.LastOrDefault()?.MessageId ?? string.Empty; + // Before chat completion hooks MUST run before the provider builds its message list: + // a hook that mutates `conversations` (mid-turn user injection, the request-size budget) + // would otherwise only take effect on the NEXT call, so the very request it is meant to + // shrink would still be sent oversized. var contentHooks = _services.GetHooks(agent.Id); - // Before chat completion hook foreach (var hook in contentHooks) { await hook.BeforeGenerating(agent, conversations); } + var (prompt, messages, options) = PrepareOptions(agent, conversations); + hub.Push(new() { EventName = ChatEvent.BeforeReceiveLlmStreamMessage, diff --git a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs index ab60d87d..111208e9 100644 --- a/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs +++ b/src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs @@ -203,19 +203,23 @@ public class ChatCompletionProvider : IChatCompletion { var client = ProviderHelper.GetClient(Provider, _model, _services); var chatClient = client.GetChatClient(_model); - var (prompt, messages, options) = PrepareOptions(agent, conversations); var hub = _services.GetRequiredService>>(); var conv = _services.GetRequiredService(); var messageId = conversations.LastOrDefault()?.MessageId ?? string.Empty; + // Before chat completion hooks MUST run before the provider builds its message list: a hook + // that mutates `conversations` (mid-turn user injection, the request-size budget) would + // otherwise only take effect on the NEXT call, so the very request it is meant to shrink + // would still be sent oversized. var contentHooks = _services.GetHooks(agent.Id); - // Before chat completion hook foreach (var hook in contentHooks) { await hook.BeforeGenerating(agent, conversations); } + var (prompt, messages, options) = PrepareOptions(agent, conversations); + hub.Push(new() { EventName = ChatEvent.BeforeReceiveLlmStreamMessage,