Skip to content
Merged
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
33 changes: 16 additions & 17 deletions EssentialCSharp.Chat.Shared/Services/AIChatService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public AIChatService(IOptions<AIOptions> options, AISearchService searchService,
bool enableContextualSearch = false,
CancellationToken cancellationToken = default)
{
var responseOptions = await CreateResponseOptionsAsync(previousResponseId, tools, reasoningEffortLevel, mcpClient: mcpClient, cancellationToken: cancellationToken);
var responseOptions = await CreateResponseOptionsAsync(systemPrompt, previousResponseId, tools, reasoningEffortLevel, mcpClient: mcpClient, cancellationToken: cancellationToken);
var enrichedPrompt = await EnrichPromptWithContext(prompt, enableContextualSearch, cancellationToken);
return await GetChatCompletionCore(enrichedPrompt, responseOptions, systemPrompt, mcpClient, cancellationToken);
return await GetChatCompletionCore(enrichedPrompt, responseOptions, mcpClient, cancellationToken);
}

/// <summary>
Expand All @@ -82,17 +82,12 @@ public AIChatService(IOptions<AIOptions> options, AISearchService searchService,
bool enableContextualSearch = false,
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var responseOptions = await CreateResponseOptionsAsync(previousResponseId, tools, reasoningEffortLevel, mcpClient: mcpClient, cancellationToken: cancellationToken);
var responseOptions = await CreateResponseOptionsAsync(systemPrompt, previousResponseId, tools, reasoningEffortLevel, mcpClient: mcpClient, cancellationToken: cancellationToken);
var enrichedPrompt = await EnrichPromptWithContext(prompt, enableContextualSearch, cancellationToken);

// Construct the user input with system context if provided
var systemContext = !string.IsNullOrWhiteSpace(systemPrompt) ? systemPrompt : _Options.SystemPrompt;

// Create the streaming response using the Responses API
#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.
List<ResponseItem> responseItems = systemContext is not null
? [ResponseItem.CreateSystemMessageItem(systemContext), ResponseItem.CreateUserMessageItem(enrichedPrompt)]
: [ResponseItem.CreateUserMessageItem(enrichedPrompt)];
List<ResponseItem> responseItems = [ResponseItem.CreateUserMessageItem(enrichedPrompt)];
#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.
var streamingUpdates = _ResponseClient.CreateResponseStreamingAsync(
responseItems,
Expand Down Expand Up @@ -259,7 +254,8 @@ private async Task<string> EnrichPromptWithContext(string prompt, bool enableCon
/// Creates response options with optional features
/// </summary>
#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.
private static async Task<ResponseCreationOptions> CreateResponseOptionsAsync(
private async Task<ResponseCreationOptions> CreateResponseOptionsAsync(
string? systemPrompt = null,
string? previousResponseId = null,
IEnumerable<ResponseTool>? tools = null,
ResponseReasoningEffortLevel? reasoningEffortLevel = null,
Expand All @@ -270,6 +266,14 @@ private static async Task<ResponseCreationOptions> CreateResponseOptionsAsync(
var options = new ResponseCreationOptions();
#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.

// Set the system prompt via Instructions — this is stateless across turns when using previous_response_id,
// preventing accumulation of system messages in the conversation context.
var resolvedSystemPrompt = !string.IsNullOrWhiteSpace(systemPrompt) ? systemPrompt : _Options.SystemPrompt;
if (!string.IsNullOrWhiteSpace(resolvedSystemPrompt))
{
options.Instructions = resolvedSystemPrompt;
}

// Add conversation context if available
if (!string.IsNullOrEmpty(previousResponseId))
{
Expand Down Expand Up @@ -318,17 +322,12 @@ private static async Task<ResponseCreationOptions> CreateResponseOptionsAsync(
#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.
ResponseCreationOptions responseOptions,
#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.
string? systemPrompt = null,
McpClient? mcpClient = null,
CancellationToken cancellationToken = default)
{
// Construct the user input with system context if provided
var systemContext = !string.IsNullOrWhiteSpace(systemPrompt) ? systemPrompt : _Options.SystemPrompt;

// Create the response using the Responses API
#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.
List<ResponseItem> responseItems = systemContext is not null
? [ResponseItem.CreateSystemMessageItem(systemContext), ResponseItem.CreateUserMessageItem(prompt)]
: [ResponseItem.CreateUserMessageItem(prompt)];
List<ResponseItem> responseItems = [ResponseItem.CreateUserMessageItem(prompt)];
#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.

const int MaxToolCallIterations = 10;
Expand Down
Loading