Skip to content

Commit

Permalink
Fix typos, docs, and code style
Browse files Browse the repository at this point in the history
  • Loading branch information
dluc committed Nov 8, 2024
1 parent f2f4a32 commit 81f0a62
Show file tree
Hide file tree
Showing 54 changed files with 662 additions and 234 deletions.
304 changes: 304 additions & 0 deletions CopilotChat.sln.DotSettings

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions integration-tests/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[**/**.cs]
resharper_inconsistent_naming_highlighting = none
dotnet_diagnostic.IDE1006.severity = none # No need for Async suffix on test names
32 changes: 16 additions & 16 deletions integration-tests/ChatCopilotIntegrationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,25 @@ public abstract class ChatCopilotIntegrationTest : IDisposable
protected const string PasswordSettingName = "TestPassword";
protected const string ScopesSettingName = "Scopes";

protected readonly HttpClient _httpClient;
protected readonly IConfigurationRoot configuration;
protected readonly HttpClient HTTPClient;
protected readonly IConfigurationRoot Configuration;

protected ChatCopilotIntegrationTest()
{
// Load configuration
this.configuration = new ConfigurationBuilder()
this.Configuration = new ConfigurationBuilder()
.AddJsonFile(path: "testsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(path: "testsettings.development.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.AddUserSecrets<HealthzTests>()
.Build();

string? baseUrl = this.configuration[BaseUrlSettingName];
string? baseUrl = this.Configuration[BaseUrlSettingName];
Assert.False(string.IsNullOrEmpty(baseUrl));
Assert.True(baseUrl.EndsWith('/'));

this._httpClient = new HttpClient();
this._httpClient.BaseAddress = new Uri(baseUrl);
this.HTTPClient = new HttpClient();
this.HTTPClient.BaseAddress = new Uri(baseUrl);
}

public void Dispose()
Expand All @@ -55,25 +55,25 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
this._httpClient.Dispose();
this.HTTPClient.Dispose();
}
}

protected async Task SetUpAuth()
protected async Task SetUpAuthAsync()
{
string accesstoken = await this.GetUserTokenByPassword();
string accesstoken = await this.GetUserTokenByPasswordAsync();
Assert.True(!string.IsNullOrEmpty(accesstoken));

this._httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accesstoken);
this.HTTPClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accesstoken);
}

protected async Task<string> GetUserTokenByPassword()
protected async Task<string> GetUserTokenByPasswordAsync()
{
IPublicClientApplication app = PublicClientApplicationBuilder.Create(this.configuration[ClientIdSettingName])
.WithAuthority(this.configuration[AuthoritySettingName])
.Build();
IPublicClientApplication app = PublicClientApplicationBuilder.Create(this.Configuration[ClientIdSettingName])
.WithAuthority(this.Configuration[AuthoritySettingName])
.Build();

string? scopeString = this.configuration[ScopesSettingName];
string? scopeString = this.Configuration[ScopesSettingName];
Assert.NotNull(scopeString);

string[] scopes = scopeString.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
Expand All @@ -88,7 +88,7 @@ protected async Task<string> GetUserTokenByPassword()
}
else
{
result = await app.AcquireTokenByUsernamePassword(scopes, this.configuration[UsernameSettingName], this.configuration[PasswordSettingName]).ExecuteAsync();
result = await app.AcquireTokenByUsernamePassword(scopes, this.Configuration[UsernameSettingName], this.Configuration[PasswordSettingName]).ExecuteAsync();
}

return result?.AccessToken ?? string.Empty;
Expand Down
16 changes: 16 additions & 0 deletions integration-tests/ChatCopilotIntegrationTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.11.20">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Analyzers" Version="4.12.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.12.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.12.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
12 changes: 5 additions & 7 deletions integration-tests/ChatTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ public class ChatTests : ChatCopilotIntegrationTest
[Fact]
public async void ChatMessagePostSucceedsWithValidInput()
{
await this.SetUpAuth();
await this.SetUpAuthAsync();

// Create chat session
var createChatParams = new CreateChatParameters() { Title = nameof(ChatMessagePostSucceedsWithValidInput) };
HttpResponseMessage response = await this._httpClient.PostAsJsonAsync("chats", createChatParams);
var createChatParams = new CreateChatParameters() { Title = nameof(this.ChatMessagePostSucceedsWithValidInput) };
HttpResponseMessage response = await this.HTTPClient.PostAsJsonAsync("chats", createChatParams);
response.EnsureSuccessStatusCode();

var contentStream = await response.Content.ReadAsStreamAsync();
Expand All @@ -33,18 +33,16 @@ public async void ChatMessagePostSucceedsWithValidInput()
Input = "Who is Satya Nadella?",
Variables = new KeyValuePair<string, string>[] { new("MessageType", ChatMessageType.Message.ToString()) }
};
response = await this._httpClient.PostAsJsonAsync($"chats/{createChatResponse.ChatSession.Id}/messages", ask);
response = await this.HTTPClient.PostAsJsonAsync($"chats/{createChatResponse.ChatSession.Id}/messages", ask);
response.EnsureSuccessStatusCode();

contentStream = await response.Content.ReadAsStreamAsync();
var askResult = await JsonSerializer.DeserializeAsync<AskResult>(contentStream, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Assert.NotNull(askResult);
Assert.False(string.IsNullOrEmpty(askResult.Value));


// Clean up
response = await this._httpClient.DeleteAsync($"chats/{createChatResponse.ChatSession.Id}");
response = await this.HTTPClient.DeleteAsync($"chats/{createChatResponse.ChatSession.Id}");
response.EnsureSuccessStatusCode();
}
}

2 changes: 1 addition & 1 deletion integration-tests/HealthzTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class HealthzTests : ChatCopilotIntegrationTest
[Fact]
public async void HealthzSuccessfullyReturns()
{
HttpResponseMessage response = await this._httpClient.GetAsync("healthz");
HttpResponseMessage response = await this.HTTPClient.GetAsync("healthz");

response.EnsureSuccessStatusCode();
}
Expand Down
11 changes: 5 additions & 6 deletions integration-tests/ServiceInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ public class ServiceInfoTests : ChatCopilotIntegrationTest
[Fact]
public async void GetServiceInfo()
{
await this.SetUpAuth();
await this.SetUpAuthAsync();

HttpResponseMessage response = await this._httpClient.GetAsync("info/");
HttpResponseMessage response = await this.HTTPClient.GetAsync("info/");
response.EnsureSuccessStatusCode();

var contentStream = await response.Content.ReadAsStreamAsync();
Expand All @@ -29,17 +29,16 @@ public async void GetServiceInfo()
[Fact]
public async void GetAuthConfig()
{
HttpResponseMessage response = await this._httpClient.GetAsync("authConfig/");
HttpResponseMessage response = await this.HTTPClient.GetAsync("authConfig/");
response.EnsureSuccessStatusCode();

var contentStream = await response.Content.ReadAsStreamAsync();
var objectFromResponse = await JsonSerializer.DeserializeAsync<FrontendAuthConfig>(contentStream, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

Assert.NotNull(objectFromResponse);
Assert.Equal(ChatAuthenticationOptions.AuthenticationType.AzureAd.ToString(), objectFromResponse.AuthType);
Assert.Equal(this.configuration[AuthoritySettingName], objectFromResponse.AadAuthority);
Assert.Equal(this.configuration[ClientIdSettingName], objectFromResponse.AadClientId);
Assert.Equal(this.Configuration[AuthoritySettingName], objectFromResponse.AadAuthority);
Assert.Equal(this.Configuration[ClientIdSettingName], objectFromResponse.AadClientId);
Assert.False(string.IsNullOrEmpty(objectFromResponse.AadApiScope));
}
}

6 changes: 3 additions & 3 deletions integration-tests/SpeechTokenTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ public class SpeechTokenTests : ChatCopilotIntegrationTest
[Fact]
public async void GetSpeechToken()
{
await this.SetUpAuth();
await this.SetUpAuthAsync();

HttpResponseMessage response = await this._httpClient.GetAsync("speechToken/");
HttpResponseMessage response = await this.HTTPClient.GetAsync("speechToken/");
response.EnsureSuccessStatusCode();

var contentStream = await response.Content.ReadAsStreamAsync();
var speechTokenResponse = await JsonSerializer.DeserializeAsync<SpeechTokenResponse>(contentStream, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

Assert.NotNull(speechTokenResponse);
Assert.True((speechTokenResponse.IsSuccess == true && !string.IsNullOrEmpty(speechTokenResponse.Token)) ||
speechTokenResponse.IsSuccess == false);
speechTokenResponse.IsSuccess == false);
}
}
4 changes: 2 additions & 2 deletions integration-tests/StaticFiles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ public class StaticFiles : ChatCopilotIntegrationTest
[Fact]
public async void GetStaticFiles()
{
HttpResponseMessage response = await this._httpClient.GetAsync("index.html");
HttpResponseMessage response = await this.HTTPClient.GetAsync("index.html");
response.EnsureSuccessStatusCode();
Assert.True(response.Content.Headers.ContentLength > 1);

response = await this._httpClient.GetAsync("favicon.ico");
response = await this.HTTPClient.GetAsync("favicon.ico");
response.EnsureSuccessStatusCode();
Assert.True(response.Content.Headers.ContentLength > 1);
}
Expand Down
16 changes: 16 additions & 0 deletions memorypipeline/CopilotChatMemoryPipeline.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />
<PackageReference Include="Microsoft.KernelMemory.Core" Version="0.66.240709.1" />
<PackageReference Include="Microsoft.SemanticKernel" Version="1.15.1" />
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.11.20">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Analyzers" Version="4.12.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.12.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Formatting.Analyzers" Version="4.12.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions memorypipeline/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
{
message += $" Environment: {environment}";
}

return Results.Ok(message);
});

Expand Down
16 changes: 8 additions & 8 deletions memorypipeline/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Please refer to the [webapi README](../webapi/README.md).

#### Memorypipeline

The memorypipeline is only needed when `SemanticMemory:DataIngestion:OrchestrationType` is set to `Distributed` in [../webapi/appsettings.json](./appsettings.json).
The memorypipeline is only needed when `KernelMemory:DataIngestion:OrchestrationType` is set to `Distributed` in [../webapi/appsettings.json](./appsettings.json).

- Content Storage: storage solution to save the original contents. Available options:
- AzureBlobs
Expand All @@ -48,7 +48,7 @@ The memorypipeline is only needed when `SemanticMemory:DataIngestion:Orchestrati
- SimpleVectorDb
- TextFile: stores vectors on your local file system.
- Volatile: stores vectors in RAM.
> Note that do not configure the memory pipeline to use Volatile. Use volatile in the webapi only when its `SemanticMemory:DataIngestion:OrchestrationType` is set to `InProcess`.
> Note that do not configure the memory pipeline to use Volatile. Use volatile in the webapi only when its `KernelMemory:DataIngestion:OrchestrationType` is set to `InProcess`.
##### AzureBlobs & AzureQueue

Expand All @@ -58,10 +58,10 @@ The memorypipeline is only needed when `SemanticMemory:DataIngestion:Orchestrati
2. Find the **connection string** under **Access keys** on the portal.
3. Run the following to set up the authentication to the resources:
```bash
dotnet user-secrets set SemanticMemory:Services:AzureBlobs:Auth ConnectionString
dotnet user-secrets set SemanticMemory:Services:AzureBlobs:ConnectionString [your secret]
dotnet user-secrets set SemanticMemory:Services:AzureQueue:Auth ConnectionString
dotnet user-secrets set SemanticMemory:Services:AzureQueue:ConnectionString [your secret]
dotnet user-secrets set KernelMemory:Services:AzureBlobs:Auth ConnectionString
dotnet user-secrets set KernelMemory:Services:AzureBlobs:ConnectionString [your secret]
dotnet user-secrets set KernelMemory:Services:AzureQueue:Auth ConnectionString
dotnet user-secrets set KernelMemory:Services:AzureQueue:ConnectionString [your secret]
```

##### [Azure Cognitive Search](https://learn.microsoft.com/en-us/azure/search/search-what-is-azure-search)
Expand All @@ -72,8 +72,8 @@ The memorypipeline is only needed when `SemanticMemory:DataIngestion:Orchestrati
2. Find the **Url** under **Overview** and the **key** under **Keys** on the portal.
3. Run the following to set up the authentication to the resources:
```bash
dotnet user-secrets set SemanticMemory:Services:AzureAISearch:Endpoint [your secret]
dotnet user-secrets set SemanticMemory:Services:AzureAISearch:APIKey [your secret]
dotnet user-secrets set KernelMemory:Services:AzureAISearch:Endpoint [your secret]
dotnet user-secrets set KernelMemory:Services:AzureAISearch:APIKey [your secret]
```

##### RabbitMQ
Expand Down
24 changes: 12 additions & 12 deletions memorypipeline/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
},
//
// Configuration for the various services used by kernel memory and semantic kernel.
// Section names correspond to type specified in SemanticMemory section. All supported
// Section names correspond to type specified in KernelMemory section. All supported
// sections are listed below for reference. Only referenced sections are required.
//
"Services": {
Expand Down Expand Up @@ -85,7 +85,7 @@
//
"AzureBlobs": {
"Auth": "ConnectionString",
//"ConnectionString": "", // dotnet user-secrets set "SemanticMemory:Services:AzureBlobs:ConnectionString" "MY_AZUREBLOB_CONNECTIONSTRING"
//"ConnectionString": "", // dotnet user-secrets set "KernelMemory:Services:AzureBlobs:ConnectionString" "MY_AZUREBLOB_CONNECTIONSTRING"
//"Account": "",
"Container": "chatmemory"
//"EndpointSuffix": "core.windows.net"
Expand All @@ -99,7 +99,7 @@
//
"AzureQueue": {
"Auth": "ConnectionString"
//"ConnectionString": "", // dotnet user-secrets set "SemanticMemory:Services:AzureQueue:ConnectionString" "MY_AZUREQUEUE_CONNECTIONSTRING"
//"ConnectionString": "", // dotnet user-secrets set "KernelMemory:Services:AzureQueue:ConnectionString" "MY_AZUREQUEUE_CONNECTIONSTRING"
//"Account": "",
//"EndpointSuffix": "core.windows.net"
},
Expand All @@ -111,8 +111,8 @@
// - Port is the RabbitMq service port.
//
"RabbitMq": {
//"Username": "user", // dotnet user-secrets set "SemanticMemory:Services:RabbitMq:Username" "MY_RABBITMQ_USER"
//"Password": "", // dotnet user-secrets set "SemanticMemory:Services:RabbitMq:Password" "MY_RABBITMQ_KEY"
//"Username": "user", // dotnet user-secrets set "KernelMemory:Services:RabbitMq:Username" "MY_RABBITMQ_USER"
//"Password": "", // dotnet user-secrets set "KernelMemory:Services:RabbitMq:Password" "MY_RABBITMQ_KEY"
"Host": "127.0.0.1",
"Port": "5672"
},
Expand All @@ -124,7 +124,7 @@
//
"AzureAISearch": {
"Auth": "ApiKey",
//"APIKey": "", // dotnet user-secrets set "SemanticMemory:Services:AzureAISearch:APIKey" "MY_ACS_KEY"
//"APIKey": "", // dotnet user-secrets set "KernelMemory:Services:AzureAISearch:APIKey" "MY_ACS_KEY"
"Endpoint": ""
},
//
Expand All @@ -133,7 +133,7 @@
// - Endpoint is the service endpoint url.
//
"Qdrant": {
//"APIKey": "", // dotnet user-secrets set "SemanticMemory:Services:Qdrant:APIKey" "MY_QDRANT_KEY"
//"APIKey": "", // dotnet user-secrets set "KernelMemory:Services:Qdrant:APIKey" "MY_QDRANT_KEY"
"Endpoint": "http://127.0.0.1:6333"
},
//
Expand All @@ -147,7 +147,7 @@
//
"AzureOpenAIText": {
"Auth": "ApiKey",
//"APIKey": "", // dotnet user-secrets set "SemanticMemory:Services:AzureOpenAIText:APIKey" "MY_AZUREOPENAI_KEY"
//"APIKey": "", // dotnet user-secrets set "KernelMemory:Services:AzureOpenAIText:APIKey" "MY_AZUREOPENAI_KEY"
"Endpoint": "",
"Deployment": "gpt-4o",
"APIType": "ChatCompletion",
Expand All @@ -162,7 +162,7 @@
//
"AzureOpenAIEmbedding": {
"Auth": "ApiKey",
// "APIKey": "", // dotnet user-secrets set "SemanticMemory:Services:AzureOpenAIEmbedding:APIKey" "MY_AZUREOPENAI_KEY"
// "APIKey": "", // dotnet user-secrets set "KernelMemory:Services:AzureOpenAIEmbedding:APIKey" "MY_AZUREOPENAI_KEY"
"Endpoint": ".openai.azure.com/",
"Deployment": "text-embedding-ada-002"
},
Expand All @@ -177,7 +177,7 @@
"OpenAI": {
"TextModel": "gpt-3.5-turbo",
"EmbeddingModel": "text-embedding-ada-002",
//"APIKey": "", // dotnet user-secrets set "SemanticMemory:Services:OpenAI:APIKey" "MY_OPENAI_KEY"
//"APIKey": "", // dotnet user-secrets set "KernelMemory:Services:OpenAI:APIKey" "MY_OPENAI_KEY"
"OrgId": "",
"MaxRetries": 10
},
Expand All @@ -189,14 +189,14 @@
//
"AzureAIDocIntel": {
"Auth": "APIKey",
//"APIKey": "", // dotnet user-secrets set "SemanticMemory:Services:AzureAIDocIntel:APIKey" "MY_AZURE_AI_DOC_INTEL_KEY"
//"APIKey": "", // dotnet user-secrets set "KernelMemory:Services:AzureAIDocIntel:APIKey" "MY_AZURE_AI_DOC_INTEL_KEY"
"Endpoint": ""
},
//
// Tesseract configuration for memory pipeline OCR.
// - Language is the language supported by the data file.
// - FilePath is the path to the data file.
//
//
// Note: When using Tesseract OCR Support (In order to upload image file formats such as png, jpg and tiff):
// 1. Obtain language data files here: https://github.com/tesseract-ocr/tessdata .
// 2. Add these files to your `data` folder or the path specified in the "FilePath" property and set the "Copy to Output Directory" value to "Copy if newer".
Expand Down
Loading

0 comments on commit 81f0a62

Please sign in to comment.