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

View File

@@ -150,27 +150,42 @@ try (var client = new CopilotClient()) {
## Handling tool errors ## 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 ```java
import com.github.copilot.sdk.json.ToolResultObject; import com.github.copilot.sdk.json.ToolDefinition;
import java.util.concurrent.CompletableFuture;
session.addTool( var readFileTool = ToolDefinition.create(
ToolDefinition.builder() "read_file",
.name("read_file") "Read a file from disk",
.description("Read a file from disk") Map.of(
.parameter("path", "string", "File path", true) "type", "object",
.build(), "properties", Map.of(
(args) -> { "path", Map.of("type", "string", "description", "File path")
),
"required", List.of("path")
),
invocation -> {
try { try {
var path = (String) invocation.getArguments().get("path");
var content = java.nio.file.Files.readString( var content = java.nio.file.Files.readString(
java.nio.file.Path.of(args.get("path").toString())); java.nio.file.Path.of(path));
return ToolResultObject.success(content); return CompletableFuture.completedFuture(content);
} catch (IOException ex) { } catch (java.io.IOException ex) {
return ToolResultObject.error("Failed to read file: " + ex.getMessage()); 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 ## 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. 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. 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. 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. 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(); session3.sendAndWait(new MessageOptions().setPrompt("How do I initialize a module?")).get();
// Clean up all sessions // Clean up all sessions
session1.destroy().get(); session1.close();
session2.destroy().get(); session2.close();
session3.destroy().get(); session3.close();
} }
} }
} }
@@ -136,7 +136,7 @@ var session = client.createSession(new SessionConfig()
session.sendAndWait(new MessageOptions().setPrompt("Hello!")).get(); session.sendAndWait(new MessageOptions().setPrompt("Hello!")).get();
session.destroy().get(); session.close();
client.stop().get(); client.stop().get();
executor.shutdown(); executor.shutdown();
``` ```

View File

@@ -43,11 +43,12 @@ public class AccessibilityReport {
client.start().get(); client.start().get();
// Configure Playwright MCP server for browser automation // Configure Playwright MCP server for browser automation
var mcpConfig = new McpServerConfig() Map<String, Object> mcpConfig = Map.of(
.setType("local") "type", "local",
.setCommand("npx") "command", "npx",
.setArgs(List.of("@playwright/mcp@latest")) "args", List.of("@playwright/mcp@latest"),
.setTools(List.of("*")); "tools", List.of("*")
);
var session = client.createSession( var session = client.createSession(
new SessionConfig() 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()); System.out.println("S3: " + s3.sendAndWait(new MessageOptions().setPrompt("Explain pattern matching")).get().getData().content());
// Clean up // Clean up
s1.destroy().get(); s2.destroy().get(); s3.destroy().get(); s1.close(); s2.close(); s3.close();
client.stop().get();
} }
} }
} }