.NET: Add GitHub Copilot BYOK sample (#7337)
* .NET: Add GitHub Copilot BYOK sample Demonstrates routing GitHubCopilotAgent requests through a custom OpenAI-compatible endpoint via SessionConfig.Provider instead of the default GitHub Copilot backend. * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Update dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> * Update dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> * .NET: Address remaining BYOK sample review feedback - Make the provider type configurable via BYOK_PROVIDER_TYPE (default "openai") instead of hardcoding "openai", since the sample already documents Azure/Anthropic support. - Stop calling the endpoint "OpenAI-compatible" everywhere; Anthropic isn't OpenAI-wire- compatible, so reword to "your own endpoint" and list the actual supported providers. - Move the "About BYOK" explainer to the top of the README so the term is introduced before it's used, and finish applying the WireApi/ModelId comment suggestions. - Reword the AgentProviders/README.md entry to match (not OpenAI-specific). * .NET: Fix UTF-8 BOM on BYOK sample Program.cs The repo's .editorconfig requires utf-8-bom for .cs files; check-format was failing because the new file was written without one. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
<Project Path="samples/02-agents/AgentProviders/custom/Agent_With_CustomImplementation/Agent_With_CustomImplementation.csproj" />
|
||||
<Project Path="samples/02-agents/AgentProviders/dapr/Agent_With_Dapr/Agent_With_Dapr.csproj" />
|
||||
<Project Path="samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot/Agent_With_GitHubCopilot.csproj" />
|
||||
<Project Path="samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Agent_With_GitHubCopilot_BYOK.csproj" />
|
||||
<Project Path="samples/02-agents/AgentProviders/google-gemini/Agent_With_GoogleGemini/Agent_With_GoogleGemini.csproj" />
|
||||
<Project Path="samples/02-agents/AgentProviders/ollama/Agent_With_Ollama/Agent_With_Ollama.csproj" />
|
||||
<Project Path="samples/02-agents/AgentProviders/onnx/Agent_With_ONNX/Agent_With_ONNX.csproj" />
|
||||
|
||||
@@ -836,6 +836,19 @@ internal static class AgentsSamples
|
||||
],
|
||||
},
|
||||
|
||||
new SampleDefinition
|
||||
{
|
||||
Name = "Agent_With_GitHubCopilot_BYOK",
|
||||
ProjectPath = "samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK",
|
||||
RequiredEnvironmentVariables = ["BYOK_BASE_URL", "BYOK_API_KEY"],
|
||||
OptionalEnvironmentVariables = ["BYOK_PROVIDER_TYPE", "BYOK_MODEL_ID"],
|
||||
ExpectedOutputDescription =
|
||||
[
|
||||
"The output should contain a user prompt and a response about the benefits of BYOK.",
|
||||
"The output should not contain error messages or stack traces.",
|
||||
],
|
||||
},
|
||||
|
||||
new SampleDefinition
|
||||
{
|
||||
Name = "Agent_With_GoogleGemini",
|
||||
|
||||
@@ -60,6 +60,7 @@ covering basics, function tools, structured output, middleware, MCP, code interp
|
||||
| Sample | Description |
|
||||
| --- | --- |
|
||||
| [GitHub Copilot](./github-copilot/Agent_With_GitHubCopilot/) | Create an AIAgent using GitHub Copilot SDK |
|
||||
| [GitHub Copilot BYOK](./github-copilot/Agent_With_GitHubCopilot_BYOK/) | Route GitHub Copilot agent requests through your own endpoint (Bring Your Own Key) |
|
||||
|
||||
### [Google Gemini](./google-gemini/)
|
||||
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net10.0</TargetFrameworks>
|
||||
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<NoWarn>$(NoWarn);GHCP001</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="GitHub.Copilot.SDK" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\..\src\Microsoft.Agents.AI.GitHub.Copilot\Microsoft.Agents.AI.GitHub.Copilot.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
// This sample shows how to configure a GitHub Copilot agent with BYOK (Bring Your Own Key),
|
||||
// routing requests through your own endpoint (OpenAI, Azure OpenAI, Anthropic, or an
|
||||
// OpenAI-compatible service such as vLLM/LiteLLM/Ollama) instead of the GitHub Copilot backend.
|
||||
//
|
||||
// SECURITY NOTE: BYOK uses static credentials (no automatic token refresh) and usage is tracked
|
||||
// by your provider rather than GitHub. Keep API keys out of source control; load them from
|
||||
// environment variables or a secret store, as shown here.
|
||||
|
||||
using GitHub.Copilot;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
string providerType = Environment.GetEnvironmentVariable("BYOK_PROVIDER_TYPE") ?? "openai";
|
||||
string baseUrl = Environment.GetEnvironmentVariable("BYOK_BASE_URL")
|
||||
?? throw new InvalidOperationException("The BYOK_BASE_URL environment variable is not set.");
|
||||
string apiKey = Environment.GetEnvironmentVariable("BYOK_API_KEY")
|
||||
?? throw new InvalidOperationException("The BYOK_API_KEY environment variable is not set.");
|
||||
string modelId = Environment.GetEnvironmentVariable("BYOK_MODEL_ID") ?? "gpt-4o";
|
||||
|
||||
// Create and start a Copilot client
|
||||
await using CopilotClient copilotClient = new();
|
||||
await copilotClient.StartAsync();
|
||||
|
||||
// Provider routes the session through a custom endpoint instead of the GitHub Copilot backend.
|
||||
// Type is "openai", "azure", or "anthropic". WireApi "completions" is the broadly compatible
|
||||
// choice; use "responses" for providers that support the OpenAI Responses API. BYOK also
|
||||
// requires Model to be set at the session level.
|
||||
SessionConfig sessionConfig = new()
|
||||
{
|
||||
Model = modelId,
|
||||
Provider = new ProviderConfig
|
||||
{
|
||||
Type = providerType,
|
||||
WireApi = "completions",
|
||||
BaseUrl = baseUrl,
|
||||
ApiKey = apiKey,
|
||||
ModelId = modelId,
|
||||
},
|
||||
};
|
||||
|
||||
AIAgent agent = copilotClient.AsAIAgent(sessionConfig, ownsClient: true);
|
||||
|
||||
string prompt = "What are the benefits of using your own API keys with an agent framework?";
|
||||
Console.WriteLine($"User: {prompt}\n");
|
||||
|
||||
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(prompt))
|
||||
{
|
||||
Console.Write(update);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
# About BYOK (Bring Your Own Key)
|
||||
|
||||
BYOK lets you route model requests through your own API keys and infrastructure instead of the
|
||||
GitHub Copilot backend — useful for enterprise deployments, custom hosting, or direct billing
|
||||
arrangements. See [GitHub's BYOK documentation](https://docs.github.com/en/copilot/how-tos/copilot-sdk/auth/byok)
|
||||
for the full list of supported providers and configuration options.
|
||||
|
||||
# Prerequisites
|
||||
|
||||
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)
|
||||
- An OpenAI, Azure OpenAI, Anthropic, or OpenAI-compatible endpoint and API key (e.g. vLLM,
|
||||
LiteLLM, or Ollama)
|
||||
|
||||
## 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
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `BYOK_PROVIDER_TYPE` | Provider type (`openai`, `azure`, `anthropic`) | `openai` |
|
||||
| `BYOK_BASE_URL` | Base URL of your provider endpoint | *(required)* |
|
||||
| `BYOK_API_KEY` | API key for that endpoint | *(required)* |
|
||||
| `BYOK_MODEL_ID` | Model name to request (e.g. "gpt-4o") | `gpt-4o` |
|
||||
|
||||
## Running the Sample
|
||||
|
||||
```powershell
|
||||
dotnet run
|
||||
```
|
||||
|
||||
The sample will:
|
||||
|
||||
1. Create a GitHub Copilot client with default options
|
||||
2. Configure a session with a `Provider` (BYOK) pointing at your own endpoint instead of the
|
||||
default GitHub Copilot backend
|
||||
3. Send a message to the agent
|
||||
4. Stream the response
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
```csharp
|
||||
using GitHub.Copilot;
|
||||
using Microsoft.Agents.AI;
|
||||
|
||||
await using CopilotClient copilotClient = new();
|
||||
await copilotClient.StartAsync();
|
||||
|
||||
SessionConfig sessionConfig = new()
|
||||
{
|
||||
// BYOK requires Model to also be set at the session level.
|
||||
Model = "gpt-4o",
|
||||
Provider = new ProviderConfig
|
||||
{
|
||||
Type = "azure", // or "openai", "anthropic"
|
||||
WireApi = "completions", // or "responses"
|
||||
BaseUrl = "https://api.example.com/v1",
|
||||
ApiKey = "your-api-key",
|
||||
ModelId = "your-model-id", // "deployment-name"
|
||||
},
|
||||
};
|
||||
|
||||
AIAgent agent = copilotClient.AsAIAgent(sessionConfig, ownsClient: true);
|
||||
AgentResponse response = await agent.RunAsync("Hello!");
|
||||
Console.WriteLine(response);
|
||||
```
|
||||
|
||||
> **Note:** BYOK uses static credentials only — dynamic token refresh is not automatic, and
|
||||
> model availability depends entirely on your provider's offerings. Usage is tracked through
|
||||
> your provider rather than GitHub.
|
||||
Reference in New Issue
Block a user