Conversation
…ack, and E2E test coverage Source changes from c063458 (Expand SDK E2E runtime coverage): - Add waitFor() after destroyForcibly() in process cleanup - Expand connect method fallback to match 'Unhandled method connect' message - Extract formatCliExitedMessage helper for consistent error formatting - Wait for stderr reader before throwing in port announcement New E2E tests ported: - EventFidelityTest: assistant.usage and session.usage_info event tests - ToolResultsTest: rejected and denied resultType handling - StreamingFidelityTest: streaming disabled on resume, reasoning effort - ToolsTest: parallel tools, availableTools/excludedTools combined - PermissionsTest: noResult kind, setApproveAll, slow handler Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
…om.xml CLI version, and update scripts/codegen @github/copilot version Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Sync Reference Implementation with new commits from Copilot SDK
Merge reference implementation SDK changes (2026-05-05)
May 5, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Ports updates from the upstream reference implementation to improve Copilot CLI process lifecycle robustness, broaden legacy server compatibility during connection setup, standardize CLI stderr error formatting, and expand E2E runtime coverage.
Changes:
- Improve CLI process shutdown and stderr-context error reporting (including waiting for stderr reader before throwing on missing port announcement).
- Expand
connectfallback detection for legacy servers. - Add/extend E2E tests covering event fidelity, tool result types, streaming resume behavior, permission edge-cases, and tool availability/exclusion behavior.
Show a summary per file
| File | Description |
|---|---|
src/main/java/com/github/copilot/sdk/CopilotClient.java |
Standardizes stderr-inclusive error formatting, expands legacy connect fallback detection, and changes process teardown to wait for termination. |
src/main/java/com/github/copilot/sdk/CliServerManager.java |
Tracks stderr reader thread and waits briefly for it to finish before reading stderr on early process exit; reuses shared error formatting. |
src/test/java/com/github/copilot/sdk/ToolsTest.java |
Adds E2E coverage for multi-tool usage in a single turn and combined availableTools + excludedTools behavior. |
src/test/java/com/github/copilot/sdk/ToolResultsTest.java |
Adds E2E tests validating tool executions reported as failed for rejected/denied tool result types. |
src/test/java/com/github/copilot/sdk/StreamingFidelityTest.java |
Extends streaming tests to cover resume-with-streaming-disabled and streaming with reasoningEffort. |
src/test/java/com/github/copilot/sdk/PermissionsTest.java |
Extends permission tests to cover NO_RESULT handling, approve-all short-circuiting, and slow permission handlers. |
src/test/java/com/github/copilot/sdk/EventFidelityTest.java |
Adds E2E tests asserting presence of key usage-related events after model calls. |
.lastmerge |
Updates the recorded upstream reference-implementation merge base. |
Copilot's findings
- Files reviewed: 8/8 changed files
- Comments generated: 5
| if (connection.process.isAlive()) { | ||
| connection.process.destroyForcibly(); | ||
| connection.process.destroyForcibly().waitFor(); | ||
| } |
Contributor
Author
Comment on lines
229
to
235
| String line = reader.readLine(); | ||
| if (line == null) { | ||
| awaitStderrReader(); | ||
| String stderr = getStderrOutput(); | ||
| if (!stderr.isEmpty()) { | ||
| throw new IOException("CLI process exited unexpectedly. stderr: " + stderr); | ||
| } | ||
| throw new IOException("CLI process exited unexpectedly"); | ||
| throw new IOException( | ||
| CopilotClient.formatCliExitedMessage("CLI process exited unexpectedly.", stderr)); | ||
| } |
Contributor
Author
There was a problem hiding this comment.
Addressed in ee55571: moved CLI exit message formatting into CliServerManager and updated CopilotClient to call it, removing the reverse dependency.
Comment on lines
+364
to
+410
| /** | ||
| * Verifies that the model can call multiple custom tools in parallel within a | ||
| * single turn. | ||
| * | ||
| * @see Snapshot: | ||
| * tools/should_execute_multiple_custom_tools_in_parallel_single_turn | ||
| */ | ||
| @Test | ||
| void testShouldExecuteMultipleCustomToolsInParallelSingleTurn() throws Exception { | ||
| ctx.configureForTest("tools", "should_execute_multiple_custom_tools_in_parallel_single_turn"); | ||
|
|
||
| var toolACalled = new CompletableFuture<String>(); | ||
| var toolBCalled = new CompletableFuture<String>(); | ||
|
|
||
| Map<String, Object> cityParams = Map.of("type", "object", "properties", | ||
| Map.of("city", Map.of("type", "string", "description", "City name")), "required", List.of("city")); | ||
| Map<String, Object> countryParams = Map.of("type", "object", "properties", | ||
| Map.of("country", Map.of("type", "string", "description", "Country name")), "required", | ||
| List.of("country")); | ||
|
|
||
| ToolDefinition lookupCity = ToolDefinition.create("lookup_city", "Looks up city information", cityParams, | ||
| (invocation) -> { | ||
| String city = (String) invocation.getArguments().get("city"); | ||
| toolACalled.complete(city); | ||
| return CompletableFuture.completedFuture("CITY_" + city.toUpperCase()); | ||
| }); | ||
|
|
||
| ToolDefinition lookupCountry = ToolDefinition.create("lookup_country", "Looks up country information", | ||
| countryParams, (invocation) -> { | ||
| String country = (String) invocation.getArguments().get("country"); | ||
| toolBCalled.complete(country); | ||
| return CompletableFuture.completedFuture("COUNTRY_" + country.toUpperCase()); | ||
| }); | ||
|
|
||
| try (CopilotClient client = ctx.createClient()) { | ||
| CopilotSession session = client.createSession(new SessionConfig() | ||
| .setTools(List.of(lookupCity, lookupCountry)).setOnPermissionRequest(PermissionHandler.APPROVE_ALL)) | ||
| .get(); | ||
|
|
||
| AssistantMessageEvent response = session.sendAndWait(new MessageOptions().setPrompt( | ||
| "Use lookup_city with 'Paris' and lookup_country with 'France' at the same time, then combine both results in your reply.")) | ||
| .get(60, TimeUnit.SECONDS); | ||
|
|
||
| // Both tools should have been called | ||
| assertEquals("Paris", toolACalled.get(10, TimeUnit.SECONDS)); | ||
| assertEquals("France", toolBCalled.get(10, TimeUnit.SECONDS)); | ||
|
|
Contributor
Author
There was a problem hiding this comment.
Addressed in ee55571: the test now uses latches/overlap tracking to require both handlers to start and overlap before release, so it validates parallel execution behavior.
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/38b90523-b5be-4dbd-9d33-36361110399b Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/38b90523-b5be-4dbd-9d33-36361110399b Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Copilot
AI
changed the title
Merge reference implementation SDK changes (2026-05-05)
Merge reference implementation SDK changes (2026-05-05) and address review feedback
May 5, 2026
edburns
approved these changes
May 5, 2026
This was referenced May 5, 2026
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before the change?
CopilotClientandCliServerManagersend()behavior while usingsendAndWait(...)After the change?
waitFor(timeout, unit), logs timeout cases, and preserves thread interrupt status when interruptedisUnsupportedConnectMethod()matches both error code-32601and"Unhandled method connect"messageCliServerManagerand used byCopilotClient, removing the reverse class dependencyawaitStderrReader()joins the reader thread before reading the buffer in port announcement, ensuring complete error contextsendAndWait(...)future usagePorts source changes from
c063458(Expand SDK E2E runtime coverage), with follow-up fixes from review feedback.Pull request checklist
mvn spotless:applyhas been run to format the codemvn clean verifypasses locallyDoes this introduce a breaking change?