Phase 7/13 — API Surface
Phase 7: Complete API Surface Reference
Every public symbol, method, type, and extension point across TypeScript Python Go C# .
Table of Contents
Exported Symbols Per SDK
Client API
Session API
Type System
Tool Definition API
Hook / Callback API
Permission API
Extension Points
JSON-RPC Methods
Cross-Language API Comparison
Appendix: SDK-Specific Differences
1. Exported Symbols Per SDK
TypeScript nodejs/src/index.ts
// Classes
export { CopilotClient } from "./client.js";
export { CopilotSession, type AssistantMessageEvent } from "./session.js";
// Functions
export { defineTool, approveAll } from "./types.js";
// Types (re-exported)
export type {
ConnectionState, CopilotClientOptions, CustomAgentConfig,
ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse,
InfiniteSessionConfig, MCPLocalServerConfig, MCPRemoteServerConfig,
MCPServerConfig, MessageOptions, ModelBilling, ModelCapabilities,
ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest,
PermissionRequestResult, ResumeSessionConfig, SessionConfig,
SessionEvent, SessionEventHandler, SessionEventPayload,
SessionEventType, SessionLifecycleEvent, SessionLifecycleEventType,
SessionLifecycleHandler, SessionContext, SessionListFilter,
SessionMetadata, SystemMessageAppendConfig, SystemMessageConfig,
SystemMessageReplaceConfig, Tool, ToolHandler, ToolInvocation,
ToolResultObject, TypedSessionEventHandler,
TypedSessionLifecycleHandler, ZodSchema,
} from "./types.js";
Python python/copilot/__init__.py
# Classes
from .client import CopilotClient
from .session import CopilotSession
# Functions
from .tools import define_tool
# Types (re-exported)
from .types import (
AzureProviderOptions, ConnectionState, CustomAgentConfig,
GetAuthStatusResponse, GetStatusResponse, MCPLocalServerConfig,
MCPRemoteServerConfig, MCPServerConfig, MessageOptions,
ModelBilling, ModelCapabilities, ModelInfo, ModelPolicy,
PermissionHandler, PermissionRequest, PermissionRequestResult,
PingResponse, ProviderConfig, ResumeSessionConfig, SessionConfig,
SessionContext, SessionEvent, SessionListFilter, SessionMetadata,
StopError, Tool, ToolHandler, ToolInvocation, ToolResult,
)
Go go/ package
Category Symbols
Structs Client, Session, ClientOptions, SessionConfig, ResumeSessionConfig, Tool, ToolInvocation, ToolResult, ToolBinaryResult, MessageOptions, ProviderConfig, AzureProviderOptions, SystemMessageConfig, MCPLocalServerConfig, MCPRemoteServerConfig, CustomAgentConfig, InfiniteSessionConfig, PermissionRequestResult, SessionHooks, PreToolUseHookInput/Output, PostToolUseHookInput/Output, SessionStartHookInput/Output, SessionEndHookInput/Output, ErrorOccurredHookInput/Output, ModelInfo, SessionContext, SessionMetadata
Type Aliases ConnectionState, SessionEventHandler, SessionLifecycleHandler, PermissionRequestResultKind, MCPServerConfig
Functions NewClient(), Bool(), String(), Float64(), DefineTool()
Variables PermissionHandler.ApproveAll
Constants StateDisconnected, StateConnecting, StateConnected, StateError, PermissionRequestResultKindApproved, ...Denied*, SessionLifecycleCreated/Deleted/Updated/Foreground/Background
C# dotnet/src/ namespace GitHub.Copilot.SDK
Category Symbols
Classes CopilotClient, CopilotSession, CopilotClientOptions, SessionConfig, ResumeSessionConfig, ToolResultObject, ToolInvocation, PermissionRequestResult, SessionHooks, PreToolUseHookInput/Output, PostToolUseHookInput/Output, SessionStartHookInput/Output, SessionEndHookInput/Output, ErrorOccurredHookInput/Output, ProviderConfig, McpLocalServerConfig, McpRemoteServerConfig, CustomAgentConfig, InfiniteSessionConfig, SystemMessageConfig, ModelInfo, SessionContext, SessionMetadata
Enums ConnectionState, SystemMessageMode
Delegates ToolHandler, PermissionRequestHandler, UserInputHandler, PreToolUseHandler, PostToolUseHandler, SessionEventHandler
Static PermissionHandler.ApproveAll
2. Client API
Constructor
Language Signature
TS new CopilotClient(options?: CopilotClientOptions)
Py CopilotClient(options?: CopilotClientOptions)
Go NewClient(options *ClientOptions) *Client
C# new CopilotClient(options?: CopilotClientOptions)
CopilotClientOptions
Field TS Py Go C#
CLI path cliPath?: stringcli_path: strCLIPath stringCliPath string?
CLI args cliArgs?: string[]cli_args: list[str]CLIArgs []stringCliArgs string[]?
Working dir cwd?: stringcwd: strCwd stringCwd string?
Port port?: numberport: intPort intPort int
Use stdio useStdio?: booleanuse_stdio: boolUseStdio *boolUseStdio bool
CLI URL cliUrl?: stringcli_url: strCLIUrl stringCliUrl string?
Auto start autoStart?: booleanauto_start: boolAutoStart *boolAutoStart bool
Auto restart autoRestart?: booleanauto_restart: boolAutoRestart *boolAutoRestart bool
Environment env?: Record<string,string>env: dictEnv []stringEnvironment IReadOnlyDictionary?
GitHub token githubToken?: stringgithub_token: strGitHubToken stringGitHubToken string?
Model lister onListModels?: () => Promise<ModelInfo[]>on_list_models: CallableOnListModels func(ctx)([]ModelInfo, error)OnListModels Func<..., Task<List<ModelInfo>>>?
Client Methods
Method TS Py Go C#
Start start(): Promise<void>async start()Start(ctx) errorStartAsync(ct) Task
Stop stop(): Promise<Error[]>async stop()Stop() errorStopAsync(ct) Task
Force stop forceStop()async force_stop()ForceStop()ForceStopAsync() Task
Create session createSession(config)create_session(config)CreateSession(ctx, *SessionConfig)CreateSessionAsync(config, ct)
Resume session resumeSession(id, config)resume_session(id, config)ResumeSession(ctx, id, *ResumeSessionConfig)ResumeSessionAsync(id, config, ct)
Ping ping(msg?)ping(msg?)Ping(ctx, msg)PingAsync(msg?, ct)
Get status getStatus()get_status()GetStatus(ctx)GetStatusAsync(ct)
Auth status getAuthStatus()get_auth_status()GetAuthStatus(ctx)GetAuthStatusAsync(ct)
List models listModels()list_models()ListModels(ctx)ListModelsAsync(ct)
List sessions listSessions(filter?)list_sessions(filter?)ListSessions(ctx, *SessionListFilter)ListSessionsAsync(filter?, ct)
Delete session deleteSession(id)delete_session(id)DeleteSession(ctx, id)DeleteSessionAsync(id, ct)
Lifecycle events on(handler): () => voidon(handler) -> CallableOn(handler) func()On(handler) IDisposable
Dispose [Symbol.asyncDispose]()async __aexit__()Stop()DisposeAsync()
3. Session API
Session Properties
Property TS Py Go C#
Session ID readonly sessionId: stringsession_id: strSessionID stringSessionId { get; }
Workspace get workspacePath()workspace_path (property)WorkspacePath() stringWorkspacePath { get; }
Typed RPC get rpc()rpc (property)RPC *rpc.SessionRpcRpc (property)
Session Methods
Method TS Py Go C#
Send send(options)send(options)Send(ctx, MessageOptions)SendAsync(options, ct)
Send & wait sendAndWait(options, timeout?)send_and_wait(options, timeout?)SendAndWait(ctx, MessageOptions)SendAndWaitAsync(options, timeout?, ct)
Subscribe on(handler): () => voidon(handler) -> CallableOn(handler) func()On(handler) IDisposable
Typed subscribe on<K>(type, handler)N/A N/A N/A (pattern matching)
Get messages getMessages()get_messages()GetMessages(ctx)GetMessagesAsync(ct)
Disconnect disconnect()disconnect()Disconnect() errorDisposeAsync()
Abort abort()abort()Abort(ctx) errorAbortAsync(ct)
Set model setModel(model)set_model(model)SetModel(ctx, model)SetModelAsync(model, ct)
Log log(message, options?)log(message, level?, ephemeral?)Log(ctx, message, *LogOptions)LogAsync(message, level?, ephemeral?, ct)
MessageOptions
TypeScript
Python
Go
C#
interface MessageOptions {
prompt: string;
attachments?: Array<FileAttachment | DirectoryAttachment | SelectionAttachment>;
mode?: "enqueue" | "immediate";
}
class MessageOptions(TypedDict):
prompt: str
attachments: NotRequired[list[Attachment]]
mode: NotRequired[Literal["enqueue", "immediate"]]
type MessageOptions struct {
Prompt string
Attachments []Attachment
Mode string // "enqueue" or "immediate"
}
public class MessageOptions {
public string Prompt { get; init; }
public List<Attachment>? Attachments { get; init; }
public string? Mode { get; init; }
}
4. Type System
SessionConfig
The most important configuration type — controls model selection, tools, permissions, hooks, provider, MCP servers, and more.
Field TS Py Go C#
Model model?: stringmodel: strModel stringModel string?
Tools tools?: Tool<any>[]tools: list[Tool]Tools []ToolTools List<AIFunction>?
System message systemMessage?: SystemMessageConfigsystem_messageSystemMessage *SystemMessageConfigSystemMessage?
Permission handler onPermissionRequest: PermissionHandleron_permission_requestOnPermissionRequest PermissionHandlerFuncOnPermissionRequest?
User input onUserInputRequest?on_user_input_requestOnUserInputRequestOnUserInputRequest?
Hooks hooks?: SessionHookshooksHooks *SessionHooksHooks?
Provider (BYOK) provider?: ProviderConfigproviderProvider *ProviderConfigProvider?
MCP servers mcpServers?: Record<string, MCPServerConfig>mcp_servers: dictMCPServers map[string]MCPServerConfigMcpServers Dictionary?
Custom agents customAgents?: CustomAgentConfig[]custom_agentsCustomAgents []CustomAgentConfigCustomAgents?
Working dir workingDirectory?: stringworking_directoryWorkingDirectory stringWorkingDirectory?
Streaming streaming?: booleanstreaming: boolStreaming boolStreaming bool?
Infinite sessions infiniteSessions?infinite_sessionsInfiniteSessionsInfiniteSessions?
Reasoning effort reasoningEffort?reasoning_effortReasoningEffort stringReasoningEffort?
ProviderConfig (BYOK)
TypeScript
Go
interface ProviderConfig {
type?: "openai" | "azure" | "anthropic";
wireApi?: "completions" | "responses";
baseUrl: string;
apiKey?: string;
bearerToken?: string;
azure?: { apiVersion?: string };
}
type ProviderConfig struct {
Type string `json:"type,omitempty"`
WireApi string `json:"wireApi,omitempty"`
BaseURL string `json:"baseUrl"`
APIKey string `json:"apiKey,omitempty"`
BearerToken string `json:"bearerToken,omitempty"`
Azure *AzureProviderOptions `json:"azure,omitempty"`
}
SessionEvent
Code-generated from a shared schema. Different patterns per language:
TypeScript
Go
C#
// Discriminated union on `type`
type SessionEvent =
| { type: "assistant.message"; data: { content: string; ... }; ... }
| { type: "session.idle"; data: { ... }; ... }
| { type: "session.error"; data: { message: string; ... }; ... }
| { type: "external_tool.requested"; data: { requestId: string; ... }; ... }
| { type: "permission.requested"; data: { ... }; ... }
// ... many more
// Single struct with typed data
type SessionEvent struct {
Data Data `json:"data"`
Ephemeral *bool `json:"ephemeral,omitempty"`
ID string `json:"id"`
ParentID *string `json:"parentId"`
Timestamp time.Time `json:"timestamp"`
Type SessionEventType `json:"type"`
}
// Class hierarchy
public abstract class SessionEvent { ... }
public class AssistantMessageEvent : SessionEvent { ... }
public class SessionIdleEvent : SessionEvent { ... }
public class SessionErrorEvent : SessionEvent { ... }
public class ExternalToolRequestedEvent : SessionEvent { ... }
public class PermissionRequestedEvent : SessionEvent { ... }
ConnectionState
TS Py Go C#
"disconnected" | "connecting" | "connected" | "error"Literal["disconnected", ...]StateDisconnected | StateConnecting | ...enum ConnectionState { ... }
5. Tool Definition API
ToolResult Types
TypeScript
Go
type ToolResultObject = {
textResultForLlm: string;
binaryResultsForLlm?: ToolBinaryResult[];
resultType: "success" | "failure" | "rejected" | "denied";
error?: string;
sessionLog?: string;
toolTelemetry?: Record<string, unknown>;
};
type ToolResult struct {
TextResultForLLM string `json:"textResultForLlm"`
BinaryResultsForLLM []ToolBinaryResult `json:"binaryResultsForLlm,omitempty"`
ResultType string `json:"resultType"`
Error string `json:"error,omitempty"`
SessionLog string `json:"sessionLog,omitempty"`
ToolTelemetry map[string]any `json:"toolTelemetry,omitempty"`
}
6. Hook / Callback API
Six lifecycle hooks via SessionHooks:
Hook When Invoked Input Output
onPreToolUseBefore tool execution PreToolUseHookInputallow / deny / ask + modified args
onPostToolUseAfter tool execution PostToolUseHookInputOptional modifications
onUserPromptSubmittedUser sends prompt UserPromptSubmittedHookInputOptional modifications
onSessionStartSession starts SessionStartHookInputOptional system prompt additions
onSessionEndSession ends SessionEndHookInputOptional summary
onErrorOccurredError happens ErrorOccurredHookInputretry / skip / abort
PreToolUseHookInput/Output
interface PreToolUseHookInput {
timestamp: number; // Unix ms
cwd: string;
toolName: string;
toolArgs: unknown;
}
interface PreToolUseHookOutput {
permissionDecision?: "allow" | "deny" | "ask";
permissionDecisionReason?: string;
modifiedArgs?: unknown;
additionalContext?: string;
suppressOutput?: boolean;
}
SessionHooks Configuration
TypeScript
Python
Go
C#
interface SessionHooks {
onPreToolUse?: PreToolUseHandler;
onPostToolUse?: PostToolUseHandler;
onUserPromptSubmitted?: UserPromptSubmittedHandler;
onSessionStart?: SessionStartHandler;
onSessionEnd?: SessionEndHandler;
onErrorOccurred?: ErrorOccurredHandler;
}
class SessionHooks(TypedDict, total=False):
on_pre_tool_use: PreToolUseHandler
on_post_tool_use: PostToolUseHandler
on_user_prompt_submitted: UserPromptSubmittedHandler
on_session_start: SessionStartHandler
on_session_end: SessionEndHandler
on_error_occurred: ErrorOccurredHandler
type SessionHooks struct {
OnPreToolUse PreToolUseHandler
OnPostToolUse PostToolUseHandler
OnUserPromptSubmitted UserPromptSubmittedHandler
OnSessionStart SessionStartHandler
OnSessionEnd SessionEndHandler
OnErrorOccurred ErrorOccurredHandler
}
public class SessionHooks {
public PreToolUseHandler? OnPreToolUse { get; set; }
public PostToolUseHandler? OnPostToolUse { get; set; }
public UserPromptSubmittedHandler? OnUserPromptSubmitted { get; set; }
public SessionStartHandler? OnSessionStart { get; set; }
public SessionEndHandler? OnSessionEnd { get; set; }
public ErrorOccurredHandler? OnErrorOccurred { get; set; }
}
7. Permission API
Permission Handler Signature
Language Signature
TS (request: PermissionRequest, inv: { sessionId }) => Promise<PermissionRequestResult>
Py (request, inv) -> PermissionRequestResult | Awaitable[...]
Go func(request, inv) (PermissionRequestResult, error)
C# delegate Task<PermissionRequestResult> PermissionRequestHandler(...)
PermissionRequest
interface PermissionRequest {
kind: "shell" | "write" | "mcp" | "read" | "url" | "custom-tool";
toolCallId?: string;
[key: string]: unknown; // Additional fields vary by kind
}
PermissionRequestResult
type PermissionRequestResult = {
kind: "approved"
| "denied-by-rules"
| "denied-interactively-by-user"
| "denied-no-approval-rule-and-could-not-request-from-user";
rules?: any[];
};
Built-in approveAll
Language Usage
TS import { approveAll } from "@github/copilot-sdk"
Py PermissionHandler.approve_all
Go copilot.PermissionHandler.ApproveAll
C# PermissionHandler.ApproveAll
User Input Handler
type UserInputHandler = (
request: UserInputRequest,
invocation: { sessionId: string }
) => Promise<UserInputResponse> | UserInputResponse;
interface UserInputRequest {
question: string;
choices?: string[];
allowFreeform?: boolean;
}
interface UserInputResponse {
answer: string;
wasFreeform: boolean;
}
8. Extension Points
Extension Points
flowchart LR
A["<b>1. Custom Tools</b><br/>Register via SessionConfig.tools.<br/>Each has name, description,<br/>schema, handler."]
B["<b>2. Permission Handlers</b><br/>Required for session creation.<br/>Controls shell, write, MCP, read,<br/>URL, and custom-tool permissions."]
C["<b>3. User Input Handlers</b><br/>Optional. Enables ask_user tool<br/>for agent-to-user questions."]
D["<b>4. Lifecycle Hooks</b><br/>Six hook points #40;see Section 6#41;.<br/>Intercept and modify<br/>session lifecycle."]
A ~~~ B ~~~ C ~~~ D
5. Custom Agents
const config: SessionConfig = {
customAgents: [{
name: "code-reviewer",
displayName: "Code Reviewer",
description: "Reviews code for quality",
prompt: "You are a code reviewer...",
tools: ["read_file", "grep"],
mcpServers: { ... },
infer: true,
}],
agent: "code-reviewer", // Activate this agent
};
6. MCP Server Integration
const config: SessionConfig = {
mcpServers: {
"my-server": {
type: "local",
tools: ["*"],
command: "node",
args: ["./mcp-server.js"],
env: { API_KEY: "..." },
},
"remote-server": {
type: "http",
tools: ["*"],
url: "https://example.com/mcp",
headers: { Authorization: "Bearer ..." },
},
},
};
7. BYOK Provider Configuration
const config: SessionConfig = {
provider: {
type: "openai",
baseUrl: "https://api.openai.com/v1",
apiKey: "sk-...",
},
model: "gpt-4",
};
8. Extension Module (TypeScript Only)
// nodejs/src/extension.ts
import { joinSession } from "@github/copilot-sdk/extension";
const session = await joinSession({
onPermissionRequest: approveAll,
tools: [myTool],
});
9. Custom Model Lister
const client = new CopilotClient({
onListModels: async () => [
{ id: "my-model", name: "My Model", capabilities: { ... } }
],
});
10. Typed RPC Access
await session.rpc.tools.handlePendingToolCall({ requestId, result });
await session.rpc.permissions.handlePendingPermissionRequest({ requestId, result });
await session.rpc.model.switchTo({ modelId: "gpt-4.1" });
await session.rpc.log({ message: "Hello", level: "info" });
9. JSON-RPC Methods
All SDKs communicate with the Copilot CLI via the same JSON-RPC protocol.
Server-Level Methods
RPC Method Direction Description
pingClient → Server Health check, returns message + timestamp + protocol version
status.getClient → Server Get CLI version and protocol version
auth.getStatusClient → Server Get authentication status
models.listClient → Server List available models
Session Lifecycle Methods
RPC Method Direction Description
session.createClient → Server Create a new session
session.resumeClient → Server Resume an existing session
session.destroyClient → Server Disconnect / release a session
session.deleteClient → Server Permanently delete session data
session.listClient → Server List all sessions
session.getLastIdClient → Server Get most recently used session ID
session.getForegroundClient → Server Get TUI foreground session ID
session.setForegroundClient → Server Set TUI foreground session
Session Communication Methods
RPC Method Direction Description
session.sendClient → Server Send a message to a session
session.abortClient → Server Abort current processing
session.getMessagesClient → Server Get session event history
Session-Scoped RPC Methods
RPC Method Direction Description
session.tools.handlePendingToolCallClient → Server Respond to a tool call request
session.permissions.handlePendingPermissionRequestClient → Server Respond to a permission request
session.model.switchToClient → Server Change model mid-session
session.logClient → Server Log a message to timeline
Server → Client Notifications (Session Events)
Event Type Description
assistant.messageFinal assistant response
assistant.message_deltaStreaming message chunk
assistant.reasoning_deltaStreaming reasoning chunk
session.idleSession finished processing
session.errorSession encountered an error
session.startSession started
external_tool.requestedTool call broadcast (v3)
permission.requestedPermission request broadcast (v3)
user_input.requestedUser input request broadcast
hook.invokedHook invocation request
tool.executingTool is being executed
tool.executedTool execution completed
plan.updatedPlan file updated
Client-Level Lifecycle Notifications
Event Type Description
session.createdA session was created
session.deletedA session was deleted
session.updatedA session was updated
session.foregroundSession moved to foreground
session.backgroundSession moved to background
10. Cross-Language API Comparison
Creating a Client and Session
TypeScript
Python
Go
C#
import { CopilotClient, approveAll } from "@github/copilot-sdk";
const client = new CopilotClient({ autoStart: true });
const session = await client.createSession({
onPermissionRequest: approveAll,
model: "gpt-4",
});
from copilot import CopilotClient, PermissionHandler
async with CopilotClient() as client:
session = await client.create_session({
"on_permission_request": PermissionHandler.approve_all,
"model": "gpt-4",
})
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil {
log.Fatal(err)
}
defer client.Stop()
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
Model: "gpt-4",
})
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new()
{
OnPermissionRequest = PermissionHandler.ApproveAll,
Model = "gpt-4",
});
Sending a Message
TypeScript
Python
Go
C#
const response = await session.sendAndWait({ prompt: "What is 2+2?" });
console.log(response?.data.content);
response = await session.send_and_wait({"prompt": "What is 2+2?"})
if response:
print(response.data.content)
response, err := session.SendAndWait(ctx, copilot.MessageOptions{
Prompt: "What is 2+2?",
})
if response != nil {
fmt.Println(*response.Data.Content)
}
var response = await session.SendAndWaitAsync(new MessageOptions
{
Prompt = "What is 2+2?"
});
Console.WriteLine(response?.Data?.Content);
Defining a Custom Tool
TypeScript
Python
Go
C#
const tool = defineTool("get_weather", {
description: "Get weather for a location",
parameters: z.object({ city: z.string() }),
handler: async (args) => `Weather in ${args.city}: 72F`,
});
from pydantic import BaseModel
from copilot import define_tool
class WeatherParams(BaseModel):
city: str
@define_tool(description="Get weather for a location")
def get_weather(params: WeatherParams) -> str:
return f"Weather in {params.city}: 72F"
type WeatherParams struct {
City string `json:"city"`
}
tool := copilot.DefineTool("get_weather", "Get weather for a location",
func(params WeatherParams, inv copilot.ToolInvocation) (any, error) {
return fmt.Sprintf("Weather in %s: 72F", params.City), nil
})
[Description("Get weather for a location")]
static string GetWeather(string city) => $"Weather in {city}: 72F";
// Pass as: Tools = [AIFunctionFactory.Create(GetWeather)]
Subscribing to Events
TypeScript
Python
Go
C#
const unsubscribe = session.on("assistant.message", (event) => {
console.log("Assistant:", event.data.content);
});
// Later: unsubscribe();
def handler(event):
if event.type == "assistant.message":
print(f"Assistant: {event.data.content}")
unsubscribe = session.on(handler)
# Later: unsubscribe()
unsubscribe := session.On(func(event copilot.SessionEvent) {
if event.Type == copilot.AssistantMessage {
fmt.Println("Assistant:", *event.Data.Content)
}
})
// Later: unsubscribe()
using var subscription = session.On(evt =>
{
if (evt is AssistantMessageEvent msg)
{
Console.WriteLine($"Assistant: {msg.Data?.Content}");
}
});
// Auto-unsubscribed when disposed
Resource Cleanup
TypeScript
Python
Go
C#
// Manual
await session.disconnect();
await client.stop();
// Auto-dispose
await using session = await client.createSession({ ... });
# Manual
await session.disconnect()
await client.stop()
# Context manager
async with CopilotClient() as client:
session = await client.create_session({ ... })
// Always manual with defer
defer client.Stop()
defer session.Disconnect()
// Manual
await session.DisposeAsync();
await client.DisposeAsync();
// Auto-dispose
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new() { ... });
Appendix: SDK-Specific Differences
Feature TS Py Go C#
Tool schema source Zod / raw JSON Schema Pydantic BaseModel Struct tags + jsonschema-go AIFunctionFactory (M.E.AI)
Async model Promise / async/awaitasyncio / async/awaitcontext.Context / goroutinesTask / async/await
Event pattern Typed discriminated union Enum-based SessionEventType String-typed SessionEventType Class hierarchy + pattern matching
Typed subscribe session.on<K>(type, handler)N/A N/A C# pattern matching
Dispose pattern Symbol.asyncDispose__aenter__/__aexit__defer session.Disconnect()IAsyncDisposable
Permission handler approveAll functionPermissionHandler.approve_allPermissionHandler.ApproveAll varPermissionHandler.ApproveAll static
Error handling Exceptions ExceptionGroup (stop)error return valuesExceptions + CancellationToken
Thread safety Single-threaded (event loop) Locks + asyncio sync.Mutex / sync.RWMutexConcurrentDictionary + SemaphoreSlim
Child process ext joinSession()N/A N/A N/A
Optional bool N/A N/A Bool(v bool) *boolN/A (nullable)