GitHub.Copilot.SDK 0.1.18

Prefix Reserved
dotnet add package GitHub.Copilot.SDK --version 0.1.18
                    
NuGet\Install-Package GitHub.Copilot.SDK -Version 0.1.18
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GitHub.Copilot.SDK" Version="0.1.18" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GitHub.Copilot.SDK" Version="0.1.18" />
                    
Directory.Packages.props
<PackageReference Include="GitHub.Copilot.SDK" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GitHub.Copilot.SDK --version 0.1.18
                    
#r "nuget: GitHub.Copilot.SDK, 0.1.18"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GitHub.Copilot.SDK@0.1.18
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GitHub.Copilot.SDK&version=0.1.18
                    
Install as a Cake Addin
#tool nuget:?package=GitHub.Copilot.SDK&version=0.1.18
                    
Install as a Cake Tool

Copilot SDK

SDK for programmatic control of GitHub Copilot CLI.

Note: This SDK is in technical preview and may change in breaking ways.

Installation

dotnet add package GitHub.Copilot.SDK

Quick Start

using GitHub.Copilot.SDK;

// Create and start client
await using var client = new CopilotClient();
await client.StartAsync();

// Create a session
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5"
});

// Wait for response using session.idle event
var done = new TaskCompletionSource();

session.On(evt =>
{
    if (evt is AssistantMessageEvent msg)
    {
        Console.WriteLine(msg.Data.Content);
    }
    else if (evt is SessionIdleEvent)
    {
        done.SetResult();
    }
});

// Send a message and wait for completion
await session.SendAsync(new MessageOptions { Prompt = "What is 2+2?" });
await done.Task;

API Reference

CopilotClient

Constructor
new CopilotClient(CopilotClientOptions? options = null)

Options:

  • CliPath - Path to CLI executable (default: "copilot" from PATH)
  • CliArgs - Extra arguments prepended before SDK-managed flags
  • CliUrl - URL of existing CLI server to connect to (e.g., "localhost:8080"). When provided, the client will not spawn a CLI process.
  • Port - Server port (default: 0 for random)
  • UseStdio - Use stdio transport instead of TCP (default: true)
  • LogLevel - Log level (default: "info")
  • AutoStart - Auto-start server (default: true)
  • AutoRestart - Auto-restart on crash (default: true)
  • Cwd - Working directory for the CLI process
  • Environment - Environment variables to pass to the CLI process
  • Logger - ILogger instance for SDK logging
Methods
StartAsync(): Task

Start the CLI server and establish connection.

StopAsync(): Task

Stop the server and close all sessions. Throws if errors are encountered during cleanup.

ForceStopAsync(): Task

Force stop the CLI server without graceful cleanup. Use when StopAsync() takes too long.

CreateSessionAsync(SessionConfig? config = null): Task<CopilotSession>

Create a new conversation session.

Config:

  • SessionId - Custom session ID
  • Model - Model to use ("gpt-5", "claude-sonnet-4.5", etc.)
  • Tools - Custom tools exposed to the CLI
  • SystemMessage - System message customization
  • AvailableTools - List of tool names to allow
  • ExcludedTools - List of tool names to disable
  • Provider - Custom API provider configuration (BYOK)
  • Streaming - Enable streaming of response chunks (default: false)
  • InfiniteSessions - Configure automatic context compaction (see below)
ResumeSessionAsync(string sessionId, ResumeSessionConfig? config = null): Task<CopilotSession>

Resume an existing session. Returns the session with WorkspacePath populated if infinite sessions were enabled.

PingAsync(string? message = null): Task<PingResponse>

Ping the server to check connectivity.

State: ConnectionState

Get current connection state.

ListSessionsAsync(): Task<List<SessionMetadata>>

List all available sessions.

DeleteSessionAsync(string sessionId): Task

Delete a session and its data from disk.


CopilotSession

Represents a single conversation session.

Properties
  • SessionId - The unique identifier for this session
  • WorkspacePath - Path to the session workspace directory when infinite sessions are enabled. Contains checkpoints/, plan.md, and files/ subdirectories. Null if infinite sessions are disabled.
Methods
SendAsync(MessageOptions options): Task<string>

Send a message to the session.

Options:

  • Prompt - The message/prompt to send
  • Attachments - File attachments
  • Mode - Delivery mode ("enqueue" or "immediate")

Returns the message ID.

On(SessionEventHandler handler): IDisposable

Subscribe to session events. Returns a disposable to unsubscribe.

var subscription = session.On(evt =>
{
    Console.WriteLine($"Event: {evt.Type}");
});

// Later...
subscription.Dispose();
AbortAsync(): Task

Abort the currently processing message in this session.

GetMessagesAsync(): Task<IReadOnlyList<SessionEvent>>

Get all events/messages from this session.

DisposeAsync(): ValueTask

Dispose the session and free resources.


Event Types

Sessions emit various events during processing. Each event type is a class that inherits from SessionEvent:

  • UserMessageEvent - User message added
  • AssistantMessageEvent - Assistant response
  • ToolExecutionStartEvent - Tool execution started
  • ToolExecutionCompleteEvent - Tool execution completed
  • SessionStartEvent - Session started
  • SessionIdleEvent - Session is idle
  • SessionErrorEvent - Session error occurred
  • And more...

Use pattern matching to handle specific event types:

session.On(evt =>
{
    switch (evt)
    {
        case AssistantMessageEvent msg:
            Console.WriteLine(msg.Data.Content);
            break;
        case SessionErrorEvent err:
            Console.WriteLine($"Error: {err.Data.Message}");
            break;
    }
});

Image Support

The SDK supports image attachments via the Attachments parameter. You can attach images by providing their file path:

await session.SendAsync(new MessageOptions
{
    Prompt = "What's in this image?",
    Attachments = new List<UserMessageDataAttachmentsItem>
    {
        new UserMessageDataAttachmentsItem
        {
            Type = UserMessageDataAttachmentsItemType.File,
            Path = "/path/to/image.jpg"
        }
    }
});

Supported image formats include JPG, PNG, GIF, and other common image types. The agent's view tool can also read images directly from the filesystem, so you can also ask questions like:

await session.SendAsync(new MessageOptions { Prompt = "What does the most recent jpg in this directory portray?" });

Streaming

Enable streaming to receive assistant response chunks as they're generated:

var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5",
    Streaming = true
});

// Use TaskCompletionSource to wait for completion
var done = new TaskCompletionSource();

session.On(evt =>
{
    switch (evt)
    {
        case AssistantMessageDeltaEvent delta:
            // Streaming message chunk - print incrementally
            Console.Write(delta.Data.DeltaContent);
            break;
        case AssistantReasoningDeltaEvent reasoningDelta:
            // Streaming reasoning chunk (if model supports reasoning)
            Console.Write(reasoningDelta.Data.DeltaContent);
            break;
        case AssistantMessageEvent msg:
            // Final message - complete content
            Console.WriteLine("\n--- Final message ---");
            Console.WriteLine(msg.Data.Content);
            break;
        case AssistantReasoningEvent reasoningEvt:
            // Final reasoning content (if model supports reasoning)
            Console.WriteLine("--- Reasoning ---");
            Console.WriteLine(reasoningEvt.Data.Content);
            break;
        case SessionIdleEvent:
            // Session finished processing
            done.SetResult();
            break;
    }
});

await session.SendAsync(new MessageOptions { Prompt = "Tell me a short story" });
await done.Task; // Wait for streaming to complete

When Streaming = true:

  • AssistantMessageDeltaEvent events are sent with DeltaContent containing incremental text
  • AssistantReasoningDeltaEvent events are sent with DeltaContent for reasoning/chain-of-thought (model-dependent)
  • Accumulate DeltaContent values to build the full response progressively
  • The final AssistantMessageEvent and AssistantReasoningEvent events contain the complete content

Note: AssistantMessageEvent and AssistantReasoningEvent (final events) are always sent regardless of streaming setting.

Infinite Sessions

By default, sessions use infinite sessions which automatically manage context window limits through background compaction and persist state to a workspace directory.

// Default: infinite sessions enabled with default thresholds
var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5"
});

// Access the workspace path for checkpoints and files
Console.WriteLine(session.WorkspacePath);
// => ~/.copilot/session-state/{sessionId}/

// Custom thresholds
var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5",
    InfiniteSessions = new InfiniteSessionConfig
    {
        Enabled = true,
        BackgroundCompactionThreshold = 0.80, // Start compacting at 80% context usage
        BufferExhaustionThreshold = 0.95      // Block at 95% until compaction completes
    }
});

// Disable infinite sessions
var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5",
    InfiniteSessions = new InfiniteSessionConfig { Enabled = false }
});

When enabled, sessions emit compaction events:

  • SessionCompactionStartEvent - Background compaction started
  • SessionCompactionCompleteEvent - Compaction finished (includes token counts)

Advanced Usage

Manual Server Control

var client = new CopilotClient(new CopilotClientOptions { AutoStart = false });

// Start manually
await client.StartAsync();

// Use client...

// Stop manually
await client.StopAsync();

Tools

You can let the CLI call back into your process when the model needs capabilities you own. Use AIFunctionFactory.Create from Microsoft.Extensions.AI for type-safe tool definitions:

using Microsoft.Extensions.AI;
using System.ComponentModel;

var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5",
    Tools = [
        AIFunctionFactory.Create(
            async ([Description("Issue identifier")] string id) => {
                var issue = await FetchIssueAsync(id);
                return issue;
            },
            "lookup_issue",
            "Fetch issue details from our tracker"),
    ]
});

When Copilot invokes lookup_issue, the client automatically runs your handler and responds to the CLI. Handlers can return any JSON-serializable value (automatically wrapped), or a ToolResultAIContent wrapping a ToolResultObject for full control over result metadata.

System Message Customization

Control the system prompt using SystemMessage in session config:

var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5",
    SystemMessage = new SystemMessageConfig
    {
        Mode = SystemMessageMode.Append,
        Content = @"
<workflow_rules>
- Always check for security vulnerabilities
- Suggest performance improvements when applicable
</workflow_rules>
"
    }
});

For full control (removes all guardrails), use Mode = SystemMessageMode.Replace:

var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5",
    SystemMessage = new SystemMessageConfig
    {
        Mode = SystemMessageMode.Replace,
        Content = "You are a helpful assistant."
    }
});

Multiple Sessions

var session1 = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-5" });
var session2 = await client.CreateSessionAsync(new SessionConfig { Model = "claude-sonnet-4.5" });

// Both sessions are independent
await session1.SendAsync(new MessageOptions { Prompt = "Hello from session 1" });
await session2.SendAsync(new MessageOptions { Prompt = "Hello from session 2" });

File Attachments

await session.SendAsync(new MessageOptions
{
    Prompt = "Analyze this file",
    Attachments = new List<UserMessageDataAttachmentsItem>
    {
        new UserMessageDataAttachmentsItem
        {
            Type = UserMessageDataAttachmentsItemType.File,
            Path = "/path/to/file.cs",
            DisplayName = "My File"
        }
    }
});

Bring Your Own Key (BYOK)

Use a custom API provider:

var session = await client.CreateSessionAsync(new SessionConfig
{
    Provider = new ProviderConfig
    {
        Type = "openai",
        BaseUrl = "https://api.openai.com/v1",
        ApiKey = "your-api-key"
    }
});

Error Handling

try
{
    var session = await client.CreateSessionAsync();
    await session.SendAsync(new MessageOptions { Prompt = "Hello" });
}
catch (StreamJsonRpc.RemoteInvocationException ex)
{
    Console.Error.WriteLine($"JSON-RPC Error: {ex.Message}");
}
catch (Exception ex)
{
    Console.Error.WriteLine($"Error: {ex.Message}");
}

Requirements

  • .NET 8.0 or later
  • GitHub Copilot CLI installed and in PATH (or provide custom CliPath)

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.18 0 1/24/2026
0.1.17 178 1/23/2026
0.1.16 447 1/23/2026
0.1.16-preview.0 47 1/22/2026
0.1.15 206 1/22/2026
0.1.15-preview.0 51 1/20/2026
0.1.14 220 1/19/2026
0.1.13 185 1/16/2026
0.1.13-preview.0 95 1/15/2026
0.1.12 132 1/15/2026
0.1.11 84 1/15/2026
0.1.10 242 1/14/2026