From 27156b2ef1d46bb066dc2d7881876547bc44266f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viviana=20Due=C3=B1as?= <50237907+ViveliDuCh@users.noreply.github.com> Date: Tue, 30 Sep 2025 14:32:09 -0700 Subject: [PATCH 1/3] Scope Ollama resilience settings to Web/Program.cs and restore ServiceDefaults (#6850) Move Ollama-specific HTTP client resiliency configuration out of Extensions.cs in ServiceDefaults to an extension method called later in Web/Program.cs. --- .../.template.config/template.json | 6 ++++ .../Extensions.cs | 13 ------- .../OllamaResilienceHandlerExtensions.cs | 34 +++++++++++++++++++ .../Program.Aspire.cs | 7 ++++ .../aichatweb.ServiceDefaults/Extensions.cs | 10 +----- .../OllamaResilienceHandlerExtensions.cs | 34 +++++++++++++++++++ .../aichatweb/aichatweb.Web/Program.cs | 5 +++ 7 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/OllamaResilienceHandlerExtensions.cs create mode 100644 test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/OllamaResilienceHandlerExtensions.cs diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/.template.config/template.json b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/.template.config/template.json index d95f7c41c13..3c5ca06f86d 100644 --- a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/.template.config/template.json +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/.template.config/template.json @@ -64,6 +64,12 @@ "*.sln" ] }, + { + "condition": "(!IsAspire || !IsOllama)", + "exclude": [ + "ChatWithCustomData-CSharp.Web/OllamaResilienceHandlerExtensions.cs" + ] + }, { "condition": "(IsAspire)", "exclude": [ diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.ServiceDefaults/Extensions.cs b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.ServiceDefaults/Extensions.cs index 108f1ed2a08..2fa2f11898e 100644 --- a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.ServiceDefaults/Extensions.cs +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.ServiceDefaults/Extensions.cs @@ -29,21 +29,8 @@ public static TBuilder AddServiceDefaults(this TBuilder builder) where http.RemoveAllResilienceHandlers(); #pragma warning restore EXTEXP0001 -#if (IsOllama) - // Turn on resilience by default - http.AddStandardResilienceHandler(config => - { - // Extend the HTTP Client timeout for Ollama - config.AttemptTimeout.Timeout = TimeSpan.FromMinutes(3); - - // Must be at least double the AttemptTimeout to pass options validation - config.CircuitBreaker.SamplingDuration = TimeSpan.FromMinutes(10); - config.TotalRequestTimeout.Timeout = TimeSpan.FromMinutes(10); - }); -#else // Turn on resilience by default http.AddStandardResilienceHandler(); -#endif // Turn on service discovery by default http.AddServiceDiscovery(); diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/OllamaResilienceHandlerExtensions.cs b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/OllamaResilienceHandlerExtensions.cs new file mode 100644 index 00000000000..fed9c91ca93 --- /dev/null +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/OllamaResilienceHandlerExtensions.cs @@ -0,0 +1,34 @@ +using System; +using Microsoft.Extensions.DependencyInjection; + +namespace ChatWithCustomData_CSharp.Web.Services; + +public static class OllamaResilienceHandlerExtensions +{ + public static IServiceCollection AddOllamaResilienceHandler(this IServiceCollection services) + { + services.ConfigureHttpClientDefaults(http => + { +#pragma warning disable EXTEXP0001 // RemoveAllResilienceHandlers is experimental + http.RemoveAllResilienceHandlers(); +#pragma warning restore EXTEXP0001 + + // Turn on resilience by default + http.AddStandardResilienceHandler(config => + { + // Extend the HTTP Client timeout for Ollama + config.AttemptTimeout.Timeout = TimeSpan.FromMinutes(3); + + // Must be at least double the AttemptTimeout to pass options validation + config.CircuitBreaker.SamplingDuration = TimeSpan.FromMinutes(10); + config.TotalRequestTimeout.Timeout = TimeSpan.FromMinutes(10); + }); + + // Turn on service discovery by default + http.AddServiceDiscovery(); + }); + + return services; + } +} + diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/Program.Aspire.cs b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/Program.Aspire.cs index 84475f45a54..243aa46c8d7 100644 --- a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/Program.Aspire.cs +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/Program.Aspire.cs @@ -50,6 +50,13 @@ #endif builder.Services.AddScoped(); builder.Services.AddSingleton(); +#if (IsOllama) +// Applies robust HTTP resilience settings for all HttpClients in the Web project, +// not across the entire solution. It's aimed at supporting Ollama scenarios due +// to its self-hosted nature and potentially slow responses. +// Remove this if you want to use the global or a different HTTP resilience policy instead. +builder.Services.AddOllamaResilienceHandler(); +#endif var app = builder.Build(); diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs index 81cc28b27d2..f56908872e0 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs @@ -30,15 +30,7 @@ public static TBuilder AddServiceDefaults(this TBuilder builder) where #pragma warning restore EXTEXP0001 // Turn on resilience by default - http.AddStandardResilienceHandler(config => - { - // Extend the HTTP Client timeout for Ollama - config.AttemptTimeout.Timeout = TimeSpan.FromMinutes(3); - - // Must be at least double the AttemptTimeout to pass options validation - config.CircuitBreaker.SamplingDuration = TimeSpan.FromMinutes(10); - config.TotalRequestTimeout.Timeout = TimeSpan.FromMinutes(10); - }); + http.AddStandardResilienceHandler(); // Turn on service discovery by default http.AddServiceDiscovery(); diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/OllamaResilienceHandlerExtensions.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/OllamaResilienceHandlerExtensions.cs new file mode 100644 index 00000000000..ae82393302c --- /dev/null +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/OllamaResilienceHandlerExtensions.cs @@ -0,0 +1,34 @@ +using System; +using Microsoft.Extensions.DependencyInjection; + +namespace aichatweb.Web.Services; + +public static class OllamaResilienceHandlerExtensions +{ + public static IServiceCollection AddOllamaResilienceHandler(this IServiceCollection services) + { + services.ConfigureHttpClientDefaults(http => + { +#pragma warning disable EXTEXP0001 // RemoveAllResilienceHandlers is experimental + http.RemoveAllResilienceHandlers(); +#pragma warning restore EXTEXP0001 + + // Turn on resilience by default + http.AddStandardResilienceHandler(config => + { + // Extend the HTTP Client timeout for Ollama + config.AttemptTimeout.Timeout = TimeSpan.FromMinutes(3); + + // Must be at least double the AttemptTimeout to pass options validation + config.CircuitBreaker.SamplingDuration = TimeSpan.FromMinutes(10); + config.TotalRequestTimeout.Timeout = TimeSpan.FromMinutes(10); + }); + + // Turn on service discovery by default + http.AddServiceDiscovery(); + }); + + return services; + } +} + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/Program.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/Program.cs index cdc88a082b7..c67c70db5d6 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/Program.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/Program.cs @@ -20,6 +20,11 @@ builder.Services.AddQdrantCollection("data-aichatweb-documents"); builder.Services.AddScoped(); builder.Services.AddSingleton(); +// Applies robust HTTP resilience settings for all HttpClients in the Web project, +// not across the entire solution. It's aimed at supporting Ollama scenarios due +// to its self-hosted nature and potentially slow responses. +// Remove this if you want to use the global or a different HTTP resilience policy instead. +builder.Services.AddOllamaResilienceHandler(); var app = builder.Build(); From 8d011fe8b62a6711d73031e54bf822439acb28fe Mon Sep 17 00:00:00 2001 From: Mackinnon Buck Date: Tue, 30 Sep 2025 16:58:01 -0400 Subject: [PATCH 2/3] Update `ModelContextProtocol` version (#6870) --- src/ProjectTemplates/GeneratedContent.targets | 2 +- .../mcpserver.AotTrue.verified/mcpserver/mcpserver.csproj | 2 +- .../mcpserver.Basic.verified/mcpserver/mcpserver.csproj | 2 +- .../mcpserver/mcpserver.csproj | 2 +- .../mcpserver.net10.verified/mcpserver/mcpserver.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ProjectTemplates/GeneratedContent.targets b/src/ProjectTemplates/GeneratedContent.targets index caa1ba24528..4ab34288ac1 100644 --- a/src/ProjectTemplates/GeneratedContent.targets +++ b/src/ProjectTemplates/GeneratedContent.targets @@ -56,7 +56,7 @@ 9.3.1 1.61.0 1.61.0-preview - 0.3.0-preview.2 + 0.4.0-preview.1 5.1.18 1.12.0 0.1.10 diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.AotTrue.verified/mcpserver/mcpserver.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.AotTrue.verified/mcpserver/mcpserver.csproj index 27a6ad45810..1b2dd939947 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.AotTrue.verified/mcpserver/mcpserver.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.AotTrue.verified/mcpserver/mcpserver.csproj @@ -38,7 +38,7 @@ - + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.Basic.verified/mcpserver/mcpserver.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.Basic.verified/mcpserver/mcpserver.csproj index a3199648740..f6da2d9485e 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.Basic.verified/mcpserver/mcpserver.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.Basic.verified/mcpserver/mcpserver.csproj @@ -34,7 +34,7 @@ - + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.SelfContainedFalse.verified/mcpserver/mcpserver.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.SelfContainedFalse.verified/mcpserver/mcpserver.csproj index cb3812885c6..a25caa73486 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.SelfContainedFalse.verified/mcpserver/mcpserver.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.SelfContainedFalse.verified/mcpserver/mcpserver.csproj @@ -27,7 +27,7 @@ - + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.net10.verified/mcpserver/mcpserver.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.net10.verified/mcpserver/mcpserver.csproj index 27c45f47efb..393d0558d5e 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.net10.verified/mcpserver/mcpserver.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/mcpserver.net10.verified/mcpserver/mcpserver.csproj @@ -34,7 +34,7 @@ - + From 1f12effefc9eb6b00547a51e76b37ed8d92f31f1 Mon Sep 17 00:00:00 2001 From: Varorbc Date: Wed, 1 Oct 2025 05:54:38 +0800 Subject: [PATCH 3/3] Update Aspire (#6858) * Update Aspire * Update Aspire template README --------- Co-authored-by: Mackinnon Buck --- src/ProjectTemplates/GeneratedContent.targets | 6 ++-- .../.template.config/template.json | 4 +-- .../{Program.cs => AppHost.cs} | 0 ...hatWithCustomData-CSharp.AppHost.csproj.in | 1 - .../Properties/launchSettings.json | 8 ++--- .../Extensions.cs | 16 ++++++--- .../Services/Ingestion/DataIngestor.cs | 6 ++-- .../src/ChatWithCustomData/README.Aspire.md | 36 ++----------------- .../aichatweb/README.md | 17 ++------- .../{Program.cs => AppHost.cs} | 0 .../Properties/launchSettings.json | 8 ++--- .../aichatweb.AppHost.csproj | 9 +++-- .../aichatweb.ServiceDefaults/Extensions.cs | 16 ++++++--- .../Services/Ingestion/DataIngestor.cs | 6 ++-- .../aichatweb.Web/aichatweb.Web.csproj | 6 ++-- .../Services/Ingestion/DataIngestor.cs | 6 ++-- .../aichatweb/README.md | 4 +-- .../{Program.cs => AppHost.cs} | 0 .../Properties/launchSettings.json | 8 ++--- .../aichatweb.AppHost.csproj | 5 ++- .../aichatweb.ServiceDefaults/Extensions.cs | 16 ++++++--- .../Services/Ingestion/DataIngestor.cs | 6 ++-- .../aichatweb.Web/aichatweb.Web.csproj | 4 +-- .../aichatweb/README.md | 4 +-- .../{Program.cs => AppHost.cs} | 0 .../Properties/launchSettings.json | 8 ++--- .../aichatweb.AppHost.csproj | 7 ++-- .../aichatweb.ServiceDefaults/Extensions.cs | 16 ++++++--- .../Services/Ingestion/DataIngestor.cs | 6 ++-- .../aichatweb.Web/aichatweb.Web.csproj | 2 +- .../Services/Ingestion/DataIngestor.cs | 6 ++-- 31 files changed, 112 insertions(+), 125 deletions(-) rename src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/{Program.cs => AppHost.cs} (100%) rename test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/{Program.cs => AppHost.cs} (100%) rename test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/{Program.cs => AppHost.cs} (100%) rename test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/{Program.cs => AppHost.cs} (100%) diff --git a/src/ProjectTemplates/GeneratedContent.targets b/src/ProjectTemplates/GeneratedContent.targets index 4ab34288ac1..ef1e11a3624 100644 --- a/src/ProjectTemplates/GeneratedContent.targets +++ b/src/ProjectTemplates/GeneratedContent.targets @@ -44,9 +44,9 @@ 9.9.1 9.9.1-preview.1.25474.6 - 9.4.0 - 9.4.0-preview.1.25378.8 - 2.3.0-beta.1 + 9.5.0 + 9.5.0-preview.1.25474.7 + 2.3.0-beta.2 1.0.0-beta.9 1.14.0 11.6.1 diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/.template.config/template.json b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/.template.config/template.json index 3c5ca06f86d..cffbaa7598f 100644 --- a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/.template.config/template.json +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/.template.config/template.json @@ -1,7 +1,7 @@ { "$schema": "http://json.schemastore.org/template", "author": "Microsoft", - "classifications": [ "Common", "AI", "Web", "Blazor", ".NET Aspire" ], + "classifications": [ "Common", "AI", "Web", "Blazor", "Aspire" ], "identity": "Microsoft.Extensions.AI.Templates.WebChat.CSharp", "name": "AI Chat Web App", "description": "A project template for creating an AI chat application, which uses retrieval-augmented generation (RAG) to chat with your own data.", @@ -183,7 +183,7 @@ "displayName": "Use Aspire orchestration", "datatype": "bool", "defaultValue": "false", - "description": "Create the project as a distributed application using .NET Aspire." + "description": "Create the project as a distributed application using Aspire." }, "IsAspire": { "type": "computed", diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/Program.cs b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/AppHost.cs similarity index 100% rename from src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/Program.cs rename to src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/AppHost.cs diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/ChatWithCustomData-CSharp.AppHost.csproj.in b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/ChatWithCustomData-CSharp.AppHost.csproj.in index 3bbd301af75..8f5b8baabc0 100644 --- a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/ChatWithCustomData-CSharp.AppHost.csproj.in +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/ChatWithCustomData-CSharp.AppHost.csproj.in @@ -7,7 +7,6 @@ net9.0 enable enable - true b2f4f5e9-1083-472c-8c3b-f055ac67ba54 diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/Properties/launchSettings.json b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/Properties/launchSettings.json index cff9159f816..ff3cb400c10 100644 --- a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/Properties/launchSettings.json +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.AppHost/Properties/launchSettings.json @@ -9,8 +9,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21000", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22000" + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21000", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22000" } }, "http": { @@ -21,8 +21,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19000", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20000" + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19000", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20000" } } } diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.ServiceDefaults/Extensions.cs b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.ServiceDefaults/Extensions.cs index 2fa2f11898e..204f7a64164 100644 --- a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.ServiceDefaults/Extensions.cs +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.ServiceDefaults/Extensions.cs @@ -10,11 +10,14 @@ namespace Microsoft.Extensions.Hosting; -// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. +// Adds common Aspire services: service discovery, resilience, health checks, and OpenTelemetry. // This project should be referenced by each service project in your solution. // To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults public static class Extensions { + private const string HealthEndpointPath = "/health"; + private const string AlivenessEndpointPath = "/alive"; + public static TBuilder AddServiceDefaults(this TBuilder builder) where TBuilder : IHostApplicationBuilder { builder.ConfigureOpenTelemetry(); @@ -64,7 +67,12 @@ public static TBuilder ConfigureOpenTelemetry(this TBuilder builder) w .WithTracing(tracing => { tracing.AddSource(builder.Environment.ApplicationName) - .AddAspNetCoreInstrumentation() + .AddAspNetCoreInstrumentation(tracing => + // Exclude health check requests from tracing + tracing.Filter = context => + !context.Request.Path.StartsWithSegments(HealthEndpointPath) + && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath) + ) // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) //.AddGrpcClientInstrumentation() .AddHttpClientInstrumentation() @@ -111,10 +119,10 @@ public static WebApplication MapDefaultEndpoints(this WebApplication app) if (app.Environment.IsDevelopment()) { // All health checks must pass for app to be considered ready to accept traffic after starting - app.MapHealthChecks("/health"); + app.MapHealthChecks(HealthEndpointPath); // Only health checks tagged with the "live" tag must pass for app to be considered alive - app.MapHealthChecks("/alive", new HealthCheckOptions + app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions { Predicate = r => r.Tags.Contains("live") }); diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/Services/Ingestion/DataIngestor.cs b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/Services/Ingestion/DataIngestor.cs index 7eeb41c99fb..175cc505670 100644 --- a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/Services/Ingestion/DataIngestor.cs +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/ChatWithCustomData-CSharp.Web/Services/Ingestion/DataIngestor.cs @@ -31,7 +31,7 @@ public async Task IngestDataAsync(IIngestionSource source) var deletedDocuments = await source.GetDeletedDocumentsAsync(documentsForSource); foreach (var deletedDocument in deletedDocuments) { - logger.LogInformation("Removing ingested data for {documentId}", deletedDocument.DocumentId); + logger.LogInformation("Removing ingested data for {DocumentId}", deletedDocument.DocumentId); await DeleteChunksForDocumentAsync(deletedDocument); await documentsCollection.DeleteAsync(deletedDocument.Key); } @@ -39,7 +39,7 @@ public async Task IngestDataAsync(IIngestionSource source) var modifiedDocuments = await source.GetNewOrModifiedDocumentsAsync(documentsForSource); foreach (var modifiedDocument in modifiedDocuments) { - logger.LogInformation("Processing {documentId}", modifiedDocument.DocumentId); + logger.LogInformation("Processing {DocumentId}", modifiedDocument.DocumentId); await DeleteChunksForDocumentAsync(modifiedDocument); await documentsCollection.UpsertAsync(modifiedDocument); @@ -54,7 +54,7 @@ async Task DeleteChunksForDocumentAsync(IngestedDocument document) { var documentId = document.DocumentId; var chunksToDelete = await chunksCollection.GetAsync(record => record.DocumentId == documentId, int.MaxValue).ToListAsync(); - if (chunksToDelete.Any()) + if (chunksToDelete.Count != 0) { await chunksCollection.DeleteAsync(chunksToDelete.Select(r => r.Key)); } diff --git a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/README.Aspire.md b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/README.Aspire.md index 0b1934bfff7..14aa513acae 100644 --- a/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/README.Aspire.md +++ b/src/ProjectTemplates/Microsoft.Extensions.AI.Templates/src/ChatWithCustomData/README.Aspire.md @@ -84,38 +84,8 @@ Note: Ollama and Docker are excellent open source products, but are not maintain #### ---#if (IsAzureOpenAI || UseAzureAISearch) ## Using Azure Provisioning -The project is set up to automatically provision Azure resources, but local configuration is configured. For detailed instructions, see the [Local Provisioning documentation](https://learn.microsoft.com/dotnet/aspire/azure/local-provisioning#configuration). +The project is set up to automatically provision Azure resources. When running the app for the first time, you will be prompted to provide Azure configuration values. For detailed instructions, see the [Local Provisioning documentation](https://learn.microsoft.com/dotnet/aspire/azure/local-provisioning#configuration). -#### ---#if (hostIdentifier == "vs") -Configure local provisioning for this project using .NET User Secrets: - -1. In Visual Studio, right-click on the ChatWithCustomData-CSharp.AppHost project in the Solution Explorer and select "Manage User Secrets". -2. This opens a `secrets.json` file where you can store your API keys without them being tracked in source control. Add the following configuration: - - ```json - { - "Azure": { - "SubscriptionId": "", - "AllowResourceGroupCreation": true, - "ResourceGroup": "", - "Location": "" - } - } - ``` - -#### ---#else -From the command line, configure local provisioning for this project using .NET User Secrets by running the following commands: - -```sh -cd ChatWithCustomData-CSharp.AppHost -dotnet user-secrets set Azure:SubscriptionId "" -dotnet user-secrets set Azure:AllowResourceGroupCreation "true" -dotnet user-secrets set Azure:ResourceGroup "" -dotnet user-secrets set Azure:Location "" -``` -#### ---#endif - -Make sure to replace placeholder values with real configuration values. #### ---#endif #### ---#if (UseQdrant) @@ -143,9 +113,9 @@ Note: Qdrant and Docker are excellent open source products, but are not maintain ## Trust the localhost certificate -Several .NET Aspire templates include ASP.NET Core projects that are configured to use HTTPS by default. If this is the first time you're running the project, an exception might occur when loading the Aspire dashboard. This error can be resolved by trusting the self-signed development certificate with the .NET CLI. +Several Aspire templates include ASP.NET Core projects that are configured to use HTTPS by default. If this is the first time you're running the project, an exception might occur when loading the Aspire dashboard. This error can be resolved by trusting the self-signed development certificate with the .NET CLI. -See [Troubleshoot untrusted localhost certificate in .NET Aspire](https://learn.microsoft.com/dotnet/aspire/troubleshooting/untrusted-localhost-certificate) for more information. +See [Troubleshoot untrusted localhost certificate in Aspire](https://learn.microsoft.com/dotnet/aspire/troubleshooting/untrusted-localhost-certificate) for more information. # Updating JavaScript dependencies diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/README.md b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/README.md index d1459703de1..a2f61924c32 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/README.md +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/README.md @@ -17,19 +17,8 @@ This incompatibility can be addressed by upgrading to Docker Desktop 4.41.1. See ## Using Azure Provisioning -The project is set up to automatically provision Azure resources, but local configuration is configured. For detailed instructions, see the [Local Provisioning documentation](https://learn.microsoft.com/dotnet/aspire/azure/local-provisioning#configuration). +The project is set up to automatically provision Azure resources. When running the app for the first time, you will be prompted to provide Azure configuration values. For detailed instructions, see the [Local Provisioning documentation](https://learn.microsoft.com/dotnet/aspire/azure/local-provisioning#configuration). -From the command line, configure local provisioning for this project using .NET User Secrets by running the following commands: - -```sh -cd aichatweb.AppHost -dotnet user-secrets set Azure:SubscriptionId "" -dotnet user-secrets set Azure:AllowResourceGroupCreation "true" -dotnet user-secrets set Azure:ResourceGroup "" -dotnet user-secrets set Azure:Location "" -``` - -Make sure to replace placeholder values with real configuration values. # Running the application @@ -47,9 +36,9 @@ Make sure to replace placeholder values with real configuration values. ## Trust the localhost certificate -Several .NET Aspire templates include ASP.NET Core projects that are configured to use HTTPS by default. If this is the first time you're running the project, an exception might occur when loading the Aspire dashboard. This error can be resolved by trusting the self-signed development certificate with the .NET CLI. +Several Aspire templates include ASP.NET Core projects that are configured to use HTTPS by default. If this is the first time you're running the project, an exception might occur when loading the Aspire dashboard. This error can be resolved by trusting the self-signed development certificate with the .NET CLI. -See [Troubleshoot untrusted localhost certificate in .NET Aspire](https://learn.microsoft.com/dotnet/aspire/troubleshooting/untrusted-localhost-certificate) for more information. +See [Troubleshoot untrusted localhost certificate in Aspire](https://learn.microsoft.com/dotnet/aspire/troubleshooting/untrusted-localhost-certificate) for more information. # Updating JavaScript dependencies diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/Program.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/AppHost.cs similarity index 100% rename from test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/Program.cs rename to test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/AppHost.cs diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json index 4444e808585..681e3bf0d26 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json @@ -9,8 +9,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:9999", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:9999" + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:9999", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:9999" } }, "http": { @@ -21,8 +21,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:9999", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:9999" + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:9999", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:9999" } } } diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj index 54bcd4bc3a0..2ba82b12b27 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj @@ -1,20 +1,19 @@  - + Exe net9.0 enable enable - true secret - - - + + + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs index f56908872e0..b44d60b604b 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs @@ -10,11 +10,14 @@ namespace Microsoft.Extensions.Hosting; -// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. +// Adds common Aspire services: service discovery, resilience, health checks, and OpenTelemetry. // This project should be referenced by each service project in your solution. // To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults public static class Extensions { + private const string HealthEndpointPath = "/health"; + private const string AlivenessEndpointPath = "/alive"; + public static TBuilder AddServiceDefaults(this TBuilder builder) where TBuilder : IHostApplicationBuilder { builder.ConfigureOpenTelemetry(); @@ -64,7 +67,12 @@ public static TBuilder ConfigureOpenTelemetry(this TBuilder builder) w .WithTracing(tracing => { tracing.AddSource(builder.Environment.ApplicationName) - .AddAspNetCoreInstrumentation() + .AddAspNetCoreInstrumentation(tracing => + // Exclude health check requests from tracing + tracing.Filter = context => + !context.Request.Path.StartsWithSegments(HealthEndpointPath) + && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath) + ) // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) //.AddGrpcClientInstrumentation() .AddHttpClientInstrumentation() @@ -111,10 +119,10 @@ public static WebApplication MapDefaultEndpoints(this WebApplication app) if (app.Environment.IsDevelopment()) { // All health checks must pass for app to be considered ready to accept traffic after starting - app.MapHealthChecks("/health"); + app.MapHealthChecks(HealthEndpointPath); // Only health checks tagged with the "live" tag must pass for app to be considered alive - app.MapHealthChecks("/alive", new HealthCheckOptions + app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions { Predicate = r => r.Tags.Contains("live") }); diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs index 59732141849..2fe43370071 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs @@ -26,7 +26,7 @@ public async Task IngestDataAsync(IIngestionSource source) var deletedDocuments = await source.GetDeletedDocumentsAsync(documentsForSource); foreach (var deletedDocument in deletedDocuments) { - logger.LogInformation("Removing ingested data for {documentId}", deletedDocument.DocumentId); + logger.LogInformation("Removing ingested data for {DocumentId}", deletedDocument.DocumentId); await DeleteChunksForDocumentAsync(deletedDocument); await documentsCollection.DeleteAsync(deletedDocument.Key); } @@ -34,7 +34,7 @@ public async Task IngestDataAsync(IIngestionSource source) var modifiedDocuments = await source.GetNewOrModifiedDocumentsAsync(documentsForSource); foreach (var modifiedDocument in modifiedDocuments) { - logger.LogInformation("Processing {documentId}", modifiedDocument.DocumentId); + logger.LogInformation("Processing {DocumentId}", modifiedDocument.DocumentId); await DeleteChunksForDocumentAsync(modifiedDocument); await documentsCollection.UpsertAsync(modifiedDocument); @@ -49,7 +49,7 @@ async Task DeleteChunksForDocumentAsync(IngestedDocument document) { var documentId = document.DocumentId; var chunksToDelete = await chunksCollection.GetAsync(record => record.DocumentId == documentId, int.MaxValue).ToListAsync(); - if (chunksToDelete.Any()) + if (chunksToDelete.Count != 0) { await chunksCollection.DeleteAsync(chunksToDelete.Select(r => r.Key)); } diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj index 4fe1ad84c6a..b561e076b17 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.AzureOpenAI_Qdrant_Aspire.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj @@ -8,14 +8,14 @@ - - + + - + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Basic.verified/aichatweb/Services/Ingestion/DataIngestor.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Basic.verified/aichatweb/Services/Ingestion/DataIngestor.cs index 65b520980c1..89fe287ebed 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Basic.verified/aichatweb/Services/Ingestion/DataIngestor.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Basic.verified/aichatweb/Services/Ingestion/DataIngestor.cs @@ -26,7 +26,7 @@ public async Task IngestDataAsync(IIngestionSource source) var deletedDocuments = await source.GetDeletedDocumentsAsync(documentsForSource); foreach (var deletedDocument in deletedDocuments) { - logger.LogInformation("Removing ingested data for {documentId}", deletedDocument.DocumentId); + logger.LogInformation("Removing ingested data for {DocumentId}", deletedDocument.DocumentId); await DeleteChunksForDocumentAsync(deletedDocument); await documentsCollection.DeleteAsync(deletedDocument.Key); } @@ -34,7 +34,7 @@ public async Task IngestDataAsync(IIngestionSource source) var modifiedDocuments = await source.GetNewOrModifiedDocumentsAsync(documentsForSource); foreach (var modifiedDocument in modifiedDocuments) { - logger.LogInformation("Processing {documentId}", modifiedDocument.DocumentId); + logger.LogInformation("Processing {DocumentId}", modifiedDocument.DocumentId); await DeleteChunksForDocumentAsync(modifiedDocument); await documentsCollection.UpsertAsync(modifiedDocument); @@ -49,7 +49,7 @@ async Task DeleteChunksForDocumentAsync(IngestedDocument document) { var documentId = document.DocumentId; var chunksToDelete = await chunksCollection.GetAsync(record => record.DocumentId == documentId, int.MaxValue).ToListAsync(); - if (chunksToDelete.Any()) + if (chunksToDelete.Count != 0) { await chunksCollection.DeleteAsync(chunksToDelete.Select(r => r.Key)); } diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/README.md b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/README.md index c05c18281ef..94c542fda7f 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/README.md +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/README.md @@ -43,9 +43,9 @@ Learn more about [prototyping with AI models using GitHub Models](https://docs.g ## Trust the localhost certificate -Several .NET Aspire templates include ASP.NET Core projects that are configured to use HTTPS by default. If this is the first time you're running the project, an exception might occur when loading the Aspire dashboard. This error can be resolved by trusting the self-signed development certificate with the .NET CLI. +Several Aspire templates include ASP.NET Core projects that are configured to use HTTPS by default. If this is the first time you're running the project, an exception might occur when loading the Aspire dashboard. This error can be resolved by trusting the self-signed development certificate with the .NET CLI. -See [Troubleshoot untrusted localhost certificate in .NET Aspire](https://learn.microsoft.com/dotnet/aspire/troubleshooting/untrusted-localhost-certificate) for more information. +See [Troubleshoot untrusted localhost certificate in Aspire](https://learn.microsoft.com/dotnet/aspire/troubleshooting/untrusted-localhost-certificate) for more information. # Updating JavaScript dependencies diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/Program.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/AppHost.cs similarity index 100% rename from test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/Program.cs rename to test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/AppHost.cs diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json index 4444e808585..681e3bf0d26 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json @@ -9,8 +9,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:9999", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:9999" + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:9999", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:9999" } }, "http": { @@ -21,8 +21,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:9999", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:9999" + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:9999", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:9999" } } } diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj index ffef1abf363..a7c93eb2928 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj @@ -1,18 +1,17 @@  - + Exe net9.0 enable enable - true secret - + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs index f56908872e0..b44d60b604b 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs @@ -10,11 +10,14 @@ namespace Microsoft.Extensions.Hosting; -// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. +// Adds common Aspire services: service discovery, resilience, health checks, and OpenTelemetry. // This project should be referenced by each service project in your solution. // To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults public static class Extensions { + private const string HealthEndpointPath = "/health"; + private const string AlivenessEndpointPath = "/alive"; + public static TBuilder AddServiceDefaults(this TBuilder builder) where TBuilder : IHostApplicationBuilder { builder.ConfigureOpenTelemetry(); @@ -64,7 +67,12 @@ public static TBuilder ConfigureOpenTelemetry(this TBuilder builder) w .WithTracing(tracing => { tracing.AddSource(builder.Environment.ApplicationName) - .AddAspNetCoreInstrumentation() + .AddAspNetCoreInstrumentation(tracing => + // Exclude health check requests from tracing + tracing.Filter = context => + !context.Request.Path.StartsWithSegments(HealthEndpointPath) + && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath) + ) // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) //.AddGrpcClientInstrumentation() .AddHttpClientInstrumentation() @@ -111,10 +119,10 @@ public static WebApplication MapDefaultEndpoints(this WebApplication app) if (app.Environment.IsDevelopment()) { // All health checks must pass for app to be considered ready to accept traffic after starting - app.MapHealthChecks("/health"); + app.MapHealthChecks(HealthEndpointPath); // Only health checks tagged with the "live" tag must pass for app to be considered alive - app.MapHealthChecks("/alive", new HealthCheckOptions + app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions { Predicate = r => r.Tags.Contains("live") }); diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs index 59732141849..2fe43370071 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs @@ -26,7 +26,7 @@ public async Task IngestDataAsync(IIngestionSource source) var deletedDocuments = await source.GetDeletedDocumentsAsync(documentsForSource); foreach (var deletedDocument in deletedDocuments) { - logger.LogInformation("Removing ingested data for {documentId}", deletedDocument.DocumentId); + logger.LogInformation("Removing ingested data for {DocumentId}", deletedDocument.DocumentId); await DeleteChunksForDocumentAsync(deletedDocument); await documentsCollection.DeleteAsync(deletedDocument.Key); } @@ -34,7 +34,7 @@ public async Task IngestDataAsync(IIngestionSource source) var modifiedDocuments = await source.GetNewOrModifiedDocumentsAsync(documentsForSource); foreach (var modifiedDocument in modifiedDocuments) { - logger.LogInformation("Processing {documentId}", modifiedDocument.DocumentId); + logger.LogInformation("Processing {DocumentId}", modifiedDocument.DocumentId); await DeleteChunksForDocumentAsync(modifiedDocument); await documentsCollection.UpsertAsync(modifiedDocument); @@ -49,7 +49,7 @@ async Task DeleteChunksForDocumentAsync(IngestedDocument document) { var documentId = document.DocumentId; var chunksToDelete = await chunksCollection.GetAsync(record => record.DocumentId == documentId, int.MaxValue).ToListAsync(); - if (chunksToDelete.Any()) + if (chunksToDelete.Count != 0) { await chunksCollection.DeleteAsync(chunksToDelete.Select(r => r.Key)); } diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj index 6540ee9cfa1..74589c4dc4e 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.BasicAspire.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/README.md b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/README.md index 70e543ffeae..0ef2c04a907 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/README.md +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/README.md @@ -46,9 +46,9 @@ Note: Qdrant and Docker are excellent open source products, but are not maintain ## Trust the localhost certificate -Several .NET Aspire templates include ASP.NET Core projects that are configured to use HTTPS by default. If this is the first time you're running the project, an exception might occur when loading the Aspire dashboard. This error can be resolved by trusting the self-signed development certificate with the .NET CLI. +Several Aspire templates include ASP.NET Core projects that are configured to use HTTPS by default. If this is the first time you're running the project, an exception might occur when loading the Aspire dashboard. This error can be resolved by trusting the self-signed development certificate with the .NET CLI. -See [Troubleshoot untrusted localhost certificate in .NET Aspire](https://learn.microsoft.com/dotnet/aspire/troubleshooting/untrusted-localhost-certificate) for more information. +See [Troubleshoot untrusted localhost certificate in Aspire](https://learn.microsoft.com/dotnet/aspire/troubleshooting/untrusted-localhost-certificate) for more information. # Updating JavaScript dependencies diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/Program.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/AppHost.cs similarity index 100% rename from test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/Program.cs rename to test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/AppHost.cs diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json index 4444e808585..681e3bf0d26 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/Properties/launchSettings.json @@ -9,8 +9,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:9999", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:9999" + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:9999", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:9999" } }, "http": { @@ -21,8 +21,8 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "DOTNET_ENVIRONMENT": "Development", - "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:9999", - "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:9999" + "ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:9999", + "ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:9999" } } } diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj index 7637a36ca6f..c78ef8c5d91 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.AppHost/aichatweb.AppHost.csproj @@ -1,19 +1,18 @@  - + Exe net9.0 enable enable - true secret - - + + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs index f56908872e0..b44d60b604b 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.ServiceDefaults/Extensions.cs @@ -10,11 +10,14 @@ namespace Microsoft.Extensions.Hosting; -// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. +// Adds common Aspire services: service discovery, resilience, health checks, and OpenTelemetry. // This project should be referenced by each service project in your solution. // To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults public static class Extensions { + private const string HealthEndpointPath = "/health"; + private const string AlivenessEndpointPath = "/alive"; + public static TBuilder AddServiceDefaults(this TBuilder builder) where TBuilder : IHostApplicationBuilder { builder.ConfigureOpenTelemetry(); @@ -64,7 +67,12 @@ public static TBuilder ConfigureOpenTelemetry(this TBuilder builder) w .WithTracing(tracing => { tracing.AddSource(builder.Environment.ApplicationName) - .AddAspNetCoreInstrumentation() + .AddAspNetCoreInstrumentation(tracing => + // Exclude health check requests from tracing + tracing.Filter = context => + !context.Request.Path.StartsWithSegments(HealthEndpointPath) + && !context.Request.Path.StartsWithSegments(AlivenessEndpointPath) + ) // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) //.AddGrpcClientInstrumentation() .AddHttpClientInstrumentation() @@ -111,10 +119,10 @@ public static WebApplication MapDefaultEndpoints(this WebApplication app) if (app.Environment.IsDevelopment()) { // All health checks must pass for app to be considered ready to accept traffic after starting - app.MapHealthChecks("/health"); + app.MapHealthChecks(HealthEndpointPath); // Only health checks tagged with the "live" tag must pass for app to be considered alive - app.MapHealthChecks("/alive", new HealthCheckOptions + app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions { Predicate = r => r.Tags.Contains("live") }); diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs index d0f7a6bc3a8..894b85c10de 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/Services/Ingestion/DataIngestor.cs @@ -26,7 +26,7 @@ public async Task IngestDataAsync(IIngestionSource source) var deletedDocuments = await source.GetDeletedDocumentsAsync(documentsForSource); foreach (var deletedDocument in deletedDocuments) { - logger.LogInformation("Removing ingested data for {documentId}", deletedDocument.DocumentId); + logger.LogInformation("Removing ingested data for {DocumentId}", deletedDocument.DocumentId); await DeleteChunksForDocumentAsync(deletedDocument); await documentsCollection.DeleteAsync(deletedDocument.Key); } @@ -34,7 +34,7 @@ public async Task IngestDataAsync(IIngestionSource source) var modifiedDocuments = await source.GetNewOrModifiedDocumentsAsync(documentsForSource); foreach (var modifiedDocument in modifiedDocuments) { - logger.LogInformation("Processing {documentId}", modifiedDocument.DocumentId); + logger.LogInformation("Processing {DocumentId}", modifiedDocument.DocumentId); await DeleteChunksForDocumentAsync(modifiedDocument); await documentsCollection.UpsertAsync(modifiedDocument); @@ -49,7 +49,7 @@ async Task DeleteChunksForDocumentAsync(IngestedDocument document) { var documentId = document.DocumentId; var chunksToDelete = await chunksCollection.GetAsync(record => record.DocumentId == documentId, int.MaxValue).ToListAsync(); - if (chunksToDelete.Any()) + if (chunksToDelete.Count != 0) { await chunksCollection.DeleteAsync(chunksToDelete.Select(r => r.Key)); } diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj index 4e5e3134e15..fa6f8c6bae4 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.Ollama_Qdrant.verified/aichatweb/aichatweb.Web/aichatweb.Web.csproj @@ -14,7 +14,7 @@ - + diff --git a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.OpenAI_AzureAISearch.verified/aichatweb/Services/Ingestion/DataIngestor.cs b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.OpenAI_AzureAISearch.verified/aichatweb/Services/Ingestion/DataIngestor.cs index 65b520980c1..89fe287ebed 100644 --- a/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.OpenAI_AzureAISearch.verified/aichatweb/Services/Ingestion/DataIngestor.cs +++ b/test/ProjectTemplates/Microsoft.Extensions.AI.Templates.IntegrationTests/Snapshots/aichatweb.OpenAI_AzureAISearch.verified/aichatweb/Services/Ingestion/DataIngestor.cs @@ -26,7 +26,7 @@ public async Task IngestDataAsync(IIngestionSource source) var deletedDocuments = await source.GetDeletedDocumentsAsync(documentsForSource); foreach (var deletedDocument in deletedDocuments) { - logger.LogInformation("Removing ingested data for {documentId}", deletedDocument.DocumentId); + logger.LogInformation("Removing ingested data for {DocumentId}", deletedDocument.DocumentId); await DeleteChunksForDocumentAsync(deletedDocument); await documentsCollection.DeleteAsync(deletedDocument.Key); } @@ -34,7 +34,7 @@ public async Task IngestDataAsync(IIngestionSource source) var modifiedDocuments = await source.GetNewOrModifiedDocumentsAsync(documentsForSource); foreach (var modifiedDocument in modifiedDocuments) { - logger.LogInformation("Processing {documentId}", modifiedDocument.DocumentId); + logger.LogInformation("Processing {DocumentId}", modifiedDocument.DocumentId); await DeleteChunksForDocumentAsync(modifiedDocument); await documentsCollection.UpsertAsync(modifiedDocument); @@ -49,7 +49,7 @@ async Task DeleteChunksForDocumentAsync(IngestedDocument document) { var documentId = document.DocumentId; var chunksToDelete = await chunksCollection.GetAsync(record => record.DocumentId == documentId, int.MaxValue).ToListAsync(); - if (chunksToDelete.Any()) + if (chunksToDelete.Count != 0) { await chunksCollection.DeleteAsync(chunksToDelete.Select(r => r.Key)); }