fix: Java cookbook recipes to compile with copilot-sdk-java 0.2.1-java.1

Fix compilation errors and documentation inaccuracies in Java cookbook
recipes against the actual SDK API:

- MultipleSessions: Replace non-existent destroy() with close()
- AccessibilityReport: Replace non-existent McpServerConfig class with
  Map<String, Object> (the actual type accepted by setMcpServers)
- error-handling.md: Replace non-existent session.addTool(),
  ToolDefinition.builder(), and ToolResultObject with actual SDK APIs
  (ToolDefinition.create(), SessionConfig.setTools(),
  CompletableFuture<Object> return type)

All 7 recipes now compile successfully with jbang build.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Bruno Borges
2026-04-06 15:12:06 -04:00
parent 0f06f346be
commit e03ccb978a
5 changed files with 52 additions and 35 deletions

View File

@@ -67,11 +67,12 @@ public class AccessibilityReport {
client.start().get();
// Configure Playwright MCP server for browser automation
var mcpConfig = new McpServerConfig()
.setType("local")
.setCommand("npx")
.setArgs(List.of("@playwright/mcp@latest"))
.setTools(List.of("*"));
Map<String, Object> mcpConfig = Map.of(
"type", "local",
"command", "npx",
"args", List.of("@playwright/mcp@latest"),
"tools", List.of("*")
);
var session = client.createSession(
new SessionConfig()
@@ -167,11 +168,12 @@ public class AccessibilityReport {
The recipe configures a local MCP server that runs alongside the session:
```java
var mcpConfig = new McpServerConfig()
.setType("local")
.setCommand("npx")
.setArgs(List.of("@playwright/mcp@latest"))
.setTools(List.of("*"));
Map<String, Object> mcpConfig = Map.of(
"type", "local",
"command", "npx",
"args", List.of("@playwright/mcp@latest"),
"tools", List.of("*")
);
var session = client.createSession(
new SessionConfig()

View File

@@ -150,27 +150,42 @@ try (var client = new CopilotClient()) {
## Handling tool errors
When defining tools, return an error result to signal a failure back to the model instead of throwing.
When defining tools, return an error string to signal a failure back to the model instead of throwing.
```java
import com.github.copilot.sdk.json.ToolResultObject;
import com.github.copilot.sdk.json.ToolDefinition;
import java.util.concurrent.CompletableFuture;
session.addTool(
ToolDefinition.builder()
.name("read_file")
.description("Read a file from disk")
.parameter("path", "string", "File path", true)
.build(),
(args) -> {
var readFileTool = ToolDefinition.create(
"read_file",
"Read a file from disk",
Map.of(
"type", "object",
"properties", Map.of(
"path", Map.of("type", "string", "description", "File path")
),
"required", List.of("path")
),
invocation -> {
try {
var path = (String) invocation.getArguments().get("path");
var content = java.nio.file.Files.readString(
java.nio.file.Path.of(args.get("path").toString()));
return ToolResultObject.success(content);
} catch (IOException ex) {
return ToolResultObject.error("Failed to read file: " + ex.getMessage());
java.nio.file.Path.of(path));
return CompletableFuture.completedFuture(content);
} catch (java.io.IOException ex) {
return CompletableFuture.completedFuture(
"Error: Failed to read file: " + ex.getMessage());
}
}
);
// Register tools when creating the session
var session = client.createSession(
new SessionConfig()
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
.setModel("gpt-5")
.setTools(List.of(readFileTool))
).get();
```
## Best practices
@@ -179,5 +194,5 @@ session.addTool(
2. **Unwrap `ExecutionException`**: Call `getCause()` to inspect the real error — the outer `ExecutionException` is just a `CompletableFuture` wrapper.
3. **Restore interrupt flag**: When catching `InterruptedException`, call `Thread.currentThread().interrupt()` to preserve the interrupted status.
4. **Set timeouts**: Use `get(timeout, TimeUnit)` instead of bare `get()` for any call that could block indefinitely.
5. **Return tool errors, don't throw**: Use `ToolResultObject.error()` so the model can recover gracefully.
5. **Return tool errors, don't throw**: Return an error string from the `CompletableFuture` so the model can recover gracefully.
6. **Log errors**: Capture error details for debugging — consider a logging framework like SLF4J for production applications.

View File

@@ -48,9 +48,9 @@ public class MultipleSessions {
session3.sendAndWait(new MessageOptions().setPrompt("How do I initialize a module?")).get();
// Clean up all sessions
session1.destroy().get();
session2.destroy().get();
session3.destroy().get();
session1.close();
session2.close();
session3.close();
}
}
}
@@ -136,7 +136,7 @@ var session = client.createSession(new SessionConfig()
session.sendAndWait(new MessageOptions().setPrompt("Hello!")).get();
session.destroy().get();
session.close();
client.stop().get();
executor.shutdown();
```

View File

@@ -43,11 +43,12 @@ public class AccessibilityReport {
client.start().get();
// Configure Playwright MCP server for browser automation
var mcpConfig = new McpServerConfig()
.setType("local")
.setCommand("npx")
.setArgs(List.of("@playwright/mcp@latest"))
.setTools(List.of("*"));
Map<String, Object> mcpConfig = Map.of(
"type", "local",
"command", "npx",
"args", List.of("@playwright/mcp@latest"),
"tools", List.of("*")
);
var session = client.createSession(
new SessionConfig()

View File

@@ -30,8 +30,7 @@ public class MultipleSessions {
System.out.println("S3: " + s3.sendAndWait(new MessageOptions().setPrompt("Explain pattern matching")).get().getData().content());
// Clean up
s1.destroy().get(); s2.destroy().get(); s3.destroy().get();
client.stop().get();
s1.close(); s2.close(); s3.close();
}
}
}