From 99e30b3e290d90222a4d56c99d7cb7c146c8d093 Mon Sep 17 00:00:00 2001 From: droideronline Date: Sun, 26 Jul 2026 23:17:20 +0530 Subject: [PATCH 1/6] .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. --- dotnet/agent-framework-dotnet.slnx | 1 + dotnet/eng/verify-samples/AgentsSamples.cs | 13 ++++ .../02-agents/AgentProviders/README.md | 1 + .../Agent_With_GitHubCopilot_BYOK.csproj | 20 +++++ .../Agent_With_GitHubCopilot_BYOK/Program.cs | 49 +++++++++++++ .../Agent_With_GitHubCopilot_BYOK/README.md | 73 +++++++++++++++++++ 6 files changed, 157 insertions(+) create mode 100644 dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Agent_With_GitHubCopilot_BYOK.csproj create mode 100644 dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs create mode 100644 dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md diff --git a/dotnet/agent-framework-dotnet.slnx b/dotnet/agent-framework-dotnet.slnx index 9cc20db18b..c3423c509a 100644 --- a/dotnet/agent-framework-dotnet.slnx +++ b/dotnet/agent-framework-dotnet.slnx @@ -31,6 +31,7 @@ + diff --git a/dotnet/eng/verify-samples/AgentsSamples.cs b/dotnet/eng/verify-samples/AgentsSamples.cs index 3e95524c07..85e8f74026 100644 --- a/dotnet/eng/verify-samples/AgentsSamples.cs +++ b/dotnet/eng/verify-samples/AgentsSamples.cs @@ -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_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", diff --git a/dotnet/samples/02-agents/AgentProviders/README.md b/dotnet/samples/02-agents/AgentProviders/README.md index 6592d7cdf0..00eb48dcec 100644 --- a/dotnet/samples/02-agents/AgentProviders/README.md +++ b/dotnet/samples/02-agents/AgentProviders/README.md @@ -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 OpenAI-compatible endpoint (Bring Your Own Key) | ### [Google Gemini](./google-gemini/) diff --git a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Agent_With_GitHubCopilot_BYOK.csproj b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Agent_With_GitHubCopilot_BYOK.csproj new file mode 100644 index 0000000000..f9e3c1f2ee --- /dev/null +++ b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Agent_With_GitHubCopilot_BYOK.csproj @@ -0,0 +1,20 @@ + + + + Exe + net10.0 + + enable + enable + $(NoWarn);GHCP001 + + + + + + + + + + + diff --git a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs new file mode 100644 index 0000000000..e12746bda6 --- /dev/null +++ b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs @@ -0,0 +1,49 @@ +// 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 OpenAI-compatible endpoint 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 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. +// 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 = "openai", + 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(); diff --git a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md new file mode 100644 index 0000000000..fcfe93b4b1 --- /dev/null +++ b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md @@ -0,0 +1,73 @@ +# 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-compatible endpoint and API key (OpenAI, Azure OpenAI, Anthropic, or a compatible + service such as 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_BASE_URL` | Base URL of your OpenAI-compatible 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 + +## 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. + +```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 = "openai", + WireApi = "completions", + BaseUrl = "https://api.example.com/v1", + ApiKey = "your-api-key", + ModelId = "gpt-4o", + }, +}; + +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. From adf12edf49d1621aabaa5b49aa419cd9a3271c70 Mon Sep 17 00:00:00 2001 From: Dineshsuriya D <43177361+droideronline@users.noreply.github.com> Date: Sun, 26 Jul 2026 23:28:27 +0530 Subject: [PATCH 2/6] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../github-copilot/Agent_With_GitHubCopilot_BYOK/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md index fcfe93b4b1..a007dad4c7 100644 --- a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md +++ b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md @@ -4,8 +4,7 @@ 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-compatible endpoint and API key (OpenAI, Azure OpenAI, Anthropic, or a compatible - service such as vLLM, LiteLLM, or Ollama) +- An OpenAI-compatible endpoint and API key (OpenAI, Azure OpenAI, or a compatible service such as vLLM, LiteLLM, or Ollama) ## Setting up GitHub Copilot CLI From 96ecbf2bfc6277d39d1e44c2c7085a05941d136e Mon Sep 17 00:00:00 2001 From: Dineshsuriya D <43177361+droideronline@users.noreply.github.com> Date: Mon, 27 Jul 2026 21:43:17 +0530 Subject: [PATCH 3/6] 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> --- .../github-copilot/Agent_With_GitHubCopilot_BYOK/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md index a007dad4c7..21e4745e0d 100644 --- a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md +++ b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md @@ -58,7 +58,7 @@ SessionConfig sessionConfig = new() WireApi = "completions", BaseUrl = "https://api.example.com/v1", ApiKey = "your-api-key", - ModelId = "gpt-4o", + ModelId = "your-model-id", }, }; From 55bb63ed2aa33a6e93d5795e9e3080bd642e1dca Mon Sep 17 00:00:00 2001 From: Dineshsuriya D <43177361+droideronline@users.noreply.github.com> Date: Mon, 27 Jul 2026 21:46:33 +0530 Subject: [PATCH 4/6] 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> --- .../github-copilot/Agent_With_GitHubCopilot_BYOK/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md index 21e4745e0d..e1597404db 100644 --- a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md +++ b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md @@ -54,7 +54,7 @@ SessionConfig sessionConfig = new() Model = "gpt-4o", Provider = new ProviderConfig { - Type = "openai", + Type = "azure", // or "openai", "anthropic" WireApi = "completions", BaseUrl = "https://api.example.com/v1", ApiKey = "your-api-key", From 022a3703b52ba4dcaa397251e103bb2e7f9b4570 Mon Sep 17 00:00:00 2001 From: droideronline Date: Mon, 27 Jul 2026 21:56:59 +0530 Subject: [PATCH 5/6] .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). --- dotnet/eng/verify-samples/AgentsSamples.cs | 2 +- .../02-agents/AgentProviders/README.md | 2 +- .../Agent_With_GitHubCopilot_BYOK/Program.cs | 11 +++++---- .../Agent_With_GitHubCopilot_BYOK/README.md | 24 +++++++++++-------- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/dotnet/eng/verify-samples/AgentsSamples.cs b/dotnet/eng/verify-samples/AgentsSamples.cs index 85e8f74026..512ce66027 100644 --- a/dotnet/eng/verify-samples/AgentsSamples.cs +++ b/dotnet/eng/verify-samples/AgentsSamples.cs @@ -841,7 +841,7 @@ internal static class AgentsSamples 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_MODEL_ID"], + OptionalEnvironmentVariables = ["BYOK_PROVIDER_TYPE", "BYOK_MODEL_ID"], ExpectedOutputDescription = [ "The output should contain a user prompt and a response about the benefits of BYOK.", diff --git a/dotnet/samples/02-agents/AgentProviders/README.md b/dotnet/samples/02-agents/AgentProviders/README.md index 00eb48dcec..407c4e8e4d 100644 --- a/dotnet/samples/02-agents/AgentProviders/README.md +++ b/dotnet/samples/02-agents/AgentProviders/README.md @@ -60,7 +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 OpenAI-compatible endpoint (Bring Your Own Key) | +| [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/) diff --git a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs index e12746bda6..4b714e7200 100644 --- a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs +++ b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs @@ -1,7 +1,8 @@ // 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 OpenAI-compatible endpoint instead of the GitHub Copilot backend. +// 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 @@ -10,6 +11,7 @@ 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") @@ -21,14 +23,15 @@ await copilotClient.StartAsync(); // Provider routes the session through a custom endpoint instead of the GitHub Copilot backend. -// 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. +// 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 = "openai", + Type = providerType, WireApi = "completions", BaseUrl = baseUrl, ApiKey = apiKey, diff --git a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md index e1597404db..cafadf45c3 100644 --- a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md +++ b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/README.md @@ -1,10 +1,18 @@ +# 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-compatible endpoint and API key (OpenAI, Azure OpenAI, or a compatible service such as vLLM, LiteLLM, or Ollama) +- An OpenAI, Azure OpenAI, Anthropic, or OpenAI-compatible endpoint and API key (e.g. vLLM, + LiteLLM, or Ollama) ## Setting up GitHub Copilot CLI @@ -16,7 +24,8 @@ https://github.com/github/copilot-sdk | Variable | Description | Default | |----------|-------------|---------| -| `BYOK_BASE_URL` | Base URL of your OpenAI-compatible endpoint | *(required)* | +| `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` | @@ -34,12 +43,7 @@ The sample will: 3. Send a message to the agent 4. Stream the response -## 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. +## Advanced Usage ```csharp using GitHub.Copilot; @@ -55,10 +59,10 @@ SessionConfig sessionConfig = new() Provider = new ProviderConfig { Type = "azure", // or "openai", "anthropic" - WireApi = "completions", + WireApi = "completions", // or "responses" BaseUrl = "https://api.example.com/v1", ApiKey = "your-api-key", - ModelId = "your-model-id", + ModelId = "your-model-id", // "deployment-name" }, }; From 8560e789bb7e09e2ea40bfd8549c295a0450482a Mon Sep 17 00:00:00 2001 From: droideronline Date: Mon, 27 Jul 2026 23:05:14 +0530 Subject: [PATCH 6/6] .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. --- .../github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs index 4b714e7200..a7c42bd350 100644 --- a/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs +++ b/dotnet/samples/02-agents/AgentProviders/github-copilot/Agent_With_GitHubCopilot_BYOK/Program.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All rights reserved. +// 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