All notable changes to the Copilot SDK are documented in this file.
This changelog is automatically generated by an AI agent when stable releases are published. See GitHub Releases for the full list.
v0.1.32 (2026-03-07)
SDK applications written against the v3 API now also work when connected to a v2 CLI server, with no code changes required. The SDK detects the server's protocol version and automatically adapts v2 tool.call and permission.request messages into the same user-facing handlers used by v3. (#706)
const session = await client.createSession({
tools: [myTool], // unchanged — works with v2 and v3 servers
onPermissionRequest: approveAll,
});var session = await client.CreateSessionAsync(new SessionConfig {
Tools = [myTool], // unchanged — works with v2 and v3 servers
OnPermissionRequest = approveAll,
});v0.1.31 (2026-03-07)
The SDK now uses protocol version 3, where the runtime broadcasts external_tool.requested and permission.requested as session events to all connected clients. This enables multi-client architectures where different clients contribute different tools, or where multiple clients observe the same permission prompts — if one client approves, all clients see the result. Your existing tool and permission handler code is unchanged. (#686)
// Two clients each register different tools; the agent can use both
const session1 = await client1.createSession({
tools: [defineTool("search", { handler: doSearch })],
onPermissionRequest: approveAll,
});
const session2 = await client2.resumeSession(session1.id, {
tools: [defineTool("analyze", { handler: doAnalyze })],
onPermissionRequest: approveAll,
});var session1 = await client1.CreateSessionAsync(new SessionConfig {
Tools = [AIFunctionFactory.Create(DoSearch, "search")],
OnPermissionRequest = PermissionHandlers.ApproveAll,
});
var session2 = await client2.ResumeSessionAsync(session1.Id, new ResumeSessionConfig {
Tools = [AIFunctionFactory.Create(DoAnalyze, "analyze")],
OnPermissionRequest = PermissionHandlers.ApproveAll,
});Rather than comparing result.Kind against undiscoverable magic strings like "approved" or "denied-interactively-by-user", .NET and Go now provide typed constants. Node and Python already had typed unions for this; this brings full parity. (#631)
session.OnPermissionCompleted += (e) => {
if (e.Result.Kind == PermissionRequestResultKind.Approved) { /* ... */ }
if (e.Result.Kind == PermissionRequestResultKind.DeniedInteractivelyByUser) { /* ... */ }
};// Go: PermissionKindApproved, PermissionKindDeniedByRules,
// PermissionKindDeniedCouldNotRequestFromUser, PermissionKindDeniedInteractivelyByUser
if result.Kind == copilot.PermissionKindApproved { /* ... */ }- feature: [Python] [Go] add
get_last_session_id()/GetLastSessionID()for SDK-wide parity (was already available in Node and .NET) (#671) - improvement: [Python] add
timeoutparameter to generated RPC methods, allowing callers to override the default 30s timeout for long-running operations (#681) - bugfix: [Go]
PermissionRequestfields are now properly typed (ToolName,Diff,Path, etc.) instead of a genericExtra map[string]anycatch-all (#685)
v0.1.30 (2026-03-03)
Applications can now override built-in tools such as grep, edit_file, or read_file. To do this, register a custom tool with the same name and set the override flag. Without the flag, the runtime will return an error if the name clashes with a built-in. (#636)
import { defineTool } from "@github/copilot-sdk";
const session = await client.createSession({
tools: [defineTool("grep", {
overridesBuiltInTool: true,
handler: async (params) => `CUSTOM_GREP_RESULT: ${params.query}`,
})],
onPermissionRequest: approveAll,
});var grep = AIFunctionFactory.Create(
([Description("Search query")] string query) => $"CUSTOM_GREP_RESULT: {query}",
"grep",
"Custom grep implementation",
new AIFunctionFactoryOptions
{
AdditionalProperties = new ReadOnlyDictionary<string, object?>(
new Dictionary<string, object?> { ["is_override"] = true })
});While session.rpc.model.switchTo() already worked, there is now a convenience method directly on the session object. (#621)
- TypeScript:
await session.setModel("gpt-4.1") - C#:
await session.SetModelAsync("gpt-4.1") - Python:
await session.set_model("gpt-4.1") - Go:
err := session.SetModel(ctx, "gpt-4.1")
- improvement: [C#] use event delegate for thread-safe, insertion-ordered event handler dispatch (#624)
- improvement: [C#] deduplicate
OnDisposeCalland improve implementation (#626) - improvement: [C#] remove unnecessary
SemaphoreSlimlocks for handler fields (#625) - bugfix: [Python] correct
PermissionHandler.approve_alltype annotations (#618)
- @giulio-leone made their first contribution in #618