Skip to content

Commit c8f8025

Browse files
Copilotbrunoborges
andcommitted
Add Java SDK cookbooks based on official .NET and Go SDKs
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
1 parent 3854c4c commit c8f8025

6 files changed

Lines changed: 1062 additions & 0 deletions

File tree

cookbook/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# GitHub Copilot SDK Cookbook — Java
2+
3+
This folder hosts short, practical recipes for using the GitHub Copilot SDK with Java. Each recipe is concise, copy‑pasteable, and points to fuller examples and tests.
4+
5+
## Recipes
6+
7+
- [Error Handling](error-handling.md): Handle errors gracefully including connection failures, timeouts, and cleanup.
8+
- [Multiple Sessions](multiple-sessions.md): Manage multiple independent conversations simultaneously.
9+
- [Managing Local Files](managing-local-files.md): Organize files by metadata using AI-powered grouping strategies.
10+
- [PR Visualization](pr-visualization.md): Generate interactive PR age charts using GitHub MCP Server.
11+
- [Persisting Sessions](persisting-sessions.md): Save and resume sessions across restarts.
12+
13+
## Contributing
14+
15+
Add a new recipe by creating a markdown file in this folder and linking it above. Follow repository guidance in [CONTRIBUTING.md](../CONTRIBUTING.md).
16+
17+
## Status
18+
19+
These recipes are complete, practical examples and can be used directly or adapted for your own projects.

cookbook/error-handling.md

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
# Error Handling Patterns
2+
3+
Handle errors gracefully in your Copilot SDK applications.
4+
5+
## Example scenario
6+
7+
You need to handle various error conditions like connection failures, timeouts, and invalid responses.
8+
9+
## Basic error handling
10+
11+
```java
12+
import com.github.copilot.sdk.*;
13+
import com.github.copilot.sdk.events.*;
14+
import com.github.copilot.sdk.json.*;
15+
16+
public class BasicErrorHandling {
17+
public static void main(String[] args) {
18+
try (var client = new CopilotClient()) {
19+
client.start().get();
20+
21+
var session = client.createSession(
22+
new SessionConfig().setModel("gpt-5")).get();
23+
24+
session.on(AssistantMessageEvent.class, msg -> {
25+
System.out.println(msg.getData().getContent());
26+
});
27+
28+
session.sendAndWait(new MessageOptions()
29+
.setPrompt("Hello!")).get();
30+
31+
session.close();
32+
} catch (Exception ex) {
33+
System.err.println("Error: " + ex.getMessage());
34+
ex.printStackTrace();
35+
}
36+
}
37+
}
38+
```
39+
40+
## Handling specific error types
41+
42+
```java
43+
import java.io.IOException;
44+
import java.util.concurrent.ExecutionException;
45+
import java.util.concurrent.TimeoutException;
46+
47+
public class SpecificErrorHandling {
48+
public static void startClient() {
49+
try (var client = new CopilotClient()) {
50+
client.start().get();
51+
// ... use client ...
52+
} catch (IOException ex) {
53+
System.err.println("Copilot CLI not found. Please install it first.");
54+
System.err.println("Details: " + ex.getMessage());
55+
} catch (TimeoutException ex) {
56+
System.err.println("Could not connect to Copilot CLI server.");
57+
System.err.println("Details: " + ex.getMessage());
58+
} catch (ExecutionException ex) {
59+
System.err.println("Unexpected error: " + ex.getCause().getMessage());
60+
ex.getCause().printStackTrace();
61+
} catch (Exception ex) {
62+
System.err.println("Unexpected error: " + ex.getMessage());
63+
ex.printStackTrace();
64+
}
65+
}
66+
}
67+
```
68+
69+
## Timeout handling
70+
71+
```java
72+
import java.util.concurrent.TimeUnit;
73+
import java.util.concurrent.TimeoutException;
74+
75+
public class TimeoutHandling {
76+
public static void sendWithTimeout(CopilotSession session) {
77+
try {
78+
session.on(AssistantMessageEvent.class, msg -> {
79+
System.out.println(msg.getData().getContent());
80+
});
81+
82+
// Wait up to 30 seconds for response
83+
session.sendAndWait(new MessageOptions()
84+
.setPrompt("Complex question..."))
85+
.get(30, TimeUnit.SECONDS);
86+
87+
} catch (TimeoutException ex) {
88+
System.err.println("Request timed out");
89+
} catch (Exception ex) {
90+
System.err.println("Error: " + ex.getMessage());
91+
}
92+
}
93+
}
94+
```
95+
96+
## Aborting a request
97+
98+
```java
99+
import java.util.concurrent.Executors;
100+
import java.util.concurrent.ScheduledExecutorService;
101+
import java.util.concurrent.TimeUnit;
102+
103+
public class AbortRequest {
104+
public static void abortAfterDelay(CopilotSession session) {
105+
// Start a request (non-blocking)
106+
session.send(new MessageOptions()
107+
.setPrompt("Write a very long story..."));
108+
109+
// Schedule abort after 5 seconds
110+
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
111+
scheduler.schedule(() -> {
112+
try {
113+
session.abort().get();
114+
System.out.println("Request aborted");
115+
} catch (Exception ex) {
116+
System.err.println("Failed to abort: " + ex.getMessage());
117+
}
118+
}, 5, TimeUnit.SECONDS);
119+
}
120+
}
121+
```
122+
123+
## Graceful shutdown
124+
125+
```java
126+
public class GracefulShutdown {
127+
public static void main(String[] args) {
128+
var client = new CopilotClient();
129+
130+
// Set up shutdown hook
131+
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
132+
System.out.println("\nShutting down...");
133+
try {
134+
client.close();
135+
} catch (Exception ex) {
136+
System.err.println("Error during shutdown: " + ex.getMessage());
137+
}
138+
}));
139+
140+
try {
141+
client.start().get();
142+
// ... do work ...
143+
} catch (Exception ex) {
144+
ex.printStackTrace();
145+
}
146+
}
147+
}
148+
```
149+
150+
## Try-with-resources pattern
151+
152+
```java
153+
public class TryWithResources {
154+
public static void doWork() throws Exception {
155+
try (var client = new CopilotClient()) {
156+
client.start().get();
157+
158+
try (var session = client.createSession(
159+
new SessionConfig().setModel("gpt-5")).get()) {
160+
161+
session.on(AssistantMessageEvent.class, msg -> {
162+
System.out.println(msg.getData().getContent());
163+
});
164+
165+
session.sendAndWait(new MessageOptions()
166+
.setPrompt("Hello!")).get();
167+
168+
// Session and client are automatically closed
169+
}
170+
}
171+
}
172+
}
173+
```
174+
175+
## Handling tool errors
176+
177+
```java
178+
import java.util.Map;
179+
import java.util.List;
180+
import java.util.concurrent.CompletableFuture;
181+
182+
public class ToolErrorHandling {
183+
public static void handleToolErrors() throws Exception {
184+
var errorTool = ToolDefinition.create(
185+
"get_user_location",
186+
"Gets the user's location",
187+
Map.of("type", "object", "properties", Map.of()),
188+
invocation -> {
189+
// Return an error result
190+
return CompletableFuture.completedFuture(
191+
ToolResultObject.error("Location service unavailable")
192+
);
193+
}
194+
);
195+
196+
try (var client = new CopilotClient()) {
197+
client.start().get();
198+
199+
var session = client.createSession(
200+
new SessionConfig().setTools(List.of(errorTool))).get();
201+
202+
session.on(AssistantMessageEvent.class, msg -> {
203+
System.out.println(msg.getData().getContent());
204+
});
205+
206+
// Session continues even when tool fails
207+
session.sendAndWait(new MessageOptions()
208+
.setPrompt("What is my location? If you can't find out, just say 'unknown'."))
209+
.get();
210+
211+
session.close();
212+
}
213+
}
214+
}
215+
```
216+
217+
## Best practices
218+
219+
1. **Always clean up**: Use try-with-resources to ensure `close()` is called
220+
2. **Handle connection errors**: The CLI might not be installed or running
221+
3. **Set appropriate timeouts**: Use `get(timeout, TimeUnit)` for long-running requests
222+
4. **Log errors**: Capture error details for debugging
223+
5. **Wrap operations**: Consider wrapping SDK operations in methods that handle common errors
224+
6. **Check error causes**: Use `ExecutionException.getCause()` to get the actual error from `CompletableFuture`

0 commit comments

Comments
 (0)