diff --git a/SqlDatabaseVectorSearch/Program.cs b/SqlDatabaseVectorSearch/Program.cs index 76177f0..6428050 100644 --- a/SqlDatabaseVectorSearch/Program.cs +++ b/SqlDatabaseVectorSearch/Program.cs @@ -100,7 +100,7 @@ builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); @@ -249,7 +249,7 @@ builder.Services.AddAIAgent("RagAgent", (services, key) => && m.GetAgentRequestMessageSourceType() != AgentRequestMessageSourceType.AIContextProvider); } }), - AIContextProviders = [new TextSearchProvider(services.GetRequiredService().SearchAsync, textSearchOptions)] + AIContextProviders = [new TextSearchProvider(services.GetRequiredService().SearchAsync, textSearchOptions)] }, loggerFactory: services.GetRequiredService(), services: services); diff --git a/SqlDatabaseVectorSearch/Services/DocumentContextProviderService.cs b/SqlDatabaseVectorSearch/Services/DocumentContextProviderService.cs new file mode 100644 index 0000000..4b29b5d --- /dev/null +++ b/SqlDatabaseVectorSearch/Services/DocumentContextProviderService.cs @@ -0,0 +1,35 @@ +using System.Data; +using Microsoft.Agents.AI; +using Microsoft.Data.SqlTypes; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.Options; +using SqlDatabaseVectorSearch.Data; +using SqlDatabaseVectorSearch.Settings; + +namespace SqlDatabaseVectorSearch.Services; + +public class DocumentContextProviderService(ApplicationDbContext dbContext, IEmbeddingGenerator> embeddingGenerator, IOptions appSettingsOptions) +{ + private readonly AppSettings appSettings = appSettingsOptions.Value; + + public async Task> SearchAsync(string query, CancellationToken cancellationToken) + { + // Perform Vector Search on SQL Database. + var questionEmbedding = await embeddingGenerator.GenerateVectorAsync(query, cancellationToken: cancellationToken); + var embeddingVector = new SqlVector(questionEmbedding); + + var chunks = await dbContext.DocumentChunks.Include(c => c.Document) + .OrderBy(c => EF.Functions.VectorDistance("cosine", c.Embedding, embeddingVector)) + .Take(appSettings.MaxRelevantChunks).Select(c => new TextSearchProvider.TextSearchResult + { + SourceLink = c.Id.ToString().ToLowerInvariant(), + SourceName = c.Document.Name, + Text = c.Content, + RawRepresentation = c.PageNumber + }) + .ToListAsync(cancellationToken); + + return chunks; + } +} \ No newline at end of file diff --git a/SqlDatabaseVectorSearch/Services/VectorSearchService.cs b/SqlDatabaseVectorSearch/Services/VectorSearchService.cs index e6edd4e..edcaee8 100644 --- a/SqlDatabaseVectorSearch/Services/VectorSearchService.cs +++ b/SqlDatabaseVectorSearch/Services/VectorSearchService.cs @@ -3,13 +3,8 @@ using System.Runtime.CompilerServices; using Microsoft.Agents.AI; using Microsoft.Agents.AI.Hosting; using Microsoft.Agents.AI.Workflows; -using Microsoft.Data.SqlTypes; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.AI; -using Microsoft.Extensions.Options; -using SqlDatabaseVectorSearch.Data; using SqlDatabaseVectorSearch.Models; -using SqlDatabaseVectorSearch.Settings; using SqlDatabaseVectorSearch.Workflows; namespace SqlDatabaseVectorSearch.Services; @@ -87,28 +82,3 @@ public partial class VectorSearchService([FromKeyedServices("EmbeddingWorkflow") yield return new(question.ConversationId, StreamState.End, new TokenUsageResponse(null, response.Usage)); } } - -public class ContextProvider(ApplicationDbContext dbContext, IEmbeddingGenerator> embeddingGenerator, IOptions appSettingsOptions) -{ - private readonly AppSettings appSettings = appSettingsOptions.Value; - - public async Task> SearchAsync(string query, CancellationToken cancellationToken) - { - // Perform Vector Search on SQL Database. - var questionEmbedding = await embeddingGenerator.GenerateVectorAsync(query, cancellationToken: cancellationToken); - var embeddingVector = new SqlVector(questionEmbedding); - - var chunks = await dbContext.DocumentChunks.Include(c => c.Document) - .OrderBy(c => EF.Functions.VectorDistance("cosine", c.Embedding, embeddingVector)) - .Take(appSettings.MaxRelevantChunks).Select(c => new TextSearchProvider.TextSearchResult - { - SourceLink = c.Id.ToString().ToLowerInvariant(), - SourceName = c.Document.Name, - Text = c.Content, - RawRepresentation = c.PageNumber - }) - .ToListAsync(cancellationToken); - - return chunks; - } -} \ No newline at end of file