Skip to content

Commit 283640f

Browse files
chore: Upgrade NuGet dependencies to latest compatible versions (#1120)
## Overview Updates all production NuGet dependencies to their latest stable and preview releases. This captures recent improvements, features, and security updates across the dependency tree while maintaining compatibility with .NET 10.0 and the existing codebase. ## Changes - **Directory.Packages.props**: Bumped 8 packages to latest compatible versions - **EssentialCSharp.Chat.Shared/Services/AIChatService.cs**: Migrated to OpenAI SDK 2.10.0 API surface ## Notable Dependency Updates - **Semantic Kernel**: 1.72.0 → 1.76.0 (multiple features and fixes) - **ModelContextProtocol**: 1.2.0 → 1.3.0 - **Microsoft.Extensions.Http.Resilience**: 10.5.0 → 10.6.0 - **NuGet.Packaging/Protocol**: 7.3.1 → 7.6.0 - Other: System.CommandLine, SourceLink, OpenTelemetry Profiler minor/patch versions ## Breaking Changes & Mitigation **OpenAI SDK 2.10.0** (pulled via Semantic Kernel 1.76.0) deprecates the old Responses API. Migrated `AIChatService` from: - `OpenAIResponseClient` → `ResponsesClient` - `ResponseCreationOptions` → `CreateResponseOptions` Updated method invocations to populate `InputItems` directly on options rather than as separate arguments. This maintains full feature parity while using the current SDK surface. ## Verification - Chat service tests pass (EssentialCSharp.Chat.Tests) - Solution builds successfully - No runtime or integration test failures observed
1 parent 65e0b60 commit 283640f

2 files changed

Lines changed: 38 additions & 39 deletions

File tree

Directory.Packages.props

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
escalated to an error by TreatWarningsAsErrors. -->
1010
<NuGetAudit Condition="'$(AccessToNugetFeed)' != 'true'">false</NuGetAudit>
1111
</PropertyGroup>
12-
<PropertyGroup>
13-
<SemanticKernelVersion>1.72.0</SemanticKernelVersion>
14-
</PropertyGroup>
1512
<ItemGroup Condition="$(AccessToNugetFeed)">
1613
<PackageVersion Include="ContentFeedNuget" Version="$(ToolingPackagesVersion)" />
1714
</ItemGroup>
@@ -23,7 +20,7 @@
2320
<PackageVersion Include="Azure.Identity" Version="1.21.0" />
2421
<PackageVersion Include="Azure.Monitor.OpenTelemetry.AspNetCore" Version="1.5.0" />
2522
<!-- TODO: update to stable release when Azure.Monitor.OpenTelemetry.Profiler reaches GA -->
26-
<PackageVersion Include="Azure.Monitor.OpenTelemetry.Profiler" Version="1.0.0-beta9" />
23+
<PackageVersion Include="Azure.Monitor.OpenTelemetry.Profiler" Version="1.0.1-beta.1" />
2724
<PackageVersion Include="TUnit" Version="1.40.5" />
2825
<PackageVersion Include="EssentialCSharp.Shared.Models" Version="$(ToolingPackagesVersion)" />
2926
<PackageVersion Include="HtmlAgilityPack" Version="1.12.4" />
@@ -39,22 +36,22 @@
3936
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.8" />
4037
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.8" />
4138
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.8" />
42-
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="10.5.0" />
43-
<PackageVersion Include="Microsoft.SemanticKernel" Version="$(SemanticKernelVersion)" />
44-
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.PgVector" Version="$(SemanticKernelVersion)-preview" />
45-
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.203" />
39+
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="10.6.0" />
40+
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.76.0" />
41+
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.PgVector" Version="1.74.0-preview" />
42+
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.300" />
4643
<!-- Pin to patched versions; NuGet.Protocol 6.12.5+ fixes GHSA-g4vj-cjjj-v7hg (pulled in by Microsoft.VisualStudio.Web.CodeGeneration.Design) -->
47-
<PackageVersion Include="NuGet.Packaging" Version="7.3.1" />
48-
<PackageVersion Include="NuGet.Protocol" Version="7.3.1" />
44+
<PackageVersion Include="NuGet.Packaging" Version="7.6.0" />
45+
<PackageVersion Include="NuGet.Protocol" Version="7.6.0" />
4946
<PackageVersion Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
5047
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="10.0.2" />
51-
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="10.0.1-preview.1.25571.5" />
52-
<PackageVersion Include="ModelContextProtocol" Version="1.2.0" />
53-
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="1.2.0" />
48+
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="10.5.0" />
49+
<PackageVersion Include="ModelContextProtocol" Version="1.3.0" />
50+
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="1.3.0" />
5451
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.8" />
5552
<PackageVersion Include="Moq" Version="4.20.72" />
5653
<PackageVersion Include="Moq.AutoMock" Version="4.0.2" />
57-
<PackageVersion Include="System.CommandLine" Version="2.0.7" />
54+
<PackageVersion Include="System.CommandLine" Version="2.0.8" />
5855
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
5956
<PackageVersion Include="Octokit" Version="14.0.0" />
6057
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />

EssentialCSharp.Chat.Shared/Services/AIChatService.cs

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public partial class AIChatService
1717
private readonly AIOptions _Options;
1818
private readonly AzureOpenAIClient _AzureClient;
1919
#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.
20-
private readonly OpenAIResponseClient _ResponseClient;
20+
private readonly ResponsesClient _ResponseClient;
2121
#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.
2222
private readonly AISearchService _SearchService;
2323
private readonly ILogger<AIChatService> _Logger;
@@ -34,7 +34,7 @@ public AIChatService(IOptions<AIOptions> options, AISearchService searchService,
3434
_AzureClient = azureClient;
3535

3636
#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.
37-
_ResponseClient = _AzureClient.GetOpenAIResponseClient(_Options.ChatDeploymentName);
37+
_ResponseClient = _AzureClient.GetResponsesClient();
3838
#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.
3939
}
4040

@@ -47,8 +47,8 @@ public AIChatService(IOptions<AIOptions> options, AISearchService searchService,
4747
/// <param name="tools">Optional tools for the AI to use</param>
4848
/// <param name="reasoningEffortLevel">Optional reasoning effort level for reasoning models</param>
4949
/// <param name="enableContextualSearch">Enable vector search for contextual information</param>
50-
/// <param name="endUserId">Authenticated end-user identifier. Currently reserved for forwarding
51-
/// to Azure OpenAI for abuse monitoring once the SDK exposes <c>ResponseCreationOptions.User</c>.</param>
50+
/// <param name="endUserId">Forwarded to Azure OpenAI for abuse monitoring and Microsoft Defender
51+
/// prompt-shield correlation via <c>CreateResponseOptions.EndUserId</c>.</param>
5252
/// <param name="cancellationToken">Cancellation token</param>
5353
/// <returns>The AI response text and response ID for conversation continuity</returns>
5454
public async Task<(string response, string responseId)> GetChatCompletion(
@@ -78,8 +78,8 @@ public AIChatService(IOptions<AIOptions> options, AISearchService searchService,
7878
/// <param name="tools">Optional tools for the AI to use</param>
7979
/// <param name="reasoningEffortLevel">Optional reasoning effort level for reasoning models</param>
8080
/// <param name="enableContextualSearch">Enable vector search for contextual information</param>
81-
/// <param name="endUserId">Authenticated end-user identifier. Currently reserved for forwarding
82-
/// to Azure OpenAI for abuse monitoring once the SDK exposes <c>ResponseCreationOptions.User</c>.</param>
81+
/// <param name="endUserId">Forwarded to Azure OpenAI for abuse monitoring and Microsoft Defender
82+
/// prompt-shield correlation via <c>CreateResponseOptions.EndUserId</c>.</param>
8383
/// <param name="cancellationToken">Cancellation token</param>
8484
/// <returns>An async enumerable of response text chunks and final response ID</returns>
8585
public async IAsyncEnumerable<(string text, string? responseId)> GetChatCompletionStream(
@@ -100,12 +100,10 @@ public AIChatService(IOptions<AIOptions> options, AISearchService searchService,
100100

101101
// Create the streaming response using the Responses API
102102
#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.
103-
List<ResponseItem> responseItems = [ResponseItem.CreateUserMessageItem(enrichedPrompt)];
103+
responseOptions.InputItems.Clear();
104+
responseOptions.InputItems.Add(ResponseItem.CreateUserMessageItem(enrichedPrompt));
105+
var streamingUpdates = _ResponseClient.CreateResponseStreamingAsync(responseOptions, cancellationToken);
104106
#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.
105-
var streamingUpdates = _ResponseClient.CreateResponseStreamingAsync(
106-
responseItems,
107-
options: responseOptions,
108-
cancellationToken: cancellationToken);
109107

110108
await foreach (var result in ProcessStreamingUpdatesAsync(streamingUpdates, responseOptions, mcpClient, toolCallDepth: 0, endUserId: endUserId, cancellationToken: cancellationToken))
111109
{
@@ -181,7 +179,7 @@ private static string SanitizeForXmlContext(string? input) =>
181179
private async IAsyncEnumerable<(string text, string? responseId)> ProcessStreamingUpdatesAsync(
182180
#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.
183181
IAsyncEnumerable<StreamingResponseUpdate> streamingUpdates,
184-
ResponseCreationOptions responseOptions,
182+
CreateResponseOptions responseOptions,
185183
#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.
186184
McpClient? mcpClient,
187185
int toolCallDepth = 0,
@@ -247,7 +245,10 @@ private static string SanitizeForXmlContext(string? input) =>
247245
outputItems.Add(await ExecuteSingleToolCallAsync(functionCallItem, toolCallDepth, endUserId, mcpClient, cancellationToken));
248246
}
249247

250-
var continuationStream = _ResponseClient.CreateResponseStreamingAsync(outputItems, continuationOptions, cancellationToken);
248+
continuationOptions.InputItems.Clear();
249+
foreach (var outputItem in outputItems)
250+
continuationOptions.InputItems.Add(outputItem);
251+
var continuationStream = _ResponseClient.CreateResponseStreamingAsync(continuationOptions, cancellationToken);
251252
#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.
252253

253254
await foreach (var result in ProcessStreamingUpdatesAsync(continuationStream, continuationOptions, mcpClient, toolCallDepth + 1, endUserId, cancellationToken))
@@ -338,7 +339,7 @@ private async Task<ResponseItem> ExecuteSingleToolCallAsync(
338339
/// Creates response options with optional features
339340
/// </summary>
340341
#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.
341-
private async Task<ResponseCreationOptions> CreateResponseOptionsAsync(
342+
private async Task<CreateResponseOptions> CreateResponseOptionsAsync(
342343
string? systemPrompt = null,
343344
string? previousResponseId = null,
344345
IEnumerable<ResponseTool>? tools = null,
@@ -348,8 +349,9 @@ private async Task<ResponseCreationOptions> CreateResponseOptionsAsync(
348349
CancellationToken cancellationToken = default
349350
)
350351
{
351-
var options = new ResponseCreationOptions();
352+
var options = new CreateResponseOptions();
352353
#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.
354+
options.Model = _Options.ChatDeploymentName;
353355

354356
// Set the system prompt via Instructions — this is stateless across turns when using previous_response_id,
355357
// preventing accumulation of system messages in the conversation context.
@@ -423,7 +425,7 @@ private async Task<ResponseCreationOptions> CreateResponseOptionsAsync(
423425
private async Task<(string response, string responseId)> GetChatCompletionCore(
424426
string prompt,
425427
#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.
426-
ResponseCreationOptions responseOptions,
428+
CreateResponseOptions responseOptions,
427429
#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.
428430
McpClient? mcpClient = null,
429431
string? endUserId = null,
@@ -436,13 +438,13 @@ private async Task<ResponseCreationOptions> CreateResponseOptionsAsync(
436438
const int MaxToolCallIterations = 10;
437439
for (int iteration = 0; iteration < MaxToolCallIterations; iteration++)
438440
{
439-
ClientResult<OpenAIResponse> response;
441+
ClientResult<ResponseResult> response;
440442
try
441443
{
442-
response = await _ResponseClient.CreateResponseAsync(
443-
responseItems,
444-
options: responseOptions,
445-
cancellationToken: cancellationToken);
444+
responseOptions.InputItems.Clear();
445+
foreach (var responseItem in responseItems)
446+
responseOptions.InputItems.Add(responseItem);
447+
response = await _ResponseClient.CreateResponseAsync(responseOptions, cancellationToken);
446448
}
447449
catch (ClientResultException ex) when (IsContextLengthError(ex))
448450
{
@@ -532,16 +534,16 @@ private bool IsMcpToolAllowed(string toolName)
532534

533535
/// <summary>
534536
/// Returns a clone of <paramref name="source"/> with
535-
/// <see cref="ResponseCreationOptions.PreviousResponseId"/> replaced.
537+
/// <see cref="CreateResponseOptions.PreviousResponseId"/> replaced.
536538
/// All behavior-affecting properties are copied so that tool-call continuation legs
537539
/// produce identical generation behavior to the initial leg.
538540
/// </summary>
539541
#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.
540-
private static ResponseCreationOptions CloneOptionsWithPreviousResponseId(
541-
ResponseCreationOptions source,
542+
private static CreateResponseOptions CloneOptionsWithPreviousResponseId(
543+
CreateResponseOptions source,
542544
string? previousResponseId)
543545
{
544-
var clone = new ResponseCreationOptions
546+
var clone = new CreateResponseOptions
545547
{
546548
Instructions = source.Instructions,
547549
PreviousResponseId = previousResponseId,

0 commit comments

Comments
 (0)