-
Notifications
You must be signed in to change notification settings - Fork 1.1k
.NET: Add AIAgent implementation for GitHub Copilot SDK #3395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
41 commits
Select commit
Hold shift + click to select a range
4c55bd9
Initial plan
Copilot 5a39df4
Add GitHub Copilot SDK AIAgent implementation with tests
Copilot 9178095
Add projects to solution and fix sample imports
Copilot b365707
Improve pragma comment clarity in GithubCopilotAgentThread
Copilot 44f3ab6
Address PR feedback: internal constructor/setter, remove CopilotClien…
Copilot 09d526f
Merge branch 'main' into copilot/add-aiagent-implementation
westey-m 52ba627
Add ownsClient parameter to allow caller control over client disposal
Copilot c348e7d
Fix unit tests by removing await using to avoid StreamJsonRpc disposa…
Copilot b45d14a
Fix file encoding: add UTF-8 BOM to Program.cs
Copilot c3f94cb
Fix dotnet-format errors: UTF-8 BOM, remove unused logger, add this q…
Copilot 97f4457
Fix test file encoding and remove redundant cast
Copilot 4ae34d3
Merge branch 'main' into copilot/add-aiagent-implementation
westey-m a5b7aeb
Add AsAIAgent extension methods for CopilotClient with tests
Copilot 02e6c0e
Merge branch 'main' into copilot/add-aiagent-implementation
dmytrostruk c643abc
Remove IL suppressions, use TryComplete for channel writer, remove TC…
Copilot 7f82795
Keep session alive across calls, add tools overload, add tests
Copilot 4d781b8
Revert session persistence changes - sessions dispose after each call
Copilot 8501a5d
Add CreatedAt property mapping using DateTimeOffset.UtcNow
Copilot a8dd828
Add DataContent handling via temp files and attachments
Copilot e28bb5e
Fix formatting: remove extra indentation, simplify Path references, r…
Copilot 6836ca1
Refactor: extract helper methods to reduce duplication in DataContent…
Copilot 9172cac
Merge branch 'main' into copilot/add-aiagent-implementation
dmytrostruk 67d7b11
Updated sample and session config mapping
dmytrostruk efef054
Added instructions parameter
dmytrostruk 7c9d36c
Updated README
dmytrostruk 5b07a21
Address PR feedback: reorder params, optimize dictionary, update pref…
Copilot 8ec23a1
Remove StreamJsonRpc reference from sample project
Copilot 251ad7c
Fix parameter ordering: tools now after description, rename to s_medi…
Copilot ced7299
Fix streaming prompt: change Python to C# for Fibonacci example
Copilot 396d0aa
Handle all SDK events, add UsageContent support, fix model name, remo…
Copilot 105ce0b
Merge branch 'main' into copilot/add-aiagent-implementation
dmytrostruk 1a38887
Merge branch 'main' into copilot/add-aiagent-implementation
dmytrostruk 77b50d7
Resolved build errors
dmytrostruk 9cb4c1f
Addressed comments
dmytrostruk 6e36901
Small fix
dmytrostruk 493536b
Addressed comment
dmytrostruk 50f7c47
Small fix
dmytrostruk 0ae50a6
Addressed comments
dmytrostruk c9b4753
Added integration tests
dmytrostruk 6ccde66
Small update
dmytrostruk 6803d49
Merge branch 'main' into copilot/add-aiagent-implementation
dmytrostruk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
...es/GettingStarted/AgentProviders/Agent_With_GithubCopilot/Agent_With_GithubCopilot.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFrameworks>net10.0</TargetFrameworks> | ||
|
|
||
| <Nullable>enable</Nullable> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="GitHub.Copilot.SDK" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.GithubCopilot\Microsoft.Agents.AI.GithubCopilot.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> |
51 changes: 51 additions & 0 deletions
51
dotnet/samples/GettingStarted/AgentProviders/Agent_With_GithubCopilot/Program.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
|
|
||
| // This sample shows how to create a GitHub Copilot agent with shell command permissions. | ||
|
|
||
| using GitHub.Copilot.SDK; | ||
| using Microsoft.Agents.AI; | ||
|
|
||
| // Permission handler that prompts the user for approval | ||
| static Task<PermissionRequestResult> PromptPermission(PermissionRequest request, PermissionInvocation invocation) | ||
| { | ||
| Console.WriteLine($"\n[Permission Request: {request.Kind}]"); | ||
| Console.Write("Approve? (y/n): "); | ||
|
|
||
| string? input = Console.ReadLine()?.Trim().ToUpperInvariant(); | ||
| string kind = input is "Y" or "YES" ? "approved" : "denied-interactively-by-user"; | ||
|
|
||
| return Task.FromResult(new PermissionRequestResult { Kind = kind }); | ||
| } | ||
|
|
||
| // Create and start a Copilot client | ||
| await using CopilotClient copilotClient = new(); | ||
| await copilotClient.StartAsync(); | ||
|
|
||
| // Create an agent with a session config that enables permission handling | ||
| SessionConfig sessionConfig = new() | ||
| { | ||
| OnPermissionRequest = PromptPermission, | ||
dmytrostruk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| AIAgent agent = copilotClient.AsAIAgent(sessionConfig, ownsClient: true); | ||
|
|
||
| // Toggle between streaming and non-streaming modes | ||
| bool useStreaming = true; | ||
|
|
||
| string prompt = "List all files in the current directory"; | ||
| Console.WriteLine($"User: {prompt}\n"); | ||
|
|
||
| if (useStreaming) | ||
| { | ||
| await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(prompt)) | ||
| { | ||
| Console.Write(update); | ||
| } | ||
|
|
||
| Console.WriteLine(); | ||
| } | ||
| else | ||
| { | ||
| AgentResponse response = await agent.RunAsync(prompt); | ||
| Console.WriteLine(response); | ||
| } | ||
76 changes: 76 additions & 0 deletions
76
dotnet/samples/GettingStarted/AgentProviders/Agent_With_GithubCopilot/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| # Prerequisites | ||
westey-m marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| > **⚠️ WARNING: Container Recommendation** | ||
| > | ||
| > GitHub Copilot can execute tools and commands that may interact with your system. For safety, it is strongly recommended to run this sample in a containerized environment (e.g., Docker, Dev Container) to avoid unintended consequences to your machine. | ||
|
|
||
| Before you begin, ensure you have the following prerequisites: | ||
|
|
||
| - .NET 10 SDK or later | ||
| - GitHub Copilot CLI installed and available in your PATH (or provide a custom path) | ||
|
|
||
| ## Setting up GitHub Copilot CLI | ||
|
|
||
| To use this sample, you need to have the GitHub Copilot CLI installed. You can install it by following the instructions at: | ||
| https://github.com/github/copilot-sdk | ||
|
|
||
| Once installed, ensure the `copilot` command is available in your PATH, or configure a custom path using `CopilotClientOptions`. | ||
|
|
||
| ## Running the Sample | ||
|
|
||
| No additional environment variables are required if using default configuration. The sample will: | ||
|
|
||
| 1. Create a GitHub Copilot client with default options | ||
| 2. Create an AI agent using the Copilot SDK | ||
| 3. Send a message to the agent | ||
| 4. Display the response | ||
|
|
||
| Run the sample: | ||
|
|
||
| ```powershell | ||
| dotnet run | ||
| ``` | ||
|
|
||
| ## Advanced Usage | ||
|
|
||
| You can customize the agent by providing additional configuration: | ||
|
|
||
| ```csharp | ||
| using GitHub.Copilot.SDK; | ||
| using Microsoft.Agents.AI; | ||
|
|
||
| // Create and start a Copilot client | ||
| await using CopilotClient copilotClient = new(); | ||
| await copilotClient.StartAsync(); | ||
|
|
||
| // Create session configuration with specific model | ||
| SessionConfig sessionConfig = new() | ||
| { | ||
| Model = "claude-opus-4.5", | ||
| Streaming = false | ||
| }; | ||
|
|
||
| // Create an agent with custom configuration using the extension method | ||
| AIAgent agent = copilotClient.AsAIAgent( | ||
| sessionConfig, | ||
| ownsClient: true, | ||
| id: "my-copilot-agent", | ||
| name: "My Copilot Assistant", | ||
| description: "A helpful AI assistant powered by GitHub Copilot" | ||
| ); | ||
|
|
||
| // Use the agent - ask it to write code for us | ||
| AgentResponse response = await agent.RunAsync("Write a small .NET 10 C# hello world single file application"); | ||
| Console.WriteLine(response); | ||
| ``` | ||
|
|
||
| ## Streaming Responses | ||
|
|
||
| To get streaming responses: | ||
|
|
||
| ```csharp | ||
| await foreach (AgentResponseUpdate update in agent.RunStreamingAsync("Write a C# function to calculate Fibonacci numbers")) | ||
| { | ||
| Console.Write(update.Text); | ||
| } | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
73 changes: 73 additions & 0 deletions
73
dotnet/src/Microsoft.Agents.AI.GithubCopilot/CopilotClientExtensions.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
|
|
||
| using System.Collections.Generic; | ||
| using Microsoft.Agents.AI; | ||
| using Microsoft.Agents.AI.GithubCopilot; | ||
| using Microsoft.Extensions.AI; | ||
| using Microsoft.Shared.Diagnostics; | ||
|
|
||
| namespace GitHub.Copilot.SDK; | ||
|
|
||
| /// <summary> | ||
| /// Provides extension methods for <see cref="CopilotClient"/> | ||
| /// to simplify the creation of GitHub Copilot agents. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// These extensions bridge the gap between GitHub Copilot SDK client objects | ||
| /// and the Microsoft Agent Framework. | ||
| /// <para> | ||
| /// They allow developers to easily create AI agents that can interact | ||
| /// with GitHub Copilot by handling the conversion from Copilot clients to | ||
| /// <see cref="GithubCopilotAgent"/> instances that implement the <see cref="AIAgent"/> interface. | ||
| /// </para> | ||
| /// </remarks> | ||
| public static class CopilotClientExtensions | ||
| { | ||
| /// <summary> | ||
| /// Retrieves an instance of <see cref="AIAgent"/> for a GitHub Copilot client. | ||
| /// </summary> | ||
| /// <param name="client">The <see cref="CopilotClient"/> to use for the agent.</param> | ||
| /// <param name="sessionConfig">Optional session configuration for the agent.</param> | ||
| /// <param name="ownsClient">Whether the agent owns the client and should dispose it. Default is false.</param> | ||
| /// <param name="id">The unique identifier for the agent.</param> | ||
| /// <param name="name">The name of the agent.</param> | ||
| /// <param name="description">The description of the agent.</param> | ||
| /// <returns>An <see cref="AIAgent"/> instance backed by the GitHub Copilot client.</returns> | ||
| public static AIAgent AsAIAgent( | ||
| this CopilotClient client, | ||
| SessionConfig? sessionConfig = null, | ||
| bool ownsClient = false, | ||
| string? id = null, | ||
| string? name = null, | ||
| string? description = null) | ||
| { | ||
| Throw.IfNull(client); | ||
|
|
||
| return new GithubCopilotAgent(client, sessionConfig, ownsClient, id, name, description); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Retrieves an instance of <see cref="AIAgent"/> for a GitHub Copilot client. | ||
| /// </summary> | ||
| /// <param name="client">The <see cref="CopilotClient"/> to use for the agent.</param> | ||
| /// <param name="ownsClient">Whether the agent owns the client and should dispose it. Default is false.</param> | ||
| /// <param name="id">The unique identifier for the agent.</param> | ||
| /// <param name="name">The name of the agent.</param> | ||
| /// <param name="description">The description of the agent.</param> | ||
| /// <param name="tools">The tools to make available to the agent.</param> | ||
| /// <param name="instructions">Optional instructions to append as a system message.</param> | ||
| /// <returns>An <see cref="AIAgent"/> instance backed by the GitHub Copilot client.</returns> | ||
| public static AIAgent AsAIAgent( | ||
| this CopilotClient client, | ||
| bool ownsClient = false, | ||
| string? id = null, | ||
| string? name = null, | ||
| string? description = null, | ||
| IList<AITool>? tools = null, | ||
| string? instructions = null) | ||
| { | ||
| Throw.IfNull(client); | ||
|
|
||
| return new GithubCopilotAgent(client, ownsClient, id, name, description, tools, instructions); | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.