You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
chat: fix system prompt accumulation across conversation turns (#1076)
## Problem
In both `GetChatCompletionStream` and `GetChatCompletionCore`, the
system prompt was added as a `ResponseItem.CreateSystemMessageItem(...)`
in the input items list on every call. When `previous_response_id` is
used on follow-up turns, OpenAI already holds the full conversation
server-side — including the system message from turn 1. Every subsequent
turn (and every tool-call leg) was adding it again, causing the system
prompt to accumulate in context.
## Fix
Move the system prompt to `ResponseCreationOptions.Instructions` in
`CreateResponseOptionsAsync`, and remove the system message item from
both call sites.
Per the Azure OpenAI Responses API docs:
> "When using along with `previous_response_id`, the instructions from a
previous response will not be carried over to the next response. This
makes it simple to swap out system (or developer) messages in new
responses."
`Instructions` is stateless across turns by design — applied fresh each
call, never accumulated.
## Changes
- **`CreateResponseOptionsAsync`**: Added `string? systemPrompt`
parameter; sets `options.Instructions` from it (falling back to
`_Options.SystemPrompt`). Changed from `static` to instance method to
access `_Options`.
- **`GetChatCompletionCore`**: Removed `systemPrompt` parameter; input
list is always `[ResponseItem.CreateUserMessageItem(prompt)]`.
- **`GetChatCompletionStream`**: Same simplification — no system message
item in input list.
- **`GetChatCompletion`**: Passes `systemPrompt` to
`CreateResponseOptionsAsync` instead of downstream to
`GetChatCompletionCore`.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: BenjaminMichaelis <22186029+BenjaminMichaelis@users.noreply.github.com>
// Create the streaming response using the Responses API
92
89
#pragma warning disable OPENAI001// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
93
-
List<ResponseItem>responseItems=systemContextis not null
#pragma warning restore OPENAI001// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
/// Creates response options with optional features
260
255
/// </summary>
261
256
#pragma warning disable OPENAI001// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
#pragma warning restore OPENAI001// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
272
268
269
+
// Set the system prompt via Instructions — this is stateless across turns when using previous_response_id,
270
+
// preventing accumulation of system messages in the conversation context.
#pragma warning disable OPENAI001// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
319
323
ResponseCreationOptionsresponseOptions,
320
324
#pragma warning restore OPENAI001// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
321
-
string?systemPrompt=null,
322
325
McpClient?mcpClient=null,
323
326
CancellationTokencancellationToken=default)
324
327
{
325
-
// Construct the user input with system context if provided
#pragma warning disable OPENAI001// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
329
-
List<ResponseItem>responseItems=systemContextis not null
#pragma warning restore OPENAI001// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
0 commit comments