Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -367,42 +367,8 @@ public async Task<RoleDialogModel> GetChatCompletionsStreamingAsync(Agent agent,
// Prepare instruction and functions
var renderData = agentService.CollectRenderData(agent);
var (instruction, functions) = agentService.PrepareInstructionAndFunctions(agent, renderData);
if (!string.IsNullOrWhiteSpace(instruction))
{
renderedInstructions.Add(instruction);
messages.Add(new SystemChatMessage(instruction));
}

// Render functions
if (options.WebSearchOptions == null)
{
foreach (var function in functions)
{
if (!agentService.RenderFunction(agent, function, renderData))
{
continue;
}

var property = agentService.RenderFunctionProperty(agent, function, renderData);

options.Tools.Add(ChatTool.CreateFunctionTool(
functionName: function.Name,
functionDescription: function.Description,
functionParameters: BinaryData.FromObjectAsJson(property)));
}
}

if (!string.IsNullOrEmpty(agent.Knowledges))
{
messages.Add(new SystemChatMessage(agent.Knowledges));
}

var samples = ProviderHelper.GetChatSamples(agent.Samples);
foreach (var sample in samples)
{
messages.Add(sample.Role == AgentRole.User ? new UserChatMessage(sample.Content) : new AssistantChatMessage(sample.Content));
}

// Build messages
var filteredMessages = conversations.Select(x => x).ToList();
var firstUserMsgIdx = filteredMessages.FindIndex(x => x.Role == AgentRole.User);
if (firstUserMsgIdx > 0)
Expand Down Expand Up @@ -453,6 +419,43 @@ public async Task<RoleDialogModel> GetChatCompletionsStreamingAsync(Agent agent,
}
}

// Build system messages
if (!string.IsNullOrWhiteSpace(instruction))
{
renderedInstructions.Add(instruction);
messages.Add(new SystemChatMessage(instruction));
}

if (!string.IsNullOrEmpty(agent.Knowledges))
{
messages.Add(new SystemChatMessage(agent.Knowledges));
}

var samples = ProviderHelper.GetChatSamples(agent.Samples);
foreach (var sample in samples)
{
messages.Add(sample.Role == AgentRole.User ? new UserChatMessage(sample.Content) : new AssistantChatMessage(sample.Content));
}

// Render functions
if (options.WebSearchOptions == null)
{
foreach (var function in functions)
{
if (!agentService.RenderFunction(agent, function, renderData))
{
continue;
}

var property = agentService.RenderFunctionProperty(agent, function, renderData);

options.Tools.Add(ChatTool.CreateFunctionTool(
functionName: function.Name,
functionDescription: function.Description,
functionParameters: BinaryData.FromObjectAsJson(property)));
}
}
Comment on lines +422 to +457

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Samples/system appended after chat 🐞 Bug ✓ Correctness

PrepareOptions now appends system instruction/knowledges and few-shot samples after all conversation
turns, so the final messages sent to OpenAI may no longer end with the latest user message (often
ending with a system or assistant-sample message instead). This can cause the model to continue a
sample exchange or otherwise respond off-context compared to the previous/expected ordering used
elsewhere in the codebase.
Agent Prompt
## Issue description
`PrepareOptions` in the OpenAI ChatCompletionProvider appends system/knowledge and sample (few-shot) messages after the conversation messages. This changes the sequence sent to `chatClient.CompleteChat(...)` and can cause the model to respond to trailing system/sample content instead of the latest user input.

## Issue Context
Other providers in this repo (e.g., AzureOpenAI) build messages in the order: system instruction -> knowledges -> samples -> conversation turns. The OpenAI provider should match this pattern unless there is a deliberate and validated behavioral reason.

## Fix Focus Areas
- src/Plugins/BotSharp.Plugin.OpenAI/Providers/Chat/ChatCompletionProvider.cs[371-458]
- src/Plugins/BotSharp.Plugin.AzureOpenAI/Providers/Chat/ChatCompletionProvider.cs[382-419] (reference behavior)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


var prompt = GetPrompt(messages, options);
return (prompt, messages, options);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,37 +575,8 @@ private async Task<RoleDialogModel> OnUserAudioTranscriptionCompleted(RealtimeHu
// Prepare instruction and functions
var renderData = agentService.CollectRenderData(agent);
var (instruction, functions) = agentService.PrepareInstructionAndFunctions(agent, renderData);
if (!string.IsNullOrWhiteSpace(instruction))
{
messages.Add(new SystemChatMessage(instruction));
}

foreach (var function in functions)
{
if (!agentService.RenderFunction(agent, function, renderData))
{
continue;
}

var property = agentService.RenderFunctionProperty(agent, function, renderData);

options.Tools.Add(ChatTool.CreateFunctionTool(
functionName: function.Name,
functionDescription: function.Description,
functionParameters: BinaryData.FromObjectAsJson(property)));
}

if (!string.IsNullOrEmpty(agent.Knowledges))
{
messages.Add(new SystemChatMessage(agent.Knowledges));
}

var samples = ProviderHelper.GetChatSamples(agent.Samples);
foreach (var sample in samples)
{
messages.Add(sample.Role == AgentRole.User ? new UserChatMessage(sample.Content) : new AssistantChatMessage(sample.Content));
}


// Build messages
var filteredMessages = conversations.Select(x => x).ToList();
var firstUserMsgIdx = filteredMessages.FindIndex(x => x.Role == AgentRole.User);
if (firstUserMsgIdx > 0)
Expand Down Expand Up @@ -634,6 +605,39 @@ private async Task<RoleDialogModel> OnUserAudioTranscriptionCompleted(RealtimeHu
}
}

// Build system messages
if (!string.IsNullOrWhiteSpace(instruction))
{
messages.Add(new SystemChatMessage(instruction));
}

if (!string.IsNullOrEmpty(agent.Knowledges))
{
messages.Add(new SystemChatMessage(agent.Knowledges));
}

var samples = ProviderHelper.GetChatSamples(agent.Samples);
foreach (var sample in samples)
{
messages.Add(sample.Role == AgentRole.User ? new UserChatMessage(sample.Content) : new AssistantChatMessage(sample.Content));
}

// Build functions
foreach (var function in functions)
{
if (!agentService.RenderFunction(agent, function, renderData))
{
continue;
}

var property = agentService.RenderFunctionProperty(agent, function, renderData);

options.Tools.Add(ChatTool.CreateFunctionTool(
functionName: function.Name,
functionDescription: function.Description,
functionParameters: BinaryData.FromObjectAsJson(property)));
}

var prompt = GetPrompt(messages, options);
return (prompt, messages, options);
}
Expand Down
Loading