Skip to content

Commit bab45d3

Browse files
Copilotedburns
andauthored
Fix 3 CI test failures: PerSessionAuth proxy init, McpAndAgents prompt/tool mismatch, session destroy before resume
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/1cce7322-6672-4e54-be77-b026e33610d7 Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
1 parent 997ec57 commit bab45d3

3 files changed

Lines changed: 58 additions & 4 deletions

File tree

src/test/java/com/github/copilot/sdk/E2ETestContext.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,33 @@ public void setCopilotUserByToken(String token, String login, String copilotPlan
327327
proxy.setCopilotUserByToken(token, login, copilotPlan, apiUrl, telemetryUrl, analyticsTrackingId);
328328
}
329329

330+
/**
331+
* Initializes the proxy state without loading a snapshot.
332+
* <p>
333+
* Use this for tests that need the proxy to be active (e.g., for per-session
334+
* auth token resolution via {@code /copilot_internal/user}) but do not make AI
335+
* completion requests and therefore have no snapshot to load.
336+
* </p>
337+
* <p>
338+
* The proxy requires its internal {@code state} to be initialized before it can
339+
* handle most endpoints. Without this call the proxy throws an error and
340+
* returns HTTP 500 for any request that arrives before a {@code /config} POST
341+
* has been made.
342+
* </p>
343+
*
344+
* @throws IOException
345+
* if the proxy configuration request fails
346+
* @throws InterruptedException
347+
* if the request is interrupted
348+
*/
349+
public void initializeProxy() throws IOException, InterruptedException {
350+
ensureProxyAlive();
351+
// Pass a non-existent snapshot path. The proxy initializes its state even when
352+
// the file is absent (storedData simply remains undefined), which is fine for
353+
// tests that never make AI chat-completion requests.
354+
proxy.configure(workDir.resolve("no-snapshot.yaml").toString(), workDir.toString());
355+
}
356+
330357
@Override
331358
public void close() throws Exception {
332359
proxy.stop();

src/test/java/com/github/copilot/sdk/McpAndAgentsTest.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import java.util.HashMap;
1010
import java.util.List;
11+
import java.util.Map;
12+
import java.util.concurrent.CompletableFuture;
1113
import java.util.concurrent.TimeUnit;
1214

1315
import org.junit.jupiter.api.AfterAll;
@@ -23,6 +25,7 @@
2325
import com.github.copilot.sdk.json.PermissionHandler;
2426
import com.github.copilot.sdk.json.ResumeSessionConfig;
2527
import com.github.copilot.sdk.json.SessionConfig;
28+
import com.github.copilot.sdk.json.ToolDefinition;
2629

2730
/**
2831
* Tests for MCP Servers and Custom Agents functionality.
@@ -349,17 +352,33 @@ void testShouldHideExcludedToolsFromDefaultAgent() throws Exception {
349352
ctx.configureForTest("mcp_and_agents", "should_hide_excluded_tools_from_default_agent");
350353

351354
try (CopilotClient client = ctx.createClient()) {
355+
// Register a secret_tool and exclude it from the default agent — the LLM
356+
// should report it has no access to the tool.
357+
Map<String, Object> parameters = new HashMap<>();
358+
parameters.put("type", "object");
359+
parameters.put("properties", Map.of("input", Map.of("type", "string")));
360+
parameters.put("required", List.of("input"));
361+
362+
ToolDefinition secretTool = ToolDefinition.create("secret_tool",
363+
"A secret tool hidden from the default agent", parameters,
364+
invocation -> CompletableFuture.completedFuture("SECRET"));
365+
352366
SessionConfig config = new SessionConfig().setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
353-
.setDefaultAgent(new DefaultAgentConfig().setExcludedTools(List.of("view")));
367+
.setTools(List.of(secretTool))
368+
.setDefaultAgent(new DefaultAgentConfig().setExcludedTools(List.of("secret_tool")));
354369

355370
CopilotSession session = client.createSession(config).get();
356371

357372
assertNotNull(session.getSessionId());
358373

359-
AssistantMessageEvent response = session.sendAndWait(new MessageOptions().setPrompt("What is 2+2?")).get(60,
360-
TimeUnit.SECONDS);
374+
AssistantMessageEvent response = session
375+
.sendAndWait(new MessageOptions()
376+
.setPrompt("Do you have access to a tool called secret_tool? Answer yes or no."))
377+
.get(60, TimeUnit.SECONDS);
361378

362379
assertNotNull(response);
380+
assertTrue(response.getData().content().toLowerCase().contains("no"),
381+
"Response should indicate that secret_tool is not accessible: " + response.getData().content());
363382
session.close();
364383
}
365384
}
@@ -380,7 +399,11 @@ void testShouldAcceptDefaultAgentConfigurationOnSessionResume() throws Exception
380399

381400
assertNotNull(session.getSessionId());
382401
String sessionId = session.getSessionId();
383-
session.close();
402+
// Do not call session.close() here — that invokes session.destroy on the
403+
// server,
404+
// which removes the session and causes the subsequent resumeSession to fail
405+
// with "Session not found". The session handle is simply abandoned and the
406+
// server-side session remains alive for the resume call below.
384407

385408
CopilotSession resumedSession = client.resumeSession(sessionId,
386409
new ResumeSessionConfig().setOnPermissionRequest(PermissionHandler.APPROVE_ALL)

src/test/java/com/github/copilot/sdk/PerSessionAuthTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ private CopilotClient createAuthTestClient() {
5454
}
5555

5656
private void setupCopilotUsers() throws Exception {
57+
// Initialize proxy state before registering tokens — the proxy requires its
58+
// internal state to be initialized (via /config) before it can handle the
59+
// /copilot_internal/user endpoint used for per-session auth resolution.
60+
ctx.initializeProxy();
5761
ctx.setCopilotUserByToken("token-alice", "alice", "individual_pro", ctx.getProxyUrl(),
5862
"https://localhost:1/telemetry", "alice-tracking-id");
5963
ctx.setCopilotUserByToken("token-bob", "bob", "business", ctx.getProxyUrl(), "https://localhost:1/telemetry",

0 commit comments

Comments
 (0)