Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dotnet/agent-framework-dotnet.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down
13 changes: 13 additions & 0 deletions dotnet/eng/verify-samples/AgentsSamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions dotnet/samples/02-agents/AgentProviders/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/)

Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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();
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# 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)

## 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.
Loading