Skip to content

Commit e44cb70

Browse files
Cleanup :)
1 parent 1c00f56 commit e44cb70

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+128
-55038
lines changed

Directory.Packages.props

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
<CentralPackageTransitivePinningEnabled>false</CentralPackageTransitivePinningEnabled>
55
<ToolingPackagesVersion>1.1.1.5540</ToolingPackagesVersion>
6-
<AccessToNugetFeed>true</AccessToNugetFeed>
6+
<AccessToNugetFeed>false</AccessToNugetFeed>
77
<RestoreSources>
88
https://api.nuget.org/v3/index.json;
99
</RestoreSources>
@@ -14,11 +14,6 @@
1414
</PropertyGroup>
1515
<ItemGroup Condition="$(AccessToNugetFeed)">
1616
<PackageVersion Include="ContentFeedNuget" Version="$(ToolingPackagesVersion)" />
17-
<PackageVersion Include="Markdig" Version="0.41.3" />
18-
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
19-
<PackageVersion Include="ModelContextProtocol" Version="0.3.0-preview.3" />
20-
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="0.3.0-preview.3" />
21-
<PackageVersion Include="Moq" Version="4.20.72" />
2217
</ItemGroup>
2318
<ItemGroup>
2419
<PackageVersion Include="AspNet.Security.OAuth.GitHub" Version="8.3.0" />
@@ -41,22 +36,14 @@
4136
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.10" />
4237
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.10" />
4338
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
39+
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.60.0" />
40+
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.PgVector" Version="1.60.0-preview" />
4441
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
4542
<PackageVersion Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
4643
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
47-
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.0" />
48-
<PackageVersion Include="Microsoft.Extensions.Configuration.CommandLine" Version="9.0.0" />
49-
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.0" />
50-
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="9.0.0" />
51-
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0" />
52-
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" />
53-
<PackageVersion Include="Microsoft.Extensions.VectorData" Version="9.0.1-preview.1.24570.5" />
54-
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.PgVector" Version="1.60.0-preview" />
55-
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.5" />
56-
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.60.0" />
57-
<PackageVersion Include="OpenAI" Version="2.2.0-beta.4" />
58-
<PackageVersion Include="Npgsql" Version="9.0.0" />
59-
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.0" />
44+
<PackageVersion Include="ModelContextProtocol" Version="0.3.0-preview.3" />
45+
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="0.3.0-preview.3" />
46+
<PackageVersion Include="Moq" Version="4.20.72" />
6047
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta6.25358.103" />
6148
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
6249
<PackageVersion Include="Octokit" Version="14.0.0" />

EssentialCSharp.Chat.Shared/EssentialCSharp.Chat.Common.csproj

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,10 @@
77
</PropertyGroup>
88

99
<ItemGroup>
10-
<PackageReference Include="Markdig" />
1110
<PackageReference Include="Microsoft.SemanticKernel" />
12-
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
1311
<PackageReference Include="Microsoft.SemanticKernel.Connectors.PgVector" />
14-
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" />
1512
<PackageReference Include="ModelContextProtocol" />
1613
<PackageReference Include="ModelContextProtocol.AspNetCore" />
17-
<PackageReference Include="OpenAI" />
18-
<PackageReference Include="Npgsql" />
1914
<PackageReference Include="Microsoft.SourceLink.GitHub">
2015
<PrivateAssets>all</PrivateAssets>
2116
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using EssentialCSharp.Chat.Common.Services;
2+
using Microsoft.Extensions.Configuration;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.SemanticKernel;
5+
6+
namespace EssentialCSharp.Chat.Common.Extensions;
7+
8+
public static class ServiceCollectionExtensions
9+
{
10+
/// <summary>
11+
/// Adds Azure OpenAI and related AI services to the service collection
12+
/// </summary>
13+
/// <param name="services">The service collection to add services to</param>
14+
/// <param name="aiOptions">The AI configuration options</param>
15+
/// <returns>The service collection for chaining</returns>
16+
public static IServiceCollection AddAzureOpenAIServices(this IServiceCollection services, AIOptions aiOptions)
17+
{
18+
// Validate required configuration
19+
if (aiOptions == null)
20+
{
21+
throw new InvalidOperationException("AIOptions cannot be null.");
22+
}
23+
24+
if (string.IsNullOrEmpty(aiOptions.Endpoint) ||
25+
string.IsNullOrEmpty(aiOptions.ApiKey))
26+
{
27+
throw new InvalidOperationException("Azure OpenAI Endpoint and ApiKey must be properly configured in AIOptions. Please update your configuration with valid values.");
28+
}
29+
30+
if (string.IsNullOrEmpty(aiOptions.PostgresConnectionString) ||
31+
aiOptions.PostgresConnectionString.Contains("your-postgres-connection-string"))
32+
{
33+
throw new InvalidOperationException("PostgreSQL connection string must be properly configured in AIOptions for vector store. Please update your configuration with a valid connection string.");
34+
}
35+
36+
#pragma warning disable SKEXP0010 // Type is for evaluation purposes only and is subject to change or removal in future updates.
37+
38+
// Register Azure OpenAI services
39+
services.AddAzureOpenAIEmbeddingGenerator(
40+
aiOptions.VectorGenerationDeploymentName,
41+
aiOptions.Endpoint,
42+
aiOptions.ApiKey);
43+
44+
services.AddAzureOpenAIChatClient(
45+
aiOptions.ChatDeploymentName,
46+
aiOptions.Endpoint,
47+
aiOptions.ApiKey);
48+
49+
// Add PostgreSQL vector store
50+
services.AddPostgresVectorStore(aiOptions.PostgresConnectionString);
51+
52+
#pragma warning restore SKEXP0010
53+
54+
// Register shared AI services
55+
services.AddSingleton<EmbeddingService>();
56+
services.AddSingleton<AISearchService>();
57+
services.AddSingleton<AIChatService>();
58+
services.AddSingleton<MarkdownChunkingService>();
59+
60+
return services;
61+
}
62+
63+
/// <summary>
64+
/// Adds Azure OpenAI and related AI services to the service collection using configuration
65+
/// </summary>
66+
/// <param name="services">The service collection to add services to</param>
67+
/// <param name="configuration">The configuration to read AIOptions from</param>
68+
/// <returns>The service collection for chaining</returns>
69+
public static IServiceCollection AddAzureOpenAIServices(this IServiceCollection services, IConfiguration configuration)
70+
{
71+
// Configure AI options from configuration
72+
services.Configure<AIOptions>(configuration.GetSection("AIOptions"));
73+
74+
var aiOptions = configuration.GetSection("AIOptions").Get<AIOptions>();
75+
76+
return aiOptions == null
77+
? throw new InvalidOperationException("AIOptions section is missing from configuration.")
78+
: services.AddAzureOpenAIServices(aiOptions);
79+
}
80+
}

EssentialCSharp.Chat.Shared/Models/AIOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class AIOptions
2121
/// The Azure OpenAI endpoint URL.
2222
/// </summary>
2323
public string Endpoint { get; set; } = string.Empty;
24+
2425
/// <summary>
2526
/// The API key for accessing Azure OpenAI services.
2627
/// </summary>

EssentialCSharp.Chat.Shared/Services/AIChatService.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public AIChatService(IOptions<AIOptions> options, AISearchService searchService)
7777
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken = default)
7878
{
7979
// Add logging to help debug the conversation state issue
80-
System.Diagnostics.Debug.WriteLine($"GetChatCompletionStream called with previousResponseId: {previousResponseId}");
80+
Debug.WriteLine($"GetChatCompletionStream called with previousResponseId: {previousResponseId}");
8181

8282
var responseOptions = await CreateResponseOptionsAsync(previousResponseId, tools, reasoningEffortLevel, mcpClient: mcpClient, cancellationToken: cancellationToken);
8383
var enrichedPrompt = await EnrichPromptWithContext(prompt, enableContextualSearch, cancellationToken);
@@ -137,7 +137,7 @@ private async Task<string> EnrichPromptWithContext(string prompt, bool enableCon
137137
catch (Exception ex)
138138
{
139139
// Log the error but don't fail the request
140-
System.Diagnostics.Debug.WriteLine($"Error enriching prompt with context: {ex.Message}");
140+
Debug.WriteLine($"Error enriching prompt with context: {ex.Message}");
141141
return prompt;
142142
}
143143
}
@@ -151,10 +151,9 @@ private async Task<string> EnrichPromptWithContext(string prompt, bool enableCon
151151
IMcpClient? mcpClient,
152152
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken = default)
153153
{
154-
string? responseId = null;
155-
156154
await foreach (var update in streamingUpdates.WithCancellation(cancellationToken))
157155
{
156+
string? responseId;
158157
if (update is StreamingResponseCreatedUpdate created)
159158
{
160159
// Remember the response ID for later function calls
@@ -182,8 +181,7 @@ private async Task<string> EnrichPromptWithContext(string prompt, bool enableCon
182181
}
183182
else if (update is StreamingResponseCompletedUpdate completedUpdate)
184183
{
185-
responseId = completedUpdate.Response.Id;
186-
yield return (string.Empty, responseId); // Signal completion with response ID
184+
yield return (string.Empty, responseId: completedUpdate.Response.Id); // Signal completion with response ID
187185
}
188186
}
189187
}
@@ -198,7 +196,7 @@ private async Task<string> EnrichPromptWithContext(string prompt, bool enableCon
198196
[System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken = default)
199197
{
200198
// A dictionary of arguments to pass to the tool. Each key represents a parameter name, and its associated value represents the argument value.
201-
Dictionary<string, object?> arguments = new Dictionary<string, object?>();
199+
Dictionary<string, object?> arguments = [];
202200
// example JsonResponse:
203201
// "{\"question\":\"Azure OpenAI Responses API (Preview)\"}"
204202
var jsonResponse = functionCallItem.FunctionArguments.ToString();

EssentialCSharp.Chat.Shared/Services/AISearchService.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,9 @@
33

44
namespace EssentialCSharp.Chat.Common.Services;
55

6-
#pragma warning disable SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
76
public class AISearchService(VectorStore vectorStore, EmbeddingService embeddingService)
8-
#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
97
{
108
// TODO: Implement Hybrid Search functionality, may need to switch db providers to support full text search?
11-
//public async Task ExecuteHybridSearch(string query, string? collectionName = null)
12-
//{
13-
// collectionName ??= EmbeddingService.CollectionName;
14-
15-
// IKeywordHybridSearchable<BookContentChunk> collection = (IKeywordHybridSearchable<BookContentChunk>)vectorStore.GetCollection<string, BookContentChunk>(collectionName);
16-
17-
// ReadOnlyMemory<float> searchVector = await embeddingService.GenerateEmbeddingAsync(query);
18-
19-
// var hybridSearchOptions = new HybridSearchOptions<BookContentChunk>
20-
// {
21-
22-
// };
23-
24-
// var searchResults = await collection.HybridSearchAsync (searchVector, ["C#"], top: 3);
25-
// foreach (var result in results)
26-
// {
27-
// Console.WriteLine($"Found chunk: {result.Value.Heading} in file {result.Value.FileName}");
28-
// }
29-
//}
309

3110
public async Task<IAsyncEnumerable<VectorSearchResult<BookContentChunk>>> ExecuteVectorSearch(string query, string? collectionName = null)
3211
{

EssentialCSharp.Chat.Shared/Services/EmbeddingService.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ namespace EssentialCSharp.Chat.Common.Services;
77
/// <summary>
88
/// Service for generating embeddings for markdown chunks using Azure OpenAI
99
/// </summary>
10-
#pragma warning disable SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
1110
public class EmbeddingService(VectorStore vectorStore, IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator)
1211
{
1312
public static string CollectionName { get; } = "markdown_chunks";
@@ -54,4 +53,3 @@ await Parallel.ForEachAsync(bookContents, parallelOptions, async (chunk, cancell
5453
Console.WriteLine($"Successfully generated embeddings and uploaded {bookContents.Count()} chunks to collection '{collectionName}'.");
5554
}
5655
}
57-
#pragma warning restore SKEXP0001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.

EssentialCSharp.Chat.Shared/Services/MarkdownChunkingService.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public partial class MarkdownChunkingService(
1212
int maxTokensPerChunk = 256,
1313
int overlapTokens = 25)
1414
{
15-
private static readonly string[] _NewLineSeparators = new[] { "\r\n", "\n", "\r" };
15+
private static readonly string[] _NewLineSeparators = ["\r\n", "\n", "\r"];
1616
private readonly int _MaxTokensPerChunk = maxTokensPerChunk;
1717
private readonly int _OverlapTokens = overlapTokens;
1818

@@ -73,14 +73,14 @@ public FileChunkingResult ProcessSingleMarkdownFile(
7373
int totalChunkCharacters = 0;
7474
int chunkCount = 0;
7575

76-
foreach (var section in sections)
76+
foreach (var (Header, Content) in sections)
7777
{
7878
#pragma warning disable SKEXP0050
7979
var chunks = TextChunker.SplitMarkdownParagraphs(
80-
lines: section.Content,
80+
lines: Content,
8181
maxTokensPerParagraph: _MaxTokensPerChunk,
8282
overlapTokens: _OverlapTokens,
83-
chunkHeader: section.Header + " - "
83+
chunkHeader: Header + " - "
8484
);
8585
#pragma warning restore SKEXP0050
8686
allChunks.AddRange(chunks);

EssentialCSharp.Chat/EssentialCSharp.Chat.csproj

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,9 @@
1818
</PropertyGroup>
1919

2020
<ItemGroup>
21-
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
22-
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
2321
<PackageReference Include="Microsoft.SemanticKernel" />
2422
<PackageReference Include="Microsoft.SemanticKernel.Connectors.PgVector" />
25-
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
26-
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
2723
<PackageReference Include="ModelContextProtocol" />
28-
<PackageReference Include="Npgsql" />
2924
<PackageReference Include="IntelliTect.Multitool" />
3025
<PackageReference Include="System.CommandLine" />
3126
<PackageReference Include="Microsoft.SourceLink.GitHub">

0 commit comments

Comments
 (0)