Skip to content
Open
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
19 changes: 14 additions & 5 deletions cookbook/copilot-sdk/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# GitHub Copilot SDK Cookbook

This cookbook collects small, focused recipes showing how to accomplish common tasks with the GitHub Copilot SDK across languages. Each recipe is intentionally short and practical, with copy‑pasteable snippets and pointers to fuller examples and tests.
This cookbook collects small, focused recipes showing how to accomplish common tasks with the [GitHub Copilot SDK](https://github.com/github/copilot-sdk) across languages. Each recipe is intentionally short and practical, with copy‑pasteable snippets and pointers to fuller examples and tests.

## Recipes by Language

Expand Down Expand Up @@ -54,17 +54,26 @@ This cookbook collects small, focused recipes showing how to accomplish common t
- [PR Visualization](java/pr-visualization.md): Generate interactive PR age charts using GitHub MCP Server.
- [Persisting Sessions](java/persisting-sessions.md): Save and resume sessions across restarts.
- [Accessibility Report](java/accessibility-report.md): Generate WCAG accessibility reports using the Playwright MCP server.
- [In-Process Runtime](java/in-process-runtime.md): Load the native Copilot runtime library into the JVM process instead of spawning a separate runtime process.

## How to Use

- Browse your language section above and open the recipe links
- Each recipe includes runnable examples in a `recipe/` subfolder with language-specific tooling
- See existing examples and tests for working references:
- Node.js examples: `nodejs/examples/basic-example.ts`
- E2E tests: `go/e2e`, `python/e2e`, `nodejs/test/e2e`, `dotnet/test/Harness`
- See existing examples and tests at the official SDK repository's `java/v1.0.21` tag for version-specific references:
- [Node.js example](https://github.com/github/copilot-sdk/blob/java/v1.0.21/nodejs/examples/basic-example.ts)
- E2E tests: [Go](https://github.com/github/copilot-sdk/tree/java/v1.0.21/go/internal/e2e), [Python](https://github.com/github/copilot-sdk/tree/java/v1.0.21/python/e2e), [Node.js](https://github.com/github/copilot-sdk/tree/java/v1.0.21/nodejs/test/e2e), [.NET](https://github.com/github/copilot-sdk/tree/java/v1.0.21/dotnet/test/Harness), [Java](https://github.com/github/copilot-sdk/tree/java/v1.0.21/java/sdk/src/test/java/com/github/copilot/e2e)

## Running Examples

Before running examples, follow the prerequisites in your language's recipe README:

- [.NET](dotnet/recipe/README.md#prerequisites)
- [Node.js](nodejs/recipe/README.md#prerequisites)
- [Python](python/recipe/README.md#prerequisites)
- [Go](go/recipe/README.md#prerequisites)
- [Java](java/recipe/README.md#prerequisites)

### .NET

```bash
Expand Down Expand Up @@ -109,4 +118,4 @@ jbang <FileName>.java

## Status

Cookbook structure is complete with 7 recipes across all 5 supported languages. Each recipe includes both markdown documentation and runnable examples.
The cookbook covers 5 languages, with 8 recipes for .NET and Java and 7 shared recipes for Node.js, Python, and Go. Each recipe includes both markdown documentation and runnable examples.
8 changes: 7 additions & 1 deletion cookbook/copilot-sdk/java/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# GitHub Copilot SDK Cookbook — Java

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. All examples can be run directly with [JBang](https://www.jbang.dev/).
This folder hosts short, practical recipes for using the [GitHub Copilot SDK for Java](https://github.com/github/copilot-sdk/tree/main/java). Each recipe is concise, copy‑pasteable, and points to fuller examples and tests. All examples can be run directly with [JBang](https://www.jbang.dev/).

Examples target the official SDK 1.0.21 and Java 17 or later. SDK 1.x uses
`com.github.copilot` for clients, `com.github.copilot.generated` for events, and
`com.github.copilot.rpc` for configuration instead of the archived SDK's
`com.github.copilot.sdk` packages.

## Recipes

Expand All @@ -11,6 +16,7 @@ This folder hosts short, practical recipes for using the GitHub Copilot SDK with
- [PR Visualization](pr-visualization.md): Generate interactive PR age charts using GitHub MCP Server.
- [Persisting Sessions](persisting-sessions.md): Save and resume sessions across restarts.
- [Accessibility Report](accessibility-report.md): Generate WCAG accessibility reports using the Playwright MCP server.
- [In-Process Runtime](in-process-runtime.md): Load the native Copilot runtime library into the JVM process instead of spawning a separate runtime process.

## Contributing

Expand Down
32 changes: 16 additions & 16 deletions cookbook/copilot-sdk/java/accessibility-report.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Generating Accessibility Reports

> **Demo permissions:** These examples use `PermissionHandler.APPROVE_ALL` only
> for isolated, trusted demonstrations. Replace it with a restrictive permission
> handler before using untrusted prompts or workspaces.

Build a CLI tool that analyzes web page accessibility using the Playwright MCP server and generates detailed WCAG-compliant reports with optional test generation.

> **Runnable example:** [recipe/AccessibilityReport.java](recipe/AccessibilityReport.java)
Expand Down Expand Up @@ -35,11 +39,11 @@ jbang recipe/AccessibilityReport.java

```java
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS com.github:copilot-sdk-java:0.2.1-java.1
//DEPS com.github:copilot-sdk-java:1.0.21

import com.github.copilot.sdk.*;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;
import com.github.copilot.*;
import com.github.copilot.generated.*;
import com.github.copilot.rpc.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.*;
Expand Down Expand Up @@ -67,12 +71,10 @@ public class AccessibilityReport {
client.start().get();

// Configure Playwright MCP server for browser automation
Map<String, Object> mcpConfig = Map.of(
"type", "local",
"command", "npx",
"args", List.of("@playwright/mcp@latest"),
"tools", List.of("*")
);
var mcpConfig = new McpStdioServerConfig()
.setCommand("npx")
.setArgs(List.of("@playwright/mcp@latest"))
.setTools(List.of("*"));

var session = client.createSession(
new SessionConfig()
Expand Down Expand Up @@ -168,12 +170,10 @@ public class AccessibilityReport {
The recipe configures a local MCP server that runs alongside the session:

```java
Map<String, Object> mcpConfig = Map.of(
"type", "local",
"command", "npx",
"args", List.of("@playwright/mcp@latest"),
"tools", List.of("*")
);
var mcpConfig = new McpStdioServerConfig()
.setCommand("npx")
.setArgs(List.of("@playwright/mcp@latest"))
.setTools(List.of("*"));

var session = client.createSession(
new SessionConfig()
Expand Down
67 changes: 63 additions & 4 deletions cookbook/copilot-sdk/java/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Handle errors gracefully in your Copilot SDK applications.

> **Demo permissions:** These examples use `PermissionHandler.APPROVE_ALL` only
> for isolated, trusted demonstrations. Replace it with a restrictive permission
> handler before using untrusted prompts or workspaces.

> **Runnable example:** [recipe/ErrorHandling.java](recipe/ErrorHandling.java)
>
> ```bash
Expand All @@ -17,10 +21,10 @@ You need to handle various error conditions like connection failures, timeouts,
Java's `try-with-resources` ensures the client is always cleaned up, even when exceptions occur.

```java
//DEPS com.github:copilot-sdk-java:0.2.1-java.1
//DEPS com.github:copilot-sdk-java:1.0.21

import com.github.copilot.sdk.*;
import com.github.copilot.sdk.json.*;
import com.github.copilot.*;
import com.github.copilot.rpc.*;

public class BasicErrorHandling {
public static void main(String[] args) {
Expand Down Expand Up @@ -128,6 +132,13 @@ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
}));
```

`client.stop()` returns a `CompletableFuture`; observe it to catch failures
surfaced by the SDK rather than relying only on `close()`, which suppresses
cleanup failures. In-process FFI cleanup can also log failures or continue
asynchronously, so a completed stop is not proof that every native teardown
phase succeeded. If a graceful stop exceeds your application's shutdown deadline,
use `client.forceStop()` to retire the connection and sessions locally.

## Try-with-resources (nested)

When working with multiple sessions, nest `try-with-resources` blocks to guarantee each resource is closed.
Expand All @@ -148,12 +159,60 @@ try (var client = new CopilotClient()) {
} // client is closed here
```

## Tagging message provenance

Use `MessageOptions.setSource(...)` to distinguish user-attributed messages from
application context or another agent's messages when diagnosing unexpected turns:

```java
import com.github.copilot.rpc.MessageSource;

session.sendAndWait(new MessageOptions()
.setPrompt("What changed in the last release?")
.setSource(MessageSource.USER)).get();

session.sendAndWait(new MessageOptions()
.setPrompt("Re-run the failed step and report the result.")
.setSource(MessageSource.SYSTEM)).get();

session.sendAndWait(new MessageOptions()
.setPrompt("Summarize the open incidents.")
.setSource(MessageSource.agent("incident-bot"))).get();
```

Omitting `source` delegates to the selected runtime; the runtime packaged with
SDK 1.0.21 treats it as user provenance, equivalent to `MessageSource.USER`.
That attribution does not prove a person physically entered the message.
`MessageSource.agent(id)` serializes as `"agent-<id>"`; pass the identifier
without adding that prefix. The factory rejects only `null`; it does not
normalize prefixes or validate blank, format, or length constraints. Validate
identifiers crossing a trust boundary. Source values and agent IDs can appear
in events, history, queue snapshots, and diagnostics, so do not put secrets in them.

Source is caller-supplied provenance with behavioral effects, not authenticated
identity. The runtime can use it for queueing and steering, visibility and
filtering, inter-agent routing, conversation/context reconstruction, and
classification of human authorization evidence. It cannot itself grant, deny,
or respond to a permission request, but source classification can indirectly
affect auto-approval. Never authorize an action from the source value alone.

`MessageSource.SYSTEM` is not a model system-role message: it does not change the
model-visible role, modify the session's system prompt, or elevate instruction
priority. The separate delivery `mode` controls queued admission (`enqueue`, the
default) versus attempting to steer an active turn (`immediate`); it is independent
of source even though source can affect runtime handling.

`send(...)` and `sendAndWait(...)` preserve the same source values. Non-user
attribution is persisted in durable `user.message` events and restored on replay.
User provenance is stored as an absent source, so explicit `USER` and an omitted
source are indistinguishable after persistence.

## Handling tool errors

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.ToolDefinition;
import com.github.copilot.rpc.ToolDefinition;
import java.util.concurrent.CompletableFuture;

var readFileTool = ToolDefinition.create(
Expand Down
Loading
Loading