Skip to content

Commit 1bbb3cf

Browse files
edburnsCopilot
andcommitted
Add Java scenarios: Phase 2 (size M, #17-#26)
Add 10 Java scenario implementations covering: - callbacks: hooks (pre/post tool use, session start/end), permissions - prompts: attachments - sessions: concurrent-sessions, session-resume - tools: custom-agents, tool-overrides, mcp-servers, skills - auth: gh-app (OAuth device flow) All scenarios compile successfully with mvn compile. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 9737efb commit 1bbb3cf

20 files changed

Lines changed: 786 additions & 0 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<groupId>com.github.copilot.sdk.scenarios</groupId>
9+
<artifactId>scenario-auth-gh-app</artifactId>
10+
<version>1.0.0</version>
11+
<packaging>jar</packaging>
12+
13+
<properties>
14+
<maven.compiler.release>17</maven.compiler.release>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>com.github</groupId>
21+
<artifactId>copilot-sdk-java</artifactId>
22+
<version>1.0.0-beta-java.5-SNAPSHOT</version>
23+
</dependency>
24+
</dependencies>
25+
</project>
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import com.github.copilot.sdk.CopilotClient;
2+
import com.github.copilot.sdk.json.CopilotClientOptions;
3+
import com.github.copilot.sdk.json.MessageOptions;
4+
import com.github.copilot.sdk.json.SessionConfig;
5+
6+
import java.net.URI;
7+
import java.net.http.HttpClient;
8+
import java.net.http.HttpRequest;
9+
import java.net.http.HttpResponse;
10+
11+
import com.fasterxml.jackson.databind.JsonNode;
12+
import com.fasterxml.jackson.databind.ObjectMapper;
13+
14+
public class Main {
15+
public static void main(String[] args) throws Exception {
16+
var clientId = System.getenv("GITHUB_OAUTH_CLIENT_ID");
17+
if (clientId == null || clientId.isEmpty()) {
18+
System.err.println("Missing GITHUB_OAUTH_CLIENT_ID");
19+
System.exit(1);
20+
}
21+
22+
var mapper = new ObjectMapper();
23+
var httpClient = HttpClient.newHttpClient();
24+
25+
// Step 1: Request device code
26+
var deviceCodeReq = HttpRequest.newBuilder()
27+
.uri(URI.create("https://github.com/login/device/code"))
28+
.header("Accept", "application/json")
29+
.header("User-Agent", "copilot-sdk-java")
30+
.POST(HttpRequest.BodyPublishers.ofString("client_id=" + clientId))
31+
.header("Content-Type", "application/x-www-form-urlencoded")
32+
.build();
33+
var deviceCodeResp = httpClient.send(deviceCodeReq, HttpResponse.BodyHandlers.ofString());
34+
var deviceCode = mapper.readTree(deviceCodeResp.body());
35+
36+
var userCode = deviceCode.get("user_code").asText();
37+
var verificationUri = deviceCode.get("verification_uri").asText();
38+
var code = deviceCode.get("device_code").asText();
39+
var interval = deviceCode.get("interval").asInt();
40+
41+
System.out.println("Please visit: " + verificationUri);
42+
System.out.println("Enter code: " + userCode);
43+
44+
// Step 2: Poll for access token
45+
String accessToken = null;
46+
while (accessToken == null) {
47+
Thread.sleep(interval * 1000L);
48+
var tokenReq = HttpRequest.newBuilder()
49+
.uri(URI.create("https://github.com/login/oauth/access_token"))
50+
.header("Accept", "application/json")
51+
.header("Content-Type", "application/x-www-form-urlencoded")
52+
.POST(HttpRequest.BodyPublishers.ofString(
53+
"client_id=" + clientId
54+
+ "&device_code=" + code
55+
+ "&grant_type=urn:ietf:params:oauth:grant-type:device_code"))
56+
.build();
57+
var tokenResp = httpClient.send(tokenReq, HttpResponse.BodyHandlers.ofString());
58+
var tokenData = mapper.readTree(tokenResp.body());
59+
60+
if (tokenData.has("access_token")) {
61+
accessToken = tokenData.get("access_token").asText();
62+
} else if (tokenData.has("error")) {
63+
var err = tokenData.get("error").asText();
64+
if ("authorization_pending".equals(err)) continue;
65+
if ("slow_down".equals(err)) { interval += 5; continue; }
66+
throw new RuntimeException("OAuth error: " + err);
67+
}
68+
}
69+
70+
// Step 3: Verify authentication
71+
var userReq = HttpRequest.newBuilder()
72+
.uri(URI.create("https://api.github.com/user"))
73+
.header("Authorization", "Bearer " + accessToken)
74+
.header("User-Agent", "copilot-sdk-java")
75+
.GET()
76+
.build();
77+
var userResp = httpClient.send(userReq, HttpResponse.BodyHandlers.ofString());
78+
var userData = mapper.readTree(userResp.body());
79+
System.out.println("Authenticated as: " + userData.get("login").asText());
80+
81+
// Step 4: Use the token with Copilot
82+
try (var client = new CopilotClient(new CopilotClientOptions()
83+
.setGitHubToken(accessToken))) {
84+
client.start().get();
85+
var session = client.createSession(
86+
new SessionConfig()
87+
.setModel("claude-haiku-4.5"))
88+
.get();
89+
var response = session.sendAndWait(
90+
new MessageOptions().setPrompt("What is the capital of France?"))
91+
.get();
92+
if (response != null) {
93+
System.out.println(response.getData().content());
94+
}
95+
client.stop().get();
96+
}
97+
}
98+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<groupId>com.github.copilot.sdk.scenarios</groupId>
9+
<artifactId>scenario-callbacks-hooks</artifactId>
10+
<version>1.0.0</version>
11+
<packaging>jar</packaging>
12+
13+
<properties>
14+
<maven.compiler.release>17</maven.compiler.release>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>com.github</groupId>
21+
<artifactId>copilot-sdk-java</artifactId>
22+
<version>1.0.0-beta-java.5-SNAPSHOT</version>
23+
</dependency>
24+
</dependencies>
25+
</project>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import com.github.copilot.sdk.CopilotClient;
2+
import com.github.copilot.sdk.json.HookInvocation;
3+
import com.github.copilot.sdk.json.MessageOptions;
4+
import com.github.copilot.sdk.json.PermissionHandler;
5+
import com.github.copilot.sdk.json.PostToolUseHookOutput;
6+
import com.github.copilot.sdk.json.PreToolUseHookOutput;
7+
import com.github.copilot.sdk.json.SessionConfig;
8+
import com.github.copilot.sdk.json.SessionEndHookOutput;
9+
import com.github.copilot.sdk.json.SessionHooks;
10+
import com.github.copilot.sdk.json.SessionStartHookOutput;
11+
import com.github.copilot.sdk.json.UserPromptSubmittedHookOutput;
12+
13+
import java.util.ArrayList;
14+
import java.util.concurrent.CompletableFuture;
15+
16+
public class Main {
17+
public static void main(String[] args) throws Exception {
18+
var hookLog = new ArrayList<String>();
19+
20+
try (var client = new CopilotClient()) {
21+
client.start().get();
22+
var session = client.createSession(
23+
new SessionConfig()
24+
.setModel("claude-haiku-4.5")
25+
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
26+
.setHooks(new SessionHooks()
27+
.setOnSessionStart((input, invocation) -> {
28+
hookLog.add("onSessionStart");
29+
return CompletableFuture.completedFuture(null);
30+
})
31+
.setOnSessionEnd((input, invocation) -> {
32+
hookLog.add("onSessionEnd");
33+
return CompletableFuture.completedFuture(null);
34+
})
35+
.setOnPreToolUse((input, invocation) -> {
36+
hookLog.add("onPreToolUse:" + input.getToolName());
37+
return CompletableFuture.completedFuture(PreToolUseHookOutput.allow());
38+
})
39+
.setOnPostToolUse((input, invocation) -> {
40+
hookLog.add("onPostToolUse:" + input.getToolName());
41+
return CompletableFuture.completedFuture(null);
42+
})
43+
.setOnUserPromptSubmitted((input, invocation) -> {
44+
hookLog.add("onUserPromptSubmitted");
45+
return CompletableFuture.completedFuture(null);
46+
})))
47+
.get();
48+
var response = session.sendAndWait(
49+
new MessageOptions().setPrompt(
50+
"List the files in the current directory using the glob tool with pattern '*.md'."))
51+
.get();
52+
if (response != null) {
53+
System.out.println(response.getData().content());
54+
}
55+
System.out.println("\n--- Hook execution log ---");
56+
for (var entry : hookLog) {
57+
System.out.println(" " + entry);
58+
}
59+
System.out.println("\nTotal hooks fired: " + hookLog.size());
60+
client.stop().get();
61+
}
62+
}
63+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<groupId>com.github.copilot.sdk.scenarios</groupId>
9+
<artifactId>scenario-callbacks-permissions</artifactId>
10+
<version>1.0.0</version>
11+
<packaging>jar</packaging>
12+
13+
<properties>
14+
<maven.compiler.release>17</maven.compiler.release>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>com.github</groupId>
21+
<artifactId>copilot-sdk-java</artifactId>
22+
<version>1.0.0-beta-java.5-SNAPSHOT</version>
23+
</dependency>
24+
</dependencies>
25+
</project>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import com.github.copilot.sdk.CopilotClient;
2+
import com.github.copilot.sdk.json.MessageOptions;
3+
import com.github.copilot.sdk.json.PermissionHandler;
4+
import com.github.copilot.sdk.json.PermissionRequest;
5+
import com.github.copilot.sdk.json.PermissionRequestResult;
6+
import com.github.copilot.sdk.json.PermissionRequestResultKind;
7+
import com.github.copilot.sdk.json.PreToolUseHookOutput;
8+
import com.github.copilot.sdk.json.SessionConfig;
9+
import com.github.copilot.sdk.json.SessionHooks;
10+
11+
import java.util.ArrayList;
12+
import java.util.concurrent.CompletableFuture;
13+
14+
public class Main {
15+
public static void main(String[] args) throws Exception {
16+
var permissionLog = new ArrayList<String>();
17+
18+
try (var client = new CopilotClient()) {
19+
client.start().get();
20+
var session = client.createSession(
21+
new SessionConfig()
22+
.setModel("claude-haiku-4.5")
23+
.setOnPermissionRequest((request, invocation) -> {
24+
permissionLog.add("approved:" + request.getKind());
25+
return CompletableFuture.completedFuture(
26+
new PermissionRequestResult()
27+
.setKind(PermissionRequestResultKind.APPROVED));
28+
})
29+
.setHooks(new SessionHooks()
30+
.setOnPreToolUse((input, invocation) ->
31+
CompletableFuture.completedFuture(PreToolUseHookOutput.allow()))))
32+
.get();
33+
var response = session.sendAndWait(
34+
new MessageOptions().setPrompt(
35+
"List the files in the current directory using glob with pattern '*.md'."))
36+
.get();
37+
if (response != null) {
38+
System.out.println(response.getData().content());
39+
}
40+
System.out.println("\n--- Permission request log ---");
41+
for (var entry : permissionLog) {
42+
System.out.println(" " + entry);
43+
}
44+
System.out.println("\nTotal permission requests: " + permissionLog.size());
45+
client.stop().get();
46+
}
47+
}
48+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<groupId>com.github.copilot.sdk.scenarios</groupId>
9+
<artifactId>scenario-prompts-attachments</artifactId>
10+
<version>1.0.0</version>
11+
<packaging>jar</packaging>
12+
13+
<properties>
14+
<maven.compiler.release>17</maven.compiler.release>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>com.github</groupId>
21+
<artifactId>copilot-sdk-java</artifactId>
22+
<version>1.0.0-beta-java.5-SNAPSHOT</version>
23+
</dependency>
24+
</dependencies>
25+
</project>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import com.github.copilot.sdk.CopilotClient;
2+
import com.github.copilot.sdk.json.Attachment;
3+
import com.github.copilot.sdk.json.MessageOptions;
4+
import com.github.copilot.sdk.json.SessionConfig;
5+
import com.github.copilot.sdk.json.SystemMessageConfig;
6+
import com.github.copilot.sdk.SystemMessageMode;
7+
8+
import java.nio.file.Path;
9+
import java.util.List;
10+
11+
public class Main {
12+
public static void main(String[] args) throws Exception {
13+
try (var client = new CopilotClient()) {
14+
client.start().get();
15+
var session = client.createSession(
16+
new SessionConfig()
17+
.setModel("claude-haiku-4.5")
18+
.setSystemMessage(new SystemMessageConfig()
19+
.setMode(SystemMessageMode.REPLACE)
20+
.setContent("You are a helpful assistant. Answer questions about attached files concisely."))
21+
.setAvailableTools(List.of()))
22+
.get();
23+
24+
var sampleFile = Path.of(System.getProperty("user.dir"), "..", "sample-data.txt")
25+
.toAbsolutePath().normalize().toString();
26+
27+
var response = session.sendAndWait(
28+
new MessageOptions()
29+
.setPrompt("What languages are listed in the attached file?")
30+
.setAttachments(List.of(
31+
new Attachment("file", sampleFile, "sample-data.txt"))))
32+
.get();
33+
if (response != null) {
34+
System.out.println(response.getData().content());
35+
}
36+
client.stop().get();
37+
}
38+
}
39+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<groupId>com.github.copilot.sdk.scenarios</groupId>
9+
<artifactId>scenario-sessions-concurrent-sessions</artifactId>
10+
<version>1.0.0</version>
11+
<packaging>jar</packaging>
12+
13+
<properties>
14+
<maven.compiler.release>17</maven.compiler.release>
15+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
16+
</properties>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>com.github</groupId>
21+
<artifactId>copilot-sdk-java</artifactId>
22+
<version>1.0.0-beta-java.5-SNAPSHOT</version>
23+
</dependency>
24+
</dependencies>
25+
</project>

0 commit comments

Comments
 (0)