Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions dotnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ new CopilotClient(CopilotClientOptions? options = null)
- `Cwd` - Working directory for the CLI process
- `Environment` - Environment variables to pass to the CLI process
- `Logger` - `ILogger` instance for SDK logging
- `GithubToken` - GitHub token for authentication. When provided, takes priority over other auth methods.
- `UseLoggedInUser` - Whether to use logged-in user for authentication (default: true, but false when `GithubToken` is provided). Cannot be used with `CliUrl`.

#### Methods

Expand Down Expand Up @@ -98,6 +100,8 @@ Create a new conversation session.
- `Provider` - Custom API provider configuration (BYOK)
- `Streaming` - Enable streaming of response chunks (default: false)
- `InfiniteSessions` - Configure automatic context compaction (see below)
- `OnUserInputRequest` - Handler for user input requests from the agent (enables ask_user tool). See [User Input Requests](#user-input-requests) section.
- `Hooks` - Hook handlers for session lifecycle events. See [Session Hooks](#session-hooks) section.

##### `ResumeSessionAsync(string sessionId, ResumeSessionConfig? config = null): Task<CopilotSession>`

Expand Down Expand Up @@ -444,6 +448,118 @@ var session = await client.CreateSessionAsync(new SessionConfig
});
```

## User Input Requests

Enable the agent to ask questions to the user using the `ask_user` tool by providing an `OnUserInputRequest` handler:

```csharp
var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-5",
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example uses model "gpt-5", but this model does not exist. OpenAI's latest models are GPT-4 variants (e.g., "gpt-4", "gpt-4-turbo", "gpt-4o"). Using a non-existent model in documentation examples could confuse users.

Copilot uses AI. Check for mistakes.
OnUserInputRequest = async (request, invocation) =>
{
// request.Question - The question to ask
// request.Choices - Optional list of choices for multiple choice
// request.AllowFreeform - Whether freeform input is allowed (default: true)
Console.WriteLine($"Agent asks: {request.Question}");
if (request.Choices?.Count > 0)
{
Console.WriteLine($"Choices: {string.Join(", ", request.Choices)}");
}

// Return the user's response
return new UserInputResponse
{
Answer = "User's answer here",
WasFreeform = true // Whether the answer was freeform (not from choices)
};
}
});
```

## Session Hooks

Hook into session lifecycle events by providing handlers in the `Hooks` configuration:

```csharp
var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-5",
Hooks = new SessionHooks
{
// Called before each tool execution
OnPreToolUse = async (input, invocation) =>
{
Console.WriteLine($"About to run tool: {input.ToolName}");
// Return permission decision and optionally modify args
return new PreToolUseHookOutput
{
PermissionDecision = "allow", // "allow", "deny", or "ask"
ModifiedArgs = input.ToolArgs, // Optionally modify tool arguments
AdditionalContext = "Extra context for the model"
};
},

// Called after each tool execution
OnPostToolUse = async (input, invocation) =>
{
Console.WriteLine($"Tool {input.ToolName} completed");
return new PostToolUseHookOutput
{
AdditionalContext = "Post-execution notes"
};
},

// Called when user submits a prompt
OnUserPromptSubmitted = async (input, invocation) =>
{
Console.WriteLine($"User prompt: {input.Prompt}");
return new UserPromptSubmittedHookOutput
{
ModifiedPrompt = input.Prompt // Optionally modify the prompt
};
},

// Called when session starts
OnSessionStart = async (input, invocation) =>
{
Console.WriteLine($"Session started from: {input.Source}"); // "startup", "resume", "new"
return new SessionStartHookOutput
{
AdditionalContext = "Session initialization context"
};
},

// Called when session ends
OnSessionEnd = async (input, invocation) =>
{
Console.WriteLine($"Session ended: {input.Reason}");
return null;
},

// Called when an error occurs
OnErrorOccurred = async (input, invocation) =>
{
Console.WriteLine($"Error in {input.ErrorContext}: {input.Error}");
return new ErrorOccurredHookOutput
{
ErrorHandling = "retry" // "retry", "skip", or "abort"
};
}
}
});
```

**Available hooks:**

- `OnPreToolUse` - Intercept tool calls before execution. Can allow/deny or modify arguments.
- `OnPostToolUse` - Process tool results after execution. Can modify results or add context.
- `OnUserPromptSubmitted` - Intercept user prompts. Can modify the prompt before processing.
- `OnSessionStart` - Run logic when a session starts or resumes.
- `OnSessionEnd` - Cleanup or logging when session ends.
- `OnErrorOccurred` - Handle errors with retry/skip/abort strategies.

## Error Handling

```csharp
Expand Down
99 changes: 99 additions & 0 deletions go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ func main() {
- `AutoStart` (\*bool): Auto-start server on first use (default: true). Use `Bool(false)` to disable.
- `AutoRestart` (\*bool): Auto-restart on crash (default: true). Use `Bool(false)` to disable.
- `Env` ([]string): Environment variables for CLI process (default: inherits from current process)
- `GithubToken` (string): GitHub token for authentication. When provided, takes priority over other auth methods.
- `UseLoggedInUser` (\*bool): Whether to use logged-in user for authentication (default: true, but false when `GithubToken` is provided). Cannot be used with `CLIUrl`.

**SessionConfig:**

Expand All @@ -106,6 +108,8 @@ func main() {
- `Provider` (\*ProviderConfig): Custom API provider configuration (BYOK). See [Custom Providers](#custom-providers) section.
- `Streaming` (bool): Enable streaming delta events
- `InfiniteSessions` (\*InfiniteSessionConfig): Automatic context compaction configuration
- `OnUserInputRequest` (UserInputHandler): Handler for user input requests from the agent (enables ask_user tool). See [User Input Requests](#user-input-requests) section.
- `Hooks` (\*SessionHooks): Hook handlers for session lifecycle events. See [Session Hooks](#session-hooks) section.

**ResumeSessionConfig:**

Expand Down Expand Up @@ -397,6 +401,101 @@ session, err := client.CreateSession(&copilot.SessionConfig{
> - For Azure OpenAI endpoints (`*.openai.azure.com`), you **must** use `Type: "azure"`, not `Type: "openai"`.
> - The `BaseURL` should be just the host (e.g., `https://my-resource.openai.azure.com`). Do **not** include `/openai/v1` in the URL - the SDK handles path construction automatically.

## User Input Requests

Enable the agent to ask questions to the user using the `ask_user` tool by providing an `OnUserInputRequest` handler:

```go
session, err := client.CreateSession(&copilot.SessionConfig{
Model: "gpt-5",
OnUserInputRequest: func(request copilot.UserInputRequest, invocation copilot.UserInputInvocation) (copilot.UserInputResponse, error) {
// request.Question - The question to ask
// request.Choices - Optional slice of choices for multiple choice
// request.AllowFreeform - Whether freeform input is allowed (default: true)

fmt.Printf("Agent asks: %s\n", request.Question)
if len(request.Choices) > 0 {
fmt.Printf("Choices: %v\n", request.Choices)
}

// Return the user's response
return copilot.UserInputResponse{
Answer: "User's answer here",
WasFreeform: true, // Whether the answer was freeform (not from choices)
}, nil
},
})
```

## Session Hooks

Hook into session lifecycle events by providing handlers in the `Hooks` configuration:

```go
session, err := client.CreateSession(&copilot.SessionConfig{
Model: "gpt-5",
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example uses model "gpt-5", but this model does not exist. OpenAI's latest models are GPT-4 variants (e.g., "gpt-4", "gpt-4-turbo", "gpt-4o"). Using a non-existent model in documentation examples could confuse users.

Copilot uses AI. Check for mistakes.
Hooks: &copilot.SessionHooks{
// Called before each tool execution
OnPreToolUse: func(input copilot.PreToolUseHookInput, invocation copilot.HookInvocation) (*copilot.PreToolUseHookOutput, error) {
fmt.Printf("About to run tool: %s\n", input.ToolName)
// Return permission decision and optionally modify args
return &copilot.PreToolUseHookOutput{
PermissionDecision: "allow", // "allow", "deny", or "ask"
ModifiedArgs: input.ToolArgs, // Optionally modify tool arguments
AdditionalContext: "Extra context for the model",
}, nil
},

// Called after each tool execution
OnPostToolUse: func(input copilot.PostToolUseHookInput, invocation copilot.HookInvocation) (*copilot.PostToolUseHookOutput, error) {
fmt.Printf("Tool %s completed\n", input.ToolName)
return &copilot.PostToolUseHookOutput{
AdditionalContext: "Post-execution notes",
}, nil
},

// Called when user submits a prompt
OnUserPromptSubmitted: func(input copilot.UserPromptSubmittedHookInput, invocation copilot.HookInvocation) (*copilot.UserPromptSubmittedHookOutput, error) {
fmt.Printf("User prompt: %s\n", input.Prompt)
return &copilot.UserPromptSubmittedHookOutput{
ModifiedPrompt: input.Prompt, // Optionally modify the prompt
}, nil
},

// Called when session starts
OnSessionStart: func(input copilot.SessionStartHookInput, invocation copilot.HookInvocation) (*copilot.SessionStartHookOutput, error) {
fmt.Printf("Session started from: %s\n", input.Source) // "startup", "resume", "new"
return &copilot.SessionStartHookOutput{
AdditionalContext: "Session initialization context",
}, nil
},

// Called when session ends
OnSessionEnd: func(input copilot.SessionEndHookInput, invocation copilot.HookInvocation) (*copilot.SessionEndHookOutput, error) {
fmt.Printf("Session ended: %s\n", input.Reason)
return nil, nil
},

// Called when an error occurs
OnErrorOccurred: func(input copilot.ErrorOccurredHookInput, invocation copilot.HookInvocation) (*copilot.ErrorOccurredHookOutput, error) {
fmt.Printf("Error in %s: %s\n", input.ErrorContext, input.Error)
return &copilot.ErrorOccurredHookOutput{
ErrorHandling: "retry", // "retry", "skip", or "abort"
}, nil
},
},
})
```

**Available hooks:**

- `OnPreToolUse` - Intercept tool calls before execution. Can allow/deny or modify arguments.
- `OnPostToolUse` - Process tool results after execution. Can modify results or add context.
- `OnUserPromptSubmitted` - Intercept user prompts. Can modify the prompt before processing.
- `OnSessionStart` - Run logic when a session starts or resumes.
- `OnSessionEnd` - Cleanup or logging when session ends.
- `OnErrorOccurred` - Handle errors with retry/skip/abort strategies.

## Transport Modes

### stdio (Default)
Expand Down
99 changes: 99 additions & 0 deletions nodejs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ new CopilotClient(options?: CopilotClientOptions)
- `logLevel?: string` - Log level (default: "info")
- `autoStart?: boolean` - Auto-start server (default: true)
- `autoRestart?: boolean` - Auto-restart on crash (default: true)
- `githubToken?: string` - GitHub token for authentication. When provided, takes priority over other auth methods.
- `useLoggedInUser?: boolean` - Whether to use logged-in user for authentication (default: true, but false when `githubToken` is provided). Cannot be used with `cliUrl`.

#### Methods

Expand Down Expand Up @@ -91,6 +93,8 @@ Create a new conversation session.
- `systemMessage?: SystemMessageConfig` - System message customization (see below)
- `infiniteSessions?: InfiniteSessionConfig` - Configure automatic context compaction (see below)
- `provider?: ProviderConfig` - Custom API provider configuration (BYOK - Bring Your Own Key). See [Custom Providers](#custom-providers) section.
- `onUserInputRequest?: UserInputHandler` - Handler for user input requests from the agent. Enables the `ask_user` tool. See [User Input Requests](#user-input-requests) section.
- `hooks?: SessionHooks` - Hook handlers for session lifecycle events. See [Session Hooks](#session-hooks) section.

##### `resumeSession(sessionId: string, config?: ResumeSessionConfig): Promise<CopilotSession>`

Expand Down Expand Up @@ -470,6 +474,101 @@ const session = await client.createSession({
> - For Azure OpenAI endpoints (`*.openai.azure.com`), you **must** use `type: "azure"`, not `type: "openai"`.
> - The `baseUrl` should be just the host (e.g., `https://my-resource.openai.azure.com`). Do **not** include `/openai/v1` in the URL - the SDK handles path construction automatically.

## User Input Requests

Enable the agent to ask questions to the user using the `ask_user` tool by providing an `onUserInputRequest` handler:

```typescript
const session = await client.createSession({
model: "gpt-5",
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example uses model "gpt-5", but this model does not exist. OpenAI's latest models are GPT-4 variants (e.g., "gpt-4", "gpt-4-turbo", "gpt-4o"). Using a non-existent model in documentation examples could confuse users.

Copilot uses AI. Check for mistakes.
onUserInputRequest: async (request, invocation) => {
// request.question - The question to ask
// request.choices - Optional array of choices for multiple choice
// request.allowFreeform - Whether freeform input is allowed (default: true)

console.log(`Agent asks: ${request.question}`);
if (request.choices) {
console.log(`Choices: ${request.choices.join(", ")}`);
}

// Return the user's response
return {
answer: "User's answer here",
wasFreeform: true, // Whether the answer was freeform (not from choices)
};
},
});
```

## Session Hooks

Hook into session lifecycle events by providing handlers in the `hooks` configuration:

```typescript
const session = await client.createSession({
model: "gpt-5",
hooks: {
// Called before each tool execution
onPreToolUse: async (input, invocation) => {
console.log(`About to run tool: ${input.toolName}`);
// Return permission decision and optionally modify args
return {
permissionDecision: "allow", // "allow", "deny", or "ask"
modifiedArgs: input.toolArgs, // Optionally modify tool arguments
additionalContext: "Extra context for the model",
};
},

// Called after each tool execution
onPostToolUse: async (input, invocation) => {
console.log(`Tool ${input.toolName} completed`);
// Optionally modify the result or add context
return {
additionalContext: "Post-execution notes",
};
},

// Called when user submits a prompt
onUserPromptSubmitted: async (input, invocation) => {
console.log(`User prompt: ${input.prompt}`);
return {
modifiedPrompt: input.prompt, // Optionally modify the prompt
};
},

// Called when session starts
onSessionStart: async (input, invocation) => {
console.log(`Session started from: ${input.source}`); // "startup", "resume", "new"
return {
additionalContext: "Session initialization context",
};
},

// Called when session ends
onSessionEnd: async (input, invocation) => {
console.log(`Session ended: ${input.reason}`);
},

// Called when an error occurs
onErrorOccurred: async (input, invocation) => {
console.error(`Error in ${input.errorContext}: ${input.error}`);
return {
errorHandling: "retry", // "retry", "skip", or "abort"
};
},
},
});
```

**Available hooks:**

- `onPreToolUse` - Intercept tool calls before execution. Can allow/deny or modify arguments.
- `onPostToolUse` - Process tool results after execution. Can modify results or add context.
- `onUserPromptSubmitted` - Intercept user prompts. Can modify the prompt before processing.
- `onSessionStart` - Run logic when a session starts or resumes.
- `onSessionEnd` - Cleanup or logging when session ends.
- `onErrorOccurred` - Handle errors with retry/skip/abort strategies.

## Error Handling

```typescript
Expand Down
Loading
Loading