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
52 changes: 52 additions & 0 deletions docs/auth/byok.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,36 @@ Console.WriteLine(response?.Data.Content);

</details>

<details>
<summary><strong>Java</strong></summary>

```java
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;

var client = new CopilotClient();
client.start().get();

var session = client.createSession(new SessionConfig()
.setModel("gpt-5.2-codex") // Your deployment name
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
.setProvider(new ProviderConfig()
.setType("openai")
.setBaseUrl("https://your-resource.openai.azure.com/openai/v1/")
.setWireApi("responses") // Use "completions" for older models
.setApiKey(System.getenv("FOUNDRY_API_KEY")))
).get();

var response = session.sendAndWait(new MessageOptions()
.setPrompt("What is 2+2?")).get();
System.out.println(response.getData().content());

client.stop().get();
```

</details>

## Provider Configuration Reference

### ProviderConfig Fields
Expand Down Expand Up @@ -412,6 +442,28 @@ var client = new CopilotClient(new CopilotClientOptions

</details>

<details>
<summary><strong>Java</strong></summary>

```java
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.json.*;
import java.util.concurrent.CompletableFuture;

var client = new CopilotClient(new CopilotClientOptions()
.setOnListModels(() -> CompletableFuture.completedFuture(List.of(
new ModelInfo()
.setId("my-custom-model")
.setName("My Custom Model")
.setCapabilities(new ModelCapabilities()
.setSupports(new ModelSupports().setVision(false).setReasoningEffort(false))
.setLimits(new ModelLimits().setMaxContextWindowTokens(128000)))
)))
);
Comment on lines +448 to +462

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

This Java onListModels example references List and several model types (ModelInfo, ModelCapabilities, etc.) but doesn't import java.util.List or the SDK JSON types package. As written, it won't compile; please add the missing imports to make the snippet copy/pasteable.

Copilot uses AI. Check for mistakes.
```

</details>

Results are cached after the first call, just like the default behavior. The handler completely replaces the CLI's `models.list` RPC — no fallback to the server occurs.

## Limitations
Expand Down
44 changes: 44 additions & 0 deletions docs/auth/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ await using var client = new CopilotClient();

</details>

<details>
<summary><strong>Java</strong></summary>

```java
import com.github.copilot.sdk.CopilotClient;

// Default: uses logged-in user credentials
var client = new CopilotClient();
client.start().get();
```

</details>

**When to use:**
- Desktop applications where users interact directly
- Development and testing environments
Expand Down Expand Up @@ -189,6 +202,22 @@ await using var client = new CopilotClient(new CopilotClientOptions

</details>

<details>
<summary><strong>Java</strong></summary>

```java
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.json.*;

var client = new CopilotClient(new CopilotClientOptions()
.setGitHubToken(userAccessToken) // Token from OAuth flow
.setUseLoggedInUser(false) // Don't use stored CLI credentials
);
client.start().get();
```

</details>

**Supported token types:**
- `gho_` - OAuth user access tokens
- `ghu_` - GitHub App user access tokens
Expand Down Expand Up @@ -351,6 +380,21 @@ await using var client = new CopilotClient(new CopilotClientOptions

</details>

<details>
<summary><strong>Java</strong></summary>

```java
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.json.*;

var client = new CopilotClient(new CopilotClientOptions()
.setUseLoggedInUser(false) // Only use explicit tokens
);
client.start().get();
```

</details>

## Next Steps

- [BYOK Documentation](./byok.md) - Learn how to use your own API keys
Expand Down
85 changes: 85 additions & 0 deletions docs/features/custom-agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,41 @@ await using var session = await client.CreateSessionAsync(new SessionConfig

</details>

<details>
<summary><strong>Java</strong></summary>

```java
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;

try (var client = new CopilotClient()) {
client.start().get();

var session = client.createSession(
new SessionConfig()
.setModel("gpt-4.1")
.setCustomAgents(List.of(
new CustomAgentConfig()
.setName("researcher")
.setDisplayName("Research Agent")
.setDescription("Explores codebases and answers questions using read-only tools")
.setTools(List.of("grep", "glob", "view"))
.setPrompt("You are a research assistant. Analyze code and answer questions. Do not modify any files."),
Comment on lines +221 to +228

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

This Java custom-agents snippet uses List.of(...) but doesn't import java.util.List, so it won't compile as shown. Please add the missing import (or use fully-qualified names).

This issue also appears on line 359 of the same file.

Copilot uses AI. Check for mistakes.
new CustomAgentConfig()
.setName("editor")
.setDisplayName("Editor Agent")
.setDescription("Makes targeted code changes")
.setTools(List.of("view", "edit", "bash"))
.setPrompt("You are a code editor. Make minimal, surgical changes to files as requested.")
))
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
}
```

</details>

## Configuration Reference

| Property | Type | Required | Description |
Expand Down Expand Up @@ -316,6 +351,28 @@ var session = await client.CreateSessionAsync(new SessionConfig

</details>

<details>
<summary><strong>Java</strong></summary>

<!-- docs-validate: skip -->
```java
var session = client.createSession(
new SessionConfig()
.setCustomAgents(List.of(
new CustomAgentConfig()
.setName("researcher")
.setPrompt("You are a research assistant. Analyze code and answer questions."),
new CustomAgentConfig()
.setName("editor")
.setPrompt("You are a code editor. Make minimal, surgical changes.")
))
.setAgent("researcher") // Pre-select the researcher agent
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
```

</details>

## How Sub-Agent Delegation Works

When you send a prompt to a session with custom agents, the runtime evaluates whether to delegate to a sub-agent:
Expand Down Expand Up @@ -561,6 +618,34 @@ await session.SendAndWaitAsync(new MessageOptions

</details>

<details>
<summary><strong>Java</strong></summary>

```java
session.on(event -> {
if (event instanceof SubagentStartedEvent e) {
System.out.println("▶ Sub-agent started: " + e.getData().agentDisplayName());
System.out.println(" Description: " + e.getData().agentDescription());
System.out.println(" Tool call ID: " + e.getData().toolCallId());
} else if (event instanceof SubagentCompletedEvent e) {
System.out.println("✅ Sub-agent completed: " + e.getData().agentName());
} else if (event instanceof SubagentFailedEvent e) {
System.out.println("❌ Sub-agent failed: " + e.getData().agentName());
System.out.println(" Error: " + e.getData().error());
} else if (event instanceof SubagentSelectedEvent e) {
System.out.println("🎯 Agent selected: " + e.getData().agentDisplayName());
} else if (event instanceof SubagentDeselectedEvent e) {
System.out.println("↩ Agent deselected, returning to parent");
}
});

var response = session.sendAndWait(
new MessageOptions().setPrompt("Research how authentication works in this codebase")
).get();
```

</details>

## Building an Agent Tree UI

Sub-agent events include `toolCallId` fields that let you reconstruct the execution tree. Here's a pattern for tracking agent activity:
Expand Down
53 changes: 53 additions & 0 deletions docs/features/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,33 @@ var session = await client.CreateSessionAsync(new SessionConfig

</details>

<details>
<summary><strong>Java</strong></summary>

```java
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;

try (var client = new CopilotClient()) {
client.start().get();

var hooks = new SessionHooks()
.setOnSessionStart((input, inv) -> CompletableFuture.completedFuture(null))
.setOnPreToolUse((input, inv) -> CompletableFuture.completedFuture(null))
.setOnPostToolUse((input, inv) -> CompletableFuture.completedFuture(null));
Comment on lines +206 to +212

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

This Java example uses CompletableFuture.completedFuture(...) but doesn't import java.util.concurrent.CompletableFuture, so it won't compile as shown. Please add the missing import (or qualify the type) for consistency with other Java snippets.

Copilot uses AI. Check for mistakes.
// ... add only the hooks you need

var session = client.createSession(
new SessionConfig()
.setHooks(hooks)
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
}
```

</details>

> **Tip:** Every hook handler receives an `invocation` parameter containing the `sessionId`, which is useful for correlating logs and maintaining per-session state.
---
Expand Down Expand Up @@ -380,6 +407,32 @@ var session = await client.CreateSessionAsync(new SessionConfig

</details>

<details>
<summary><strong>Java</strong></summary>

```java
var readOnlyTools = Set.of("read_file", "glob", "grep", "view");

var hooks = new SessionHooks()
.setOnPreToolUse((input, invocation) -> {
if (!readOnlyTools.contains(input.getToolName())) {
return CompletableFuture.completedFuture(
PreToolUseHookOutput.deny(
"Only read-only tools are allowed. \"" + input.getToolName() + "\" was blocked.")
);
}
return CompletableFuture.completedFuture(PreToolUseHookOutput.allow());
});

var session = client.createSession(
new SessionConfig()
.setHooks(hooks)
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
```

</details>

### Restrict file access to specific directories

```typescript
Expand Down
60 changes: 60 additions & 0 deletions docs/features/image-input.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,34 @@ await session.SendAsync(new MessageOptions

</details>

<details>
<summary><strong>Java</strong></summary>

```java
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;

try (var client = new CopilotClient()) {
client.start().get();

var session = client.createSession(
new SessionConfig()
.setModel("gpt-4.1")
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();

session.send(new MessageOptions()
.setPrompt("Describe what you see in this image")
.setAttachments(List.of(
new Attachment("file", "/absolute/path/to/screenshot.png", "screenshot.png")
))
).get();
Comment on lines +239 to +244

Copilot AI Apr 6, 2026

Copy link

Choose a reason for hiding this comment

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

This Java file-attachment example uses List.of(...) but doesn't import java.util.List, so it won't compile as shown. Please add the missing import (or qualify it).

This issue also appears on line 448 of the same file.

Copilot uses AI. Check for mistakes.
}
```

</details>

## Quick Start — Blob Attachment

When you already have image data in memory (e.g., a screenshot captured by your app, or an image fetched from an API), use a blob attachment to send it directly without writing to disk.
Expand Down Expand Up @@ -400,6 +428,38 @@ await session.SendAsync(new MessageOptions

</details>

<details>
<summary><strong>Java</strong></summary>

```java
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;

try (var client = new CopilotClient()) {
client.start().get();

var session = client.createSession(
new SessionConfig()
.setModel("gpt-4.1")
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();

var base64ImageData = "..."; // your base64-encoded image
session.send(new MessageOptions()
.setPrompt("Describe what you see in this image")
.setAttachments(List.of(
new BlobAttachment()
.setData(base64ImageData)
.setMimeType("image/png")
.setDisplayName("screenshot.png")
))
).get();
}
```

</details>

## Supported Formats

Supported image formats include JPG, PNG, GIF, and other common image types. For file attachments, the runtime reads the image from disk and converts it as needed. For blob attachments, you provide the base64 data and MIME type directly. Use PNG or JPEG for best results, as these are the most widely supported formats.
Expand Down
2 changes: 1 addition & 1 deletion docs/features/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Features

These guides cover the capabilities you can add to your Copilot SDK application. Each guide includes examples in all supported languages (TypeScript, Python, Go, and .NET).
These guides cover the capabilities you can add to your Copilot SDK application. Each guide includes examples in all supported languages (TypeScript, Python, Go, .NET, and Java).

> **New to the SDK?** Start with the [Getting Started tutorial](../getting-started.md) first, then come back here to add more capabilities.
Expand Down
Loading