Skip to content

Commit dfd2881

Browse files
authored
.NET Connector improvements (#263)
1 parent 31d5f72 commit dfd2881

17 files changed

Lines changed: 551 additions & 88 deletions

File tree

examples/dotnet/dotnet-01-echo-bot/dotnet-01-echo-bot.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<Nullable>enable</Nullable>
77
<RootNamespace>AgentExample</RootNamespace>
88
<PackageId>AgentExample</PackageId>
9+
<NoWarn>$(NoWarn);CA1515;IDE0290;</NoWarn>
910
</PropertyGroup>
1011

1112
<ItemGroup>
@@ -27,15 +28,15 @@
2728
<PrivateAssets>all</PrivateAssets>
2829
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2930
</PackageReference>
30-
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
31+
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
3132
<PrivateAssets>all</PrivateAssets>
3233
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3334
</PackageReference>
3435
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
3536
<PrivateAssets>all</PrivateAssets>
3637
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3738
</PackageReference>
38-
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.11.20">
39+
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.12.19">
3940
<PrivateAssets>all</PrivateAssets>
4041
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4142
</PackageReference>

examples/dotnet/dotnet-02-message-types-demo/MyAgent.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,20 @@ public override Task ReceiveMessageAsync(
8787
Message message,
8888
CancellationToken cancellationToken = default)
8989
{
90-
switch (this.Config.Behavior.ToLowerInvariant())
90+
return this.Config.Behavior.ToLowerInvariant() switch
9191
{
92-
case "echo": return this.EchoExampleAsync(conversationId, message, cancellationToken);
93-
case "reverse": return this.ReverseExampleAsync(conversationId, message, cancellationToken);
94-
case "safety check": return this.SafetyCheckExampleAsync(conversationId, message, cancellationToken);
95-
case "markdown sample": return this.MarkdownExampleAsync(conversationId, message, cancellationToken);
96-
case "html sample": return this.HTMLExampleAsync(conversationId, message, cancellationToken);
97-
case "code sample": return this.CodeExampleAsync(conversationId, message, cancellationToken);
98-
case "json sample": return this.JSONExampleAsync(conversationId, message, cancellationToken);
99-
case "mermaid sample": return this.MermaidExampleAsync(conversationId, message, cancellationToken);
100-
case "music sample": return this.MusicExampleAsync(conversationId, message, cancellationToken);
101-
case "none": return this.NoneExampleAsync(conversationId, message, cancellationToken);
102-
default: return this.NoneExampleAsync(conversationId, message, cancellationToken);
103-
}
92+
"echo" => this.EchoExampleAsync(conversationId, message, cancellationToken),
93+
"reverse" => this.ReverseExampleAsync(conversationId, message, cancellationToken),
94+
"safety check" => this.SafetyCheckExampleAsync(conversationId, message, cancellationToken),
95+
"markdown sample" => this.MarkdownExampleAsync(conversationId, message, cancellationToken),
96+
"html sample" => this.HTMLExampleAsync(conversationId, message, cancellationToken),
97+
"code sample" => this.CodeExampleAsync(conversationId, message, cancellationToken),
98+
"json sample" => this.JSONExampleAsync(conversationId, message, cancellationToken),
99+
"mermaid sample" => this.MermaidExampleAsync(conversationId, message, cancellationToken),
100+
"music sample" => this.MusicExampleAsync(conversationId, message, cancellationToken),
101+
"none" => this.NoneExampleAsync(conversationId, message, cancellationToken),
102+
_ => this.NoneExampleAsync(conversationId, message, cancellationToken)
103+
};
104104
}
105105

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

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

116116
return (isSafe, report);
117117
}

examples/dotnet/dotnet-02-message-types-demo/dotnet-02-message-types-demo.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Nullable>enable</Nullable>
77
<RootNamespace>AgentExample</RootNamespace>
88
<PackageId>AgentExample</PackageId>
9-
<NoWarn>$(NoWarn);CA1308;CA1861;</NoWarn>
9+
<NoWarn>$(NoWarn);CA1308;CA1861;CA1515;IDE0290;</NoWarn>
1010
</PropertyGroup>
1111

1212
<ItemGroup>
@@ -31,15 +31,15 @@
3131
<PrivateAssets>all</PrivateAssets>
3232
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3333
</PackageReference>
34-
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
34+
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
3535
<PrivateAssets>all</PrivateAssets>
3636
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3737
</PackageReference>
3838
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
3939
<PrivateAssets>all</PrivateAssets>
4040
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4141
</PackageReference>
42-
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.11.20">
42+
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.12.19">
4343
<PrivateAssets>all</PrivateAssets>
4444
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4545
</PackageReference>

examples/dotnet/dotnet-03-simple-chatbot/MyAgent.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,14 @@ public override async Task ReceiveMessageAsync(
102102
{
103103
// Show some status while working...
104104
await this.SetAgentStatusAsync(conversationId, "Thinking...", cancellationToken).ConfigureAwait(false);
105+
}
106+
catch (Exception e)
107+
{
108+
this.Log.LogWarning(e, "Something went wrong while setting temporary status");
109+
}
105110

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

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

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

324331
return (isSafe, report);
325332
}

examples/dotnet/dotnet-03-simple-chatbot/MyWorkbenchConnector.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// Copyright (c) Microsoft. All rights reserved.
22

33
using System.Text.Json;
4+
using Microsoft.AspNetCore.Hosting.Server;
45
using Microsoft.Extensions.Logging.Abstractions;
56
using Microsoft.SemanticWorkbench.Connector;
67

78
namespace AgentExample;
89

9-
public sealed class MyWorkbenchConnector : WorkbenchConnector<MyAgentConfig>
10+
internal sealed class MyWorkbenchConnector : WorkbenchConnector<MyAgentConfig>
1011
{
1112
private readonly IServiceProvider _sp;
1213
private readonly IConfiguration _appConfig;
@@ -15,11 +16,13 @@ public MyWorkbenchConnector(
1516
IServiceProvider sp,
1617
IConfiguration appConfig,
1718
IAgentServiceStorage storage,
19+
IServer httpServer,
1820
ILoggerFactory? loggerFactory = null)
1921
: base(
2022
workbenchConfig: appConfig.GetSection("Workbench").Get<WorkbenchConfig>(),
2123
defaultAgentConfig: appConfig.GetSection("Agent").Get<MyAgentConfig>(),
2224
storage: storage,
25+
httpServer: httpServer,
2326
logger: loggerFactory?.CreateLogger<MyWorkbenchConnector>() ?? new NullLogger<MyWorkbenchConnector>())
2427
{
2528
this._sp = sp;

examples/dotnet/dotnet-03-simple-chatbot/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ internal static async Task Main(string[] args)
3535
app.UseCors(CORSPolicyName);
3636

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

4242
// Start app and webservice
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "http://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"http": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": false,
8+
"environmentVariables": {
9+
"ASPNETCORE_ENVIRONMENT": "Development"
10+
}
11+
},
12+
"https": {
13+
"commandName": "Project",
14+
"dotnetRunMessages": true,
15+
"launchBrowser": false,
16+
"environmentVariables": {
17+
"ASPNETCORE_ENVIRONMENT": "Development"
18+
}
19+
}
20+
}
21+
}

examples/dotnet/dotnet-03-simple-chatbot/appsettings.json

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,17 @@
44
// Unique ID of the service. Semantic Workbench will store this event to identify the server
55
// so you should keep the value fixed to match the conversations tracked across service restarts.
66
"ConnectorId": "AgentExample03",
7-
// The endpoint of your service, where semantic workbench will send communications too.
8-
// This should match hostname, port, protocol and path of the web service. You can use
9-
// this also to route semantic workbench through a proxy or a gateway if needed.
10-
"ConnectorEndpoint": "http://127.0.0.1:9103/myagents",
11-
// Semantic Workbench endpoint.
7+
// The host where the connector receives requests sent by the workbench.
8+
// Locally, this is usually "http://127.0.0.1:<some port>"
9+
// On Azure, this will be something like "https://contoso.azurewebsites.net"
10+
// Leave this setting empty to use "127.0.0.1" and autodetect the port in use.
11+
// You can use an env var to set this value, e.g. Workbench__ConnectorHost=https://contoso.azurewebsites.net
12+
"ConnectorHost": "",
13+
// This is the prefix of all the endpoints exposed by the connector
14+
"ConnectorApiPrefix": "/myagents",
15+
// Semantic Workbench backend endpoint.
16+
// The connector connects to this workbench endpoint to register its presence.
17+
// The workbench connects back to the connector to send events (see ConnectorHost and ConnectorApiPrefix).
1218
"WorkbenchEndpoint": "http://127.0.0.1:3000",
1319
// Name of your agent service
1420
"ConnectorName": ".NET Multi Agent Service",
@@ -48,18 +54,6 @@
4854
"Endpoint": "https://api.openai.com/v1/",
4955
"ApiKey": "sk-..."
5056
},
51-
// Web service settings
52-
"AllowedHosts": "*",
53-
"Kestrel": {
54-
"Endpoints": {
55-
"Http": {
56-
"Url": "http://*:9103"
57-
}
58-
// "Https": {
59-
// "Url": "https://*:19103
60-
// }
61-
}
62-
},
6357
// .NET Logger settings
6458
"Logging": {
6559
"LogLevel": {

examples/dotnet/dotnet-03-simple-chatbot/dotnet-03-simple-chatbot.csproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,9 @@
66
<Nullable>enable</Nullable>
77
<RootNamespace>AgentExample</RootNamespace>
88
<PackageId>AgentExample</PackageId>
9-
<NoWarn>$(NoWarn);SKEXP0010;CA1861;</NoWarn>
9+
<NoWarn>$(NoWarn);SKEXP0010;CA1861;CA1515;IDE0290;CA1031;CA1812;</NoWarn>
1010
</PropertyGroup>
1111

12-
<ItemGroup>
13-
<PackageReference Include="Microsoft.SemanticWorkbench.Connector" Version="0.3.241104.1" />
14-
</ItemGroup>
15-
1612
<ItemGroup>
1713
<PackageReference Include="Azure.AI.ContentSafety" Version="1.0.0" />
1814
<PackageReference Include="Azure.Identity" Version="1.13.1" />
@@ -34,15 +30,15 @@
3430
<PrivateAssets>all</PrivateAssets>
3531
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3632
</PackageReference>
37-
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">
33+
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0">
3834
<PrivateAssets>all</PrivateAssets>
3935
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4036
</PackageReference>
4137
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0">
4238
<PrivateAssets>all</PrivateAssets>
4339
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4440
</PackageReference>
45-
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.11.20">
41+
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.12.19">
4642
<PrivateAssets>all</PrivateAssets>
4743
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4844
</PackageReference>
@@ -60,4 +56,8 @@
6056
</PackageReference>
6157
</ItemGroup>
6258

59+
<ItemGroup>
60+
<ProjectReference Include="..\..\..\libraries\dotnet\WorkbenchConnector\WorkbenchConnector.csproj" />
61+
</ItemGroup>
62+
6363
</Project>

0 commit comments

Comments
 (0)