Skip to content

Commit 60af59b

Browse files
tommasodotNETCopilotrogerbarretoCopilot
authored
.NET: Features/3768-devui-aspire-integration (#3771)
* adds devui integration and samples * adds unit tests for devui integration * fix: correct formatting of copyright notice in unit test files * fixes formatting issues * fixes build for net8 target * fixes formatting errors on test apphost * adds copyright notice to multiple files and removes unnecessary using directives * Update dotnet/aspire-integration/Aspire.Hosting.AgentFramework.DevUI/DevUIAggregatorHostedService.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/aspire-integration/Aspire.Hosting.AgentFramework.DevUI/DevUIAggregatorHostedService.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/tests/Aspire.Hosting.AgentFramework.DevUI.UnitTests/Aspire.Hosting.AgentFramework.DevUI.UnitTests.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/samples/DevUIIntegration/DevUIIntegration.AppHost/DevUIIntegration.AppHost.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/aspire-integration/Aspire.Hosting.AgentFramework.DevUI/DevUIAggregatorHostedService.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Refactor project files to use TargetFrameworks instead of TargetFramework for multi-targeting support; add optional port property to DevUIResource class. * Add unit tests for DevUIAggregatorHostedService; refactor project files for TargetFrameworks support * Refactor project files to use TargetFrameworks for multi-targeting support in DevUIIntegration samples * Remove unnecessary using directive for Aspire.Hosting in DevUIAggregatorHostedServiceTests * merge * fixes Conversation routing for non-first backends * add documentation for devui integration sample * update project references in solution file for improved integration * fixes package versions post merge * move Aspire.Hosting.AgentFramework.DevUI to dotnet/src Move the project from aspire-integration/ to src/ to be consistent with the location of all other projects in the repo. * move DevUI sample to samples/05-end-to-end/DevUIAspireIntegration Move the sample from samples/DevUIIntegration/ to samples/05-end-to-end/DevUIAspireIntegration/ to match the location of other end-to-end samples. * remove unnecessary net472 framework condition from sample csproj files These projects only target net10.0, so the Condition="'$(TargetFramework)' != 'net472'" on ItemGroup is unnecessary. * update sample model name from gpt-4.1 to gpt-5.4 Use a more up-to-date model name in the DevUI integration samples. * Revert "remove unnecessary net472 framework condition from sample csproj files" This reverts commit 08cf412. * fix: use TargetFrameworks to override multi-targeting from Directory.Build.props The parent Directory.Build.props sets TargetFrameworks to net10.0;net472, which overrides the singular TargetFramework in each csproj. Use the plural TargetFrameworks property set to net10.0 only to properly override it, and remove the now-unnecessary net472 condition on ItemGroup. * fixes aspire config * fix: update Microsoft.Extensions packages to version 10.0.1 * Address Copilot review feedback on DevUI Aspire integration - Fix request body dropping in ProxyConversationsAsync: always read the body when ContentLength > 0 before routing, then pass it through to all proxy calls (previously null was passed when backend was resolved from query param or conversation map) - Fix resource leak: dispose aggregator on startup failure in catch block - Fix XML docs: accurately describe embedded resource serving behavior - Remove reflection from DevUIResourceTests (InternalsVisibleTo already set) - Make sensitive telemetry conditional on Development environment in samples Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: update chat client version to gpt41 in both EditorAgent and WriterAgent --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 69894ed commit 60af59b

33 files changed

Lines changed: 3225 additions & 17 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,4 @@ python/dotnet-ref
235235

236236
# Generated filtered solution files (created by eng/scripts/New-FilteredSolution.ps1)
237237
dotnet/filtered-*.slnx
238+
**/*.lscache

dotnet/Directory.Packages.props

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77
</PropertyGroup>
88
<PropertyGroup>
99
<!-- Aspire -->
10-
<AspireAppHostSdkVersion>13.0.2</AspireAppHostSdkVersion>
10+
<AspireAppHostSdkVersion>13.1.0</AspireAppHostSdkVersion>
1111
</PropertyGroup>
1212
<ItemGroup>
1313
<!-- Aspire.* -->
1414
<PackageVersion Include="Anthropic" Version="12.13.0" />
1515
<PackageVersion Include="Anthropic.Foundry" Version="0.5.0" />
16+
<PackageVersion Include="Aspire.Hosting" Version="$(AspireAppHostSdkVersion)" />
1617
<PackageVersion Include="Aspire.Azure.AI.OpenAI" Version="13.0.0-preview.1.25560.3" />
18+
<PackageVersion Include="Aspire.Azure.AI.Inference" Version="13.1.0-preview.1.25616.3" />
19+
<PackageVersion Include="Aspire.Hosting.Azure.AIFoundry" Version="13.1.0-preview.1.25616.3" />
1720
<PackageVersion Include="Aspire.Hosting.AppHost" Version="$(AspireAppHostSdkVersion)" />
1821
<PackageVersion Include="Aspire.Hosting.Azure.CognitiveServices" Version="$(AspireAppHostSdkVersion)" />
1922
<PackageVersion Include="Aspire.Microsoft.Azure.Cosmos" Version="$(AspireAppHostSdkVersion)" />
@@ -48,12 +51,12 @@
4851
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.6.3" />
4952
<PackageVersion Include="System.Net.Security" Version="4.3.2" />
5053
<!-- OpenTelemetry -->
51-
<PackageVersion Include="OpenTelemetry" Version="1.13.1" />
52-
<PackageVersion Include="OpenTelemetry.Api" Version="1.13.1" />
53-
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.13.1" />
54-
<PackageVersion Include="OpenTelemetry.Exporter.InMemory" Version="1.13.1" />
55-
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.13.1" />
56-
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.13.1" />
54+
<PackageVersion Include="OpenTelemetry" Version="1.14.0" />
55+
<PackageVersion Include="OpenTelemetry.Api" Version="1.14.0" />
56+
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.14.0" />
57+
<PackageVersion Include="OpenTelemetry.Exporter.InMemory" Version="1.14.0" />
58+
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.14.0" />
59+
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.14.0" />
5760
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.13.0" />
5861
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.13.0" />
5962
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.13.0" />
@@ -71,18 +74,18 @@
7174
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="10.5.0" />
7275
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />
7376
<PackageVersion Include="Microsoft.Extensions.Compliance.Abstractions" Version="10.5.0" />
74-
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.0" />
75-
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" />
76-
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.0" />
77-
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" />
78-
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.0" />
79-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
77+
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.1" />
78+
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.1" />
79+
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.1" />
80+
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.1" />
81+
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.1" />
82+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.1" />
8083
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.6" />
81-
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
84+
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.1" />
8285
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="10.0.0" />
83-
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.0" />
86+
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.1" />
8487
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.6" />
85-
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.0" />
88+
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.1" />
8689
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="10.0.0" />
8790
<PackageVersion Include="Microsoft.Extensions.VectorData.Abstractions" Version="9.7.0" />
8891
<!-- Vector Stores -->

dotnet/agent-framework-dotnet.slnx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
<BuildType Name="Publish" />
55
<BuildType Name="Release" />
66
</Configurations>
7+
<Folder Name="/src/Aspire.Hosting.AgentFramework.DevUI/">
8+
<Project Path="src/Aspire.Hosting.AgentFramework.DevUI/Aspire.Hosting.AgentFramework.DevUI.csproj" />
9+
</Folder>
710
<Folder Name="/Samples/">
811
<File Path="samples/AGENTS.md" />
912
<File Path="samples/README.md" />
@@ -37,6 +40,12 @@
3740
<Project Path="samples/02-agents/AgentProviders/Agent_With_OpenAIChatCompletion/Agent_With_OpenAIChatCompletion.csproj" />
3841
<Project Path="samples/02-agents/AgentProviders/Agent_With_OpenAIResponses/Agent_With_OpenAIResponses.csproj" />
3942
</Folder>
43+
<Folder Name="/Samples/05-end-to-end/DevUIAspireIntegration/">
44+
<Project Path="samples/05-end-to-end/DevUIAspireIntegration/DevUIIntegration.AppHost/DevUIIntegration.AppHost.csproj" />
45+
<Project Path="samples/05-end-to-end/DevUIAspireIntegration/DevUIIntegration.ServiceDefaults/DevUIIntegration.ServiceDefaults.csproj" />
46+
<Project Path="samples/05-end-to-end/DevUIAspireIntegration/EditorAgent/EditorAgent.csproj" />
47+
<Project Path="samples/05-end-to-end/DevUIAspireIntegration/WriterAgent/WriterAgent.csproj" />
48+
</Folder>
4049
<Folder Name="/Samples/02-agents/Agents/">
4150
<File Path="samples/02-agents/Agents/README.md" />
4251
<Project Path="samples/02-agents/Agents/Agent_Step01_UsingFunctionToolsWithApprovals/Agent_Step01_UsingFunctionToolsWithApprovals.csproj" />
@@ -542,6 +551,7 @@
542551
<Project Path="tests/OpenAIResponse.IntegrationTests/OpenAIResponse.IntegrationTests.csproj" />
543552
</Folder>
544553
<Folder Name="/Tests/UnitTests/">
554+
<Project Path="tests/Aspire.Hosting.AgentFramework.DevUI.UnitTests/Aspire.Hosting.AgentFramework.DevUI.UnitTests.csproj" />
545555
<Project Path="tests/Microsoft.Agents.AI.A2A.UnitTests/Microsoft.Agents.AI.A2A.UnitTests.csproj" />
546556
<Project Path="tests/Microsoft.Agents.AI.Abstractions.UnitTests/Microsoft.Agents.AI.Abstractions.UnitTests.csproj" />
547557
<Project Path="tests/Microsoft.Agents.AI.AGUI.UnitTests/Microsoft.Agents.AI.AGUI.UnitTests.csproj" />

dotnet/agent-framework-release.slnf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
"src\\Microsoft.Agents.AI.Workflows.Declarative\\Microsoft.Agents.AI.Workflows.Declarative.csproj",
2929
"src\\Microsoft.Agents.AI.Workflows.Generators\\Microsoft.Agents.AI.Workflows.Generators.csproj",
3030
"src\\Microsoft.Agents.AI.Workflows\\Microsoft.Agents.AI.Workflows.csproj",
31-
"src\\Microsoft.Agents.AI\\Microsoft.Agents.AI.csproj"
31+
"src\\Microsoft.Agents.AI\\Microsoft.Agents.AI.csproj",
32+
"src\\Aspire.Hosting.AgentFramework.DevUI\\Aspire.Hosting.AgentFramework.DevUI.csproj"
3233
]
3334
}
3435
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"appHostPath": "../DevUIIntegration.AppHost/DevUIIntegration.AppHost.csproj"
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
**/**/*.Development.json
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<Sdk Name="Aspire.AppHost.Sdk" Version="$(AspireAppHostSdkVersion)" />
4+
5+
<PropertyGroup>
6+
<OutputType>Exe</OutputType>
7+
<TargetFrameworks>net10.0</TargetFrameworks>
8+
<ImplicitUsings>enable</ImplicitUsings>
9+
<Nullable>enable</Nullable>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
</ItemGroup>
14+
15+
<ItemGroup>
16+
<PackageReference Include="Aspire.Hosting.AppHost" />
17+
</ItemGroup>
18+
19+
<ItemGroup>
20+
<PackageReference Include="Aspire.Hosting.Azure.AIFoundry" />
21+
<PackageReference Include="OpenAI" />
22+
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.OpenAI\Microsoft.Agents.AI.OpenAI.csproj" IsAspireProjectResource="false" />
23+
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.DevUI\Microsoft.Agents.AI.DevUI.csproj" IsAspireProjectResource="false" />
24+
<ProjectReference Include="..\..\..\..\src\Aspire.Hosting.AgentFramework.DevUI\Aspire.Hosting.AgentFramework.DevUI.csproj" IsAspireProjectResource="false" />
25+
<ProjectReference Include="..\WriterAgent\WriterAgent.csproj" />
26+
<ProjectReference Include="..\EditorAgent\EditorAgent.csproj" />
27+
</ItemGroup>
28+
29+
</Project>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
var builder = DistributedApplication.CreateBuilder(args);
4+
5+
var foundry = builder.AddAzureAIFoundry("foundry");
6+
7+
// Comment the following lines to create a new Foundry instance instead of connecting to an existing one. If creating a new instance, the DevUI resource will wait for the Foundry to be ready before starting, ensuring the DevUI frontend is available as soon as the app starts.
8+
var existingFoundryName = builder.AddParameter("existingFoundryName")
9+
.WithDescription("The name of the existing Azure Foundry resource.");
10+
var existingFoundryResourceGroup = builder.AddParameter("existingFoundryResourceGroup")
11+
.WithDescription("The resource group of the existing Azure Foundry resource.");
12+
foundry.AsExisting(existingFoundryName, existingFoundryResourceGroup);
13+
14+
// Add the writer agent service
15+
var writerAgent = builder.AddProject<Projects.WriterAgent>("writer-agent")
16+
.WithHttpHealthCheck("/health")
17+
.WithReference(foundry).WaitFor(foundry);
18+
19+
// Add the editor agent service
20+
var editorAgent = builder.AddProject<Projects.EditorAgent>("editor-agent")
21+
.WithHttpHealthCheck("/health")
22+
.WithReference(foundry).WaitFor(foundry);
23+
24+
// Add DevUI integration that aggregates agents from all agent services.
25+
// Agent metadata is declared here so backends don't need a /v1/entities endpoint.
26+
_ = builder.AddDevUI("devui")
27+
.WithAgentService(writerAgent, agents: [new("writer")]) // the name of the agent should match the agent declaration in WriterAgent/Program.cs
28+
.WithAgentService(editorAgent, agents: [new("editor")]) // the name of the agent should match the agent declaration in EditorAgent/Program.cs
29+
.WaitFor(writerAgent)
30+
.WaitFor(editorAgent);
31+
32+
builder.Build().Run();
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"$schema": "http://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"https": {
5+
"commandName": "Project",
6+
"dotnetRunMessages": true,
7+
"launchBrowser": true,
8+
"applicationUrl": "https://localhost:16500;http://localhost:16501",
9+
"environmentVariables": {
10+
"ASPNETCORE_ENVIRONMENT": "Development",
11+
"DOTNET_ENVIRONMENT": "Development",
12+
"ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:17250",
13+
"ASPIRE_DASHBOARD_MCP_ENDPOINT_URL": "https://localhost:18100",
14+
"ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:17250",
15+
"ASPIRE_SHOW_DASHBOARD_RESOURCES": "true"
16+
}
17+
},
18+
"http": {
19+
"commandName": "Project",
20+
"dotnetRunMessages": true,
21+
"launchBrowser": true,
22+
"applicationUrl": "http://localhost:16501",
23+
"environmentVariables": {
24+
"ASPNETCORE_ENVIRONMENT": "Development",
25+
"DOTNET_ENVIRONMENT": "Development",
26+
"ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:17251",
27+
"ASPIRE_DASHBOARD_MCP_ENDPOINT_URL": "http://localhost:18101",
28+
"ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:17251",
29+
"ASPIRE_SHOW_DASHBOARD_RESOURCES": "true",
30+
"ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true"
31+
}
32+
}
33+
}
34+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"Azure": {
3+
"TenantId": "",
4+
"SubscriptionId": "",
5+
"AllowResourceGroupCreation": true,
6+
"ResourceGroup": "",
7+
"Location": "",
8+
"CredentialSource": "AzureCli"
9+
},
10+
"Parameters": {
11+
"existingFoundryName": "",
12+
"existingFoundryResourceGroup": ""
13+
}
14+
}

0 commit comments

Comments
 (0)