Skip to content

Commit 3499c7a

Browse files
authored
.Net Agents - Introducing CopilotStudioAgent (#12372)
### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> Support _Copilot Studio Agents_ in the SK Agent Framework: `CopilotStudioAgent` ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> Implement `CopilotStudioAgent` with client factory and token handler. Includes "Action" and "Reasoning" content models. Both may be justified outside of use with `CopilotStudioAgent`. ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [X] The code builds clean without any errors or warnings - [X] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [X] All unit tests pass, and I have added new tests where possible - [X] I didn't break anyone 😄
1 parent 618169f commit 3499c7a

Some content is hidden

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

42 files changed

+1740
-69
lines changed

dotnet/Directory.Packages.props

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,14 @@
4040
<PackageVersion Include="Grpc.AspNetCore.Web" Version="2.70.0" />
4141
<PackageVersion Include="Grpc.Net.Client" Version="2.70.0" />
4242
<PackageVersion Include="Grpc.Tools" Version="2.71.0" />
43-
<PackageVersion Include="JmesPath.Net" Version="1.0.330" />
44-
<PackageVersion Include="JsonSchema.Net.Generation" Version="5.0.2" />
4543
<PackageVersion Include="Handlebars.Net.Helpers" Version="2.4.10" />
4644
<PackageVersion Include="Handlebars.Net" Version="2.1.6" />
4745
<PackageVersion Include="HtmlAgilityPack" Version="1.11.72" />
46+
<PackageVersion Include="JmesPath.Net" Version="1.0.330" />
4847
<PackageVersion Include="JsonSchema.Net" Version="7.3.4" />
48+
<PackageVersion Include="JsonSchema.Net.Generation" Version="5.0.2" />
4949
<PackageVersion Include="Markdig" Version="0.40.0" />
50+
<PackageVersion Include="Microsoft.Agents.CopilotStudio.Client" Version="1.1.107-beta" />
5051
<PackageVersion Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
5152
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.13" />
5253
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.14" />
@@ -65,6 +66,7 @@
6566
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.13.0" />
6667
<PackageVersion Include="Microsoft.Bcl.TimeProvider" Version="8.0.1" />
6768
<PackageVersion Include="Microsoft.Identity.Client" Version="4.67.2" />
69+
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.67.2" />
6870
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.5.1" />
6971
<PackageVersion Include="Microsoft.ML.OnnxRuntime" Version="1.21.0" />
7072
<PackageVersion Include="Microsoft.ML.Tokenizers.Data.Cl100kBase" Version="1.0.1" />
@@ -147,7 +149,6 @@
147149
<PackageVersion Include="DuckDB.NET.Data" Version="1.1.3" />
148150
<PackageVersion Include="MongoDB.Driver" Version="2.30.0" />
149151
<PackageVersion Include="Microsoft.Graph" Version="4.51.0" />
150-
<PackageVersion Include="Microsoft.Identity.Client.Extensions.Msal" Version="4.67.2" />
151152
<PackageVersion Include="Microsoft.OpenApi" Version="1.6.23" />
152153
<PackageVersion Include="Microsoft.OpenApi.Readers" Version="1.6.23" />
153154
<PackageVersion Include="Microsoft.OpenApi.ApiManifest" Version="0.5.6-preview" />

dotnet/SK-dotnet.sln

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Agents.Orchestration", "src
549549
EndProject
550550
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Agents.Magentic", "src\Agents\Magentic\Agents.Magentic.csproj", "{38059FCB-2CD7-C0DE-AE71-DA4D0245ECC7}"
551551
EndProject
552+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Agents.CopilotStudio", "src\Agents\Copilot\Agents.CopilotStudio.csproj", "{84BA9026-E05E-9B6A-C177-C04BDAA1714F}"
553+
EndProject
552554
Global
553555
GlobalSection(SolutionConfigurationPlatforms) = preSolution
554556
Debug|Any CPU = Debug|Any CPU
@@ -1510,6 +1512,12 @@ Global
15101512
{38059FCB-2CD7-C0DE-AE71-DA4D0245ECC7}.Publish|Any CPU.Build.0 = Publish|Any CPU
15111513
{38059FCB-2CD7-C0DE-AE71-DA4D0245ECC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
15121514
{38059FCB-2CD7-C0DE-AE71-DA4D0245ECC7}.Release|Any CPU.Build.0 = Release|Any CPU
1515+
{84BA9026-E05E-9B6A-C177-C04BDAA1714F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1516+
{84BA9026-E05E-9B6A-C177-C04BDAA1714F}.Debug|Any CPU.Build.0 = Debug|Any CPU
1517+
{84BA9026-E05E-9B6A-C177-C04BDAA1714F}.Publish|Any CPU.ActiveCfg = Publish|Any CPU
1518+
{84BA9026-E05E-9B6A-C177-C04BDAA1714F}.Publish|Any CPU.Build.0 = Publish|Any CPU
1519+
{84BA9026-E05E-9B6A-C177-C04BDAA1714F}.Release|Any CPU.ActiveCfg = Release|Any CPU
1520+
{84BA9026-E05E-9B6A-C177-C04BDAA1714F}.Release|Any CPU.Build.0 = Release|Any CPU
15131521
EndGlobalSection
15141522
GlobalSection(SolutionProperties) = preSolution
15151523
HideSolutionNode = FALSE
@@ -1714,6 +1722,7 @@ Global
17141722
{AAC7B5E8-CC4E-49D0-AF6A-2B4F7B43BD84} = {5A7028A7-4DDF-4E4F-84A9-37CE8F8D7E89}
17151723
{D1A02387-FA60-22F8-C2ED-4676568B6CC3} = {6823CD5E-2ABE-41EB-B865-F86EC13F0CF9}
17161724
{38059FCB-2CD7-C0DE-AE71-DA4D0245ECC7} = {6823CD5E-2ABE-41EB-B865-F86EC13F0CF9}
1725+
{84BA9026-E05E-9B6A-C177-C04BDAA1714F} = {6823CD5E-2ABE-41EB-B865-F86EC13F0CF9}
17171726
EndGlobalSection
17181727
GlobalSection(ExtensibilityGlobals) = postSolution
17191728
SolutionGuid = {FBDC56A3-86AD-4323-AA0F-201E59123B83}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using Microsoft.Agents.CopilotStudio.Client;
4+
using Microsoft.SemanticKernel;
5+
using Microsoft.SemanticKernel.Agents.Copilot;
6+
using Microsoft.SemanticKernel.ChatCompletion;
7+
8+
namespace GettingStarted.CopilotStudioAgents;
9+
10+
/// <summary>
11+
/// Demonstrates how to use the <see cref="CopilotStudioAgent"/> to interact with a Copilot Agent service.
12+
/// This sample shows how to create a CopilotStudioAgent, send user messages, and display the agent's responses.
13+
/// </summary>
14+
public sealed class Step01_CopilotStudioAgent(ITestOutputHelper output) : BaseAgentsTest(output)
15+
{
16+
[Fact]
17+
public async Task UseCopilotStudioAgent()
18+
{
19+
CopilotStudioConnectionSettings settings = new(TestConfiguration.GetSection(nameof(CopilotStudioAgent)));
20+
CopilotClient client = CopilotStudioAgent.CreateClient(settings);
21+
CopilotStudioAgent agent = new(client);
22+
23+
await InvokeAgentAsync("Why is the sky blue?");
24+
await InvokeAgentAsync("What is the speed of light?");
25+
26+
// Local function to invoke agent and display the response.
27+
async Task InvokeAgentAsync(string input)
28+
{
29+
Console.WriteLine($"\n# {AuthorRole.User}: {input}");
30+
31+
await foreach (ChatMessageContent response in agent.InvokeAsync(input))
32+
{
33+
WriteAgentChatMessage(response);
34+
}
35+
}
36+
}
37+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using Microsoft.Agents.CopilotStudio.Client;
4+
using Microsoft.SemanticKernel;
5+
using Microsoft.SemanticKernel.Agents.Copilot;
6+
using Microsoft.SemanticKernel.ChatCompletion;
7+
8+
namespace GettingStarted.CopilotStudioAgents;
9+
10+
/// <summary>
11+
/// Demonstrates how to use a <see cref="CopilotStudioAgent"/> with a persistent <see cref="CopilotStudioAgentThread"/>
12+
/// to maintain conversation context across multiple user interactions. This sample shows how to send messages to the agent,
13+
/// receive responses, and reset the conversation thread.
14+
/// </summary>
15+
public sealed class Step02_CopilotStudioAgent_Threads(ITestOutputHelper output) : BaseAgentsTest(output)
16+
{
17+
[Fact]
18+
public async Task UseCopilotStudioAgentThread()
19+
{
20+
CopilotStudioConnectionSettings settings = new(TestConfiguration.GetSection(nameof(CopilotStudioAgent)));
21+
CopilotClient client = CopilotStudioAgent.CreateClient(settings);
22+
CopilotStudioAgent agent = new(client);
23+
CopilotStudioAgentThread thread = new(client);
24+
25+
await InvokeAgentAsync("Hello! Who are you? My name is John Doe.");
26+
await InvokeAgentAsync("What is the speed of light?");
27+
await InvokeAgentAsync("What did I just ask?");
28+
await InvokeAgentAsync("What is my name?");
29+
await InvokeAgentAsync("RESET");
30+
await InvokeAgentAsync("Yes");
31+
await InvokeAgentAsync("What is my name?");
32+
33+
// Local function to invoke agent and display the response.
34+
async Task InvokeAgentAsync(string input)
35+
{
36+
Console.WriteLine($"\n# {AuthorRole.User}: {input}");
37+
38+
await foreach (ChatMessageContent response in agent.InvokeAsync(input, thread))
39+
{
40+
WriteAgentChatMessage(response);
41+
}
42+
}
43+
}
44+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft. All rights reserved.
2+
3+
using Microsoft.Agents.CopilotStudio.Client;
4+
using Microsoft.SemanticKernel;
5+
using Microsoft.SemanticKernel.Agents.Copilot;
6+
using Microsoft.SemanticKernel.ChatCompletion;
7+
8+
namespace GettingStarted.CopilotStudioAgents;
9+
10+
/// <summary>
11+
/// Demonstrates how to use a Copilot Studio Agent with a persistent conversation thread
12+
/// to perform web search queries and retrieve responses in a .NET test scenario.
13+
/// </summary>
14+
/// <remarks>
15+
/// In Copilot Studio, for the specified agent, you must enable the "Web Search" capability.
16+
/// If not already enabled, make sure to(re-)publish the agent so the changes take effect.
17+
/// </remarks>
18+
public sealed class Step03_CopilotStudioAgent_WebSearch(ITestOutputHelper output) : BaseAgentsTest(output)
19+
{
20+
[Fact]
21+
public async Task UseCopilotStudioAgentThread()
22+
{
23+
CopilotStudioConnectionSettings settings = new(TestConfiguration.GetSection(nameof(CopilotStudioAgent)));
24+
CopilotClient client = CopilotStudioAgent.CreateClient(settings);
25+
CopilotStudioAgent agent = new(client);
26+
CopilotStudioAgentThread thread = new(client);
27+
28+
await InvokeAgentAsync("Which team won the 2025 NCAA Basketball championship?");
29+
await InvokeAgentAsync("What was the final score?");
30+
31+
// Local function to invoke agent and display the response.
32+
async Task InvokeAgentAsync(string input)
33+
{
34+
Console.WriteLine($"\n# {AuthorRole.User}: {input}");
35+
36+
await foreach (ChatMessageContent response in agent.InvokeAsync(input, thread))
37+
{
38+
WriteAgentChatMessage(response);
39+
}
40+
}
41+
}
42+
}

dotnet/samples/GettingStartedWithAgents/GettingStartedWithAgents.csproj

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<IsTestProject>true</IsTestProject>
1010
<RootNamespace></RootNamespace>
1111
<!-- Suppress: "Declare types in namespaces", "Require ConfigureAwait", "Experimental" -->
12-
<NoWarn>$(NoWarn);IDE1006;IDE0009;CS8618;CA1051;CA1050;CA1707;CA1054;CA2007;CA5394;VSTHRD111;CS1591;NU1605;RCS1110;RCS1243;SKEXP0001;SKEXP0010;SKEXP0020;SKEXP0040;SKEXP0050;SKEXP0060;SKEXP0070;SKEXP0101;SKEXP0110;OPENAI001</NoWarn>
12+
<NoWarn>$(NoWarn);NU1008;CS8618,IDE0009,IDE1006,CA1051,CA1050,CA1707,CA1054,CA2007,VSTHRD111,CS1591,RCS1110,RCS1243,CA5394,SKEXP0001,SKEXP0010,SKEXP0040,SKEXP0050,SKEXP0060,SKEXP0070,SKEXP0101,SKEXP0110,OPENAI001</NoWarn>
1313
<OutputType>Library</OutputType>
1414
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
1515
</PropertyGroup>
@@ -18,16 +18,16 @@
1818
<PackageReference Include="Azure.AI.Projects" />
1919
<PackageReference Include="Azure.Identity" />
2020
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" />
21-
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" />
22-
<PackageReference Include="Microsoft.Extensions.Configuration" />
23-
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" />
21+
<PackageReference Include="Microsoft.Extensions.Configuration" VersionOverride="9.0.1" />
22+
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" VersionOverride="9.0.1" />
2423
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
25-
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
26-
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" />
27-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
28-
<PackageReference Include="Microsoft.Extensions.Http" />
29-
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
30-
<PackageReference Include="Microsoft.Extensions.Logging" />
24+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" VersionOverride="9.0.1" />
25+
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" VersionOverride="9.0.1" />
26+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" VersionOverride="9.0.1" />
27+
<PackageReference Include="Microsoft.Extensions.Http" VersionOverride="9.0.1" />
28+
<PackageReference Include="Microsoft.Extensions.Http.Resilience" VersionOverride="9.1.0" />
29+
<PackageReference Include="Microsoft.Extensions.Logging" VersionOverride="9.0.1" />
30+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" VersionOverride="9.0.1" />
3131
<PackageReference Include="Microsoft.Extensions.Logging.Console" />
3232
<PackageReference Include="OpenTelemetry.Exporter.Console" />
3333
<PackageReference Include="coverlet.collector" />
@@ -44,9 +44,10 @@
4444

4545
<ItemGroup>
4646
<ProjectReference Include="..\..\src\Agents\AzureAI\Agents.AzureAI.csproj" />
47+
<ProjectReference Include="..\..\src\Agents\Bedrock\Agents.Bedrock.csproj" />
48+
<ProjectReference Include="..\..\src\Agents\Copilot\Agents.CopilotStudio.csproj" />
4749
<ProjectReference Include="..\..\src\Agents\Core\Agents.Core.csproj" />
4850
<ProjectReference Include="..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
49-
<ProjectReference Include="..\..\src\Agents\Bedrock\Agents.Bedrock.csproj" />
5051
<ProjectReference Include="..\..\src\Agents\Orchestration\Agents.Orchestration.csproj" />
5152
<ProjectReference Include="..\..\src\Agents\Magentic\Agents.Magentic.csproj" />
5253
<ProjectReference Include="..\..\src\Agents\Runtime\InProcess\Runtime.InProcess.csproj" />

0 commit comments

Comments
 (0)