Skip to content

Releases: github/copilot-sdk

v1.0.0-beta.7

24 May 19:19
51043b1

Choose a tag to compare

v1.0.0-beta.7 Pre-release
Pre-release

Feature: canvas runtime support

Applications can now declare and handle canvases — interactive UI surfaces hosted by the Copilot runtime. Register a single CanvasHandler on a session and receive routed canvas.open, canvas.close, and canvas.action.invoke events; call session.canvas.* for native host actions. (#1401)

session.setCanvasHandler({
  onOpen: async (ctx) => { /* render canvas */ },
  onAction: async (ctx) => { /* handle action */ },
  onClose: async (ctx) => { /* cleanup */ },
});
session.SetCanvasHandler(new MyCanvasHandler());

Feature: remote session support

Applications can enable remote sessions either at the client level (all sessions in a GitHub repo get a remote URL) or on demand mid-session. (#1192)

// Always-on via client option:
const client = new CopilotClient({ remote: true });

// On-demand per session:
const result = await session.rpc.remote.enable();
console.log("Remote URL:", result.url);
await session.rpc.remote.disable();
// Always-on:
var client = new CopilotClient(new CopilotClientOptions { Remote = true });

// On-demand:
var result = await session.Rpc.Remote.EnableAsync();
await session.Rpc.Remote.DisableAsync();

Feature: preMcpToolCall hook

A new hook lets applications intercept MCP tool invocations before they execute — inspect, replace, or remove the _meta field sent to MCP servers. (#1366)

session.hooks.onPreMcpToolCall = async (input) => {
  return { metaToUse: { ...input.meta, traceId: myTraceId } };
};
session.Hooks.OnPreMcpToolCall = async (input) =>
    new PreMcpToolCallHookOutput { MetaToUse = new { traceId = myTraceId } };

Feature: cloud session config

Sessions can now be created with a cloud option to request cloud-backed remote sessions with repository metadata, without requiring a local CLI process. (#1306)

const session = await client.createSession({
  cloud: { repository: { owner: "my-org", name: "my-repo" } },
});
var session = await client.CreateSessionAsync(new SessionConfig {
    Cloud = new CloudSessionConfig { Repository = new RepositoryConfig { Owner = "my-org", Name = "my-repo" } }
});

Feature: [Rust] Copilot CLI bundled by default

The Rust SDK now bundles the Copilot CLI binary at publish time by default — no configuration needed to get a working binary. Opt out with default-features = false. (#1385)

# Default: CLI bundled automatically
copilot-sdk = "1.0.0-beta.7"

# Opt out of bundled CLI:
copilot-sdk = { version = "1.0.0-beta.7", default-features = false }

Feature: Java SDK

The Java SDK is now part of the monorepo, providing full parity with the other language SDKs including session management, tool registration, hooks, and E2E test coverage. (#1348, #1369, #1389)

var client = new CopilotClient();
var session = client.createSession(new SessionConfig()).join();
session.send("Hello from Java!").join();

Feature: SDK tracing diagnostics

The .NET, Python, and Rust SDKs now emit structured trace/log output covering CLI startup, JSON-RPC timing, session operations, and callback paths — making it easier to diagnose slow or failing connections. (#1217)

  • C#: integrates with ILogger via structured fields and TimeSpan elapsed values
  • Python: uses stdlib logging with elapsed_ms, session_id, and request identifiers
  • Rust: uses the tracing crate with structured fields

Feature: [C#] CopilotTool helper

CopilotTool.DefineTool is a typed wrapper around AIFunctionFactory.Create that applies Copilot-specific metadata (override flag, skip-permission behavior) without magic strings. (#1321)

var tool = CopilotTool.DefineTool("edit",
    new CopilotToolOptions { IsOverride = true },
    async (params) => { /* custom edit */ });
session.AddTool(tool);

Feature: sessionId on hook inputs

All hook input types (PreToolUseHookInput, PostToolUseHookInput, SessionStartHookInput, etc.) now include a sessionId field, allowing applications to distinguish parent session hooks from sub-agent hooks. (#1290)

Other changes

  • feature: add enableSessionTelemetry session option across all SDKs (#1224)
  • feature: add model field to CustomAgentConfig across all SDKs (#1309)
  • feature: add remote_session field to SessionConfig across all SDKs (#1295)
  • feature: [Rust] support binary tool results (#1222)
  • feature: restore mode handler APIs across SDKs (#1228)
  • feature: add runtime_instructions system message section across all SDKs (#1377)
  • feature: add SessionFs SQLite support for runtime routing (#1299)
  • feature: make tool callbacks optional across SDKs (#1308)
  • feature: make MCPStdioServerConfig.args optional across all SDKs (#1347)
  • feature: [C#] add netstandard and net10 targets (#1320)
  • feature: [C#] use string enums for session events (#1226)
  • feature: [C#] seal generated session event types (#1330)
  • feature: [C#] map x-opaque-json to JsonElement at RPC params boundary (#1359)
  • feature: [Go] generate typed union interfaces (#1252)
  • improvement: API review fixes for C# (#1343), TypeScript (#1357), Go (#1360), Rust (#1367), Python (#1376)
  • improvement: share generated schema definitions across SDKs (#1289)
  • improvement: hide deprecated APIs where supported (#1293)
  • improvement: use 32-bit types for bounded schema integers (#1329)
  • improvement: strip Ms suffix for duration properties in generated types (#1339)
  • improvement: [C#] publish .snupkg symbols package to NuGet.org (#1345)
  • improvement: [Go] replace RPC quicktype generation with native Go types (#1234)
  • bugfix: [Go] capture CLI stderr and fix SetProcessDone race condition (#863)
  • bugfix: [Python] fix from_dict() round-trip for optional fields with schema defaults (#1313)
  • bugfix: [C#] honor preinstalled CLI path in MSBuild targets (#1318)

New contributors

  • @cschleiden made their first contribution in #1222
  • @claudiogodoy99 made their first contribution in #863
  • @tiagonbotelho made their first contribution in #1306

Generated by Release Changelog Generator · ● 3.7M

rust/v1.0.0-beta.7

24 May 19:19
51043b1

Choose a tag to compare

rust/v1.0.0-beta.7 Pre-release
Pre-release

What's Changed

Full Changelog: rust/v1.0.0-beta.6...rust/v1.0.0-beta.7

v1.0.0-beta.6

22 May 03:13
f4d22d7

Choose a tag to compare

v1.0.0-beta.6 Pre-release
Pre-release

Feature: Java SDK joins the monorepo

The Java SDK is now a first-class part of the github/copilot-sdk monorepo, with full CI, Maven publishing workflows, and generated types that stay in sync with the rest of the SDK family. (#1348)

CopilotClient client = new CopilotClient();
CopilotSession session = client.createSession(new SessionConfig());
session.send("Hello from Java!");

Feature: preMcpToolCall hook across all SDKs

Applications can now intercept MCP tool invocations before they execute — useful for injecting, replacing, or removing the _meta field sent to MCP servers. The hook returns a tri-state result: return null to leave _meta unchanged, return a new object to replace it, or explicitly set metaToUse to null to strip it entirely. (#1366)

session.hooks.onPreMcpToolCall = async (input) => {
  return { metaToUse: { traceId: myTraceId() } };
};
session.Hooks.OnPreMcpToolCall = async (input) => {
    return new PreMcpToolCallHookOutput { MetaToUse = new { traceId = MyTraceId() } };
};

Feature: tool callbacks are now optional across all SDKs

Tools and permission handlers can be declared without providing a callback, leaving them pending for manual resolution. This makes it easier to pause execution and resolve requests from event streams rather than inline callbacks. (#1308)

// Declare without a callback — permission requests stay pending
session.setPermissionHandler({ kinds: ["edit"] });

// Later, resume manually from an event
session.resolvePermissionRequest(event.requestId, { outcome: "allow" });
// Declaration-only tool — no callback supplied
session.DefineTool(new ToolDefinition { Name = "myTool", Description = "..." });

Feature: sessionId on hook inputs — hooks now fire for sub-agents

All six hook input types (PreToolUseHookInput, PostToolUseHookInput, etc.) now carry a sessionId field. Hooks also fire for tool calls made by sub-agents spawned via the task tool, and input.sessionId lets you distinguish parent from sub-agent invocations. (#1290)

Feature: breaking API review changes for C#, TypeScript, and Go

These releases include coordinated, intentional breaking changes based on API review feedback. Key changes:

Connection configurationCliPath/Port/CliUrl properties are replaced by a single RuntimeConnection discriminated union:

  • TypeScript: new CopilotClient({ connection: RuntimeConnection.stdio(...) })
  • C#: new CopilotClientOptions { Connection = RuntimeConnection.Stdio(...) }
  • Go: CLIUrl equivalent updated

Convenience send overloadssend(string) / sendAndWait(string) string overloads added for all SDKs.

Lifecycle events — now a typed polymorphic hierarchy (SessionCreatedEvent, etc.) instead of stringly-typed discriminators.

C# specificsCopilotHomeBaseDirectory, delegate types replaced with Func<...>, LogLevel retyped to CopilotLogLevel, SessionConfigBase extracted. (#1343, #1357, #1360)

Feature: model field on CustomAgentConfig

When defining custom sub-agents programmatically, you can now specify which model to use. The runtime falls back to the parent session model if the specified model is unavailable. (#1309)

  • TypeScript: customAgents: [{ name: "my-agent", model: "gpt-4o", ... }]
  • C#: new CustomAgentConfig { Name = "my-agent", Model = "gpt-4o" }
  • Python: custom_agents=[{"name": "my-agent", "model": "gpt-4o"}]
  • Go: CustomAgentConfig{Name: "my-agent", Model: "gpt-4o"}

Feature: cloud session config support

Session creation now accepts a cloud option to request cloud-backed remote sessions with repository metadata, matching the new runtime capability. (#1306)

Feature: CopilotTool.DefineTool helper for .NET

The .NET SDK now provides a typed CopilotTool.DefineTool wrapper that applies Copilot-specific metadata (override flags, skip-permission behavior) without magic strings, aligning C# with the typed helper APIs already available in other SDKs. (#1321)

var tool = CopilotTool.DefineTool("edit", new CopilotToolOptions { IsOverride = true },
    async (params, ctx) => { /* custom edit implementation */ });

Other changes

  • feature: [C#] add netstandard2.0 and net10 target frameworks (#1320)
  • feature: [C#] publish .snupkg symbols package to NuGet.org (#1345)
  • bugfix: [C#] honor preinstalled CLI path in MSBuild targets (#1318)
  • bugfix: [C#] fix argument validation edge cases (#1322, #1328)
  • feature: [Node] export generated session event types (#1316)
  • feature: make MCPStdioServerConfig.args optional across all SDKs (#1347)
  • feature: add remote_session field to all SDK SessionConfig types (#1295)
  • improvement: hide deprecated APIs where supported by the language (#1293)
  • bugfix: [Python] fix from_dict() round-trip for optional fields with schema defaults (#1313)
  • improvement: [Go] replace RPC quicktype generation with native Go codegen (#1234)
  • improvement: [Go] generate typed union interfaces and bool-discriminated unions (#1252, #1284)
  • improvement: [Rust] derive Default on generated types (#1272)

New contributors

  • @tiagonbotelho made their first contribution in #1306

Generated by Release Changelog Generator · ● 6.2M

rust/v1.0.0-beta.6

22 May 03:13
f4d22d7

Choose a tag to compare

rust/v1.0.0-beta.6 Pre-release
Pre-release

What's Changed

New Contributors

Full Changelog: rust/v1.0.0-beta.4...rust/v1.0.0-beta.6

v1.0.0-beta.4

13 May 09:36
4e3dc73

Choose a tag to compare

v1.0.0-beta.4 Pre-release
Pre-release

Feature: typed Go union interfaces

Go SDK union types are now modelled as typed interfaces with concrete variants instead of flattened structs with many optional fields. Callers can switch on concrete variants and get compile-time safety — invalid union states that were previously representable are no longer possible. Unknown union members and session event payloads are preserved rather than dropped. (#1252)

switch v := event.Data.(type) {
case *SessionEventDataAssistantMessage:
    fmt.Println(v.Content)
case *RawSessionEventData:
    // forward-compatible: unknown future event type preserved
}

Feature: experimental schema type annotations

Generated types that carry stability: "experimental" in the protocol schema now surface language-appropriate markers so callers get compiler warnings when using unstable APIs. (#1267)

  • C#: [Experimental("GitHub.Copilot.SDK.Experimental")]
  • TypeScript: @experimental JSDoc tag
  • Go/Python: doc-comment warning
  • Rust: #[doc = "⚠️ Experimental"]

Other changes

  • improvement: [Go] replace quicktype-based RPC codegen with a custom schema-aware generator; preserves distinct named types that quicktype previously merged due to identical structure, and aligns generated casing with the repo's naming policy — note: this is a breaking change for Go callers using generated RPC types (#1234)
  • bugfix: [Go] CLI stderr is now captured and included in startup errors, making failure root causes (missing module, auth error, version mismatch) immediately visible instead of showing a generic opaque message (#863)

New contributors

  • @claudiogodoy99 made their first contribution in #863

Generated by Release Changelog Generator · ● 302.2K

rust/v1.0.0-beta.4

13 May 09:36
4e3dc73

Choose a tag to compare

What's Changed

New Contributors

Full Changelog: rust-v0.1.0...rust/v1.0.0-beta.4

v1.0.0-beta.3

08 May 16:10
ce56eb8

Choose a tag to compare

Feature: mode handler APIs for plan approval and rate-limit recovery

Applications can now register callbacks for exitPlanMode.request and autoModeSwitch.request from the Copilot runtime, giving full control over plan-mode transitions and automatic model switching after rate-limit events. (#1228)

const session = await client.createSession({
  onExitPlanMode: async (request) => ({ approved: true }),
  onAutoModeSwitch: (request) => "yes",
});
var session = await client.CreateSessionAsync(new SessionConfig
{
    OnExitPlanMode = (request, _) => Task.FromResult(new ExitPlanModeResult { Approved = true }),
    OnAutoModeSwitch = (request, _) => Task.FromResult(AutoModeSwitchResponse.Yes),
});
  • Python: on_exit_plan_mode / on_auto_mode_switch kwargs on create_session()
  • Go: ExitPlanModeHandler / AutoModeSwitchHandler fields on SessionConfig

Feature: SDK tracing diagnostics

The .NET, Python, and Rust SDKs now emit structured diagnostic logs covering CLI startup, TCP connection, JSON-RPC request timing, session lifecycle, and error paths. (#1217)

var client = new CopilotClient(new CopilotClientOptions
{
    Logger = loggerFactory.CreateLogger<CopilotClient>(),
});

Python emits logs via stdlib logging under copilot.* loggers at DEBUG level. Rust uses tracing structured fields; wire up a tracing_subscriber as usual.

Feature: enableSessionTelemetry session option

A new enableSessionTelemetry option on SessionConfig and ResumeSessionConfig lets applications explicitly enable or disable the runtime's internal session telemetry. (#1224)

const session = await client.createSession({ enableSessionTelemetry: true });
var session = await client.CreateSessionAsync(new SessionConfig { EnableSessionTelemetry = true });

Other changes

  • bugfix: [C#] session-event enums are now string-backed readonly structs, preventing deserialization failures when the runtime adds new enum values (#1226)
  • bugfix: [Rust] binary tool result resource blobs now default to application/octet-stream when mimeType is absent (#1222)

New contributors

  • @sunbrye made their first contribution in #1208
  • @cschleiden made their first contribution in #1222
  • @IeuanWalker made their first contribution in #1232

Generated by Release Changelog Generator · ● 225.2K

Generated by Release Changelog Generator · ● 1.3M

v1.0.0-beta.2

06 May 20:02
06bfc5d

Choose a tag to compare

v1.0.0-beta.2 Pre-release
Pre-release

Feature: remote session support

Applications can now enable remote session support across all SDKs, providing parity with the CLI's --remote flag. There are two complementary mechanisms: a client-level option that enables remote for all sessions, and per-session RPC methods to toggle remote on demand. (#1192)

Always-on via client option:

const client = new CopilotClient({ remote: true });
session.on("session.info", (event) => {
  if (event.data.infoType === "remote") {
    console.log("Remote URL:", event.data.url);
  }
});
var client = new CopilotClient(new CopilotClientOptions { Remote = true });
session.OnSessionInfo += (e) => {
    if (e.InfoType == "remote")
        Console.WriteLine($"Remote URL: {e.Url}");
};

On-demand via RPC:

const result = await session.rpc.remote.enable();
console.log("Remote URL:", result.url);
await session.rpc.remote.disable();
var result = await session.Rpc.Remote.EnableAsync();
Console.WriteLine($"Remote URL: {result.Url}");
await session.Rpc.Remote.DisableAsync();
  • Python: await session.rpc.remote.enable() / session.rpc.remote.disable()
  • Go: session.RPC.Remote.Enable(ctx) / session.RPC.Remote.Disable(ctx)

Other changes

  • improvement: [Rust] align Rust SDK public surface with C#, Go, Python, and TypeScript — removes autoModeSwitch, exitPlanMode, disabled_mcp_servers; adds available_tools/disabled_skills to ResumeSessionConfig; expands tool results with binary payloads and MCP CallToolResult conversion (#1212)
  • improvement: [Rust] internalize env_value_mode for cross-SDK parity — envValueMode is now always sent as "direct" on the wire, consistent with all other SDKs (#1215)

Generated by Release Changelog Generator · ● 225.2K

rust-v0.1.0

06 May 14:12
19b4ad5

Choose a tag to compare

rust-v0.1.0 Pre-release
Pre-release
chore: Release package github-copilot-sdk version 0.1.0

v1.0.0-beta.1

04 May 12:53
6a0e065

Choose a tag to compare

v1.0.0-beta.1 Pre-release
Pre-release

This is the first beta release of the Copilot SDK. The release includes all features we have committed to including in the upcoming General Availability (GA) release.

But note - we're not stopping here! Before GA, we still plan to add more top-requested features, as well as any critical bugfixes. We'll also carry out a final round of API reviews and will likely make further breaking changes to streamline naming before it locks down at 1.0.0.

Highlights of 1.0.0 Beta 1 include custom instruction directories, configurable data directories, TCP connection tokens for headless servers, and a more self-contained .NET distribution (eliminating third-party dependencies).


New features

Custom instruction directories

Sessions can now specify additional directories to search for custom instruction files via the instructionDirectories option on session create and resume config. This lets applications point the CLI at project-specific or team-shared instruction files beyond the default locations. (#1190)

// TypeScript
const session = await client.createSession({
  onPermissionRequest: approveAll,
  instructionDirectories: [
    "/repo/.copilot/instructions",
    "/shared/team-instructions",
  ],
});
// C#
var session = await client.CreateSessionAsync(new() {
    OnPermissionRequest = PermissionHandler.ApproveAll,
    InstructionDirectories = ["/repo/.copilot/instructions", "/shared/team-instructions"],
});
  • Python: await client.create_session(on_permission_request=..., instruction_directories=["/repo/.copilot/instructions"])
  • Go: client.CreateSession(ctx, &copilot.SessionConfig{InstructionDirectories: []string{"/repo/.copilot/instructions"}})

TCP connection token

When the SDK spawns a CLI server in TCP mode, it now auto-generates a connection token to authenticate the handshake — closing the loopback listener to unauthorized connections by default. For applications connecting to an externally managed TCP server that requires a token, the new tcpConnectionToken client option lets you supply it explicitly. (#1176)

// TypeScript
// After starting runtime with env var COPILOT_CONNECTION_TOKEN=<some_uuid>
const client = new CopilotClient({
  cliUrl: "localhost:3000",
  tcpConnectionToken: "<some_uuid>",
});
// C#
// After starting runtime with env var COPILOT_CONNECTION_TOKEN=<some_uuid>
var client = new CopilotClient(new() {
    CliUrl = "localhost:3000",
    TcpConnectionToken = "<some_uuid>",
});
  • Python: CopilotClient(ExternalServerConfig(url="localhost:3000", tcp_connection_token="<some_uuid>"))
  • Go: copilot.NewClient(&copilot.ClientOptions{CLIUrl: "localhost:3000", TCPConnectionToken: "<some_uuid>"})

Configurable Copilot data directory

A new copilotHome client option controls where the CLI stores session state, configuration, and other persistent data. This is useful for isolating data across environments, running multiple CLI instances side-by-side, or customizing the storage location for containerized deployments. Defaults to ~/.copilot when not set, and is applicable only when the SDK spawns the CLI process (ignored when connecting to an external server via cliUrl). (#1191).

const client = new CopilotClient({ copilotHome: "/var/data/copilot" });

If you need more control than simply passing a directory path, consider the existing and more advanced SessionFs API. This lets you map all session storage into your own custom storage through callbacks, for example to store data in the cloud or in a database. See Improved SessionFs provider API in the 0.3.0 release - full docs coming soon.


Other changes and improvements

[.NET] Improved NativeAOT and trimming compatibility by replacing the StreamJsonRpc dependency with a custom JSON-RPC implementation, reducing external dependencies and deployment overhead (#1170)

Bug fixes

[.NET] Fix AOT serialization for SetForegroundSessionIdAsync() by adding a source-generated request type (#1144)


⚠️ Breaking changes

RPC type renames

Schema updates in this release renamed several generated types across all SDKs. If your code references these types by name (via imports or type annotations), you'll need to update:

Previous Now
PermissionCompletedResult PermissionResult
PermissionCompletedKind PermissionResultKind
ToolsHandlePendingToolCallRequest HandlePendingToolCallRequest
HandleToolCallResult HandlePendingToolCallResult

The ToolCallResult type and ToolsHandlePendingToolCall type alias have been removed and replaced by the types above.

Cross-language note: As with previous releases, the same logical renames apply across all four SDKs with language-appropriate casing.

[.NET] StreamJsonRpc dependency removed

The .NET SDK no longer depends on StreamJsonRpc, having replaced it with a custom JSON-RPC implementation (#1170). If your application was relying on StreamJsonRpc as a transitive dependency from the SDK, you'll need to add a direct reference to your project.

New contributors

  • @Encryptoid made their first contribution in #1144