Skip to content

Commit 156cf1f

Browse files
brunoborgesCopilot
andauthored
docs: add Java language tabs across all SDK documentation (#1021)
* docs: add Java language tabs across all SDK documentation Add Java code examples to all 22 language-tabbed documentation files, matching the existing Node.js, Python, Go, and .NET tabs. Files updated: - docs/getting-started.md (8 sections + telemetry table + text refs) - docs/features/ (7 files: index, hooks, custom-agents, image-input, streaming-events, steering-and-queueing, skills) - docs/hooks/ (6 files: index, pre-tool-use, post-tool-use, user-prompt-submitted, session-lifecycle, error-handling) - docs/auth/ (2 files: index, byok) - docs/setup/ (4 files: local-cli, bundled-cli, backend-services, github-oauth) - docs/observability/opentelemetry.md - docs/troubleshooting/debugging.md - docs/integrations/microsoft-agent-framework.md All Java examples use idiomatic patterns: CompletableFuture, try-with-resources, ToolDefinition.create(), PermissionHandler.APPROVE_ALL, typed event handlers, and builder-style configuration. * Update docs/setup/local-cli.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/setup/bundled-cli.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/integrations/microsoft-agent-framework.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/integrations/microsoft-agent-framework.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Address review feedback on Java code snippets - Fix Maven coordinates: com.github:copilot-sdk-java with version property - Fix accessor: getContent() → content() (record-style) across all files - Fix accessor: input.toolName() → input.getToolName() (class-style) - Fix accessor: event.deltaContent() → event.getData().deltaContent() - Fix ToolDefinition: use factory method create() instead of constructor - Add missing imports (json.*, events.*) to feature doc snippets - Add client.start().get() and try-with-resources to hooks quickstart - Wrap OAuth usage example in try-with-resources * fix: audit Java code samples against SDK implementation - Fix PreToolUseHookOutput: record cannot use setters, use deny() factory - Fix SessionStartHookOutput: record cannot use setters, use constructor - Fix session.getId() → session.getSessionId() - Fix input.getPrompt() → input.prompt() (record accessor) - Fix response.data() → response.getData() (class accessor) - Fix setOnListModels: wrap return in CompletableFuture.completedFuture() - Fix custom-agents event handler: use instanceof pattern matching (AbstractSessionEvent has no getData() method) - Fix streaming-events: remove event.getData() from generic handler - Fix SubagentCompleted/Failed: use agentName() not agentDisplayName() - Fix CopilotClientOptions import: class is in json package, not sdk - Fix hook type signatures: use PreToolUseHandler etc. instead of BiFunction * Update docs/getting-started.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/getting-started.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/setup/local-cli.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/setup/backend-services.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/observability/opentelemetry.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/getting-started.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 200bfef commit 156cf1f

23 files changed

+1340
-18
lines changed

docs/auth/byok.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,36 @@ Console.WriteLine(response?.Data.Content);
164164

165165
</details>
166166

167+
<details>
168+
<summary><strong>Java</strong></summary>
169+
170+
```java
171+
import com.github.copilot.sdk.CopilotClient;
172+
import com.github.copilot.sdk.events.*;
173+
import com.github.copilot.sdk.json.*;
174+
175+
var client = new CopilotClient();
176+
client.start().get();
177+
178+
var session = client.createSession(new SessionConfig()
179+
.setModel("gpt-5.2-codex") // Your deployment name
180+
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
181+
.setProvider(new ProviderConfig()
182+
.setType("openai")
183+
.setBaseUrl("https://your-resource.openai.azure.com/openai/v1/")
184+
.setWireApi("responses") // Use "completions" for older models
185+
.setApiKey(System.getenv("FOUNDRY_API_KEY")))
186+
).get();
187+
188+
var response = session.sendAndWait(new MessageOptions()
189+
.setPrompt("What is 2+2?")).get();
190+
System.out.println(response.getData().content());
191+
192+
client.stop().get();
193+
```
194+
195+
</details>
196+
167197
## Provider Configuration Reference
168198

169199
### ProviderConfig Fields
@@ -412,6 +442,28 @@ var client = new CopilotClient(new CopilotClientOptions
412442

413443
</details>
414444

445+
<details>
446+
<summary><strong>Java</strong></summary>
447+
448+
```java
449+
import com.github.copilot.sdk.CopilotClient;
450+
import com.github.copilot.sdk.json.*;
451+
import java.util.concurrent.CompletableFuture;
452+
453+
var client = new CopilotClient(new CopilotClientOptions()
454+
.setOnListModels(() -> CompletableFuture.completedFuture(List.of(
455+
new ModelInfo()
456+
.setId("my-custom-model")
457+
.setName("My Custom Model")
458+
.setCapabilities(new ModelCapabilities()
459+
.setSupports(new ModelSupports().setVision(false).setReasoningEffort(false))
460+
.setLimits(new ModelLimits().setMaxContextWindowTokens(128000)))
461+
)))
462+
);
463+
```
464+
465+
</details>
466+
415467
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.
416468

417469
## Limitations

docs/auth/index.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,19 @@ await using var client = new CopilotClient();
8585

8686
</details>
8787

88+
<details>
89+
<summary><strong>Java</strong></summary>
90+
91+
```java
92+
import com.github.copilot.sdk.CopilotClient;
93+
94+
// Default: uses logged-in user credentials
95+
var client = new CopilotClient();
96+
client.start().get();
97+
```
98+
99+
</details>
100+
88101
**When to use:**
89102
- Desktop applications where users interact directly
90103
- Development and testing environments
@@ -189,6 +202,22 @@ await using var client = new CopilotClient(new CopilotClientOptions
189202

190203
</details>
191204

205+
<details>
206+
<summary><strong>Java</strong></summary>
207+
208+
```java
209+
import com.github.copilot.sdk.CopilotClient;
210+
import com.github.copilot.sdk.json.*;
211+
212+
var client = new CopilotClient(new CopilotClientOptions()
213+
.setGitHubToken(userAccessToken) // Token from OAuth flow
214+
.setUseLoggedInUser(false) // Don't use stored CLI credentials
215+
);
216+
client.start().get();
217+
```
218+
219+
</details>
220+
192221
**Supported token types:**
193222
- `gho_` - OAuth user access tokens
194223
- `ghu_` - GitHub App user access tokens
@@ -351,6 +380,21 @@ await using var client = new CopilotClient(new CopilotClientOptions
351380

352381
</details>
353382

383+
<details>
384+
<summary><strong>Java</strong></summary>
385+
386+
```java
387+
import com.github.copilot.sdk.CopilotClient;
388+
import com.github.copilot.sdk.json.*;
389+
390+
var client = new CopilotClient(new CopilotClientOptions()
391+
.setUseLoggedInUser(false) // Only use explicit tokens
392+
);
393+
client.start().get();
394+
```
395+
396+
</details>
397+
354398
## Next Steps
355399

356400
- [BYOK Documentation](./byok.md) - Learn how to use your own API keys

docs/features/custom-agents.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,41 @@ await using var session = await client.CreateSessionAsync(new SessionConfig
205205

206206
</details>
207207

208+
<details>
209+
<summary><strong>Java</strong></summary>
210+
211+
```java
212+
import com.github.copilot.sdk.CopilotClient;
213+
import com.github.copilot.sdk.events.*;
214+
import com.github.copilot.sdk.json.*;
215+
216+
try (var client = new CopilotClient()) {
217+
client.start().get();
218+
219+
var session = client.createSession(
220+
new SessionConfig()
221+
.setModel("gpt-4.1")
222+
.setCustomAgents(List.of(
223+
new CustomAgentConfig()
224+
.setName("researcher")
225+
.setDisplayName("Research Agent")
226+
.setDescription("Explores codebases and answers questions using read-only tools")
227+
.setTools(List.of("grep", "glob", "view"))
228+
.setPrompt("You are a research assistant. Analyze code and answer questions. Do not modify any files."),
229+
new CustomAgentConfig()
230+
.setName("editor")
231+
.setDisplayName("Editor Agent")
232+
.setDescription("Makes targeted code changes")
233+
.setTools(List.of("view", "edit", "bash"))
234+
.setPrompt("You are a code editor. Make minimal, surgical changes to files as requested.")
235+
))
236+
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
237+
).get();
238+
}
239+
```
240+
241+
</details>
242+
208243
## Configuration Reference
209244

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

317352
</details>
318353

354+
<details>
355+
<summary><strong>Java</strong></summary>
356+
357+
<!-- docs-validate: skip -->
358+
```java
359+
var session = client.createSession(
360+
new SessionConfig()
361+
.setCustomAgents(List.of(
362+
new CustomAgentConfig()
363+
.setName("researcher")
364+
.setPrompt("You are a research assistant. Analyze code and answer questions."),
365+
new CustomAgentConfig()
366+
.setName("editor")
367+
.setPrompt("You are a code editor. Make minimal, surgical changes.")
368+
))
369+
.setAgent("researcher") // Pre-select the researcher agent
370+
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
371+
).get();
372+
```
373+
374+
</details>
375+
319376
## How Sub-Agent Delegation Works
320377

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

562619
</details>
563620

621+
<details>
622+
<summary><strong>Java</strong></summary>
623+
624+
```java
625+
session.on(event -> {
626+
if (event instanceof SubagentStartedEvent e) {
627+
System.out.println("▶ Sub-agent started: " + e.getData().agentDisplayName());
628+
System.out.println(" Description: " + e.getData().agentDescription());
629+
System.out.println(" Tool call ID: " + e.getData().toolCallId());
630+
} else if (event instanceof SubagentCompletedEvent e) {
631+
System.out.println("✅ Sub-agent completed: " + e.getData().agentName());
632+
} else if (event instanceof SubagentFailedEvent e) {
633+
System.out.println("❌ Sub-agent failed: " + e.getData().agentName());
634+
System.out.println(" Error: " + e.getData().error());
635+
} else if (event instanceof SubagentSelectedEvent e) {
636+
System.out.println("🎯 Agent selected: " + e.getData().agentDisplayName());
637+
} else if (event instanceof SubagentDeselectedEvent e) {
638+
System.out.println("↩ Agent deselected, returning to parent");
639+
}
640+
});
641+
642+
var response = session.sendAndWait(
643+
new MessageOptions().setPrompt("Research how authentication works in this codebase")
644+
).get();
645+
```
646+
647+
</details>
648+
564649
## Building an Agent Tree UI
565650

566651
Sub-agent events include `toolCallId` fields that let you reconstruct the execution tree. Here's a pattern for tracking agent activity:

docs/features/hooks.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,33 @@ var session = await client.CreateSessionAsync(new SessionConfig
195195

196196
</details>
197197

198+
<details>
199+
<summary><strong>Java</strong></summary>
200+
201+
```java
202+
import com.github.copilot.sdk.CopilotClient;
203+
import com.github.copilot.sdk.events.*;
204+
import com.github.copilot.sdk.json.*;
205+
206+
try (var client = new CopilotClient()) {
207+
client.start().get();
208+
209+
var hooks = new SessionHooks()
210+
.setOnSessionStart((input, inv) -> CompletableFuture.completedFuture(null))
211+
.setOnPreToolUse((input, inv) -> CompletableFuture.completedFuture(null))
212+
.setOnPostToolUse((input, inv) -> CompletableFuture.completedFuture(null));
213+
// ... add only the hooks you need
214+
215+
var session = client.createSession(
216+
new SessionConfig()
217+
.setHooks(hooks)
218+
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
219+
).get();
220+
}
221+
```
222+
223+
</details>
224+
198225
> **Tip:** Every hook handler receives an `invocation` parameter containing the `sessionId`, which is useful for correlating logs and maintaining per-session state.
199226
200227
---
@@ -380,6 +407,32 @@ var session = await client.CreateSessionAsync(new SessionConfig
380407

381408
</details>
382409

410+
<details>
411+
<summary><strong>Java</strong></summary>
412+
413+
```java
414+
var readOnlyTools = Set.of("read_file", "glob", "grep", "view");
415+
416+
var hooks = new SessionHooks()
417+
.setOnPreToolUse((input, invocation) -> {
418+
if (!readOnlyTools.contains(input.getToolName())) {
419+
return CompletableFuture.completedFuture(
420+
PreToolUseHookOutput.deny(
421+
"Only read-only tools are allowed. \"" + input.getToolName() + "\" was blocked.")
422+
);
423+
}
424+
return CompletableFuture.completedFuture(PreToolUseHookOutput.allow());
425+
});
426+
427+
var session = client.createSession(
428+
new SessionConfig()
429+
.setHooks(hooks)
430+
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
431+
).get();
432+
```
433+
434+
</details>
435+
383436
### Restrict file access to specific directories
384437

385438
```typescript

docs/features/image-input.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,34 @@ await session.SendAsync(new MessageOptions
219219

220220
</details>
221221

222+
<details>
223+
<summary><strong>Java</strong></summary>
224+
225+
```java
226+
import com.github.copilot.sdk.CopilotClient;
227+
import com.github.copilot.sdk.events.*;
228+
import com.github.copilot.sdk.json.*;
229+
230+
try (var client = new CopilotClient()) {
231+
client.start().get();
232+
233+
var session = client.createSession(
234+
new SessionConfig()
235+
.setModel("gpt-4.1")
236+
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
237+
).get();
238+
239+
session.send(new MessageOptions()
240+
.setPrompt("Describe what you see in this image")
241+
.setAttachments(List.of(
242+
new Attachment("file", "/absolute/path/to/screenshot.png", "screenshot.png")
243+
))
244+
).get();
245+
}
246+
```
247+
248+
</details>
249+
222250
## Quick Start — Blob Attachment
223251

224252
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.
@@ -400,6 +428,38 @@ await session.SendAsync(new MessageOptions
400428

401429
</details>
402430

431+
<details>
432+
<summary><strong>Java</strong></summary>
433+
434+
```java
435+
import com.github.copilot.sdk.CopilotClient;
436+
import com.github.copilot.sdk.events.*;
437+
import com.github.copilot.sdk.json.*;
438+
439+
try (var client = new CopilotClient()) {
440+
client.start().get();
441+
442+
var session = client.createSession(
443+
new SessionConfig()
444+
.setModel("gpt-4.1")
445+
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
446+
).get();
447+
448+
var base64ImageData = "..."; // your base64-encoded image
449+
session.send(new MessageOptions()
450+
.setPrompt("Describe what you see in this image")
451+
.setAttachments(List.of(
452+
new BlobAttachment()
453+
.setData(base64ImageData)
454+
.setMimeType("image/png")
455+
.setDisplayName("screenshot.png")
456+
))
457+
).get();
458+
}
459+
```
460+
461+
</details>
462+
403463
## Supported Formats
404464

405465
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.

docs/features/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Features
22

3-
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).
3+
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).
44

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

0 commit comments

Comments
 (0)