Skip to content

Commit

Permalink
.NET Connector improvements (#263)
Browse files Browse the repository at this point in the history
  • Loading branch information
dluc authored Nov 26, 2024
1 parent 31d5f72 commit dfd2881
Show file tree
Hide file tree
Showing 17 changed files with 551 additions and 88 deletions.
5 changes: 3 additions & 2 deletions examples/dotnet/dotnet-01-echo-bot/dotnet-01-echo-bot.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Nullable>enable</Nullable>
<RootNamespace>AgentExample</RootNamespace>
<PackageId>AgentExample</PackageId>
<NoWarn>$(NoWarn);CA1515;IDE0290;</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand All @@ -27,15 +28,15 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.11.20">
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.12.19">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
28 changes: 14 additions & 14 deletions examples/dotnet/dotnet-02-message-types-demo/MyAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,20 @@ public override Task ReceiveMessageAsync(
Message message,
CancellationToken cancellationToken = default)
{
switch (this.Config.Behavior.ToLowerInvariant())
return this.Config.Behavior.ToLowerInvariant() switch
{
case "echo": return this.EchoExampleAsync(conversationId, message, cancellationToken);
case "reverse": return this.ReverseExampleAsync(conversationId, message, cancellationToken);
case "safety check": return this.SafetyCheckExampleAsync(conversationId, message, cancellationToken);
case "markdown sample": return this.MarkdownExampleAsync(conversationId, message, cancellationToken);
case "html sample": return this.HTMLExampleAsync(conversationId, message, cancellationToken);
case "code sample": return this.CodeExampleAsync(conversationId, message, cancellationToken);
case "json sample": return this.JSONExampleAsync(conversationId, message, cancellationToken);
case "mermaid sample": return this.MermaidExampleAsync(conversationId, message, cancellationToken);
case "music sample": return this.MusicExampleAsync(conversationId, message, cancellationToken);
case "none": return this.NoneExampleAsync(conversationId, message, cancellationToken);
default: return this.NoneExampleAsync(conversationId, message, cancellationToken);
}
"echo" => this.EchoExampleAsync(conversationId, message, cancellationToken),
"reverse" => this.ReverseExampleAsync(conversationId, message, cancellationToken),
"safety check" => this.SafetyCheckExampleAsync(conversationId, message, cancellationToken),
"markdown sample" => this.MarkdownExampleAsync(conversationId, message, cancellationToken),
"html sample" => this.HTMLExampleAsync(conversationId, message, cancellationToken),
"code sample" => this.CodeExampleAsync(conversationId, message, cancellationToken),
"json sample" => this.JSONExampleAsync(conversationId, message, cancellationToken),
"mermaid sample" => this.MermaidExampleAsync(conversationId, message, cancellationToken),
"music sample" => this.MusicExampleAsync(conversationId, message, cancellationToken),
"none" => this.NoneExampleAsync(conversationId, message, cancellationToken),
_ => this.NoneExampleAsync(conversationId, message, cancellationToken)
};
}

// Check text with Azure Content Safety
Expand All @@ -111,7 +111,7 @@ public override Task ReceiveMessageAsync(
Response<AnalyzeTextResult>? result = await this._contentSafety.AnalyzeTextAsync(text, cancellationToken).ConfigureAwait(false);

bool isSafe = result.HasValue && result.Value.CategoriesAnalysis.All(x => x.Severity is 0);
IEnumerable<string> report = result.HasValue ? result.Value.CategoriesAnalysis.Select(x => $"{x.Category}: {x.Severity}") : Array.Empty<string>();
IEnumerable<string> report = result.HasValue ? result.Value.CategoriesAnalysis.Select(x => $"{x.Category}: {x.Severity}") : [];

return (isSafe, report);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Nullable>enable</Nullable>
<RootNamespace>AgentExample</RootNamespace>
<PackageId>AgentExample</PackageId>
<NoWarn>$(NoWarn);CA1308;CA1861;</NoWarn>
<NoWarn>$(NoWarn);CA1308;CA1861;CA1515;IDE0290;</NoWarn>
</PropertyGroup>

<ItemGroup>
Expand All @@ -31,15 +31,15 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.11.20">
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.12.19">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
9 changes: 8 additions & 1 deletion examples/dotnet/dotnet-03-simple-chatbot/MyAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,14 @@ public override async Task ReceiveMessageAsync(
{
// Show some status while working...
await this.SetAgentStatusAsync(conversationId, "Thinking...", cancellationToken).ConfigureAwait(false);
}
catch (Exception e)
{
this.Log.LogWarning(e, "Something went wrong while setting temporary status");
}

try
{
// Update the chat history to include the message received
var conversation = await base.AddMessageToHistoryAsync(conversationId, message, cancellationToken).ConfigureAwait(false);

Expand Down Expand Up @@ -319,7 +326,7 @@ private IChatCompletionService GetChatCompletionService()
Response<AnalyzeTextResult>? result = await this._contentSafety.AnalyzeTextAsync(text, cancellationToken).ConfigureAwait(false);

bool isSafe = result.HasValue && result.Value.CategoriesAnalysis.All(x => x.Severity is 0);
IEnumerable<string> report = result.HasValue ? result.Value.CategoriesAnalysis.Select(x => $"{x.Category}: {x.Severity}") : Array.Empty<string>();
IEnumerable<string> report = result.HasValue ? result.Value.CategoriesAnalysis.Select(x => $"{x.Category}: {x.Severity}") : [];

return (isSafe, report);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// Copyright (c) Microsoft. All rights reserved.

using System.Text.Json;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.SemanticWorkbench.Connector;

namespace AgentExample;

public sealed class MyWorkbenchConnector : WorkbenchConnector<MyAgentConfig>
internal sealed class MyWorkbenchConnector : WorkbenchConnector<MyAgentConfig>
{
private readonly IServiceProvider _sp;
private readonly IConfiguration _appConfig;
Expand All @@ -15,11 +16,13 @@ public MyWorkbenchConnector(
IServiceProvider sp,
IConfiguration appConfig,
IAgentServiceStorage storage,
IServer httpServer,
ILoggerFactory? loggerFactory = null)
: base(
workbenchConfig: appConfig.GetSection("Workbench").Get<WorkbenchConfig>(),
defaultAgentConfig: appConfig.GetSection("Agent").Get<MyAgentConfig>(),
storage: storage,
httpServer: httpServer,
logger: loggerFactory?.CreateLogger<MyWorkbenchConnector>() ?? new NullLogger<MyWorkbenchConnector>())
{
this._sp = sp;
Expand Down
4 changes: 2 additions & 2 deletions examples/dotnet/dotnet-03-simple-chatbot/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ internal static async Task Main(string[] args)
app.UseCors(CORSPolicyName);

// Connect to workbench backend, keep alive, and accept incoming requests
var connectorEndpoint = app.Configuration.GetSection("Workbench").Get<WorkbenchConfig>()!.ConnectorEndpoint;
using var agentService = app.UseAgentWebservice<MyAgentConfig>(connectorEndpoint, true);
var connectorApiPrefix = app.Configuration.GetSection("Workbench").Get<WorkbenchConfig>()!.ConnectorApiPrefix;
using var agentService = app.UseAgentWebservice<MyAgentConfig>(connectorApiPrefix, true);
await agentService.ConnectAsync().ConfigureAwait(false);

// Start app and webservice
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
28 changes: 11 additions & 17 deletions examples/dotnet/dotnet-03-simple-chatbot/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
// Unique ID of the service. Semantic Workbench will store this event to identify the server
// so you should keep the value fixed to match the conversations tracked across service restarts.
"ConnectorId": "AgentExample03",
// The endpoint of your service, where semantic workbench will send communications too.
// This should match hostname, port, protocol and path of the web service. You can use
// this also to route semantic workbench through a proxy or a gateway if needed.
"ConnectorEndpoint": "http://127.0.0.1:9103/myagents",
// Semantic Workbench endpoint.
// The host where the connector receives requests sent by the workbench.
// Locally, this is usually "http://127.0.0.1:<some port>"
// On Azure, this will be something like "https://contoso.azurewebsites.net"
// Leave this setting empty to use "127.0.0.1" and autodetect the port in use.
// You can use an env var to set this value, e.g. Workbench__ConnectorHost=https://contoso.azurewebsites.net
"ConnectorHost": "",
// This is the prefix of all the endpoints exposed by the connector
"ConnectorApiPrefix": "/myagents",
// Semantic Workbench backend endpoint.
// The connector connects to this workbench endpoint to register its presence.
// The workbench connects back to the connector to send events (see ConnectorHost and ConnectorApiPrefix).
"WorkbenchEndpoint": "http://127.0.0.1:3000",
// Name of your agent service
"ConnectorName": ".NET Multi Agent Service",
Expand Down Expand Up @@ -48,18 +54,6 @@
"Endpoint": "https://api.openai.com/v1/",
"ApiKey": "sk-..."
},
// Web service settings
"AllowedHosts": "*",
"Kestrel": {
"Endpoints": {
"Http": {
"Url": "http://*:9103"
}
// "Https": {
// "Url": "https://*:19103
// }
}
},
// .NET Logger settings
"Logging": {
"LogLevel": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@
<Nullable>enable</Nullable>
<RootNamespace>AgentExample</RootNamespace>
<PackageId>AgentExample</PackageId>
<NoWarn>$(NoWarn);SKEXP0010;CA1861;</NoWarn>
<NoWarn>$(NoWarn);SKEXP0010;CA1861;CA1515;IDE0290;CA1031;CA1812;</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SemanticWorkbench.Connector" Version="0.3.241104.1" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Azure.AI.ContentSafety" Version="1.0.0" />
<PackageReference Include="Azure.Identity" Version="1.13.1" />
Expand All @@ -34,15 +30,15 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.11.20">
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.12.19">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand All @@ -60,4 +56,8 @@
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\libraries\dotnet\WorkbenchConnector\WorkbenchConnector.csproj" />
</ItemGroup>

</Project>
Loading

0 comments on commit dfd2881

Please sign in to comment.