From 33f544c71d8a311d55b5cae123ffc1691ac3d8fb Mon Sep 17 00:00:00 2001 From: James Montemagno Date: Sun, 22 Mar 2026 17:11:19 -0700 Subject: [PATCH] Align Copilot SDK documentation with permission handling requirements (#1107) * Apply permission handler requirements across Copilot SDK docs Co-authored-by: jamesmontemagno <1676321+jamesmontemagno@users.noreply.github.com> Agent-Logs-Url: https://github.com/jamesmontemagno/awesome-copilot/sessions/adf27a88-92f8-4ca6-b3fe-1204e3bb9963 * Polish permission update formatting in SDK examples Co-authored-by: jamesmontemagno <1676321+jamesmontemagno@users.noreply.github.com> Agent-Logs-Url: https://github.com/jamesmontemagno/awesome-copilot/sessions/adf27a88-92f8-4ca6-b3fe-1204e3bb9963 * Fix review comments on SDK permission handling PR Address 5 review comments from PR #1103: 1. Fix invalid object literal syntax (stray comma) in resumeSession example in copilot-sdk-nodejs.instructions.md 2. Replace unused PermissionHandler import with actual usage in cookbook/copilot-sdk/python/recipe/ralph_loop.py (was using inline lambda instead) 3. Replace unused approveAll import with actual usage in cookbook/copilot-sdk/nodejs/recipe/ralph-loop.ts (was using inline handler instead) 4. Add missing PermissionHandler import to 4 Python code snippets in skills/copilot-sdk/SKILL.md that reference it without importing 5. Add missing approveAll import to 3 TypeScript code snippets in skills/copilot-sdk/SKILL.md that reference it without importing * Refactor session creation to improve code formatting and consistency across SDK examples * Fix formatting: split multi-property lines and put closing braces on own lines Address review comments on PR #1107: - Split OnPermissionRequest + Model onto separate lines in Go, C#, TypeScript - Put closing }); on its own line consistently across all examples - Fix indentation in SKILL.md Quick Start, CLI URL, Error Handling sections - Fix cookbook Go multiple-sessions and error-handling formatting - Fix ralph-loop.md TypeScript indentation --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jamesmontemagno <1676321+jamesmontemagno@users.noreply.github.com> --- .../copilot-sdk/dotnet/persisting-sessions.md | 2 +- .../dotnet/recipe/persisting-sessions.cs | 2 +- .../copilot-sdk/go/accessibility-report.md | 2 + cookbook/copilot-sdk/go/error-handling.md | 6 +- .../copilot-sdk/go/managing-local-files.md | 1 + cookbook/copilot-sdk/go/multiple-sessions.md | 16 +++- .../copilot-sdk/go/persisting-sessions.md | 3 +- cookbook/copilot-sdk/go/pr-visualization.md | 1 + cookbook/copilot-sdk/go/ralph-loop.md | 1 + .../go/recipe/accessibility-report.go | 1 + .../copilot-sdk/go/recipe/error-handling.go | 1 + .../go/recipe/managing-local-files.go | 1 + .../go/recipe/multiple-sessions.go | 15 +++- .../go/recipe/persisting-sessions.go | 3 +- .../copilot-sdk/go/recipe/pr-visualization.go | 1 + .../nodejs/accessibility-report.md | 4 +- cookbook/copilot-sdk/nodejs/error-handling.md | 17 +++- .../nodejs/managing-local-files.md | 3 +- .../copilot-sdk/nodejs/multiple-sessions.md | 18 +++- .../copilot-sdk/nodejs/persisting-sessions.md | 5 +- .../copilot-sdk/nodejs/pr-visualization.md | 3 +- cookbook/copilot-sdk/nodejs/ralph-loop.md | 7 +- .../nodejs/recipe/accessibility-report.ts | 3 +- .../nodejs/recipe/error-handling.ts | 7 +- .../nodejs/recipe/managing-local-files.ts | 3 +- .../nodejs/recipe/multiple-sessions.ts | 17 +++- .../nodejs/recipe/persisting-sessions.ts | 5 +- .../nodejs/recipe/pr-visualization.ts | 3 +- .../copilot-sdk/nodejs/recipe/ralph-loop.ts | 4 +- .../python/accessibility-report.md | 9 +- cookbook/copilot-sdk/python/error-handling.md | 11 ++- .../python/managing-local-files.md | 8 +- .../copilot-sdk/python/multiple-sessions.md | 15 ++-- .../copilot-sdk/python/persisting-sessions.md | 6 +- .../copilot-sdk/python/pr-visualization.md | 9 +- cookbook/copilot-sdk/python/ralph-loop.md | 5 +- .../python/recipe/accessibility_report.py | 7 +- .../python/recipe/error_handling.py | 5 +- .../python/recipe/managing_local_files.py | 8 +- .../python/recipe/multiple_sessions.py | 11 ++- .../python/recipe/persisting_sessions.py | 6 +- .../python/recipe/pr_visualization.py | 9 +- .../copilot-sdk/python/recipe/ralph_loop.py | 7 +- .../copilot-sdk-csharp.instructions.md | 32 +++++-- instructions/copilot-sdk-go.instructions.md | 34 +++++-- .../copilot-sdk-nodejs.instructions.md | 48 ++++++---- .../copilot-sdk-python.instructions.md | 45 +++++++--- skills/copilot-sdk/SKILL.md | 89 +++++++++++++++---- 48 files changed, 376 insertions(+), 143 deletions(-) diff --git a/cookbook/copilot-sdk/dotnet/persisting-sessions.md b/cookbook/copilot-sdk/dotnet/persisting-sessions.md index 01883d2e..d0e4e6d3 100644 --- a/cookbook/copilot-sdk/dotnet/persisting-sessions.md +++ b/cookbook/copilot-sdk/dotnet/persisting-sessions.md @@ -46,7 +46,7 @@ await using var client = new CopilotClient(); await client.StartAsync(); // Resume the previous session -var session = await client.ResumeSessionAsync("user-123-conversation"); +var session = await client.ResumeSessionAsync("user-123-conversation", new ResumeSessionConfig { OnPermissionRequest = PermissionHandler.ApproveAll }); // Previous context is restored await session.SendAsync(new MessageOptions { Prompt = "What were we discussing?" }); diff --git a/cookbook/copilot-sdk/dotnet/recipe/persisting-sessions.cs b/cookbook/copilot-sdk/dotnet/recipe/persisting-sessions.cs index e7bb64dc..138551fd 100644 --- a/cookbook/copilot-sdk/dotnet/recipe/persisting-sessions.cs +++ b/cookbook/copilot-sdk/dotnet/recipe/persisting-sessions.cs @@ -22,7 +22,7 @@ await session.DisposeAsync(); Console.WriteLine("Session destroyed (state persisted)"); // Resume the previous session -var resumed = await client.ResumeSessionAsync("user-123-conversation"); +var resumed = await client.ResumeSessionAsync("user-123-conversation", new ResumeSessionConfig { OnPermissionRequest = PermissionHandler.ApproveAll }); Console.WriteLine($"Resumed: {resumed.SessionId}"); await resumed.SendAsync(new MessageOptions { Prompt = "What were we discussing?" }); diff --git a/cookbook/copilot-sdk/go/accessibility-report.md b/cookbook/copilot-sdk/go/accessibility-report.md index afe7ea27..3f4fdb5f 100644 --- a/cookbook/copilot-sdk/go/accessibility-report.md +++ b/cookbook/copilot-sdk/go/accessibility-report.md @@ -77,6 +77,7 @@ func main() { streaming := true session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "claude-opus-4.6", Streaming: &streaming, McpServers: map[string]interface{}{ @@ -214,6 +215,7 @@ The recipe configures a local MCP server that runs alongside the session: ```go session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, McpServers: map[string]interface{}{ "playwright": map[string]interface{}{ "type": "local", diff --git a/cookbook/copilot-sdk/go/error-handling.md b/cookbook/copilot-sdk/go/error-handling.md index 462d2706..a63079ac 100644 --- a/cookbook/copilot-sdk/go/error-handling.md +++ b/cookbook/copilot-sdk/go/error-handling.md @@ -34,6 +34,7 @@ func main() { defer client.Stop() session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", }) if err != nil { @@ -177,7 +178,10 @@ func doWork() error { } defer client.Stop() - session, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-5"}) + session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "gpt-5", + }) if err != nil { return fmt.Errorf("failed to create session: %w", err) } diff --git a/cookbook/copilot-sdk/go/managing-local-files.md b/cookbook/copilot-sdk/go/managing-local-files.md index f86871a5..1a7b0e4e 100644 --- a/cookbook/copilot-sdk/go/managing-local-files.md +++ b/cookbook/copilot-sdk/go/managing-local-files.md @@ -38,6 +38,7 @@ func main() { // Create session session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", }) if err != nil { diff --git a/cookbook/copilot-sdk/go/multiple-sessions.md b/cookbook/copilot-sdk/go/multiple-sessions.md index 82d8bf50..1e4ead3d 100644 --- a/cookbook/copilot-sdk/go/multiple-sessions.md +++ b/cookbook/copilot-sdk/go/multiple-sessions.md @@ -34,19 +34,28 @@ func main() { defer client.Stop() // Create multiple independent sessions - session1, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-5"}) + session1, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "gpt-5", + }) if err != nil { log.Fatal(err) } defer session1.Destroy() - session2, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-5"}) + session2, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "gpt-5", + }) if err != nil { log.Fatal(err) } defer session2.Destroy() - session3, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "claude-sonnet-4.5"}) + session3, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "claude-sonnet-4.5", + }) if err != nil { log.Fatal(err) } @@ -70,6 +79,7 @@ Use custom IDs for easier tracking: ```go session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, SessionID: "user-123-chat", Model: "gpt-5", }) diff --git a/cookbook/copilot-sdk/go/persisting-sessions.md b/cookbook/copilot-sdk/go/persisting-sessions.md index ea13b7ab..dba72be0 100644 --- a/cookbook/copilot-sdk/go/persisting-sessions.md +++ b/cookbook/copilot-sdk/go/persisting-sessions.md @@ -32,6 +32,7 @@ func main() { // Create session with a memorable ID session, _ := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, SessionID: "user-123-conversation", Model: "gpt-5", }) @@ -55,7 +56,7 @@ client.Start(ctx) defer client.Stop() // Resume the previous session -session, _ := client.ResumeSession(ctx, "user-123-conversation") +session, _ := client.ResumeSession(ctx, "user-123-conversation", &copilot.ResumeSessionConfig{OnPermissionRequest: copilot.PermissionHandler.ApproveAll}) // Previous context is restored session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What were we discussing?"}) diff --git a/cookbook/copilot-sdk/go/pr-visualization.md b/cookbook/copilot-sdk/go/pr-visualization.md index b0c7c0b3..c6d0fef0 100644 --- a/cookbook/copilot-sdk/go/pr-visualization.md +++ b/cookbook/copilot-sdk/go/pr-visualization.md @@ -138,6 +138,7 @@ func main() { cwd, _ := os.Getwd() session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", SystemMessage: &copilot.SystemMessageConfig{ Content: fmt.Sprintf(` diff --git a/cookbook/copilot-sdk/go/ralph-loop.md b/cookbook/copilot-sdk/go/ralph-loop.md index f8462c3d..cc73daa6 100644 --- a/cookbook/copilot-sdk/go/ralph-loop.md +++ b/cookbook/copilot-sdk/go/ralph-loop.md @@ -70,6 +70,7 @@ func ralphLoop(ctx context.Context, promptFile string, maxIterations int) error // Fresh session each iteration — context isolation is the point session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5.1-codex-mini", }) if err != nil { diff --git a/cookbook/copilot-sdk/go/recipe/accessibility-report.go b/cookbook/copilot-sdk/go/recipe/accessibility-report.go index e1ae2a49..cc743f4a 100644 --- a/cookbook/copilot-sdk/go/recipe/accessibility-report.go +++ b/cookbook/copilot-sdk/go/recipe/accessibility-report.go @@ -45,6 +45,7 @@ func main() { streaming := true session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "claude-opus-4.6", Streaming: &streaming, McpServers: map[string]interface{}{ diff --git a/cookbook/copilot-sdk/go/recipe/error-handling.go b/cookbook/copilot-sdk/go/recipe/error-handling.go index 3fc0fcdc..6760f7a4 100644 --- a/cookbook/copilot-sdk/go/recipe/error-handling.go +++ b/cookbook/copilot-sdk/go/recipe/error-handling.go @@ -18,6 +18,7 @@ func main() { defer client.Stop() session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", }) if err != nil { diff --git a/cookbook/copilot-sdk/go/recipe/managing-local-files.go b/cookbook/copilot-sdk/go/recipe/managing-local-files.go index dc3dfd84..596b93db 100644 --- a/cookbook/copilot-sdk/go/recipe/managing-local-files.go +++ b/cookbook/copilot-sdk/go/recipe/managing-local-files.go @@ -22,6 +22,7 @@ func main() { // Create session session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", }) if err != nil { diff --git a/cookbook/copilot-sdk/go/recipe/multiple-sessions.go b/cookbook/copilot-sdk/go/recipe/multiple-sessions.go index 9b99fcd2..90a42a0f 100644 --- a/cookbook/copilot-sdk/go/recipe/multiple-sessions.go +++ b/cookbook/copilot-sdk/go/recipe/multiple-sessions.go @@ -18,19 +18,28 @@ func main() { defer client.Stop() // Create multiple independent sessions - session1, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-5"}) + session1, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "gpt-5", + }) if err != nil { log.Fatal(err) } defer session1.Destroy() - session2, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-5"}) + session2, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "gpt-5", + }) if err != nil { log.Fatal(err) } defer session2.Destroy() - session3, err := client.CreateSession(ctx, &copilot.SessionConfig{Model: "claude-sonnet-4.5"}) + session3, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "claude-sonnet-4.5", + }) if err != nil { log.Fatal(err) } diff --git a/cookbook/copilot-sdk/go/recipe/persisting-sessions.go b/cookbook/copilot-sdk/go/recipe/persisting-sessions.go index 471e5757..c3a8fcef 100644 --- a/cookbook/copilot-sdk/go/recipe/persisting-sessions.go +++ b/cookbook/copilot-sdk/go/recipe/persisting-sessions.go @@ -18,6 +18,7 @@ func main() { // Create session with a memorable ID session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, SessionID: "user-123-conversation", Model: "gpt-5", }) @@ -36,7 +37,7 @@ func main() { fmt.Println("Session destroyed (state persisted)") // Resume the previous session - resumed, err := client.ResumeSession(ctx, "user-123-conversation") + resumed, err := client.ResumeSession(ctx, "user-123-conversation", &copilot.ResumeSessionConfig{OnPermissionRequest: copilot.PermissionHandler.ApproveAll}) if err != nil { log.Fatal(err) } diff --git a/cookbook/copilot-sdk/go/recipe/pr-visualization.go b/cookbook/copilot-sdk/go/recipe/pr-visualization.go index 54178eec..e9ad08b3 100644 --- a/cookbook/copilot-sdk/go/recipe/pr-visualization.go +++ b/cookbook/copilot-sdk/go/recipe/pr-visualization.go @@ -102,6 +102,7 @@ func main() { cwd, _ := os.Getwd() session, err := client.CreateSession(ctx, &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", SystemMessage: &copilot.SystemMessageConfig{ Content: fmt.Sprintf(` diff --git a/cookbook/copilot-sdk/nodejs/accessibility-report.md b/cookbook/copilot-sdk/nodejs/accessibility-report.md index 74cb7747..849dd726 100644 --- a/cookbook/copilot-sdk/nodejs/accessibility-report.md +++ b/cookbook/copilot-sdk/nodejs/accessibility-report.md @@ -35,7 +35,7 @@ npx tsx accessibility-report.ts ```typescript #!/usr/bin/env npx tsx -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; import * as readline from "node:readline"; // ============================================================================ @@ -73,6 +73,7 @@ async function main() { const client = new CopilotClient(); const session = await client.createSession({ + onPermissionRequest: approveAll, model: "claude-opus-4.6", streaming: true, mcpServers: { @@ -191,6 +192,7 @@ The recipe configures a local MCP server that runs alongside the session: ```typescript const session = await client.createSession({ + onPermissionRequest: approveAll, mcpServers: { playwright: { type: "local", diff --git a/cookbook/copilot-sdk/nodejs/error-handling.md b/cookbook/copilot-sdk/nodejs/error-handling.md index a6679502..e330a148 100644 --- a/cookbook/copilot-sdk/nodejs/error-handling.md +++ b/cookbook/copilot-sdk/nodejs/error-handling.md @@ -17,13 +17,16 @@ You need to handle various error conditions like connection failures, timeouts, ## Basic try-catch ```typescript -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; const client = new CopilotClient(); try { await client.start(); - const session = await client.createSession({ model: "gpt-5" }); + const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", + }); const response = await session.sendAndWait({ prompt: "Hello!" }); console.log(response?.data.content); @@ -55,7 +58,10 @@ try { ## Timeout handling ```typescript -const session = await client.createSession({ model: "gpt-5" }); +const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", +}); try { // sendAndWait with timeout (in milliseconds) @@ -79,7 +85,10 @@ try { ## Aborting a request ```typescript -const session = await client.createSession({ model: "gpt-5" }); +const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", +}); // Start a request session.send({ prompt: "Write a very long story..." }); diff --git a/cookbook/copilot-sdk/nodejs/managing-local-files.md b/cookbook/copilot-sdk/nodejs/managing-local-files.md index d1f02e2a..619f34d0 100644 --- a/cookbook/copilot-sdk/nodejs/managing-local-files.md +++ b/cookbook/copilot-sdk/nodejs/managing-local-files.md @@ -17,7 +17,7 @@ You have a folder with many files and want to organize them into subfolders base ## Example code ```typescript -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; import * as os from "node:os"; import * as path from "node:path"; @@ -27,6 +27,7 @@ await client.start(); // Create session const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-5", }); diff --git a/cookbook/copilot-sdk/nodejs/multiple-sessions.md b/cookbook/copilot-sdk/nodejs/multiple-sessions.md index f1c7543a..44673574 100644 --- a/cookbook/copilot-sdk/nodejs/multiple-sessions.md +++ b/cookbook/copilot-sdk/nodejs/multiple-sessions.md @@ -17,15 +17,24 @@ You need to run multiple conversations in parallel, each with its own context an ## Node.js ```typescript -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; const client = new CopilotClient(); await client.start(); // Create multiple independent sessions -const session1 = await client.createSession({ model: "gpt-5" }); -const session2 = await client.createSession({ model: "gpt-5" }); -const session3 = await client.createSession({ model: "claude-sonnet-4.5" }); +const session1 = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", +}); +const session2 = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", +}); +const session3 = await client.createSession({ + onPermissionRequest: approveAll, + model: "claude-sonnet-4.5", +}); // Each session maintains its own conversation history await session1.sendAndWait({ prompt: "You are helping with a Python project" }); @@ -50,6 +59,7 @@ Use custom IDs for easier tracking: ```typescript const session = await client.createSession({ + onPermissionRequest: approveAll, sessionId: "user-123-chat", model: "gpt-5", }); diff --git a/cookbook/copilot-sdk/nodejs/persisting-sessions.md b/cookbook/copilot-sdk/nodejs/persisting-sessions.md index ccb7b591..9b211473 100644 --- a/cookbook/copilot-sdk/nodejs/persisting-sessions.md +++ b/cookbook/copilot-sdk/nodejs/persisting-sessions.md @@ -17,13 +17,14 @@ You want users to be able to continue a conversation even after closing and reop ### Creating a session with a custom ID ```typescript -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; const client = new CopilotClient(); await client.start(); // Create session with a memorable ID const session = await client.createSession({ + onPermissionRequest: approveAll, sessionId: "user-123-conversation", model: "gpt-5", }); @@ -45,7 +46,7 @@ const client = new CopilotClient(); await client.start(); // Resume the previous session -const session = await client.resumeSession("user-123-conversation"); +const session = await client.resumeSession("user-123-conversation", { onPermissionRequest: approveAll }); // Previous context is restored await session.sendAndWait({ prompt: "What were we discussing?" }); diff --git a/cookbook/copilot-sdk/nodejs/pr-visualization.md b/cookbook/copilot-sdk/nodejs/pr-visualization.md index 1dba238a..5218be3e 100644 --- a/cookbook/copilot-sdk/nodejs/pr-visualization.md +++ b/cookbook/copilot-sdk/nodejs/pr-visualization.md @@ -42,7 +42,7 @@ npx tsx pr-visualization.ts --repo github/copilot-sdk import { execSync } from "node:child_process"; import * as readline from "node:readline"; -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; // ============================================================================ // Git & GitHub Detection @@ -138,6 +138,7 @@ async function main() { const client = new CopilotClient({ logLevel: "error" }); const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-5", systemMessage: { content: ` diff --git a/cookbook/copilot-sdk/nodejs/ralph-loop.md b/cookbook/copilot-sdk/nodejs/ralph-loop.md index 87c5225f..7ac87bf7 100644 --- a/cookbook/copilot-sdk/nodejs/ralph-loop.md +++ b/cookbook/copilot-sdk/nodejs/ralph-loop.md @@ -43,7 +43,7 @@ The minimal Ralph loop — the SDK equivalent of `while :; do cat PROMPT.md | co ```typescript import { readFile } from "fs/promises"; -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; async function ralphLoop(promptFile: string, maxIterations: number = 50) { const client = new CopilotClient(); @@ -56,7 +56,10 @@ async function ralphLoop(promptFile: string, maxIterations: number = 50) { console.log(`\n=== Iteration ${i}/${maxIterations} ===`); // Fresh session each iteration — context isolation is the point - const session = await client.createSession({ model: "gpt-5.1-codex-mini" }); + const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5.1-codex-mini", + }); try { await session.sendAndWait({ prompt }, 600_000); } finally { diff --git a/cookbook/copilot-sdk/nodejs/recipe/accessibility-report.ts b/cookbook/copilot-sdk/nodejs/recipe/accessibility-report.ts index a096726e..28ab7aba 100644 --- a/cookbook/copilot-sdk/nodejs/recipe/accessibility-report.ts +++ b/cookbook/copilot-sdk/nodejs/recipe/accessibility-report.ts @@ -1,6 +1,6 @@ #!/usr/bin/env tsx -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; import * as readline from "node:readline"; // ============================================================================ @@ -38,6 +38,7 @@ async function main() { const client = new CopilotClient(); const session = await client.createSession({ + onPermissionRequest: approveAll, model: "claude-opus-4.6", streaming: true, mcpServers: { diff --git a/cookbook/copilot-sdk/nodejs/recipe/error-handling.ts b/cookbook/copilot-sdk/nodejs/recipe/error-handling.ts index 1e8c5c54..9077c284 100644 --- a/cookbook/copilot-sdk/nodejs/recipe/error-handling.ts +++ b/cookbook/copilot-sdk/nodejs/recipe/error-handling.ts @@ -1,10 +1,13 @@ -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; const client = new CopilotClient(); try { await client.start(); - const session = await client.createSession({ model: "gpt-5" }); + const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", + }); const response = await session.sendAndWait({ prompt: "Hello!" }); console.log(response?.data.content); diff --git a/cookbook/copilot-sdk/nodejs/recipe/managing-local-files.ts b/cookbook/copilot-sdk/nodejs/recipe/managing-local-files.ts index d02427a6..20fb21b1 100644 --- a/cookbook/copilot-sdk/nodejs/recipe/managing-local-files.ts +++ b/cookbook/copilot-sdk/nodejs/recipe/managing-local-files.ts @@ -1,4 +1,4 @@ -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; import * as os from "node:os"; import * as path from "node:path"; @@ -8,6 +8,7 @@ await client.start(); // Create session const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-5", }); diff --git a/cookbook/copilot-sdk/nodejs/recipe/multiple-sessions.ts b/cookbook/copilot-sdk/nodejs/recipe/multiple-sessions.ts index 2420217f..2c830397 100644 --- a/cookbook/copilot-sdk/nodejs/recipe/multiple-sessions.ts +++ b/cookbook/copilot-sdk/nodejs/recipe/multiple-sessions.ts @@ -1,12 +1,21 @@ -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; const client = new CopilotClient(); await client.start(); // Create multiple independent sessions -const session1 = await client.createSession({ model: "gpt-5" }); -const session2 = await client.createSession({ model: "gpt-5" }); -const session3 = await client.createSession({ model: "claude-sonnet-4.5" }); +const session1 = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", +}); +const session2 = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", +}); +const session3 = await client.createSession({ + onPermissionRequest: approveAll, + model: "claude-sonnet-4.5", +}); console.log("Created 3 independent sessions"); diff --git a/cookbook/copilot-sdk/nodejs/recipe/persisting-sessions.ts b/cookbook/copilot-sdk/nodejs/recipe/persisting-sessions.ts index f015cae4..7f04f468 100644 --- a/cookbook/copilot-sdk/nodejs/recipe/persisting-sessions.ts +++ b/cookbook/copilot-sdk/nodejs/recipe/persisting-sessions.ts @@ -1,10 +1,11 @@ -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; const client = new CopilotClient(); await client.start(); // Create a session with a memorable ID const session = await client.createSession({ + onPermissionRequest: approveAll, sessionId: "user-123-conversation", model: "gpt-5", }); @@ -17,7 +18,7 @@ await session.destroy(); console.log("Session destroyed (state persisted)"); // Resume the previous session -const resumed = await client.resumeSession("user-123-conversation"); +const resumed = await client.resumeSession("user-123-conversation", { onPermissionRequest: approveAll }); console.log(`Resumed: ${resumed.sessionId}`); await resumed.sendAndWait({ prompt: "What were we discussing?" }); diff --git a/cookbook/copilot-sdk/nodejs/recipe/pr-visualization.ts b/cookbook/copilot-sdk/nodejs/recipe/pr-visualization.ts index d0c118e2..cd1d5eb1 100644 --- a/cookbook/copilot-sdk/nodejs/recipe/pr-visualization.ts +++ b/cookbook/copilot-sdk/nodejs/recipe/pr-visualization.ts @@ -1,6 +1,6 @@ #!/usr/bin/env tsx -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; import { execSync } from "node:child_process"; import * as readline from "node:readline"; @@ -98,6 +98,7 @@ async function main() { const client = new CopilotClient({ logLevel: "error" }); const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-5", systemMessage: { content: ` diff --git a/cookbook/copilot-sdk/nodejs/recipe/ralph-loop.ts b/cookbook/copilot-sdk/nodejs/recipe/ralph-loop.ts index fb0fbe45..a594fe14 100644 --- a/cookbook/copilot-sdk/nodejs/recipe/ralph-loop.ts +++ b/cookbook/copilot-sdk/nodejs/recipe/ralph-loop.ts @@ -1,5 +1,5 @@ import { readFile } from "fs/promises"; -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; /** * Ralph loop: autonomous AI task loop with fresh context per iteration. @@ -44,7 +44,7 @@ async function ralphLoop(mode: Mode, maxIterations: number) { // Pin the agent to the project directory workingDirectory: process.cwd(), // Auto-approve tool calls for unattended operation - onPermissionRequest: async () => ({ allow: true }), + onPermissionRequest: approveAll, }); // Log tool usage for visibility diff --git a/cookbook/copilot-sdk/python/accessibility-report.md b/cookbook/copilot-sdk/python/accessibility-report.md index ad22c671..93e143f5 100644 --- a/cookbook/copilot-sdk/python/accessibility-report.md +++ b/cookbook/copilot-sdk/python/accessibility-report.md @@ -35,8 +35,11 @@ python accessibility_report.py import asyncio from copilot import ( - CopilotClient, SessionConfig, MessageOptions, + CopilotClient, + SessionConfig, + MessageOptions, SessionEvent, + PermissionHandler, ) # ============================================================================ @@ -74,7 +77,7 @@ async def main(): "tools": ["*"], } }, - )) + on_permission_request=PermissionHandler.approve_all)) done = asyncio.Event() @@ -187,7 +190,7 @@ session = await client.create_session(SessionConfig( "tools": ["*"], } }, -)) + on_permission_request=PermissionHandler.approve_all)) ``` This gives the model access to Playwright browser tools like `browser_navigate`, `browser_snapshot`, and `browser_click`. diff --git a/cookbook/copilot-sdk/python/error-handling.md b/cookbook/copilot-sdk/python/error-handling.md index dfdd02b9..51b2a322 100644 --- a/cookbook/copilot-sdk/python/error-handling.md +++ b/cookbook/copilot-sdk/python/error-handling.md @@ -17,14 +17,15 @@ You need to handle various error conditions like connection failures, timeouts, ```python import asyncio -from copilot import CopilotClient, SessionConfig, MessageOptions +from copilot import CopilotClient, SessionConfig, MessageOptions, PermissionHandler async def main(): client = CopilotClient() try: await client.start() - session = await client.create_session(SessionConfig(model="gpt-5")) + session = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) response = await session.send_and_wait(MessageOptions(prompt="Hello!")) @@ -57,7 +58,8 @@ except Exception as e: ## Timeout handling ```python -session = await client.create_session(SessionConfig(model="gpt-5")) +session = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) try: # send_and_wait accepts an optional timeout in seconds @@ -73,7 +75,8 @@ except TimeoutError: ## Aborting a request ```python -session = await client.create_session(SessionConfig(model="gpt-5")) +session = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) # Start a request (non-blocking send) await session.send(MessageOptions(prompt="Write a very long story...")) diff --git a/cookbook/copilot-sdk/python/managing-local-files.md b/cookbook/copilot-sdk/python/managing-local-files.md index f1e78b02..37de1207 100644 --- a/cookbook/copilot-sdk/python/managing-local-files.md +++ b/cookbook/copilot-sdk/python/managing-local-files.md @@ -19,8 +19,11 @@ You have a folder with many files and want to organize them into subfolders base import asyncio import os from copilot import ( - CopilotClient, SessionConfig, MessageOptions, + CopilotClient, + SessionConfig, + MessageOptions, SessionEvent, + PermissionHandler, ) async def main(): @@ -29,7 +32,8 @@ async def main(): await client.start() # Create session - session = await client.create_session(SessionConfig(model="gpt-5")) + session = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) done = asyncio.Event() diff --git a/cookbook/copilot-sdk/python/multiple-sessions.md b/cookbook/copilot-sdk/python/multiple-sessions.md index 0efa3ed8..b69e6298 100644 --- a/cookbook/copilot-sdk/python/multiple-sessions.md +++ b/cookbook/copilot-sdk/python/multiple-sessions.md @@ -17,16 +17,19 @@ You need to run multiple conversations in parallel, each with its own context an ```python import asyncio -from copilot import CopilotClient, SessionConfig, MessageOptions +from copilot import CopilotClient, SessionConfig, MessageOptions, PermissionHandler async def main(): client = CopilotClient() await client.start() # Create multiple independent sessions - session1 = await client.create_session(SessionConfig(model="gpt-5")) - session2 = await client.create_session(SessionConfig(model="gpt-5")) - session3 = await client.create_session(SessionConfig(model="claude-sonnet-4.5")) + session1 = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) + session2 = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) + session3 = await client.create_session(SessionConfig(model="claude-sonnet-4.5", + on_permission_request=PermissionHandler.approve_all)) # Each session maintains its own conversation history await session1.send(MessageOptions(prompt="You are helping with a Python project")) @@ -55,8 +58,8 @@ Use custom IDs for easier tracking: ```python session = await client.create_session(SessionConfig( session_id="user-123-chat", - model="gpt-5" -)) + model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) print(session.session_id) # "user-123-chat" ``` diff --git a/cookbook/copilot-sdk/python/persisting-sessions.md b/cookbook/copilot-sdk/python/persisting-sessions.md index cc77407c..6f18d9a5 100644 --- a/cookbook/copilot-sdk/python/persisting-sessions.md +++ b/cookbook/copilot-sdk/python/persisting-sessions.md @@ -17,7 +17,7 @@ You want users to be able to continue a conversation even after closing and reop ```python import asyncio -from copilot import CopilotClient, SessionConfig, MessageOptions +from copilot import CopilotClient, SessionConfig, MessageOptions, PermissionHandler async def main(): client = CopilotClient() @@ -27,7 +27,7 @@ async def main(): session = await client.create_session(SessionConfig( session_id="user-123-conversation", model="gpt-5", - )) + on_permission_request=PermissionHandler.approve_all)) await session.send_and_wait(MessageOptions(prompt="Let's discuss TypeScript generics")) @@ -49,7 +49,7 @@ client = CopilotClient() await client.start() # Resume the previous session -session = await client.resume_session("user-123-conversation") +session = await client.resume_session("user-123-conversation", on_permission_request=PermissionHandler.approve_all) # Previous context is restored await session.send_and_wait(MessageOptions(prompt="What were we discussing?")) diff --git a/cookbook/copilot-sdk/python/pr-visualization.md b/cookbook/copilot-sdk/python/pr-visualization.md index 2e3d108b..0c4a3687 100644 --- a/cookbook/copilot-sdk/python/pr-visualization.md +++ b/cookbook/copilot-sdk/python/pr-visualization.md @@ -44,8 +44,11 @@ import sys import os import re from copilot import ( - CopilotClient, SessionConfig, MessageOptions, + CopilotClient, + SessionConfig, + MessageOptions, SessionEvent, + PermissionHandler, ) # ============================================================================ @@ -150,8 +153,8 @@ The current working directory is: {os.getcwd()} - Be concise in your responses """ - } - )) + }, + on_permission_request=PermissionHandler.approve_all)) done = asyncio.Event() diff --git a/cookbook/copilot-sdk/python/ralph-loop.md b/cookbook/copilot-sdk/python/ralph-loop.md index b0d1c4b6..50f0338f 100644 --- a/cookbook/copilot-sdk/python/ralph-loop.md +++ b/cookbook/copilot-sdk/python/ralph-loop.md @@ -48,7 +48,7 @@ The minimal Ralph loop — the SDK equivalent of `while :; do cat PROMPT.md | co ```python import asyncio from pathlib import Path -from copilot import CopilotClient, MessageOptions, SessionConfig +from copilot import CopilotClient, MessageOptions, SessionConfig, PermissionHandler async def ralph_loop(prompt_file: str, max_iterations: int = 50): @@ -63,7 +63,8 @@ async def ralph_loop(prompt_file: str, max_iterations: int = 50): # Fresh session each iteration — context isolation is the point session = await client.create_session( - SessionConfig(model="gpt-5.1-codex-mini") + SessionConfig(model="gpt-5.1-codex-mini", + on_permission_request=PermissionHandler.approve_all) ) try: await session.send_and_wait( diff --git a/cookbook/copilot-sdk/python/recipe/accessibility_report.py b/cookbook/copilot-sdk/python/recipe/accessibility_report.py index 69ca6468..2187ae72 100644 --- a/cookbook/copilot-sdk/python/recipe/accessibility_report.py +++ b/cookbook/copilot-sdk/python/recipe/accessibility_report.py @@ -2,8 +2,11 @@ import asyncio from copilot import ( - CopilotClient, SessionConfig, MessageOptions, + CopilotClient, + SessionConfig, + MessageOptions, SessionEvent, + PermissionHandler, ) # ============================================================================ @@ -41,7 +44,7 @@ async def main(): "tools": ["*"], } }, - )) + on_permission_request=PermissionHandler.approve_all)) done = asyncio.Event() diff --git a/cookbook/copilot-sdk/python/recipe/error_handling.py b/cookbook/copilot-sdk/python/recipe/error_handling.py index 7933cbba..836e0f88 100644 --- a/cookbook/copilot-sdk/python/recipe/error_handling.py +++ b/cookbook/copilot-sdk/python/recipe/error_handling.py @@ -1,14 +1,15 @@ #!/usr/bin/env python3 import asyncio -from copilot import CopilotClient, SessionConfig, MessageOptions +from copilot import CopilotClient, SessionConfig, MessageOptions, PermissionHandler async def main(): client = CopilotClient() try: await client.start() - session = await client.create_session(SessionConfig(model="gpt-5")) + session = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) response = await session.send_and_wait(MessageOptions(prompt="Hello!")) diff --git a/cookbook/copilot-sdk/python/recipe/managing_local_files.py b/cookbook/copilot-sdk/python/recipe/managing_local_files.py index f57bafcb..a1035d49 100644 --- a/cookbook/copilot-sdk/python/recipe/managing_local_files.py +++ b/cookbook/copilot-sdk/python/recipe/managing_local_files.py @@ -3,8 +3,11 @@ import asyncio import os from copilot import ( - CopilotClient, SessionConfig, MessageOptions, + CopilotClient, + SessionConfig, + MessageOptions, SessionEvent, + PermissionHandler, ) async def main(): @@ -13,7 +16,8 @@ async def main(): await client.start() # Create session - session = await client.create_session(SessionConfig(model="gpt-5")) + session = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) done = asyncio.Event() diff --git a/cookbook/copilot-sdk/python/recipe/multiple_sessions.py b/cookbook/copilot-sdk/python/recipe/multiple_sessions.py index 8d7d35d1..aec7e36b 100644 --- a/cookbook/copilot-sdk/python/recipe/multiple_sessions.py +++ b/cookbook/copilot-sdk/python/recipe/multiple_sessions.py @@ -1,16 +1,19 @@ #!/usr/bin/env python3 import asyncio -from copilot import CopilotClient, SessionConfig, MessageOptions +from copilot import CopilotClient, SessionConfig, MessageOptions, PermissionHandler async def main(): client = CopilotClient() await client.start() # Create multiple independent sessions - session1 = await client.create_session(SessionConfig(model="gpt-5")) - session2 = await client.create_session(SessionConfig(model="gpt-5")) - session3 = await client.create_session(SessionConfig(model="claude-sonnet-4.5")) + session1 = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) + session2 = await client.create_session(SessionConfig(model="gpt-5", + on_permission_request=PermissionHandler.approve_all)) + session3 = await client.create_session(SessionConfig(model="claude-sonnet-4.5", + on_permission_request=PermissionHandler.approve_all)) print("Created 3 independent sessions") diff --git a/cookbook/copilot-sdk/python/recipe/persisting_sessions.py b/cookbook/copilot-sdk/python/recipe/persisting_sessions.py index da668070..1ea2bfdd 100644 --- a/cookbook/copilot-sdk/python/recipe/persisting_sessions.py +++ b/cookbook/copilot-sdk/python/recipe/persisting_sessions.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import asyncio -from copilot import CopilotClient, SessionConfig, MessageOptions +from copilot import CopilotClient, SessionConfig, MessageOptions, PermissionHandler async def main(): client = CopilotClient() @@ -11,7 +11,7 @@ async def main(): session = await client.create_session(SessionConfig( session_id="user-123-conversation", model="gpt-5", - )) + on_permission_request=PermissionHandler.approve_all)) await session.send_and_wait(MessageOptions(prompt="Let's discuss TypeScript generics")) print(f"Session created: {session.session_id}") @@ -21,7 +21,7 @@ async def main(): print("Session destroyed (state persisted)") # Resume the previous session - resumed = await client.resume_session("user-123-conversation") + resumed = await client.resume_session("user-123-conversation", on_permission_request=PermissionHandler.approve_all) print(f"Resumed: {resumed.session_id}") await resumed.send_and_wait(MessageOptions(prompt="What were we discussing?")) diff --git a/cookbook/copilot-sdk/python/recipe/pr_visualization.py b/cookbook/copilot-sdk/python/recipe/pr_visualization.py index ace1a8a1..4e36d28b 100644 --- a/cookbook/copilot-sdk/python/recipe/pr_visualization.py +++ b/cookbook/copilot-sdk/python/recipe/pr_visualization.py @@ -6,8 +6,11 @@ import sys import os import re from copilot import ( - CopilotClient, SessionConfig, MessageOptions, + CopilotClient, + SessionConfig, + MessageOptions, SessionEvent, + PermissionHandler, ) # ============================================================================ @@ -112,8 +115,8 @@ The current working directory is: {os.getcwd()} - Be concise in your responses """ - } - )) + }, + on_permission_request=PermissionHandler.approve_all)) done = asyncio.Event() diff --git a/cookbook/copilot-sdk/python/recipe/ralph_loop.py b/cookbook/copilot-sdk/python/recipe/ralph_loop.py index 918e8c66..fb40298e 100644 --- a/cookbook/copilot-sdk/python/recipe/ralph_loop.py +++ b/cookbook/copilot-sdk/python/recipe/ralph_loop.py @@ -22,7 +22,7 @@ import asyncio import sys from pathlib import Path -from copilot import CopilotClient, MessageOptions, SessionConfig +from copilot import CopilotClient, MessageOptions, SessionConfig, PermissionHandler async def ralph_loop(mode: str = "build", max_iterations: int = 50): @@ -48,10 +48,7 @@ async def ralph_loop(mode: str = "build", max_iterations: int = 50): # Pin the agent to the project directory working_directory=str(Path.cwd()), # Auto-approve tool calls for unattended operation - on_permission_request=lambda _req, _ctx: { - "kind": "approved", - "rules": [], - }, + on_permission_request=PermissionHandler.approve_all, )) # Log tool usage for visibility diff --git a/instructions/copilot-sdk-csharp.instructions.md b/instructions/copilot-sdk-csharp.instructions.md index 87d04b82..e3e0524e 100644 --- a/instructions/copilot-sdk-csharp.instructions.md +++ b/instructions/copilot-sdk-csharp.instructions.md @@ -65,6 +65,7 @@ Use `SessionConfig` for configuration: ```csharp await using var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Model = "gpt-5", Streaming = true, Tools = [...], @@ -89,7 +90,11 @@ await using var session = await client.CreateSessionAsync(new SessionConfig ### Resuming Sessions ```csharp -var session = await client.ResumeSessionAsync(sessionId, new ResumeSessionConfig { ... }); +var session = await client.ResumeSessionAsync(sessionId, new ResumeSessionConfig +{ + OnPermissionRequest = PermissionHandler.ApproveAll, + // ... +}); ``` ### Session Operations @@ -178,6 +183,7 @@ Set `Streaming = true` in SessionConfig: ```csharp var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Model = "gpt-5", Streaming = true }); @@ -236,6 +242,7 @@ using System.ComponentModel; var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Model = "gpt-5", Tools = [ AIFunctionFactory.Create( @@ -268,6 +275,7 @@ When Copilot invokes a tool, the client automatically: ```csharp var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Model = "gpt-5", SystemMessage = new SystemMessageConfig { @@ -287,6 +295,7 @@ var session = await client.CreateSessionAsync(new SessionConfig ```csharp var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Model = "gpt-5", SystemMessage = new SystemMessageConfig { @@ -336,8 +345,16 @@ await session.SendAsync(new MessageOptions Sessions are independent and can run concurrently: ```csharp -var session1 = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-5" }); -var session2 = await client.CreateSessionAsync(new SessionConfig { Model = "claude-sonnet-4.5" }); +var session1 = await client.CreateSessionAsync(new SessionConfig +{ + OnPermissionRequest = PermissionHandler.ApproveAll, + Model = "gpt-5", +}); +var session2 = await client.CreateSessionAsync(new SessionConfig +{ + OnPermissionRequest = PermissionHandler.ApproveAll, + Model = "claude-sonnet-4.5", +}); await session1.SendAsync(new MessageOptions { Prompt = "Hello from session 1" }); await session2.SendAsync(new MessageOptions { Prompt = "Hello from session 2" }); @@ -350,6 +367,7 @@ Use custom API providers via `ProviderConfig`: ```csharp var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Provider = new ProviderConfig { Type = "openai", @@ -390,7 +408,7 @@ var state = client.State; ```csharp try { - var session = await client.CreateSessionAsync(); + var session = await client.CreateSessionAsync(new SessionConfig { OnPermissionRequest = PermissionHandler.ApproveAll }); await session.SendAsync(new MessageOptions { Prompt = "Hello" }); } catch (StreamJsonRpc.RemoteInvocationException ex) @@ -433,7 +451,7 @@ ALWAYS use `await using` for automatic disposal: ```csharp await using var client = new CopilotClient(); -await using var session = await client.CreateSessionAsync(); +await using var session = await client.CreateSessionAsync(new SessionConfig { OnPermissionRequest = PermissionHandler.ApproveAll }); // Resources automatically cleaned up ``` @@ -477,6 +495,7 @@ await client.StartAsync(); await using var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Model = "gpt-5" }); @@ -501,7 +520,7 @@ await done.Task; ### Multi-Turn Conversation ```csharp -await using var session = await client.CreateSessionAsync(); +await using var session = await client.CreateSessionAsync(new SessionConfig { OnPermissionRequest = PermissionHandler.ApproveAll }); async Task SendAndWait(string prompt) { @@ -532,6 +551,7 @@ await SendAndWait("What is its population?"); ```csharp var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Tools = [ AIFunctionFactory.Create( ([Description("User ID")] string userId) => { diff --git a/instructions/copilot-sdk-go.instructions.md b/instructions/copilot-sdk-go.instructions.md index b8741721..1bd1a018 100644 --- a/instructions/copilot-sdk-go.instructions.md +++ b/instructions/copilot-sdk-go.instructions.md @@ -72,6 +72,7 @@ Use `SessionConfig` for configuration: ```go session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", Streaming: true, Tools: []copilot.Tool{...}, @@ -104,7 +105,7 @@ if err != nil { ### Resuming Sessions ```go -session, err := client.ResumeSession("session-id") +session, err := client.ResumeSession("session-id", &copilot.ResumeSessionConfig{OnPermissionRequest: copilot.PermissionHandler.ApproveAll}) // Or with options: session, err := client.ResumeSessionWithOptions("session-id", &copilot.ResumeSessionConfig{ ... }) ``` @@ -190,6 +191,7 @@ Set `Streaming: true` in SessionConfig: ```go session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", Streaming: true, }) @@ -243,6 +245,7 @@ Note: Final events (`AssistantMessage`, `AssistantReasoning`) are ALWAYS sent re ```go session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", Tools: []copilot.Tool{ { @@ -300,6 +303,7 @@ When Copilot invokes a tool, the client automatically: ```go session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", SystemMessage: &copilot.SystemMessageConfig{ Mode: "append", @@ -317,6 +321,7 @@ session, err := client.CreateSession(&copilot.SessionConfig{ ```go session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-5", SystemMessage: &copilot.SystemMessageConfig{ Mode: "replace", @@ -361,8 +366,14 @@ session.Send(copilot.MessageOptions{ Sessions are independent and can run concurrently: ```go -session1, _ := client.CreateSession(&copilot.SessionConfig{Model: "gpt-5"}) -session2, _ := client.CreateSession(&copilot.SessionConfig{Model: "claude-sonnet-4.5"}) +session1, _ := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "gpt-5", +}) +session2, _ := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "claude-sonnet-4.5", +}) session1.Send(copilot.MessageOptions{Prompt: "Hello from session 1"}) session2.Send(copilot.MessageOptions{Prompt: "Hello from session 2"}) @@ -374,6 +385,7 @@ Use custom API providers via `ProviderConfig`: ```go session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Provider: &copilot.ProviderConfig{ Type: "openai", BaseURL: "https://api.openai.com/v1", @@ -396,7 +408,9 @@ state := client.GetState() ### Standard Exception Handling ```go -session, err := client.CreateSession(&copilot.SessionConfig{}) +session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, +}) if err != nil { log.Fatalf("Failed to create session: %v", err) } @@ -447,7 +461,7 @@ if err := client.Start(); err != nil { } defer client.Stop() -session, err := client.CreateSession(nil) +session, err := client.CreateSession(&copilot.SessionConfig{OnPermissionRequest: copilot.PermissionHandler.ApproveAll}) if err != nil { log.Fatal(err) } @@ -465,7 +479,7 @@ if err != nil { log.Fatal(err) } -session, err := client.CreateSession(nil) +session, err := client.CreateSession(&copilot.SessionConfig{OnPermissionRequest: copilot.PermissionHandler.ApproveAll}) if err != nil { client.Stop() log.Fatal(err) @@ -504,7 +518,10 @@ if err := client.Start(); err != nil { } defer client.Stop() -session, err := client.CreateSession(&copilot.SessionConfig{Model: "gpt-5"}) +session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "gpt-5", +}) if err != nil { log.Fatal(err) } @@ -527,7 +544,7 @@ session.Send(copilot.MessageOptions{Prompt: "What is 2+2?"}) ### Multi-Turn Conversation ```go -session, _ := client.CreateSession(nil) +session, _ := client.CreateSession(&copilot.SessionConfig{OnPermissionRequest: copilot.PermissionHandler.ApproveAll}) defer session.Destroy() sendAndWait := func(prompt string) error { @@ -588,6 +605,7 @@ type UserInfo struct { } session, _ := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Tools: []copilot.Tool{ { Name: "get_user", diff --git a/instructions/copilot-sdk-nodejs.instructions.md b/instructions/copilot-sdk-nodejs.instructions.md index 78c6f2b2..28de0f56 100644 --- a/instructions/copilot-sdk-nodejs.instructions.md +++ b/instructions/copilot-sdk-nodejs.instructions.md @@ -30,7 +30,7 @@ yarn add @github/copilot-sdk ### Basic Client Setup ```typescript -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; const client = new CopilotClient(); await client.start(); @@ -74,6 +74,7 @@ Use `SessionConfig` for configuration: ```typescript const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-5", streaming: true, tools: [...], @@ -106,6 +107,7 @@ const session = await client.createSession({ ```typescript const session = await client.resumeSession("session-id", { tools: [myNewTool], + onPermissionRequest: approveAll, }); ``` @@ -190,8 +192,9 @@ Set `streaming: true` in SessionConfig: ```typescript const session = await client.createSession({ - model: "gpt-5", - streaming: true, + onPermissionRequest: approveAll, + model: "gpt-5", + streaming: true, }); ``` @@ -243,7 +246,8 @@ Use `defineTool` for type-safe tool definitions: import { defineTool } from "@github/copilot-sdk"; const session = await client.createSession({ - model: "gpt-5", + onPermissionRequest: approveAll, + model: "gpt-5", tools: [ defineTool({ name: "lookup_issue", @@ -272,6 +276,7 @@ The SDK supports Zod schemas for parameters: import { z } from "zod"; const session = await client.createSession({ + onPermissionRequest: approveAll, tools: [ defineTool({ name: "get_weather", @@ -316,7 +321,8 @@ When Copilot invokes a tool, the client automatically: ```typescript const session = await client.createSession({ - model: "gpt-5", + onPermissionRequest: approveAll, + model: "gpt-5", systemMessage: { mode: "append", content: ` @@ -333,7 +339,8 @@ const session = await client.createSession({ ```typescript const session = await client.createSession({ - model: "gpt-5", + onPermissionRequest: approveAll, + model: "gpt-5", systemMessage: { mode: "replace", content: "You are a helpful assistant.", @@ -377,8 +384,14 @@ await session.send({ Sessions are independent and can run concurrently: ```typescript -const session1 = await client.createSession({ model: "gpt-5" }); -const session2 = await client.createSession({ model: "claude-sonnet-4.5" }); +const session1 = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", +}); +const session2 = await client.createSession({ + onPermissionRequest: approveAll, + model: "claude-sonnet-4.5", +}); await Promise.all([ session1.send({ prompt: "Hello from session 1" }), @@ -392,6 +405,7 @@ Use custom API providers via `provider`: ```typescript const session = await client.createSession({ + onPermissionRequest: approveAll, provider: { type: "openai", baseUrl: "https://api.openai.com/v1", @@ -422,7 +436,7 @@ await client.deleteSession(sessionId); ```typescript const lastId = await client.getLastSessionId(); if (lastId) { - const session = await client.resumeSession(lastId); + const session = await client.resumeSession(lastId, { onPermissionRequest: approveAll }); } ``` @@ -439,7 +453,7 @@ const state = client.getState(); ```typescript try { - const session = await client.createSession(); + const session = await client.createSession({ onPermissionRequest: approveAll }); await session.send({ prompt: "Hello" }); } catch (error) { console.error(`Error: ${error.message}`); @@ -477,7 +491,7 @@ ALWAYS use try-finally or cleanup in a finally block: const client = new CopilotClient(); try { await client.start(); - const session = await client.createSession(); + const session = await client.createSession({ onPermissionRequest: approveAll }); try { // Use session... } finally { @@ -507,7 +521,7 @@ async function withSession( client: CopilotClient, fn: (session: CopilotSession) => Promise, ): Promise { - const session = await client.createSession(); + const session = await client.createSession({ onPermissionRequest: approveAll }); try { return await fn(session); } finally { @@ -542,13 +556,16 @@ await withClient(async (client) => { ### Simple Query-Response ```typescript -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; const client = new CopilotClient(); try { await client.start(); - const session = await client.createSession({ model: "gpt-5" }); + const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-5", + }); try { await new Promise((resolve) => { session.on((event) => { @@ -572,7 +589,7 @@ try { ### Multi-Turn Conversation ```typescript -const session = await client.createSession(); +const session = await client.createSession({ onPermissionRequest: approveAll }); async function sendAndWait(prompt: string): Promise { await new Promise((resolve, reject) => { @@ -621,6 +638,7 @@ interface UserInfo { } const session = await client.createSession({ + onPermissionRequest: approveAll, tools: [ defineTool({ name: "get_user", diff --git a/instructions/copilot-sdk-python.instructions.md b/instructions/copilot-sdk-python.instructions.md index ae8a23d5..2978a067 100644 --- a/instructions/copilot-sdk-python.instructions.md +++ b/instructions/copilot-sdk-python.instructions.md @@ -30,7 +30,7 @@ uv add github-copilot-sdk ### Basic Client Setup ```python -from copilot import CopilotClient +from copilot import CopilotClient, PermissionHandler import asyncio async def main(): @@ -82,6 +82,7 @@ Use a dict for SessionConfig: ```python session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-5", "streaming": True, "tools": [...], @@ -113,6 +114,7 @@ session = await client.create_session({ ```python session = await client.resume_session("session-id", { + "on_permission_request": PermissionHandler.approve_all, "tools": [my_new_tool] }) ``` @@ -195,6 +197,7 @@ Set `streaming: True` in SessionConfig: ```python session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-5", "streaming": True }) @@ -248,6 +251,7 @@ async def fetch_issue(issue_id: str): return {"id": issue_id, "status": "open"} session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-5", "tools": [ define_tool( @@ -281,6 +285,7 @@ async def get_weather(args: WeatherArgs, inv): return {"temperature": 72, "units": args.units} session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "tools": [ define_tool( name="get_weather", @@ -331,6 +336,7 @@ When Copilot invokes a tool, the client automatically: ```python session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-5", "system_message": { "mode": "append", @@ -348,6 +354,7 @@ session = await client.create_session({ ```python session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-5", "system_message": { "mode": "replace", @@ -392,8 +399,14 @@ await session.send({ Sessions are independent and can run concurrently: ```python -session1 = await client.create_session({"model": "gpt-5"}) -session2 = await client.create_session({"model": "claude-sonnet-4.5"}) +session1 = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, + "model": "gpt-5", +}) +session2 = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, + "model": "claude-sonnet-4.5", +}) await asyncio.gather( session1.send({"prompt": "Hello from session 1"}), @@ -407,6 +420,7 @@ Use custom API providers via `provider`: ```python session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "provider": { "type": "openai", "base_url": "https://api.openai.com/v1", @@ -436,7 +450,7 @@ await client.delete_session(session_id) ```python last_id = await client.get_last_session_id() if last_id: - session = await client.resume_session(last_id) + session = await client.resume_session(last_id, on_permission_request=PermissionHandler.approve_all) ``` ### Checking Connection State @@ -452,7 +466,7 @@ state = client.get_state() ```python try: - session = await client.create_session() + session = await client.create_session(on_permission_request=PermissionHandler.approve_all) await session.send({"prompt": "Hello"}) except Exception as e: print(f"Error: {e}") @@ -487,7 +501,7 @@ ALWAYS use async context managers for automatic cleanup: ```python async with CopilotClient() as client: - async with await client.create_session() as session: + async with await client.create_session(on_permission_request=PermissionHandler.approve_all) as session: # Use session... await session.send({"prompt": "Hello"}) # Session automatically destroyed @@ -500,7 +514,7 @@ async with CopilotClient() as client: client = CopilotClient() try: await client.start() - session = await client.create_session() + session = await client.create_session(on_permission_request=PermissionHandler.approve_all) try: # Use session... pass @@ -529,12 +543,15 @@ finally: ### Simple Query-Response ```python -from copilot import CopilotClient +from copilot import CopilotClient, PermissionHandler import asyncio async def main(): async with CopilotClient() as client: - async with await client.create_session({"model": "gpt-5"}) as session: + async with await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, + "model": "gpt-5", + }) as session: done = asyncio.Event() def handler(event): @@ -574,7 +591,7 @@ async def send_and_wait(session, prompt: str): return result[0] if result else None -async with await client.create_session() as session: +async with await client.create_session(on_permission_request=PermissionHandler.approve_all) as session: await send_and_wait(session, "What is the capital of France?") await send_and_wait(session, "What is its population?") ``` @@ -583,7 +600,7 @@ async with await client.create_session() as session: ```python # Use built-in send_and_wait for simpler synchronous interaction -async with await client.create_session() as session: +async with await client.create_session(on_permission_request=PermissionHandler.approve_all) as session: response = await session.send_and_wait( {"prompt": "What is 2+2?"}, timeout=60.0 @@ -616,6 +633,7 @@ async def get_user(args, inv) -> dict: return asdict(user) session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "tools": [ define_tool( name="get_user", @@ -697,6 +715,7 @@ options: MessageOptions = { await session.send(options) config: SessionConfig = { + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-5", "streaming": True } @@ -775,7 +794,9 @@ def copilot_tool( def calculate(expression: str) -> float: return eval(expression) -session = await client.create_session({"tools": [calculate]}) +session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, + "tools": [calculate]}) ``` ## Python-Specific Features diff --git a/skills/copilot-sdk/SKILL.md b/skills/copilot-sdk/SKILL.md index ea18108e..7a978df0 100644 --- a/skills/copilot-sdk/SKILL.md +++ b/skills/copilot-sdk/SKILL.md @@ -49,10 +49,13 @@ dotnet add package GitHub.Copilot.SDK ### TypeScript ```typescript -import { CopilotClient } from "@github/copilot-sdk"; +import { CopilotClient, approveAll } from "@github/copilot-sdk"; const client = new CopilotClient(); -const session = await client.createSession({ model: "gpt-4.1" }); +const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-4.1", +}); const response = await session.sendAndWait({ prompt: "What is 2 + 2?" }); console.log(response?.data.content); @@ -66,13 +69,16 @@ Run: `npx tsx index.ts` ### Python ```python import asyncio -from copilot import CopilotClient +from copilot import CopilotClient, PermissionHandler async def main(): client = CopilotClient() await client.start() - session = await client.create_session({"model": "gpt-4.1"}) + session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, + "model": "gpt-4.1", + }) response = await session.send_and_wait({"prompt": "What is 2 + 2?"}) print(response.data.content) @@ -99,7 +105,10 @@ func main() { } defer client.Stop() - session, err := client.CreateSession(&copilot.SessionConfig{Model: "gpt-4.1"}) + session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "gpt-4.1", + }) if err != nil { log.Fatal(err) } @@ -119,7 +128,11 @@ func main() { using GitHub.Copilot.SDK; await using var client = new CopilotClient(); -await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" }); +await using var session = await client.CreateSessionAsync(new SessionConfig +{ + OnPermissionRequest = PermissionHandler.ApproveAll, + Model = "gpt-4.1", +}); var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2 + 2?" }); Console.WriteLine(response?.Data.Content); @@ -133,10 +146,11 @@ Enable real-time output for better UX: ### TypeScript ```typescript -import { CopilotClient, SessionEvent } from "@github/copilot-sdk"; +import { CopilotClient, approveAll, SessionEvent } from "@github/copilot-sdk"; const client = new CopilotClient(); const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-4.1", streaming: true, }); @@ -160,7 +174,7 @@ process.exit(0); ```python import asyncio import sys -from copilot import CopilotClient +from copilot import CopilotClient, PermissionHandler from copilot.generated.session_events import SessionEventType async def main(): @@ -168,6 +182,7 @@ async def main(): await client.start() session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-4.1", "streaming": True, }) @@ -189,6 +204,7 @@ asyncio.run(main()) ### Go ```go session, err := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-4.1", Streaming: true, }) @@ -209,6 +225,7 @@ _, err = session.SendAndWait(copilot.MessageOptions{Prompt: "Tell me a short jok ```csharp await using var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Model = "gpt-4.1", Streaming = true, }); @@ -233,7 +250,7 @@ Define tools that Copilot can invoke during reasoning. When you define a tool, y ### TypeScript (JSON Schema) ```typescript -import { CopilotClient, defineTool, SessionEvent } from "@github/copilot-sdk"; +import { CopilotClient, approveAll, defineTool, SessionEvent } from "@github/copilot-sdk"; const getWeather = defineTool("get_weather", { description: "Get the current weather for a city", @@ -256,6 +273,7 @@ const getWeather = defineTool("get_weather", { const client = new CopilotClient(); const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-4.1", streaming: true, tools: [getWeather], @@ -280,7 +298,7 @@ process.exit(0); import asyncio import random import sys -from copilot import CopilotClient +from copilot import CopilotClient, PermissionHandler from copilot.tools import define_tool from copilot.generated.session_events import SessionEventType from pydantic import BaseModel, Field @@ -301,6 +319,7 @@ async def main(): await client.start() session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-4.1", "streaming": True, "tools": [get_weather], @@ -350,6 +369,7 @@ getWeather := copilot.DefineTool( ) session, _ := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-4.1", Streaming: true, Tools: []copilot.Tool{getWeather}, @@ -376,6 +396,7 @@ var getWeather = AIFunctionFactory.Create( await using var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Model = "gpt-4.1", Streaming = true, Tools = [getWeather], @@ -398,7 +419,7 @@ Build a complete interactive assistant: ### TypeScript ```typescript -import { CopilotClient, defineTool, SessionEvent } from "@github/copilot-sdk"; +import { CopilotClient, approveAll, defineTool, SessionEvent } from "@github/copilot-sdk"; import * as readline from "readline"; const getWeather = defineTool("get_weather", { @@ -420,6 +441,7 @@ const getWeather = defineTool("get_weather", { const client = new CopilotClient(); const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-4.1", streaming: true, tools: [getWeather], @@ -462,7 +484,7 @@ prompt(); import asyncio import random import sys -from copilot import CopilotClient +from copilot import CopilotClient, PermissionHandler from copilot.tools import define_tool from copilot.generated.session_events import SessionEventType from pydantic import BaseModel, Field @@ -482,6 +504,7 @@ async def main(): await client.start() session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-4.1", "streaming": True, "tools": [get_weather], @@ -522,6 +545,7 @@ Connect to MCP (Model Context Protocol) servers for pre-built tools. Connect to ### TypeScript ```typescript const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-4.1", mcpServers: { github: { @@ -535,6 +559,7 @@ const session = await client.createSession({ ### Python ```python session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-4.1", "mcp_servers": { "github": { @@ -548,6 +573,7 @@ session = await client.create_session({ ### Go ```go session, _ := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, Model: "gpt-4.1", MCPServers: map[string]copilot.MCPServerConfig{ "github": { @@ -562,6 +588,7 @@ session, _ := client.CreateSession(&copilot.SessionConfig{ ```csharp await using var session = await client.CreateSessionAsync(new SessionConfig { + OnPermissionRequest = PermissionHandler.ApproveAll, Model = "gpt-4.1", McpServers = new Dictionary { @@ -581,6 +608,7 @@ Define specialized AI personas for specific tasks: ### TypeScript ```typescript const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-4.1", customAgents: [{ name: "pr-reviewer", @@ -594,6 +622,7 @@ const session = await client.createSession({ ### Python ```python session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-4.1", "custom_agents": [{ "name": "pr-reviewer", @@ -611,6 +640,7 @@ Customize the AI's behavior and personality: ### TypeScript ```typescript const session = await client.createSession({ + onPermissionRequest: approveAll, model: "gpt-4.1", systemMessage: { content: "You are a helpful assistant for our engineering team. Always be concise.", @@ -621,6 +651,7 @@ const session = await client.createSession({ ### Python ```python session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, "model": "gpt-4.1", "system_message": { "content": "You are a helpful assistant for our engineering team. Always be concise.", @@ -645,7 +676,10 @@ const client = new CopilotClient({ cliUrl: "localhost:4321" }); -const session = await client.createSession({ model: "gpt-4.1" }); +const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-4.1", +}); ``` #### Python @@ -655,7 +689,10 @@ client = CopilotClient({ }) await client.start() -session = await client.create_session({"model": "gpt-4.1"}) +session = await client.create_session({ + "on_permission_request": PermissionHandler.approve_all, + "model": "gpt-4.1", +}) ``` #### Go @@ -668,7 +705,10 @@ if err := client.Start(); err != nil { log.Fatal(err) } -session, _ := client.CreateSession(&copilot.SessionConfig{Model: "gpt-4.1"}) +session, _ := client.CreateSession(&copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + Model: "gpt-4.1", +}) ``` #### .NET @@ -678,7 +718,11 @@ using var client = new CopilotClient(new CopilotClientOptions CliUrl = "localhost:4321" }); -await using var session = await client.CreateSessionAsync(new SessionConfig { Model = "gpt-4.1" }); +await using var session = await client.CreateSessionAsync(new SessionConfig +{ + OnPermissionRequest = PermissionHandler.ApproveAll, + Model = "gpt-4.1", +}); ``` **Note:** When `cliUrl` is provided, the SDK will not spawn or manage a CLI process - it only connects to the existing server. @@ -731,6 +775,7 @@ Save and resume conversations across restarts: ### Create with Custom ID ```typescript const session = await client.createSession({ + onPermissionRequest: approveAll, sessionId: "user-123-conversation", model: "gpt-4.1" }); @@ -738,7 +783,7 @@ const session = await client.createSession({ ### Resume Session ```typescript -const session = await client.resumeSession("user-123-conversation"); +const session = await client.resumeSession("user-123-conversation", { onPermissionRequest: approveAll }); await session.send({ prompt: "What did we discuss earlier?" }); ``` @@ -753,7 +798,10 @@ await client.deleteSession("old-session-id"); ```typescript try { const client = new CopilotClient(); - const session = await client.createSession({ model: "gpt-4.1" }); + const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-4.1", + }); const response = await session.sendAndWait( { prompt: "Hello!" }, 30000 // timeout in ms @@ -785,7 +833,10 @@ process.on("SIGINT", async () => { ### Multi-turn Conversation ```typescript -const session = await client.createSession({ model: "gpt-4.1" }); +const session = await client.createSession({ + onPermissionRequest: approveAll, + model: "gpt-4.1", +}); await session.sendAndWait({ prompt: "My name is Alice" }); await session.sendAndWait({ prompt: "What's my name?" });