mirror of
https://github.com/github/awesome-copilot.git
synced 2026-06-17 13:11:27 +00:00
Update .NET Copilot SDK cookbook for GitHub.Copilot.SDK 1.0 (#2021)
* Update .NET Copilot SDK cookbook for GitHub.Copilot.SDK 1.0 Align the dotnet copilot-sdk cookbook recipes and docs with the 1.0.1 release: - Namespace GitHub.Copilot.SDK -> GitHub.Copilot - MCP config uses Dictionary<string, McpServerConfig> + McpStdioServerConfig (drop Type discriminator) - StopAsync no longer returns an error list; wrap graceful shutdown in try/catch - GetMessagesAsync -> GetEventsAsync with event pattern matching - LogLevel string -> CopilotLogLevel.Error enum * Address PR review: clarify package/namespace, default event case, MCP stdio wording - Note that the GitHub.Copilot.SDK package exposes the GitHub.Copilot namespace in each recipe - Add a default case + note to the GetEventsAsync history example so other event kinds are not silently dropped - Refine accessibility-report docs to describe a local stdio MCP server (McpStdioServerConfig via npx) * Address re-review: add using for event types, note StopAsync throw behavior
This commit is contained in:
@@ -32,7 +32,7 @@ dotnet run recipe/accessibility-report.cs
|
||||
```csharp
|
||||
#:package GitHub.Copilot.SDK@*
|
||||
|
||||
using GitHub.Copilot.SDK;
|
||||
using GitHub.Copilot;
|
||||
|
||||
// Create and start client
|
||||
await using var client = new CopilotClient();
|
||||
@@ -65,12 +65,11 @@ await using var session = await client.CreateSessionAsync(new SessionConfig
|
||||
Model = "claude-opus-4.6",
|
||||
Streaming = true,
|
||||
OnPermissionRequest = PermissionHandler.ApproveAll,
|
||||
McpServers = new Dictionary<string, object>()
|
||||
McpServers = new Dictionary<string, McpServerConfig>()
|
||||
{
|
||||
["playwright"] =
|
||||
new McpLocalServerConfig
|
||||
new McpStdioServerConfig
|
||||
{
|
||||
Type = "local",
|
||||
Command = "npx",
|
||||
Args = ["@playwright/mcp@latest"],
|
||||
Tools = ["*"]
|
||||
@@ -195,7 +194,7 @@ if (generateTests == "y" || generateTests == "yes")
|
||||
|
||||
## How it works
|
||||
|
||||
1. **Playwright MCP server**: Configures a local MCP server running `@playwright/mcp` to provide browser automation tools
|
||||
1. **Playwright MCP server**: Configures a local stdio MCP server (`McpStdioServerConfig`, launched via `npx`) running `@playwright/mcp` to provide browser automation tools
|
||||
2. **Streaming output**: Uses `Streaming = true` and `AssistantMessageDeltaEvent` for real-time token-by-token output
|
||||
3. **Accessibility snapshot**: Playwright's `browser_snapshot` tool captures the full accessibility tree of the page
|
||||
4. **Structured report**: The prompt engineers a consistent WCAG-aligned report format with emoji severity indicators
|
||||
@@ -205,15 +204,14 @@ if (generateTests == "y" || generateTests == "yes")
|
||||
|
||||
### MCP server configuration
|
||||
|
||||
The recipe configures a local MCP server that runs alongside the session:
|
||||
The recipe configures a local stdio MCP server (`McpStdioServerConfig`, launched via `npx`) that runs alongside the session:
|
||||
|
||||
```csharp
|
||||
OnPermissionRequest = PermissionHandler.ApproveAll,
|
||||
McpServers = new Dictionary<string, object>()
|
||||
McpServers = new Dictionary<string, McpServerConfig>()
|
||||
{
|
||||
["playwright"] = new McpLocalServerConfig
|
||||
["playwright"] = new McpStdioServerConfig
|
||||
{
|
||||
Type = "local",
|
||||
Command = "npx",
|
||||
Args = ["@playwright/mcp@latest"],
|
||||
Tools = ["*"]
|
||||
|
||||
@@ -15,7 +15,7 @@ You need to handle various error conditions like connection failures, timeouts,
|
||||
## Basic try-catch
|
||||
|
||||
```csharp
|
||||
using GitHub.Copilot.SDK;
|
||||
using GitHub.Copilot;
|
||||
|
||||
var client = new CopilotClient();
|
||||
|
||||
@@ -134,16 +134,23 @@ Console.CancelKeyPress += async (sender, e) =>
|
||||
e.Cancel = true;
|
||||
Console.WriteLine("Shutting down...");
|
||||
|
||||
var errors = await client.StopAsync();
|
||||
if (errors.Count > 0)
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Cleanup errors: {string.Join(", ", errors)}");
|
||||
await client.StopAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Cleanup error: {ex.Message}");
|
||||
}
|
||||
|
||||
Environment.Exit(0);
|
||||
};
|
||||
```
|
||||
|
||||
> In 1.0, `StopAsync()` throws if it encounters errors during cleanup rather than returning a
|
||||
> list of cleanup errors, so wrap it in a try/catch to log failures instead of letting them
|
||||
> crash shutdown. Use `ForceStopAsync()` if a graceful stop takes too long.
|
||||
|
||||
## Using await using for automatic disposal
|
||||
|
||||
```csharp
|
||||
@@ -163,7 +170,7 @@ var session = await client.CreateSessionAsync(new SessionConfig
|
||||
|
||||
## Best practices
|
||||
|
||||
Starting with Copilot SDK v0.1.28, permission handling is opt-in. If a session may need tool, file, or system access, set `OnPermissionRequest` explicitly when creating it.
|
||||
Permission handling is opt-in. If a session may need tool, file, or system access, set `OnPermissionRequest` explicitly when creating it.
|
||||
|
||||
1. **Always clean up**: Use try-finally or `await using` to ensure `StopAsync()` is called
|
||||
2. **Handle connection errors**: The CLI might not be installed or running
|
||||
|
||||
@@ -16,7 +16,7 @@ You have a folder with many files and want to organize them into subfolders base
|
||||
## Example code
|
||||
|
||||
```csharp
|
||||
using GitHub.Copilot.SDK;
|
||||
using GitHub.Copilot;
|
||||
|
||||
// Create and start client
|
||||
await using var client = new CopilotClient();
|
||||
|
||||
@@ -15,7 +15,7 @@ You need to run multiple conversations in parallel, each with its own context an
|
||||
## C #
|
||||
|
||||
```csharp
|
||||
using GitHub.Copilot.SDK;
|
||||
using GitHub.Copilot;
|
||||
|
||||
await using var client = new CopilotClient();
|
||||
await client.StartAsync();
|
||||
|
||||
@@ -16,7 +16,7 @@ You want users to be able to continue a conversation even after closing and reop
|
||||
### Creating a session with a custom ID
|
||||
|
||||
```csharp
|
||||
using GitHub.Copilot.SDK;
|
||||
using GitHub.Copilot;
|
||||
|
||||
await using var client = new CopilotClient();
|
||||
await client.StartAsync();
|
||||
@@ -74,16 +74,34 @@ await client.DeleteSessionAsync("user-123-conversation");
|
||||
|
||||
### Getting session history
|
||||
|
||||
Retrieve all messages from a session:
|
||||
Retrieve all events from a session:
|
||||
|
||||
```csharp
|
||||
var messages = await session.GetMessagesAsync();
|
||||
foreach (var msg in messages)
|
||||
using GitHub.Copilot; // UserMessageEvent, AssistantMessageEvent, etc. live in this namespace
|
||||
|
||||
var events = await session.GetEventsAsync();
|
||||
foreach (var evt in events)
|
||||
{
|
||||
Console.WriteLine($"[{msg.Type}] {msg.Data.Content}");
|
||||
switch (evt)
|
||||
{
|
||||
case UserMessageEvent user:
|
||||
Console.WriteLine($"[user] {user.Data.Content}");
|
||||
break;
|
||||
case AssistantMessageEvent assistant:
|
||||
Console.WriteLine($"[assistant] {assistant.Data.Content}");
|
||||
break;
|
||||
default:
|
||||
// Sessions can also contain other events (tool calls, tool results, system events).
|
||||
Console.WriteLine($"[{evt.GetType().Name}]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> A session's event stream may include event kinds beyond user and assistant messages
|
||||
> (for example tool calls, tool results, and system events). Handle the ones you care
|
||||
> about and fall back to a default case so nothing is silently dropped.
|
||||
|
||||
## Best practices
|
||||
|
||||
1. **Use meaningful session IDs**: Include user ID or context in the session ID
|
||||
|
||||
@@ -36,7 +36,7 @@ dotnet run -- --repo github/copilot-sdk
|
||||
|
||||
```csharp
|
||||
using System.Diagnostics;
|
||||
using GitHub.Copilot.SDK;
|
||||
using GitHub.Copilot;
|
||||
|
||||
// ============================================================================
|
||||
// Git & GitHub Detection
|
||||
@@ -159,7 +159,7 @@ var owner = parts[0];
|
||||
var repoName = parts[1];
|
||||
|
||||
// Create Copilot client - no custom tools needed!
|
||||
await using var client = new CopilotClient(new CopilotClientOptions { LogLevel = "error" });
|
||||
await using var client = new CopilotClient(new CopilotClientOptions { LogLevel = CopilotLogLevel.Error });
|
||||
await client.StartAsync();
|
||||
|
||||
var session = await client.CreateSessionAsync(new SessionConfig
|
||||
|
||||
@@ -42,7 +42,7 @@ A [Ralph loop](https://ghuntley.com/ralph/) is an autonomous development workflo
|
||||
The minimal Ralph loop — the SDK equivalent of `while :; do cat PROMPT.md | copilot ; done`:
|
||||
|
||||
```csharp
|
||||
using GitHub.Copilot.SDK;
|
||||
using GitHub.Copilot;
|
||||
|
||||
var client = new CopilotClient();
|
||||
await client.StartAsync();
|
||||
@@ -96,7 +96,7 @@ This is all you need to get started. The prompt file tells the agent what to do;
|
||||
The full Ralph pattern with planning and building modes, matching the [Ralph Playbook](https://github.com/ClaytonFarr/ralph-playbook) architecture:
|
||||
|
||||
```csharp
|
||||
using GitHub.Copilot.SDK;
|
||||
using GitHub.Copilot;
|
||||
|
||||
// Parse args: dotnet run [plan] [max_iterations]
|
||||
var mode = args.Contains("plan") ? "plan" : "build";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#:package GitHub.Copilot.SDK@*
|
||||
|
||||
using GitHub.Copilot.SDK;
|
||||
// The GitHub.Copilot.SDK package exposes the GitHub.Copilot namespace.
|
||||
using GitHub.Copilot;
|
||||
|
||||
// Create and start client
|
||||
await using var client = new CopilotClient();
|
||||
@@ -33,12 +34,11 @@ await using var session = await client.CreateSessionAsync(new SessionConfig
|
||||
Model = "claude-opus-4.6",
|
||||
Streaming = true,
|
||||
OnPermissionRequest = PermissionHandler.ApproveAll,
|
||||
McpServers = new Dictionary<string, object>()
|
||||
McpServers = new Dictionary<string, McpServerConfig>()
|
||||
{
|
||||
["playwright"] =
|
||||
new McpLocalServerConfig
|
||||
new McpStdioServerConfig
|
||||
{
|
||||
Type = "local",
|
||||
Command = "npx",
|
||||
Args = ["@playwright/mcp@latest"],
|
||||
Tools = ["*"]
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#:package GitHub.Copilot.SDK@*
|
||||
#:property PublishAot=false
|
||||
|
||||
using GitHub.Copilot.SDK;
|
||||
// The GitHub.Copilot.SDK package exposes the GitHub.Copilot namespace.
|
||||
using GitHub.Copilot;
|
||||
|
||||
var client = new CopilotClient();
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#:package GitHub.Copilot.SDK@*
|
||||
#:property PublishAot=false
|
||||
|
||||
using GitHub.Copilot.SDK;
|
||||
// The GitHub.Copilot.SDK package exposes the GitHub.Copilot namespace.
|
||||
using GitHub.Copilot;
|
||||
|
||||
// Create and start client
|
||||
await using var client = new CopilotClient();
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#:package GitHub.Copilot.SDK@*
|
||||
#:property PublishAot=false
|
||||
|
||||
using GitHub.Copilot.SDK;
|
||||
// The GitHub.Copilot.SDK package exposes the GitHub.Copilot namespace.
|
||||
using GitHub.Copilot;
|
||||
|
||||
await using var client = new CopilotClient();
|
||||
await client.StartAsync();
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#:package GitHub.Copilot.SDK@*
|
||||
#:property PublishAot=false
|
||||
|
||||
using GitHub.Copilot.SDK;
|
||||
// The GitHub.Copilot.SDK package exposes the GitHub.Copilot namespace.
|
||||
using GitHub.Copilot;
|
||||
|
||||
await using var client = new CopilotClient();
|
||||
await client.StartAsync();
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
#:property PublishAot=false
|
||||
|
||||
using System.Diagnostics;
|
||||
using GitHub.Copilot.SDK;
|
||||
// The GitHub.Copilot.SDK package exposes the GitHub.Copilot namespace.
|
||||
using GitHub.Copilot;
|
||||
|
||||
// ============================================================================
|
||||
// Git & GitHub Detection
|
||||
@@ -126,7 +127,7 @@ var owner = parts[0];
|
||||
var repoName = parts[1];
|
||||
|
||||
// Create Copilot client - no custom tools needed!
|
||||
await using var client = new CopilotClient(new CopilotClientOptions { LogLevel = "error" });
|
||||
await using var client = new CopilotClient(new CopilotClientOptions { LogLevel = CopilotLogLevel.Error });
|
||||
await client.StartAsync();
|
||||
|
||||
var session = await client.CreateSessionAsync(new SessionConfig
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#:package GitHub.Copilot.SDK@*
|
||||
|
||||
using GitHub.Copilot.SDK;
|
||||
// The GitHub.Copilot.SDK package exposes the GitHub.Copilot namespace.
|
||||
using GitHub.Copilot;
|
||||
|
||||
// Ralph loop: autonomous AI task loop with fresh context per iteration.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user