mirror of
https://github.com/marcominerva/SqlDatabaseVectorSearch.git
synced 2026-06-20 12:23:10 +00:00
404cd7565a
Updated the application to use SQL Server's native vector data type (`SqlVector<float>`) for embeddings, replacing the previous `float[]` or `string` representations. - Updated `.editorconfig` with new code style preferences and diagnostic rule severities. - Modified `DocumentChunk.cs` to use `SqlVector<float>` for the `Embedding` property. - Updated migrations and `ApplicationDbContextModelSnapshot` to reflect the new `SqlVector<float>` type. - Replaced `AddAzureSql` with `AddSqlServer` in `Program.cs` and removed `UseVectorSearch`. - Adjusted `DocumentService` and `VectorSearchService` to handle `SqlVector<float>` and updated vector search logic. - Removed the `EFCore.SqlServer.VectorSearch` package and upgraded EF Core to `10.0.0-rc.1`. - Made minor adjustments to OpenAPI configuration and dependency management.
146 lines
5.0 KiB
C#
146 lines
5.0 KiB
C#
using System.Net.Mime;
|
|
using System.Text.Json.Serialization;
|
|
using FluentValidation;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.SemanticKernel;
|
|
using SqlDatabaseVectorSearch.Components;
|
|
using SqlDatabaseVectorSearch.ContentDecoders;
|
|
using SqlDatabaseVectorSearch.Data;
|
|
using SqlDatabaseVectorSearch.Extensions;
|
|
using SqlDatabaseVectorSearch.Services;
|
|
using SqlDatabaseVectorSearch.Settings;
|
|
using SqlDatabaseVectorSearch.TextChunkers;
|
|
using TinyHelpers.AspNetCore.Extensions;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
builder.Configuration.AddJsonFile("appsettings.local.json", optional: true, reloadOnChange: true);
|
|
|
|
// Add services to the container.
|
|
var aiSettings = builder.Services.ConfigureAndGet<AzureOpenAISettings>(builder.Configuration, "AzureOpenAI")!;
|
|
var appSettings = builder.Services.ConfigureAndGet<AppSettings>(builder.Configuration, nameof(AppSettings))!;
|
|
|
|
builder.Services.AddRazorComponents()
|
|
.AddInteractiveServerComponents();
|
|
|
|
builder.Services.AddBlazorBootstrap();
|
|
|
|
builder.Services.ConfigureHttpJsonOptions(options =>
|
|
{
|
|
options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
|
});
|
|
|
|
builder.Services.AddSingleton(TimeProvider.System);
|
|
|
|
builder.Services.AddSqlServer<ApplicationDbContext>(builder.Configuration.GetConnectionString("SqlConnection"), optionsAction: options =>
|
|
{
|
|
options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
|
|
});
|
|
|
|
builder.Services.AddHybridCache(options =>
|
|
{
|
|
options.DefaultEntryOptions = new()
|
|
{
|
|
LocalCacheExpiration = appSettings.MessageExpiration
|
|
};
|
|
});
|
|
|
|
builder.Services.ConfigureHttpClientDefaults(configure =>
|
|
{
|
|
configure.AddStandardResilienceHandler(options =>
|
|
{
|
|
options.AttemptTimeout.Timeout = TimeSpan.FromSeconds(15);
|
|
options.TotalRequestTimeout.Timeout = TimeSpan.FromMinutes(2);
|
|
});
|
|
});
|
|
|
|
// Semantic Kernel is used to generate embeddings and to reformulate questions taking into account all the previous interactions,
|
|
// so that embeddings themselves can be generated more accurately.
|
|
builder.Services.AddKernel()
|
|
.AddAzureOpenAIEmbeddingGenerator(aiSettings.Embedding.Deployment, aiSettings.Embedding.Endpoint, aiSettings.Embedding.ApiKey, modelId: aiSettings.Embedding.ModelId, dimensions: aiSettings.Embedding.Dimensions)
|
|
.AddAzureOpenAIChatCompletion(aiSettings.ChatCompletion.Deployment, aiSettings.ChatCompletion.Endpoint, aiSettings.ChatCompletion.ApiKey, modelId: aiSettings.ChatCompletion.ModelId);
|
|
|
|
builder.Services.AddKeyedSingleton<IContentDecoder, PdfContentDecoder>(MediaTypeNames.Application.Pdf);
|
|
builder.Services.AddKeyedSingleton<IContentDecoder, DocxContentDecoder>("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
|
builder.Services.AddKeyedSingleton<IContentDecoder, TextContentDecoder>(MediaTypeNames.Text.Plain);
|
|
builder.Services.AddKeyedSingleton<IContentDecoder, TextContentDecoder>(MediaTypeNames.Text.Markdown);
|
|
|
|
builder.Services.AddKeyedSingleton<ITextChunker, DefaultTextChunker>(KeyedService.AnyKey);
|
|
builder.Services.AddKeyedSingleton<ITextChunker, MarkdownTextChunker>(MediaTypeNames.Text.Markdown);
|
|
|
|
builder.Services.AddSingleton<TokenizerService>();
|
|
builder.Services.AddSingleton<ChatService>();
|
|
|
|
builder.Services.AddScoped<DocumentService>();
|
|
builder.Services.AddScoped<VectorSearchService>();
|
|
|
|
builder.Services.AddOpenApi(options =>
|
|
{
|
|
//options.RemoveServerList();
|
|
//options.AddDefaultProblemDetailsResponse();
|
|
});
|
|
|
|
ValidatorOptions.Global.LanguageManager.Enabled = false;
|
|
builder.Services.AddValidatorsFromAssemblyContaining<Program>();
|
|
|
|
builder.Services.AddDefaultProblemDetails();
|
|
builder.Services.AddDefaultExceptionHandler();
|
|
|
|
var app = builder.Build();
|
|
await ConfigureDatabaseAsync(app.Services);
|
|
|
|
// Configure the HTTP request pipeline.
|
|
app.UseHttpsRedirection();
|
|
|
|
app.UseWhen(context => context.IsWebRequest(), builder =>
|
|
{
|
|
if (!app.Environment.IsDevelopment())
|
|
{
|
|
builder.UseExceptionHandler("/error");
|
|
|
|
// The default HSTS value is 30 days.
|
|
builder.UseHsts();
|
|
}
|
|
|
|
builder.UseStatusCodePagesWithRedirects("/error?code={0}");
|
|
});
|
|
|
|
app.UseWhen(context => context.IsApiRequest(), builder =>
|
|
{
|
|
app.UseExceptionHandler(new ExceptionHandlerOptions
|
|
{
|
|
StatusCodeSelector = exception => exception switch
|
|
{
|
|
NotSupportedException => StatusCodes.Status501NotImplemented,
|
|
_ => StatusCodes.Status500InternalServerError
|
|
}
|
|
});
|
|
|
|
builder.UseStatusCodePages();
|
|
});
|
|
|
|
app.MapOpenApi();
|
|
app.UseSwaggerUI(options =>
|
|
{
|
|
options.SwaggerEndpoint("/openapi/v1.json", builder.Environment.ApplicationName);
|
|
});
|
|
|
|
app.UseRouting();
|
|
app.UseRequestLocalization();
|
|
|
|
app.UseAntiforgery();
|
|
|
|
app.MapStaticAssets();
|
|
app.MapRazorComponents<App>()
|
|
.AddInteractiveServerRenderMode();
|
|
|
|
app.MapEndpoints();
|
|
|
|
app.Run();
|
|
|
|
static async Task ConfigureDatabaseAsync(IServiceProvider serviceProvider)
|
|
{
|
|
await using var scope = serviceProvider.CreateAsyncScope();
|
|
var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
|
|
|
await dbContext.Database.MigrateAsync();
|
|
} |