hooksHandler = new AtomicReference<>();
private volatile EventErrorHandler eventErrorHandler;
private volatile EventErrorPolicy eventErrorPolicy = EventErrorPolicy.PROPAGATE_AND_LOG_ERRORS;
@@ -1317,6 +1327,32 @@ void registerElicitationHandler(ElicitationHandler handler) {
elicitationHandler.set(handler);
}
+ /**
+ * Registers an exit-plan-mode handler for this session.
+ *
+ * Called internally when creating or resuming a session with an exit-plan-mode
+ * handler.
+ *
+ * @param handler
+ * the handler to invoke when an exit-plan-mode request is received
+ */
+ void registerExitPlanModeHandler(ExitPlanModeHandler handler) {
+ exitPlanModeHandler.set(handler);
+ }
+
+ /**
+ * Registers an auto-mode-switch handler for this session.
+ *
+ * Called internally when creating or resuming a session with an
+ * auto-mode-switch handler.
+ *
+ * @param handler
+ * the handler to invoke when an auto-mode-switch request is received
+ */
+ void registerAutoModeSwitchHandler(AutoModeSwitchHandler handler) {
+ autoModeSwitchHandler.set(handler);
+ }
+
/**
* Sets the capabilities reported by the host for this session.
*
@@ -1356,6 +1392,60 @@ CompletableFuture handleUserInputRequest(UserInputRequest req
}
}
+ /**
+ * Handles an exit-plan-mode request from the Copilot CLI.
+ *
+ * Called internally when the server sends an {@code exitPlanMode.request}.
+ *
+ * @param request
+ * the exit-plan-mode request
+ * @return a future that resolves with the user's decision
+ */
+ CompletableFuture handleExitPlanModeRequest(ExitPlanModeRequest request) {
+ ExitPlanModeHandler handler = exitPlanModeHandler.get();
+ if (handler == null) {
+ return CompletableFuture.completedFuture(new ExitPlanModeResult().setApproved(true));
+ }
+
+ try {
+ var invocation = new ExitPlanModeInvocation().setSessionId(sessionId);
+ return handler.handle(request, invocation).exceptionally(ex -> {
+ LOG.log(Level.SEVERE, "Exit plan mode handler threw an exception", ex);
+ throw new RuntimeException("Exit plan mode handler error", ex);
+ });
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Failed to process exit plan mode request", e);
+ return CompletableFuture.failedFuture(e);
+ }
+ }
+
+ /**
+ * Handles an auto-mode-switch request from the Copilot CLI.
+ *
+ * Called internally when the server sends an {@code autoModeSwitch.request}.
+ *
+ * @param request
+ * the auto-mode-switch request
+ * @return a future that resolves with the user's decision
+ */
+ CompletableFuture handleAutoModeSwitchRequest(AutoModeSwitchRequest request) {
+ AutoModeSwitchHandler handler = autoModeSwitchHandler.get();
+ if (handler == null) {
+ return CompletableFuture.completedFuture(AutoModeSwitchResponse.NO);
+ }
+
+ try {
+ var invocation = new AutoModeSwitchInvocation().setSessionId(sessionId);
+ return handler.handle(request, invocation).exceptionally(ex -> {
+ LOG.log(Level.SEVERE, "Auto mode switch handler threw an exception", ex);
+ throw new RuntimeException("Auto mode switch handler error", ex);
+ });
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Failed to process auto mode switch request", e);
+ return CompletableFuture.failedFuture(e);
+ }
+ }
+
/**
* Registers hook handlers for this session.
*
@@ -1850,6 +1940,8 @@ public void close() {
permissionHandler.set(null);
userInputHandler.set(null);
elicitationHandler.set(null);
+ exitPlanModeHandler.set(null);
+ autoModeSwitchHandler.set(null);
hooksHandler.set(null);
}
diff --git a/src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java b/src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java
index d085f7fcec..2f9657132c 100644
--- a/src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java
+++ b/src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java
@@ -17,6 +17,8 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.copilot.sdk.generated.SessionEvent;
+import com.github.copilot.sdk.json.AutoModeSwitchRequest;
+import com.github.copilot.sdk.json.ExitPlanModeRequest;
import com.github.copilot.sdk.json.PermissionRequestResult;
import com.github.copilot.sdk.json.PermissionRequestResultKind;
import com.github.copilot.sdk.json.SessionLifecycleEvent;
@@ -79,6 +81,10 @@ void registerHandlers(JsonRpcClient rpc) {
(requestId, params) -> handlePermissionRequest(rpc, requestId, params));
rpc.registerMethodHandler("userInput.request",
(requestId, params) -> handleUserInputRequest(rpc, requestId, params));
+ rpc.registerMethodHandler("exitPlanMode.request",
+ (requestId, params) -> handleExitPlanModeRequest(rpc, requestId, params));
+ rpc.registerMethodHandler("autoModeSwitch.request",
+ (requestId, params) -> handleAutoModeSwitchRequest(rpc, requestId, params));
rpc.registerMethodHandler("hooks.invoke", (requestId, params) -> handleHooksInvoke(rpc, requestId, params));
rpc.registerMethodHandler("systemMessage.transform",
(requestId, params) -> handleSystemMessageTransform(rpc, requestId, params));
@@ -283,6 +289,96 @@ private void handleUserInputRequest(JsonRpcClient rpc, String requestId, JsonNod
});
}
+ private void handleExitPlanModeRequest(JsonRpcClient rpc, String requestId, JsonNode params) {
+ runAsync(() -> {
+ try {
+ String sessionId = params.get("sessionId").asText();
+
+ CopilotSession session = sessions.get(sessionId);
+ if (session == null) {
+ rpc.sendErrorResponse(Long.parseLong(requestId), -32602, "Unknown session " + sessionId);
+ return;
+ }
+
+ var request = new ExitPlanModeRequest();
+ if (params.has("summary")) {
+ request.setSummary(params.get("summary").asText());
+ }
+ if (params.has("planContent") && !params.get("planContent").isNull()) {
+ request.setPlanContent(params.get("planContent").asText());
+ }
+ if (params.has("actions") && params.get("actions").isArray()) {
+ var actions = new ArrayList();
+ for (JsonNode action : params.get("actions")) {
+ actions.add(action.asText());
+ }
+ request.setActions(actions);
+ }
+ if (params.has("recommendedAction") && !params.get("recommendedAction").isNull()) {
+ request.setRecommendedAction(params.get("recommendedAction").asText());
+ }
+
+ session.handleExitPlanModeRequest(request).thenAccept(result -> {
+ try {
+ rpc.sendResponse(Long.parseLong(requestId), MAPPER.valueToTree(result));
+ } catch (IOException e) {
+ LOG.log(Level.SEVERE, "Error sending exit plan mode response", e);
+ }
+ }).exceptionally(ex -> {
+ try {
+ rpc.sendErrorResponse(Long.parseLong(requestId), -32603,
+ "Exit plan mode handler error: " + ex.getMessage());
+ } catch (IOException e) {
+ LOG.log(Level.SEVERE, "Error sending exit plan mode error", e);
+ }
+ return null;
+ });
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Error handling exit plan mode request", e);
+ }
+ });
+ }
+
+ private void handleAutoModeSwitchRequest(JsonRpcClient rpc, String requestId, JsonNode params) {
+ runAsync(() -> {
+ try {
+ String sessionId = params.get("sessionId").asText();
+
+ CopilotSession session = sessions.get(sessionId);
+ if (session == null) {
+ rpc.sendErrorResponse(Long.parseLong(requestId), -32602, "Unknown session " + sessionId);
+ return;
+ }
+
+ var request = new AutoModeSwitchRequest();
+ if (params.has("errorCode") && !params.get("errorCode").isNull()) {
+ request.setErrorCode(params.get("errorCode").asText());
+ }
+ if (params.has("retryAfterSeconds") && !params.get("retryAfterSeconds").isNull()) {
+ request.setRetryAfterSeconds(params.get("retryAfterSeconds").asDouble());
+ }
+
+ session.handleAutoModeSwitchRequest(request).thenAccept(response -> {
+ try {
+ rpc.sendResponse(Long.parseLong(requestId), Map.of("response", response));
+ } catch (IOException e) {
+ LOG.log(Level.SEVERE, "Error sending auto mode switch response", e);
+ }
+ }).exceptionally(ex -> {
+ try {
+ rpc.sendErrorResponse(Long.parseLong(requestId), -32603,
+ "Auto mode switch handler error: " + ex.getMessage());
+ } catch (IOException e) {
+ LOG.log(Level.SEVERE, "Error sending auto mode switch error", e);
+ }
+ return null;
+ });
+ } catch (Exception e) {
+ LOG.log(Level.SEVERE, "Error handling auto mode switch request", e);
+ }
+ });
+ }
+
private void handleHooksInvoke(JsonRpcClient rpc, String requestId, JsonNode params) {
runAsync(() -> {
try {
diff --git a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
index fd96966906..d9752db7ee 100644
--- a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
+++ b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
@@ -138,6 +138,12 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
if (config.getOnElicitationRequest() != null) {
request.setRequestElicitation(true);
}
+ if (config.getOnExitPlanMode() != null) {
+ request.setRequestExitPlanMode(true);
+ }
+ if (config.getOnAutoModeSwitch() != null) {
+ request.setRequestAutoModeSwitch(true);
+ }
request.setGitHubToken(config.getGitHubToken());
return request;
@@ -216,6 +222,12 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo
if (config.getOnElicitationRequest() != null) {
request.setRequestElicitation(true);
}
+ if (config.getOnExitPlanMode() != null) {
+ request.setRequestExitPlanMode(true);
+ }
+ if (config.getOnAutoModeSwitch() != null) {
+ request.setRequestAutoModeSwitch(true);
+ }
request.setGitHubToken(config.getGitHubToken());
return request;
@@ -252,6 +264,12 @@ static void configureSession(CopilotSession session, SessionConfig config) {
if (config.getOnElicitationRequest() != null) {
session.registerElicitationHandler(config.getOnElicitationRequest());
}
+ if (config.getOnExitPlanMode() != null) {
+ session.registerExitPlanModeHandler(config.getOnExitPlanMode());
+ }
+ if (config.getOnAutoModeSwitch() != null) {
+ session.registerAutoModeSwitchHandler(config.getOnAutoModeSwitch());
+ }
if (config.getOnEvent() != null) {
session.on(config.getOnEvent());
}
@@ -288,6 +306,12 @@ static void configureSession(CopilotSession session, ResumeSessionConfig config)
if (config.getOnElicitationRequest() != null) {
session.registerElicitationHandler(config.getOnElicitationRequest());
}
+ if (config.getOnExitPlanMode() != null) {
+ session.registerExitPlanModeHandler(config.getOnExitPlanMode());
+ }
+ if (config.getOnAutoModeSwitch() != null) {
+ session.registerAutoModeSwitchHandler(config.getOnAutoModeSwitch());
+ }
if (config.getOnEvent() != null) {
session.on(config.getOnEvent());
}
diff --git a/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchHandler.java b/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchHandler.java
new file mode 100644
index 0000000000..5fa19f4b1f
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchHandler.java
@@ -0,0 +1,48 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Handler for auto-mode-switch requests from the agent.
+ *
+ * Register an auto-mode-switch handler via
+ * {@link SessionConfig#setOnAutoModeSwitch(AutoModeSwitchHandler)} or
+ * {@link ResumeSessionConfig#setOnAutoModeSwitch(AutoModeSwitchHandler)}. When
+ * provided, the server routes {@code autoModeSwitch.request} callbacks to this
+ * handler.
+ *
+ *
Example Usage
+ *
+ * {@code
+ * AutoModeSwitchHandler handler = (request, invocation) -> {
+ * System.out.println("Rate limited: " + request.getErrorCode());
+ * return CompletableFuture.completedFuture(AutoModeSwitchResponse.YES);
+ * };
+ *
+ * var session = client.createSession(new SessionConfig().setOnAutoModeSwitch(handler)).get();
+ * }
+ *
+ * @see AutoModeSwitchRequest
+ * @see AutoModeSwitchResponse
+ * @since 1.0.8
+ */
+@FunctionalInterface
+public interface AutoModeSwitchHandler {
+
+ /**
+ * Handles an auto-mode-switch request from the agent.
+ *
+ * @param request
+ * the auto-mode-switch request containing the error code and
+ * retry-after seconds
+ * @param invocation
+ * context information about the invocation
+ * @return a future that resolves with the user's decision
+ */
+ CompletableFuture handle(AutoModeSwitchRequest request,
+ AutoModeSwitchInvocation invocation);
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchInvocation.java b/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchInvocation.java
new file mode 100644
index 0000000000..278d10ccfd
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchInvocation.java
@@ -0,0 +1,36 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+/**
+ * Context for an auto-mode-switch request invocation.
+ *
+ * @since 1.0.8
+ */
+public class AutoModeSwitchInvocation {
+
+ private String sessionId;
+
+ /**
+ * Gets the session ID.
+ *
+ * @return the session ID
+ */
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ /**
+ * Sets the session ID.
+ *
+ * @param sessionId
+ * the session ID
+ * @return this instance for method chaining
+ */
+ public AutoModeSwitchInvocation setSessionId(String sessionId) {
+ this.sessionId = sessionId;
+ return this;
+ }
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchRequest.java b/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchRequest.java
new file mode 100644
index 0000000000..0ef784c02a
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchRequest.java
@@ -0,0 +1,68 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Request to switch to auto mode after an eligible rate limit.
+ *
+ * This is sent by the server when the agent encounters a rate limit and wants
+ * to switch to an alternative model automatically.
+ *
+ * @since 1.0.8
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class AutoModeSwitchRequest {
+
+ @JsonProperty("errorCode")
+ private String errorCode;
+
+ @JsonProperty("retryAfterSeconds")
+ private Double retryAfterSeconds;
+
+ /**
+ * Gets the rate-limit error code that triggered the request.
+ *
+ * @return the error code, or {@code null}
+ */
+ public String getErrorCode() {
+ return errorCode;
+ }
+
+ /**
+ * Sets the rate-limit error code.
+ *
+ * @param errorCode
+ * the error code
+ * @return this instance for method chaining
+ */
+ public AutoModeSwitchRequest setErrorCode(String errorCode) {
+ this.errorCode = errorCode;
+ return this;
+ }
+
+ /**
+ * Gets the seconds until the rate limit resets, when known.
+ *
+ * @return the retry-after seconds, or {@code null}
+ */
+ public Double getRetryAfterSeconds() {
+ return retryAfterSeconds;
+ }
+
+ /**
+ * Sets the seconds until the rate limit resets.
+ *
+ * @param retryAfterSeconds
+ * the retry-after seconds
+ * @return this instance for method chaining
+ */
+ public AutoModeSwitchRequest setRetryAfterSeconds(Double retryAfterSeconds) {
+ this.retryAfterSeconds = retryAfterSeconds;
+ return this;
+ }
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchResponse.java b/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchResponse.java
new file mode 100644
index 0000000000..c072b73e2b
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/AutoModeSwitchResponse.java
@@ -0,0 +1,40 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+
+/**
+ * Response to an auto-mode-switch request.
+ *
+ * @since 1.0.8
+ */
+public enum AutoModeSwitchResponse {
+
+ /** Approve the switch for this rate-limit cycle. */
+ YES("yes"),
+
+ /** Approve and remember the choice for this session. */
+ YES_ALWAYS("yes_always"),
+
+ /** Decline the switch. */
+ NO("no");
+
+ private final String value;
+
+ AutoModeSwitchResponse(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the wire value of this response.
+ *
+ * @return the string value
+ */
+ @JsonValue
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
index 3a0b90f19a..12bab4154c 100644
--- a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
@@ -112,6 +112,12 @@ public final class CreateSessionRequest {
@JsonProperty("requestElicitation")
private Boolean requestElicitation;
+ @JsonProperty("requestExitPlanMode")
+ private Boolean requestExitPlanMode;
+
+ @JsonProperty("requestAutoModeSwitch")
+ private Boolean requestAutoModeSwitch;
+
@JsonProperty("modelCapabilities")
private ModelCapabilitiesOverride modelCapabilities;
@@ -419,6 +425,28 @@ public void setRequestElicitation(Boolean requestElicitation) {
this.requestElicitation = requestElicitation;
}
+ /** Gets the requestExitPlanMode flag. @return the flag */
+ public Boolean getRequestExitPlanMode() {
+ return requestExitPlanMode;
+ }
+
+ /** Sets the requestExitPlanMode flag. @param requestExitPlanMode the flag */
+ public void setRequestExitPlanMode(Boolean requestExitPlanMode) {
+ this.requestExitPlanMode = requestExitPlanMode;
+ }
+
+ /** Gets the requestAutoModeSwitch flag. @return the flag */
+ public Boolean getRequestAutoModeSwitch() {
+ return requestAutoModeSwitch;
+ }
+
+ /**
+ * Sets the requestAutoModeSwitch flag. @param requestAutoModeSwitch the flag
+ */
+ public void setRequestAutoModeSwitch(Boolean requestAutoModeSwitch) {
+ this.requestAutoModeSwitch = requestAutoModeSwitch;
+ }
+
/** Gets the model capabilities override. @return the override */
public ModelCapabilitiesOverride getModelCapabilities() {
return modelCapabilities;
diff --git a/src/main/java/com/github/copilot/sdk/json/ExitPlanModeHandler.java b/src/main/java/com/github/copilot/sdk/json/ExitPlanModeHandler.java
new file mode 100644
index 0000000000..13ecbe075c
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/ExitPlanModeHandler.java
@@ -0,0 +1,48 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Handler for exit-plan-mode requests from the agent.
+ *
+ * Register an exit-plan-mode handler via
+ * {@link SessionConfig#setOnExitPlanMode(ExitPlanModeHandler)} or
+ * {@link ResumeSessionConfig#setOnExitPlanMode(ExitPlanModeHandler)}. When
+ * provided, the server routes {@code exitPlanMode.request} callbacks to this
+ * handler.
+ *
+ *
Example Usage
+ *
+ * {@code
+ * ExitPlanModeHandler handler = (request, invocation) -> {
+ * // Review the plan and decide whether to approve
+ * return CompletableFuture
+ * .completedFuture(new ExitPlanModeResult().setApproved(true).setSelectedAction("interactive"));
+ * };
+ *
+ * var session = client.createSession(new SessionConfig().setOnExitPlanMode(handler)).get();
+ * }
+ *
+ * @see ExitPlanModeRequest
+ * @see ExitPlanModeResult
+ * @since 1.0.8
+ */
+@FunctionalInterface
+public interface ExitPlanModeHandler {
+
+ /**
+ * Handles an exit-plan-mode request from the agent.
+ *
+ * @param request
+ * the exit-plan-mode request containing the summary, plan content,
+ * and available actions
+ * @param invocation
+ * context information about the invocation
+ * @return a future that resolves with the user's decision
+ */
+ CompletableFuture handle(ExitPlanModeRequest request, ExitPlanModeInvocation invocation);
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/ExitPlanModeInvocation.java b/src/main/java/com/github/copilot/sdk/json/ExitPlanModeInvocation.java
new file mode 100644
index 0000000000..6fd0231266
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/ExitPlanModeInvocation.java
@@ -0,0 +1,36 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+/**
+ * Context for an exit-plan-mode request invocation.
+ *
+ * @since 1.0.8
+ */
+public class ExitPlanModeInvocation {
+
+ private String sessionId;
+
+ /**
+ * Gets the session ID.
+ *
+ * @return the session ID
+ */
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ /**
+ * Sets the session ID.
+ *
+ * @param sessionId
+ * the session ID
+ * @return this instance for method chaining
+ */
+ public ExitPlanModeInvocation setSessionId(String sessionId) {
+ this.sessionId = sessionId;
+ return this;
+ }
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/ExitPlanModeRequest.java b/src/main/java/com/github/copilot/sdk/json/ExitPlanModeRequest.java
new file mode 100644
index 0000000000..be09350ef3
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/ExitPlanModeRequest.java
@@ -0,0 +1,119 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Request to exit plan mode and continue with a selected action.
+ *
+ * This is sent by the server when the agent wants to exit plan mode and
+ * requests user confirmation.
+ *
+ * @since 1.0.8
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ExitPlanModeRequest {
+
+ @JsonProperty("summary")
+ private String summary = "";
+
+ @JsonProperty("planContent")
+ private String planContent;
+
+ @JsonProperty("actions")
+ private List actions;
+
+ @JsonProperty("recommendedAction")
+ private String recommendedAction = "autopilot";
+
+ /**
+ * Gets the summary of the plan or proposed next step.
+ *
+ * @return the summary
+ */
+ public String getSummary() {
+ return summary;
+ }
+
+ /**
+ * Sets the summary of the plan or proposed next step.
+ *
+ * @param summary
+ * the summary
+ * @return this instance for method chaining
+ */
+ public ExitPlanModeRequest setSummary(String summary) {
+ this.summary = summary;
+ return this;
+ }
+
+ /**
+ * Gets the full plan content, when available.
+ *
+ * @return the plan content, or {@code null} if not available
+ */
+ public String getPlanContent() {
+ return planContent;
+ }
+
+ /**
+ * Sets the full plan content.
+ *
+ * @param planContent
+ * the plan content
+ * @return this instance for method chaining
+ */
+ public ExitPlanModeRequest setPlanContent(String planContent) {
+ this.planContent = planContent;
+ return this;
+ }
+
+ /**
+ * Gets the available actions the user can select.
+ *
+ * @return the list of actions, or {@code null} if not specified
+ */
+ public List getActions() {
+ return actions == null ? null : Collections.unmodifiableList(actions);
+ }
+
+ /**
+ * Sets the available actions the user can select.
+ *
+ * @param actions
+ * the list of actions
+ * @return this instance for method chaining
+ */
+ public ExitPlanModeRequest setActions(List actions) {
+ this.actions = actions;
+ return this;
+ }
+
+ /**
+ * Gets the action recommended by the runtime.
+ *
+ * @return the recommended action
+ */
+ public String getRecommendedAction() {
+ return recommendedAction;
+ }
+
+ /**
+ * Sets the action recommended by the runtime.
+ *
+ * @param recommendedAction
+ * the recommended action
+ * @return this instance for method chaining
+ */
+ public ExitPlanModeRequest setRecommendedAction(String recommendedAction) {
+ this.recommendedAction = recommendedAction;
+ return this;
+ }
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/ExitPlanModeResult.java b/src/main/java/com/github/copilot/sdk/json/ExitPlanModeResult.java
new file mode 100644
index 0000000000..876e750b46
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/ExitPlanModeResult.java
@@ -0,0 +1,87 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Response to an exit-plan-mode request.
+ *
+ * @since 1.0.8
+ */
+public class ExitPlanModeResult {
+
+ @JsonProperty("approved")
+ private boolean approved = true;
+
+ @JsonProperty("selectedAction")
+ private String selectedAction;
+
+ @JsonProperty("feedback")
+ private String feedback;
+
+ /**
+ * Returns whether the user approved exiting plan mode.
+ *
+ * @return {@code true} if approved
+ */
+ public boolean isApproved() {
+ return approved;
+ }
+
+ /**
+ * Sets whether the user approved exiting plan mode.
+ *
+ * @param approved
+ * {@code true} if approved
+ * @return this instance for method chaining
+ */
+ public ExitPlanModeResult setApproved(boolean approved) {
+ this.approved = approved;
+ return this;
+ }
+
+ /**
+ * Gets the selected action, if the user chose one.
+ *
+ * @return the selected action, or {@code null}
+ */
+ public String getSelectedAction() {
+ return selectedAction;
+ }
+
+ /**
+ * Sets the selected action.
+ *
+ * @param selectedAction
+ * the selected action
+ * @return this instance for method chaining
+ */
+ public ExitPlanModeResult setSelectedAction(String selectedAction) {
+ this.selectedAction = selectedAction;
+ return this;
+ }
+
+ /**
+ * Gets optional feedback provided by the user.
+ *
+ * @return the feedback, or {@code null}
+ */
+ public String getFeedback() {
+ return feedback;
+ }
+
+ /**
+ * Sets feedback from the user.
+ *
+ * @param feedback
+ * the feedback text
+ * @return this instance for method chaining
+ */
+ public ExitPlanModeResult setFeedback(String feedback) {
+ this.feedback = feedback;
+ return this;
+ }
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
index cb52c62e02..f2caad7710 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
@@ -66,6 +66,8 @@ public class ResumeSessionConfig {
private Consumer onEvent;
private List commands;
private ElicitationHandler onElicitationRequest;
+ private ExitPlanModeHandler onExitPlanMode;
+ private AutoModeSwitchHandler onAutoModeSwitch;
private String gitHubToken;
/**
@@ -766,6 +768,60 @@ public ResumeSessionConfig setOnElicitationRequest(ElicitationHandler onElicitat
return this;
}
+ /**
+ * Gets the exit-plan-mode request handler.
+ *
+ * @return the exit-plan-mode handler, or {@code null}
+ * @since 1.0.8
+ */
+ public ExitPlanModeHandler getOnExitPlanMode() {
+ return onExitPlanMode;
+ }
+
+ /**
+ * Sets a handler for exit-plan-mode requests from the server.
+ *
+ * When provided, the server will route {@code exitPlanMode.request} callbacks
+ * to this handler.
+ *
+ * @param onExitPlanMode
+ * the exit-plan-mode handler
+ * @return this config for method chaining
+ * @see ExitPlanModeHandler
+ * @since 1.0.8
+ */
+ public ResumeSessionConfig setOnExitPlanMode(ExitPlanModeHandler onExitPlanMode) {
+ this.onExitPlanMode = onExitPlanMode;
+ return this;
+ }
+
+ /**
+ * Gets the auto-mode-switch request handler.
+ *
+ * @return the auto-mode-switch handler, or {@code null}
+ * @since 1.0.8
+ */
+ public AutoModeSwitchHandler getOnAutoModeSwitch() {
+ return onAutoModeSwitch;
+ }
+
+ /**
+ * Sets a handler for auto-mode-switch requests from the server.
+ *
+ * When provided, the server will route {@code autoModeSwitch.request} callbacks
+ * to this handler.
+ *
+ * @param onAutoModeSwitch
+ * the auto-mode-switch handler
+ * @return this config for method chaining
+ * @see AutoModeSwitchHandler
+ * @since 1.0.8
+ */
+ public ResumeSessionConfig setOnAutoModeSwitch(AutoModeSwitchHandler onAutoModeSwitch) {
+ this.onAutoModeSwitch = onAutoModeSwitch;
+ return this;
+ }
+
/**
* Gets the GitHub token for per-session authentication.
*
@@ -839,6 +895,8 @@ public ResumeSessionConfig clone() {
copy.onEvent = this.onEvent;
copy.commands = this.commands != null ? new ArrayList<>(this.commands) : null;
copy.onElicitationRequest = this.onElicitationRequest;
+ copy.onExitPlanMode = this.onExitPlanMode;
+ copy.onAutoModeSwitch = this.onAutoModeSwitch;
copy.gitHubToken = this.gitHubToken;
return copy;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
index 9b2c17f1a4..a1af269700 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
@@ -116,6 +116,12 @@ public final class ResumeSessionRequest {
@JsonProperty("requestElicitation")
private Boolean requestElicitation;
+ @JsonProperty("requestExitPlanMode")
+ private Boolean requestExitPlanMode;
+
+ @JsonProperty("requestAutoModeSwitch")
+ private Boolean requestAutoModeSwitch;
+
@JsonProperty("modelCapabilities")
private ModelCapabilitiesOverride modelCapabilities;
@@ -439,6 +445,28 @@ public void setRequestElicitation(Boolean requestElicitation) {
this.requestElicitation = requestElicitation;
}
+ /** Gets the requestExitPlanMode flag. @return the flag */
+ public Boolean getRequestExitPlanMode() {
+ return requestExitPlanMode;
+ }
+
+ /** Sets the requestExitPlanMode flag. @param requestExitPlanMode the flag */
+ public void setRequestExitPlanMode(Boolean requestExitPlanMode) {
+ this.requestExitPlanMode = requestExitPlanMode;
+ }
+
+ /** Gets the requestAutoModeSwitch flag. @return the flag */
+ public Boolean getRequestAutoModeSwitch() {
+ return requestAutoModeSwitch;
+ }
+
+ /**
+ * Sets the requestAutoModeSwitch flag. @param requestAutoModeSwitch the flag
+ */
+ public void setRequestAutoModeSwitch(Boolean requestAutoModeSwitch) {
+ this.requestAutoModeSwitch = requestAutoModeSwitch;
+ }
+
/** Gets the model capabilities override. @return the override */
public ModelCapabilitiesOverride getModelCapabilities() {
return modelCapabilities;
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
index a4b2769b74..51cad884ed 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
@@ -66,6 +66,8 @@ public class SessionConfig {
private Consumer onEvent;
private List commands;
private ElicitationHandler onElicitationRequest;
+ private ExitPlanModeHandler onExitPlanMode;
+ private AutoModeSwitchHandler onAutoModeSwitch;
private String gitHubToken;
/**
@@ -818,6 +820,60 @@ public SessionConfig setOnElicitationRequest(ElicitationHandler onElicitationReq
return this;
}
+ /**
+ * Gets the exit-plan-mode request handler.
+ *
+ * @return the exit-plan-mode handler, or {@code null}
+ * @since 1.0.8
+ */
+ public ExitPlanModeHandler getOnExitPlanMode() {
+ return onExitPlanMode;
+ }
+
+ /**
+ * Sets a handler for exit-plan-mode requests from the server.
+ *
+ * When provided, the server will route {@code exitPlanMode.request} callbacks
+ * to this handler.
+ *
+ * @param onExitPlanMode
+ * the exit-plan-mode handler
+ * @return this config instance for method chaining
+ * @see ExitPlanModeHandler
+ * @since 1.0.8
+ */
+ public SessionConfig setOnExitPlanMode(ExitPlanModeHandler onExitPlanMode) {
+ this.onExitPlanMode = onExitPlanMode;
+ return this;
+ }
+
+ /**
+ * Gets the auto-mode-switch request handler.
+ *
+ * @return the auto-mode-switch handler, or {@code null}
+ * @since 1.0.8
+ */
+ public AutoModeSwitchHandler getOnAutoModeSwitch() {
+ return onAutoModeSwitch;
+ }
+
+ /**
+ * Sets a handler for auto-mode-switch requests from the server.
+ *
+ * When provided, the server will route {@code autoModeSwitch.request} callbacks
+ * to this handler.
+ *
+ * @param onAutoModeSwitch
+ * the auto-mode-switch handler
+ * @return this config instance for method chaining
+ * @see AutoModeSwitchHandler
+ * @since 1.0.8
+ */
+ public SessionConfig setOnAutoModeSwitch(AutoModeSwitchHandler onAutoModeSwitch) {
+ this.onAutoModeSwitch = onAutoModeSwitch;
+ return this;
+ }
+
/**
* Gets the GitHub token for per-session authentication.
*
@@ -891,6 +947,8 @@ public SessionConfig clone() {
copy.onEvent = this.onEvent;
copy.commands = this.commands != null ? new ArrayList<>(this.commands) : null;
copy.onElicitationRequest = this.onElicitationRequest;
+ copy.onExitPlanMode = this.onExitPlanMode;
+ copy.onAutoModeSwitch = this.onAutoModeSwitch;
copy.gitHubToken = this.gitHubToken;
return copy;
}
From f55af2d2be1d87c31d46eb64a5cb96f393317df6 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 11 May 2026 18:12:21 +0000
Subject: [PATCH 008/135] Update .lastmerge to
4a0437bb03a0b60a1867f14ae8e3faf053afa5aa, sync pom.xml CLI version, and
update scripts/codegen @github/copilot version
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.lastmerge | 2 +-
pom.xml | 2 +-
scripts/codegen/package-lock.json | 56 +++++++++++++++----------------
scripts/codegen/package.json | 2 +-
4 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/.lastmerge b/.lastmerge
index 142f4f7ab1..b28867a960 100644
--- a/.lastmerge
+++ b/.lastmerge
@@ -1 +1 @@
-066a69c1e849adf1bd98564ab1b52316ec471182
+4a0437bb03a0b60a1867f14ae8e3faf053afa5aa
diff --git a/pom.xml b/pom.xml
index 832f2f2c9d..c8930b3d10 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,7 +94,7 @@
reference-impl-sync workflow and deal with the subsequent
PR.
-->
- ^1.0.44-2
+ ^1.0.44-3
diff --git a/scripts/codegen/package-lock.json b/scripts/codegen/package-lock.json
index f414fec716..0846fc42e6 100644
--- a/scripts/codegen/package-lock.json
+++ b/scripts/codegen/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "copilot-sdk-java-codegen",
"dependencies": {
- "@github/copilot": "^1.0.44-2",
+ "@github/copilot": "^1.0.44-3",
"json-schema": "^0.4.0",
"tsx": "^4.20.6"
}
@@ -428,26 +428,26 @@
}
},
"node_modules/@github/copilot": {
- "version": "1.0.44-2",
- "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.44-2.tgz",
- "integrity": "sha512-MUIR4w+oXjbg1jwUS8B86eMd/bV2gVKZ61a/aEUE4gUrFFpGXO0tNk9OkfLSH5cmlhJY6lzMzb+kKQWoeAbbNQ==",
+ "version": "1.0.45",
+ "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.45.tgz",
+ "integrity": "sha512-2QADgQcw/d0GFqTq2+nHwX152ZRvZxW0CHONG5d1RCs6YJtdr/GdbnMYYeRH2BiBIhnfkcvF50ImCRvsS5Tnwg==",
"license": "SEE LICENSE IN LICENSE.md",
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
- "@github/copilot-darwin-arm64": "1.0.44-2",
- "@github/copilot-darwin-x64": "1.0.44-2",
- "@github/copilot-linux-arm64": "1.0.44-2",
- "@github/copilot-linux-x64": "1.0.44-2",
- "@github/copilot-win32-arm64": "1.0.44-2",
- "@github/copilot-win32-x64": "1.0.44-2"
+ "@github/copilot-darwin-arm64": "1.0.45",
+ "@github/copilot-darwin-x64": "1.0.45",
+ "@github/copilot-linux-arm64": "1.0.45",
+ "@github/copilot-linux-x64": "1.0.45",
+ "@github/copilot-win32-arm64": "1.0.45",
+ "@github/copilot-win32-x64": "1.0.45"
}
},
"node_modules/@github/copilot-darwin-arm64": {
- "version": "1.0.44-2",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.44-2.tgz",
- "integrity": "sha512-6o/pvew0FZJG+8saG1K/L1pUIvpz4AWkZitiqH36tDfXdXKx/PUQ+zaFg/KPeHNnxtal5OdE/7iyrJwIqm2gPg==",
+ "version": "1.0.45",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.45.tgz",
+ "integrity": "sha512-gCJy1nOIWL5lpLFJTRk2Kz7bS30emkA4p4gM+PJ5/dOwNRBOyUO0/2f03/m5vYL4DNd/T47cFIN6s82gISAIYQ==",
"cpu": [
"arm64"
],
@@ -461,9 +461,9 @@
}
},
"node_modules/@github/copilot-darwin-x64": {
- "version": "1.0.44-2",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.44-2.tgz",
- "integrity": "sha512-OMNoLNFYUynB4wiplSh4gtD5zVlvfWMKc0jKQ0oItJLGO8GRL9X0ZB2ONB+7JpVvPidz0Yy4+jU0zWNXEjMM5g==",
+ "version": "1.0.45",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.45.tgz",
+ "integrity": "sha512-nLzC7C0i/WAY+4FukHuONBDNeKUAqBBab3n36aEdpqxVDP5h2Tbzg2yShqav2blR7KDJL7YMcYTVFxmwfQj+yQ==",
"cpu": [
"x64"
],
@@ -477,9 +477,9 @@
}
},
"node_modules/@github/copilot-linux-arm64": {
- "version": "1.0.44-2",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.44-2.tgz",
- "integrity": "sha512-5WGRADU08hqBTWmQ6JVOYMximzsXGuOdFF4GFRQqfsCR8k4RE8fdPWQJa92BpqMgGWwEVPemq0wB3D4hDM5eWw==",
+ "version": "1.0.45",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.45.tgz",
+ "integrity": "sha512-MdRNZUNMrI0dpQ+DiDoZQ7AbitQp9eN7ir176Za2Kf7dkUxPwmio32yhRbBS81McU6vBw8cCzEZviwv/jc8buQ==",
"cpu": [
"arm64"
],
@@ -493,9 +493,9 @@
}
},
"node_modules/@github/copilot-linux-x64": {
- "version": "1.0.44-2",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.44-2.tgz",
- "integrity": "sha512-4ZnA2QxEwgrdCePdS5OjuksEGFpJrXgofuELANCpDSHwR3eTV7PynVyqhG6Et7ktN2KzHk7zf8kvtiWVCOxvFg==",
+ "version": "1.0.45",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.45.tgz",
+ "integrity": "sha512-xSRUjWA+wrSSjktJSjNtiS/47Cy0PviPejj7RUmtChsPfDJB8wW2iZ6NfpdiAomtxAz5xx4AjbjT1I4b1FqnwA==",
"cpu": [
"x64"
],
@@ -509,9 +509,9 @@
}
},
"node_modules/@github/copilot-win32-arm64": {
- "version": "1.0.44-2",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.44-2.tgz",
- "integrity": "sha512-klgSdBZblz9O8BRnTh9uk9uO/INQwVeTBagXuJO7MrZ7JCfBVJyFUYky2tKIjFxlwefyhrRZuniqYeOI9fQc+A==",
+ "version": "1.0.45",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.45.tgz",
+ "integrity": "sha512-lhcTlKs7MWMzIXv21hUSpL4aFW49jqVhNrQKaB8sYk2nzvGRJvNwTcBS1Tn5ndXlPzQ9P/p9B6B5uwwmZ1vHHw==",
"cpu": [
"arm64"
],
@@ -525,9 +525,9 @@
}
},
"node_modules/@github/copilot-win32-x64": {
- "version": "1.0.44-2",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.44-2.tgz",
- "integrity": "sha512-ziq3abdbMCqtAqdiEWWf6cn0whlWss7rC9VMsO/Vx2gjSEVCeJkmIiRiQO45WikheyXyxEmCTAvOwZLQvs+I9g==",
+ "version": "1.0.45",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.45.tgz",
+ "integrity": "sha512-XYZ983NQmooVr/n+pCnHIorBmf1hd3o1rMlSAodwG/VFlQaydGoOs1F1NntxWBoFAND+eM6N4PZfw8M8sRayfA==",
"cpu": [
"x64"
],
diff --git a/scripts/codegen/package.json b/scripts/codegen/package.json
index 66d5565e86..6dde795791 100644
--- a/scripts/codegen/package.json
+++ b/scripts/codegen/package.json
@@ -7,7 +7,7 @@
"generate:java": "tsx java.ts"
},
"dependencies": {
- "@github/copilot": "^1.0.44-2",
+ "@github/copilot": "^1.0.44-3",
"json-schema": "^0.4.0",
"tsx": "^4.20.6"
}
From 3e1614bbf83666b00972daf57ff5dad78e100f1d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 11 May 2026 18:12:34 +0000
Subject: [PATCH 009/135] Add unit/E2E tests and documentation for mode handler
APIs
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
src/site/markdown/advanced.md | 61 ++++++++
.../github/copilot/sdk/ConfigCloneTest.java | 30 ++++
.../github/copilot/sdk/ModeHandlersTest.java | 145 ++++++++++++++++++
.../sdk/SessionRequestBuilderTest.java | 124 +++++++++++++++
4 files changed, 360 insertions(+)
create mode 100644 src/test/java/com/github/copilot/sdk/ModeHandlersTest.java
diff --git a/src/site/markdown/advanced.md b/src/site/markdown/advanced.md
index ccf386640f..5c46313569 100644
--- a/src/site/markdown/advanced.md
+++ b/src/site/markdown/advanced.md
@@ -53,6 +53,9 @@ This guide covers advanced scenarios for extending and customizing your Copilot
- [Incoming Elicitation Handler](#Incoming_Elicitation_Handler)
- [Session Capabilities](#Session_Capabilities)
- [Outgoing Elicitation via session.getUi()](#Outgoing_Elicitation_via_session.getUi)
+- [Mode Handlers](#Mode_Handlers)
+ - [Exit Plan Mode](#Exit_Plan_Mode)
+ - [Auto Mode Switch](#Auto_Mode_Switch)
- [Getting Session Metadata by ID](#Getting_Session_Metadata_by_ID)
---
@@ -1267,6 +1270,64 @@ All `getUi()` methods throw `IllegalStateException` if the host does not support
---
+## Mode Handlers
+
+Mode handlers let your application respond to mode transitions requested by the Copilot CLI.
+
+### Exit Plan Mode
+
+When the model finishes creating a plan and wants to transition out of plan mode, it invokes the `exitPlanMode` handler. Register the handler via `SessionConfig.setOnExitPlanMode()`:
+
+```java
+var session = client.createSession(new SessionConfig()
+ .setOnExitPlanMode((request, invocation) -> {
+ System.out.println("Plan summary: " + request.getSummary());
+ System.out.println("Available actions: " + request.getActions());
+ System.out.println("Recommended: " + request.getRecommendedAction());
+
+ return CompletableFuture.completedFuture(
+ new ExitPlanModeResult()
+ .setApproved(true)
+ .setSelectedAction("interactive")
+ .setFeedback("Looks good, proceed!"));
+ })).get();
+```
+
+When no handler is registered, the SDK automatically approves the plan (`approved=true`). The handler receives an `ExitPlanModeRequest` with:
+
+| Field | Description |
+|---------------------|-------------------------------------------------|
+| `summary` | Summary of the plan that was created |
+| `planContent` | Full content of the plan file |
+| `actions` | Available actions (e.g., interactive, autopilot) |
+| `recommendedAction` | The recommended action for the user |
+
+### Auto Mode Switch
+
+When the model encounters a rate limit or similar constraint, it may request to switch modes automatically. Register the handler via `SessionConfig.setOnAutoModeSwitch()`:
+
+```java
+var session = client.createSession(new SessionConfig()
+ .setOnAutoModeSwitch((request, invocation) -> {
+ System.out.println("Error: " + request.getErrorCode());
+ System.out.println("Retry after: " + request.getRetryAfterSeconds() + "s");
+
+ return CompletableFuture.completedFuture(AutoModeSwitchResponse.YES);
+ })).get();
+```
+
+When no handler is registered, the SDK returns `NO` (declining the mode switch). The response options are:
+
+| Response | Description |
+|---------------------------------|------------------------------------------|
+| `AutoModeSwitchResponse.YES` | Allow the mode switch this time |
+| `AutoModeSwitchResponse.YES_ALWAYS`| Always allow automatic mode switches |
+| `AutoModeSwitchResponse.NO` | Decline the mode switch |
+
+Both handlers are also available on `ResumeSessionConfig` for resumed sessions.
+
+---
+
## Getting Session Metadata by ID
Retrieve metadata for a specific session without listing all sessions:
diff --git a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
index f7ce3aa4de..7abc47e4a4 100644
--- a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
+++ b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
@@ -16,8 +16,10 @@
import org.junit.jupiter.api.Test;
import com.github.copilot.sdk.generated.SessionEvent;
+import com.github.copilot.sdk.json.AutoModeSwitchResponse;
import com.github.copilot.sdk.json.CopilotClientOptions;
import com.github.copilot.sdk.json.DefaultAgentConfig;
+import com.github.copilot.sdk.json.ExitPlanModeResult;
import com.github.copilot.sdk.json.InfiniteSessionConfig;
import com.github.copilot.sdk.json.MessageOptions;
import com.github.copilot.sdk.json.ModelInfo;
@@ -375,4 +377,32 @@ void copilotClientOptionsSessionIdleTimeoutCloned() {
assertEquals(600, cloned.getSessionIdleTimeoutSeconds());
}
+
+ @Test
+ void sessionConfigCloneCopiesModeSwitchHandlers() {
+ SessionConfig original = new SessionConfig();
+ original.setOnExitPlanMode(
+ (request, invocation) -> CompletableFuture.completedFuture(new ExitPlanModeResult()));
+ original.setOnAutoModeSwitch(
+ (request, invocation) -> CompletableFuture.completedFuture(AutoModeSwitchResponse.NO));
+
+ SessionConfig cloned = original.clone();
+
+ assertSame(original.getOnExitPlanMode(), cloned.getOnExitPlanMode());
+ assertSame(original.getOnAutoModeSwitch(), cloned.getOnAutoModeSwitch());
+ }
+
+ @Test
+ void resumeSessionConfigCloneCopiesModeSwitchHandlers() {
+ ResumeSessionConfig original = new ResumeSessionConfig();
+ original.setOnExitPlanMode(
+ (request, invocation) -> CompletableFuture.completedFuture(new ExitPlanModeResult()));
+ original.setOnAutoModeSwitch(
+ (request, invocation) -> CompletableFuture.completedFuture(AutoModeSwitchResponse.NO));
+
+ ResumeSessionConfig cloned = original.clone();
+
+ assertSame(original.getOnExitPlanMode(), cloned.getOnExitPlanMode());
+ assertSame(original.getOnAutoModeSwitch(), cloned.getOnAutoModeSwitch());
+ }
}
diff --git a/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java b/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java
new file mode 100644
index 0000000000..1c2da5d094
--- /dev/null
+++ b/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java
@@ -0,0 +1,145 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import com.github.copilot.sdk.generated.ExitPlanModeCompletedEvent;
+import com.github.copilot.sdk.generated.ExitPlanModeRequestedEvent;
+import com.github.copilot.sdk.json.AutoModeSwitchRequest;
+import com.github.copilot.sdk.json.AutoModeSwitchResponse;
+import com.github.copilot.sdk.json.CopilotClientOptions;
+import com.github.copilot.sdk.json.ExitPlanModeRequest;
+import com.github.copilot.sdk.json.ExitPlanModeResult;
+import com.github.copilot.sdk.json.MessageOptions;
+import com.github.copilot.sdk.json.PermissionHandler;
+import com.github.copilot.sdk.json.SessionConfig;
+
+/**
+ * E2E tests for exit-plan-mode and auto-mode-switch handler APIs.
+ *
+ *
+ * Ported from {@code ModeHandlersE2ETests.cs} in the reference implementation
+ * dotnet SDK.
+ *
+ */
+public class ModeHandlersTest {
+
+ private static final String TOKEN = "mode-handler-token";
+
+ private static E2ETestContext ctx;
+
+ @BeforeAll
+ static void setup() throws Exception {
+ ctx = E2ETestContext.create();
+ }
+
+ @AfterAll
+ static void teardown() throws Exception {
+ if (ctx != null) {
+ ctx.close();
+ }
+ }
+
+ private CopilotClient createAuthenticatedClient() {
+ Map env = new HashMap<>(ctx.getEnvironment());
+ env.put("COPILOT_DEBUG_GITHUB_API_URL", ctx.getProxyUrl());
+
+ return ctx.createClient(new CopilotClientOptions().setEnvironment(env));
+ }
+
+ private void configureAuthenticatedUser() throws Exception {
+ ctx.setCopilotUserByToken(TOKEN, "mode-handler-user", "individual_pro", ctx.getProxyUrl(),
+ "https://localhost:1/telemetry", "mode-handler-tracking-id");
+ }
+
+ @Test
+ void shouldInvokeExitPlanModeHandlerWhenModelUsesTool() throws Exception {
+ final String summary = "Greeting file implementation plan";
+ configureAuthenticatedUser();
+
+ var handlerCalled = new CompletableFuture();
+
+ try (var client = createAuthenticatedClient()) {
+ var session = client.createSession(new SessionConfig().setGitHubToken(TOKEN)
+ .setOnPermissionRequest(PermissionHandler.APPROVE_ALL).setOnExitPlanMode((request, invocation) -> {
+ handlerCalled.complete(request);
+ return CompletableFuture.completedFuture(new ExitPlanModeResult().setApproved(true)
+ .setSelectedAction("interactive").setFeedback("Approved by the Java E2E test"));
+ })).get(30, TimeUnit.SECONDS);
+
+ var requestedEvent = new CompletableFuture();
+ var completedEvent = new CompletableFuture();
+
+ session.on(event -> {
+ if (event instanceof ExitPlanModeRequestedEvent requested
+ && summary.equals(requested.getData().summary())) {
+ requestedEvent.complete(requested);
+ } else if (event instanceof ExitPlanModeCompletedEvent completed
+ && Boolean.TRUE.equals(completed.getData().approved())
+ && "interactive".equals(completed.getData().selectedAction())) {
+ completedEvent.complete(completed);
+ }
+ });
+
+ var response = session.sendAndWait(new MessageOptions().setPrompt(
+ "Create a brief implementation plan for adding a greeting.txt file, then request approval with exit_plan_mode.")
+ .setMode("plan")).get(120, TimeUnit.SECONDS);
+
+ var request = handlerCalled.get(10, TimeUnit.SECONDS);
+ assertEquals(summary, request.getSummary());
+ assertNotNull(request.getActions());
+ assertTrue(request.getActions().contains("interactive"));
+ assertNotNull(request.getPlanContent());
+
+ var reqEvent = requestedEvent.get(10, TimeUnit.SECONDS);
+ assertEquals(request.getSummary(), reqEvent.getData().summary());
+
+ var compEvent = completedEvent.get(10, TimeUnit.SECONDS);
+ assertTrue(compEvent.getData().approved());
+ assertEquals("interactive", compEvent.getData().selectedAction());
+
+ assertNotNull(response);
+
+ session.close();
+ }
+ }
+
+ @Test
+ void shouldInvokeAutoModeSwitchHandlerWhenRateLimited() throws Exception {
+ configureAuthenticatedUser();
+
+ var handlerCalled = new CompletableFuture();
+
+ try (var client = createAuthenticatedClient()) {
+ var session = client.createSession(
+ new SessionConfig().setGitHubToken(TOKEN).setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
+ .setOnAutoModeSwitch((request, invocation) -> {
+ handlerCalled.complete(request);
+ return CompletableFuture.completedFuture(AutoModeSwitchResponse.YES);
+ }))
+ .get(30, TimeUnit.SECONDS);
+
+ session.sendAndWait(new MessageOptions()
+ .setPrompt("Explain that auto mode recovered from a rate limit in one short sentence."))
+ .get(30, TimeUnit.SECONDS);
+
+ var request = handlerCalled.get(30, TimeUnit.SECONDS);
+ assertEquals("user_weekly_rate_limited", request.getErrorCode());
+ assertEquals(1.0, request.getRetryAfterSeconds());
+
+ session.close();
+ }
+ }
+}
diff --git a/src/test/java/com/github/copilot/sdk/SessionRequestBuilderTest.java b/src/test/java/com/github/copilot/sdk/SessionRequestBuilderTest.java
index 0d13576eb8..43703831a8 100644
--- a/src/test/java/com/github/copilot/sdk/SessionRequestBuilderTest.java
+++ b/src/test/java/com/github/copilot/sdk/SessionRequestBuilderTest.java
@@ -12,11 +12,13 @@
import org.junit.jupiter.api.Test;
+import com.github.copilot.sdk.json.AutoModeSwitchResponse;
import com.github.copilot.sdk.json.CreateSessionRequest;
import com.github.copilot.sdk.json.DefaultAgentConfig;
import com.github.copilot.sdk.json.ElicitationHandler;
import com.github.copilot.sdk.json.ElicitationResult;
import com.github.copilot.sdk.json.ElicitationResultAction;
+import com.github.copilot.sdk.json.ExitPlanModeResult;
import com.github.copilot.sdk.json.ResumeSessionConfig;
import com.github.copilot.sdk.json.ResumeSessionRequest;
import com.github.copilot.sdk.json.SessionConfig;
@@ -535,4 +537,126 @@ void testResumeRequestOmitsEnableSessionTelemetryWhenNull() throws Exception {
var json = mapper.writeValueAsString(request);
assertFalse(json.contains("enableSessionTelemetry"), "enableSessionTelemetry should be omitted when null");
}
+
+ // =========================================================================
+ // Mode handler request flags
+ // =========================================================================
+
+ @Test
+ void testBuildCreateRequestWithExitPlanModeHandler() {
+ var config = new SessionConfig().setOnExitPlanMode(
+ (request, invocation) -> CompletableFuture.completedFuture(new ExitPlanModeResult()));
+
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+
+ assertTrue(request.getRequestExitPlanMode());
+ }
+
+ @Test
+ void testBuildCreateRequestWithAutoModeSwitchHandler() {
+ var config = new SessionConfig().setOnAutoModeSwitch(
+ (request, invocation) -> CompletableFuture.completedFuture(AutoModeSwitchResponse.NO));
+
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+
+ assertTrue(request.getRequestAutoModeSwitch());
+ }
+
+ @Test
+ void testBuildCreateRequestWithoutModeHandlers() {
+ var config = new SessionConfig();
+
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+
+ assertNull(request.getRequestExitPlanMode());
+ assertNull(request.getRequestAutoModeSwitch());
+ }
+
+ @Test
+ void testBuildResumeRequestWithExitPlanModeHandler() {
+ var config = new ResumeSessionConfig().setOnExitPlanMode(
+ (request, invocation) -> CompletableFuture.completedFuture(new ExitPlanModeResult()));
+
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("session-1", config);
+
+ assertTrue(request.getRequestExitPlanMode());
+ }
+
+ @Test
+ void testBuildResumeRequestWithAutoModeSwitchHandler() {
+ var config = new ResumeSessionConfig().setOnAutoModeSwitch(
+ (request, invocation) -> CompletableFuture.completedFuture(AutoModeSwitchResponse.NO));
+
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("session-1", config);
+
+ assertTrue(request.getRequestAutoModeSwitch());
+ }
+
+ @Test
+ void configureSessionWithExitPlanModeHandler_registersHandler() {
+ CopilotSession session = new CopilotSession("session-1", null);
+
+ var config = new SessionConfig().setOnExitPlanMode(
+ (request, invocation) -> CompletableFuture.completedFuture(new ExitPlanModeResult()));
+
+ SessionRequestBuilder.configureSession(session, config);
+ }
+
+ @Test
+ void configureSessionWithAutoModeSwitchHandler_registersHandler() {
+ CopilotSession session = new CopilotSession("session-1", null);
+
+ var config = new SessionConfig().setOnAutoModeSwitch(
+ (request, invocation) -> CompletableFuture.completedFuture(AutoModeSwitchResponse.NO));
+
+ SessionRequestBuilder.configureSession(session, config);
+ }
+
+ @Test
+ void configureResumedSessionWithExitPlanModeHandler_registersHandler() {
+ CopilotSession session = new CopilotSession("session-1", null);
+
+ var config = new ResumeSessionConfig().setOnExitPlanMode(
+ (request, invocation) -> CompletableFuture.completedFuture(new ExitPlanModeResult()));
+
+ SessionRequestBuilder.configureSession(session, config);
+ }
+
+ @Test
+ void configureResumedSessionWithAutoModeSwitchHandler_registersHandler() {
+ CopilotSession session = new CopilotSession("session-1", null);
+
+ var config = new ResumeSessionConfig().setOnAutoModeSwitch(
+ (request, invocation) -> CompletableFuture.completedFuture(AutoModeSwitchResponse.NO));
+
+ SessionRequestBuilder.configureSession(session, config);
+ }
+
+ @Test
+ void testCreateRequestSerializesModeFlags() throws Exception {
+ var config = new SessionConfig()
+ .setOnExitPlanMode((r, i) -> CompletableFuture.completedFuture(new ExitPlanModeResult()))
+ .setOnAutoModeSwitch((r, i) -> CompletableFuture.completedFuture(AutoModeSwitchResponse.NO));
+
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+ var mapper = JsonRpcClient.getObjectMapper();
+ var json = mapper.writeValueAsString(request);
+
+ assertTrue(json.contains("\"requestExitPlanMode\":true"));
+ assertTrue(json.contains("\"requestAutoModeSwitch\":true"));
+ }
+
+ @Test
+ void testResumeRequestSerializesModeFlags() throws Exception {
+ var config = new ResumeSessionConfig()
+ .setOnExitPlanMode((r, i) -> CompletableFuture.completedFuture(new ExitPlanModeResult()))
+ .setOnAutoModeSwitch((r, i) -> CompletableFuture.completedFuture(AutoModeSwitchResponse.NO));
+
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("session-1", config);
+ var mapper = JsonRpcClient.getObjectMapper();
+ var json = mapper.writeValueAsString(request);
+
+ assertTrue(json.contains("\"requestExitPlanMode\":true"));
+ assertTrue(json.contains("\"requestAutoModeSwitch\":true"));
+ }
}
From a427c7f6073a07d03acd852a158b3dc9afa8ac43 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 11 May 2026 18:44:37 +0000
Subject: [PATCH 010/135] Regenerate codegen output
Auto-committed by codegen-check workflow.
---
.../sdk/generated/AssistantMessageEvent.java | 6 ++++
.../sdk/generated/SessionStartEvent.java | 4 ++-
.../sdk/generated/rpc/SessionCommandsApi.java | 13 ++++++++
...nCommandsRespondToQueuedCommandParams.java | 31 +++++++++++++++++
...nCommandsRespondToQueuedCommandResult.java | 27 +++++++++++++++
.../sdk/generated/rpc/SessionTasksApi.java | 15 +++++++++
.../rpc/SessionTasksSendMessageParams.java | 33 +++++++++++++++++++
.../rpc/SessionTasksSendMessageResult.java | 29 ++++++++++++++++
.../SessionWorkspacesGetWorkspaceResult.java | 23 -------------
9 files changed, 157 insertions(+), 24 deletions(-)
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandParams.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandResult.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageParams.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageResult.java
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageEvent.java
index 2ff43e67a8..3ac0b9780a 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageEvent.java
@@ -38,6 +38,8 @@ public final class AssistantMessageEvent extends SessionEvent {
public record AssistantMessageEventData(
/** Unique identifier for this assistant message */
@JsonProperty("messageId") String messageId,
+ /** Model that produced this assistant message, if known */
+ @JsonProperty("model") String model,
/** The assistant's text response content */
@JsonProperty("content") String content,
/** Tool invocations requested by the assistant in this message */
@@ -56,6 +58,10 @@ public record AssistantMessageEventData(
@JsonProperty("interactionId") String interactionId,
/** GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs */
@JsonProperty("requestId") String requestId,
+ /** Raw Anthropic content array with advisor blocks (server_tool_use, advisor_tool_result) for verbatim round-tripping */
+ @JsonProperty("anthropicAdvisorBlocks") List anthropicAdvisorBlocks,
+ /** Anthropic advisor model ID used for this response, for timeline display on replay */
+ @JsonProperty("anthropicAdvisorModel") String anthropicAdvisorModel,
/** Identifier for the agent loop turn that produced this message, matching the corresponding assistant.turn_start event */
@JsonProperty("turnId") String turnId,
/** Tool call ID of the parent tool invocation when this event originates from a sub-agent */
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionStartEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionStartEvent.java
index 6d83575e85..f5d6378fcd 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionStartEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionStartEvent.java
@@ -55,7 +55,9 @@ public record SessionStartEventData(
/** Whether the session was already in use by another client at start time */
@JsonProperty("alreadyInUse") Boolean alreadyInUse,
/** Whether this session supports remote steering via Mission Control */
- @JsonProperty("remoteSteerable") Boolean remoteSteerable
+ @JsonProperty("remoteSteerable") Boolean remoteSteerable,
+ /** When set, identifies a parent session whose context this session continues — e.g., a detached headless rem-agent run launched on the parent's interactive shutdown. Telemetry from this session is reported under the parent's session_id. */
+ @JsonProperty("detachedFromSpawningParentSessionId") String detachedFromSpawningParentSessionId
) {
}
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java
index 351a2d14cd..0d3599a1cc 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java
@@ -42,4 +42,17 @@ public CompletableFuture handlePendin
return caller.invoke("session.commands.handlePendingCommand", _p, SessionCommandsHandlePendingCommandResult.class);
}
+ /**
+ * Invokes {@code session.commands.respondToQueuedCommand}.
+ *
+ * Note: the {@code sessionId} field in the params record is overridden
+ * by the session-scoped wrapper; any value provided is ignored.
+ * @since 1.0.0
+ */
+ public CompletableFuture respondToQueuedCommand(SessionCommandsRespondToQueuedCommandParams params) {
+ com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params);
+ _p.put("sessionId", this.sessionId);
+ return caller.invoke("session.commands.respondToQueuedCommand", _p, SessionCommandsRespondToQueuedCommandResult.class);
+ }
+
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandParams.java
new file mode 100644
index 0000000000..46796b728c
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandParams.java
@@ -0,0 +1,31 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.processing.Generated;
+
+/**
+ * Request parameters for the {@code session.commands.respondToQueuedCommand} RPC method.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record SessionCommandsRespondToQueuedCommandParams(
+ /** Target session identifier */
+ @JsonProperty("sessionId") String sessionId,
+ /** Request ID from the queued command event */
+ @JsonProperty("requestId") String requestId,
+ /** Result of the queued command execution */
+ @JsonProperty("result") Object result
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandResult.java
new file mode 100644
index 0000000000..272849411a
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandResult.java
@@ -0,0 +1,27 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.processing.Generated;
+
+/**
+ * Result for the {@code session.commands.respondToQueuedCommand} RPC method.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record SessionCommandsRespondToQueuedCommandResult(
+ /** Whether the response was accepted (false if the requestId was not found or already resolved) */
+ @JsonProperty("success") Boolean success
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksApi.java
index 8e5f0ddeb3..6ee8ed2052 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksApi.java
@@ -99,4 +99,19 @@ public CompletableFuture remove(SessionTasksRemovePara
return caller.invoke("session.tasks.remove", _p, SessionTasksRemoveResult.class);
}
+ /**
+ * Invokes {@code session.tasks.sendMessage}.
+ *
+ * Note: the {@code sessionId} field in the params record is overridden
+ * by the session-scoped wrapper; any value provided is ignored.
+ *
+ * @apiNote This method is experimental and may change in a future version.
+ * @since 1.0.0
+ */
+ public CompletableFuture sendMessage(SessionTasksSendMessageParams params) {
+ com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params);
+ _p.put("sessionId", this.sessionId);
+ return caller.invoke("session.tasks.sendMessage", _p, SessionTasksSendMessageResult.class);
+ }
+
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageParams.java
new file mode 100644
index 0000000000..70c70eed75
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageParams.java
@@ -0,0 +1,33 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.processing.Generated;
+
+/**
+ * Request parameters for the {@code session.tasks.sendMessage} RPC method.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record SessionTasksSendMessageParams(
+ /** Target session identifier */
+ @JsonProperty("sessionId") String sessionId,
+ /** Agent task identifier */
+ @JsonProperty("id") String id,
+ /** Message content to send to the agent */
+ @JsonProperty("message") String message,
+ /** Agent ID of the sender, if sent on behalf of another agent */
+ @JsonProperty("fromAgentId") String fromAgentId
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageResult.java
new file mode 100644
index 0000000000..f4aabb1710
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageResult.java
@@ -0,0 +1,29 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.processing.Generated;
+
+/**
+ * Result for the {@code session.tasks.sendMessage} RPC method.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record SessionTasksSendMessageResult(
+ /** Whether the message was successfully delivered or steered */
+ @JsonProperty("sent") Boolean sent,
+ /** Error message if delivery failed */
+ @JsonProperty("error") String error
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionWorkspacesGetWorkspaceResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionWorkspacesGetWorkspaceResult.java
index c2afa210bd..6474c29822 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionWorkspacesGetWorkspaceResult.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionWorkspacesGetWorkspaceResult.java
@@ -38,7 +38,6 @@ public record SessionWorkspacesGetWorkspaceResultWorkspace(
@JsonProperty("branch") String branch,
@JsonProperty("name") String name,
@JsonProperty("user_named") Boolean userNamed,
- @JsonProperty("summary") String summary,
@JsonProperty("summary_count") Long summaryCount,
@JsonProperty("created_at") OffsetDateTime createdAt,
@JsonProperty("updated_at") OffsetDateTime updatedAt,
@@ -46,7 +45,6 @@ public record SessionWorkspacesGetWorkspaceResultWorkspace(
@JsonProperty("mc_task_id") String mcTaskId,
@JsonProperty("mc_session_id") String mcSessionId,
@JsonProperty("mc_last_event_id") String mcLastEventId,
- @JsonProperty("session_sync_level") SessionWorkspacesGetWorkspaceResultWorkspaceSessionSyncLevel sessionSyncLevel,
@JsonProperty("chronicle_sync_dismissed") Boolean chronicleSyncDismissed
) {
@@ -68,26 +66,5 @@ public static SessionWorkspacesGetWorkspaceResultWorkspaceHostType fromValue(Str
throw new IllegalArgumentException("Unknown SessionWorkspacesGetWorkspaceResultWorkspaceHostType value: " + value);
}
}
-
- public enum SessionWorkspacesGetWorkspaceResultWorkspaceSessionSyncLevel {
- /** The {@code local} variant. */
- LOCAL("local"),
- /** The {@code user} variant. */
- USER("user"),
- /** The {@code repo_and_user} variant. */
- REPO_AND_USER("repo_and_user");
-
- private final String value;
- SessionWorkspacesGetWorkspaceResultWorkspaceSessionSyncLevel(String value) { this.value = value; }
- @com.fasterxml.jackson.annotation.JsonValue
- public String getValue() { return value; }
- @com.fasterxml.jackson.annotation.JsonCreator
- public static SessionWorkspacesGetWorkspaceResultWorkspaceSessionSyncLevel fromValue(String value) {
- for (SessionWorkspacesGetWorkspaceResultWorkspaceSessionSyncLevel v : values()) {
- if (v.value.equals(value)) return v;
- }
- throw new IllegalArgumentException("Unknown SessionWorkspacesGetWorkspaceResultWorkspaceSessionSyncLevel value: " + value);
- }
- }
}
}
From 82dc28827e584b32dcf2b1901247d793088ee8a4 Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Mon, 11 May 2026 14:48:08 -0400
Subject: [PATCH 011/135] Recompile lock file after gh-aw framework update
Address review comment: pull-requests:write is rejected by strict mode.
The close-pull-request safe-output uses GH_AW_AGENT_TOKEN (PAT), not
GITHUB_TOKEN, so pull-requests:read is sufficient. Validated by test
run 25686653754 which successfully closed 3 PRs.
---
.github/aw/actions-lock.json | 16 +-
.../workflows/reference-impl-sync.lock.yml | 277 +++++++++++++-----
2 files changed, 208 insertions(+), 85 deletions(-)
diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json
index 8bf544f4d1..6a6fa53d9f 100644
--- a/.github/aw/actions-lock.json
+++ b/.github/aw/actions-lock.json
@@ -20,6 +20,11 @@
"version": "v9",
"sha": "373c709c69115d41ff229c7e5df9f8788daa9553"
},
+ "actions/github-script@v9.0.0": {
+ "repo": "actions/github-script",
+ "version": "v9.0.0",
+ "sha": "3a2844b7e9c422d3c10d287c895573f7108da1b3"
+ },
"actions/setup-java@v4": {
"repo": "actions/setup-java",
"version": "v4",
@@ -35,15 +40,10 @@
"version": "v7.0.1",
"sha": "043fb46d1a93c77aae656e7c1c64a875d1fc6a0a"
},
- "github/gh-aw-actions/setup-cli@v0.68.3": {
- "repo": "github/gh-aw-actions/setup-cli",
- "version": "v0.68.3",
- "sha": "ba90f2186d7ad780ec640f364005fa24e797b360"
- },
- "github/gh-aw-actions/setup@v0.68.3": {
+ "github/gh-aw-actions/setup@v0.71.5": {
"repo": "github/gh-aw-actions/setup",
- "version": "v0.68.3",
- "sha": "ba90f2186d7ad780ec640f364005fa24e797b360"
+ "version": "v0.71.5",
+ "sha": "b8068426813005612b960b5ab0b8bd2c27142323"
},
"github/gh-aw/actions/setup@v0.51.6": {
"repo": "github/gh-aw/actions/setup",
diff --git a/.github/workflows/reference-impl-sync.lock.yml b/.github/workflows/reference-impl-sync.lock.yml
index 50ed7d8873..72ae7105b7 100644
--- a/.github/workflows/reference-impl-sync.lock.yml
+++ b/.github/workflows/reference-impl-sync.lock.yml
@@ -1,5 +1,5 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"54b1896209b363ceadbcb123b6c46dbbcc0118d9140313360c341b09d03bbb96","compiler_version":"v0.68.3","strict":true,"agent_id":"copilot"}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_AGENT_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"ba90f2186d7ad780ec640f364005fa24e797b360","version":"v0.68.3"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.19"},{"image":"ghcr.io/github/github-mcp-server:v0.32.0"},{"image":"node:lts-alpine"}]}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"54b1896209b363ceadbcb123b6c46dbbcc0118d9140313360c341b09d03bbb96","compiler_version":"v0.71.5","strict":true,"agent_id":"copilot"}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_AGENT_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"b8068426813005612b960b5ab0b8bd2c27142323","version":"v0.71.5"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.40","digest":"sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40","digest":"sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.40","digest":"sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
# ___ _ _
# / _ \ | | (_)
# | |_| | __ _ ___ _ __ | |_ _ ___
@@ -14,7 +14,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
-# This file was automatically generated by gh-aw (v0.68.3). DO NOT EDIT.
+# This file was automatically generated by gh-aw (v0.71.5). DO NOT EDIT.
#
# To update this file, edit the corresponding .md file and run:
# gh aw compile
@@ -36,21 +36,23 @@
# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+# - github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.25.20
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20
-# - ghcr.io/github/gh-aw-firewall/squid:0.25.20
-# - ghcr.io/github/gh-aw-mcpg:v0.2.19
-# - ghcr.io/github/github-mcp-server:v0.32.0
-# - node:lts-alpine
+# - ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280
+# - ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51
+# - ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c
+# - ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959
+# - node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
name: "Reference Implementation Sync"
"on":
schedule:
- - cron: "47 22 * * *"
+ - cron: "10 16 * * *"
# Friendly format: daily (scattered)
workflow_dispatch:
inputs:
@@ -76,6 +78,7 @@ jobs:
outputs:
comment_id: ""
comment_repo: ""
+ engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
model: ${{ steps.generate_aw_info.outputs.model }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
@@ -84,30 +87,34 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Generate agentic run info
id: generate_aw_info
env:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
- GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }}
- GH_AW_INFO_VERSION: "1.0.21"
- GH_AW_INFO_AGENT_VERSION: "1.0.21"
- GH_AW_INFO_CLI_VERSION: "v0.68.3"
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_INFO_VERSION: "1.0.40"
+ GH_AW_INFO_AGENT_VERSION: "1.0.40"
+ GH_AW_INFO_CLI_VERSION: "v0.71.5"
GH_AW_INFO_WORKFLOW_NAME: "Reference Implementation Sync"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.25.20"
+ GH_AW_INFO_AWF_VERSION: "v0.25.40"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -126,11 +133,23 @@ jobs:
sparse-checkout: |
.github
.agents
+ .claude
+ .codex
+ .crush
+ .gemini
+ .opencode
+ .pi
sparse-checkout-cone-mode: true
fetch-depth: 1
+ - name: Save agent config folders for base branch restoration
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
- name: Check workflow lock file
id: check-lock-file
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_WORKFLOW_FILE: "reference-impl-sync.lock.yml"
GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
@@ -141,9 +160,9 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
await main();
- name: Check compile-agentic version
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.68.3"
+ GH_AW_COMPILED_VERSION: "v0.71.5"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -177,6 +196,9 @@ jobs:
Tools: add_comment(max:10), create_issue, close_issue(max:10), close_pull_request(max:10), assign_to_agent, missing_tool, missing_data, noop
+ GH_AW_PROMPT_c9d6e485c3f68bea_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
+ cat << 'GH_AW_PROMPT_c9d6e485c3f68bea_EOF'
The following GitHub context information is available for this workflow:
{{#if __GH_AW_GITHUB_ACTOR__ }}
@@ -213,9 +235,10 @@ jobs:
GH_AW_PROMPT_c9d6e485c3f68bea_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_ENGINE_ID: "copilot"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -223,7 +246,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
await main();
- name: Substitute placeholders
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -234,6 +257,7 @@ jobs:
GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -252,7 +276,8 @@ jobs:
GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
- GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE
+ GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
}
});
- name: Validate prompt placeholders
@@ -270,10 +295,12 @@ jobs:
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: activation
+ include-hidden-files: true
path: |
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/aw-prompts/prompt.txt
/tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/base
if-no-files-found: ignore
retention-days: 1
@@ -309,11 +336,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Set runtime paths
id: set-runtime-paths
run: |
@@ -349,7 +380,7 @@ jobs:
id: checkout-pr
if: |
github.event.pull_request || github.event.issue.pull_request
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
with:
@@ -360,11 +391,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.40
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.20
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.40
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -375,9 +406,20 @@ jobs:
script: |
const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
await determineAutomaticLockdown(github, context, core);
+ - name: Download activation artifact
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: activation
+ path: /tmp/gh-aw
+ - name: Restore agent config folders from base branch
+ if: steps.checkout-pr.outcome == 'success'
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
- name: Download container images
- run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.20 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20 ghcr.io/github/gh-aw-firewall/squid:0.25.20 ghcr.io/github/gh-aw-mcpg:v0.2.19 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
- - name: Write Safe Outputs Config
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280 ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51 ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
+ - name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
@@ -385,7 +427,7 @@ jobs:
cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_06a3a494957bf1f1_EOF'
{"add_comment":{"max":10,"target":"*"},"assign_to_agent":{"max":1,"model":"claude-opus-4.6","name":"copilot","target":"*"},"close_issue":{"max":10,"required_labels":["reference-impl-sync"],"target":"*"},"close_pull_request":{"max":10,"target":"*"},"create_issue":{"expires":144,"labels":["reference-impl-sync"],"max":1,"title_prefix":"[reference-impl-sync] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
GH_AW_SAFE_OUTPUTS_CONFIG_06a3a494957bf1f1_EOF
- - name: Write Safe Outputs Tools
+ - name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
{
@@ -591,7 +633,7 @@ jobs:
}
}
}
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -649,11 +691,12 @@ jobs:
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
- mkdir -p /tmp/gh-aw/mcp-config
+ mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
# Export gateway environment variables for MCP config and gateway script
- export MCP_GATEWAY_PORT="80"
+ export MCP_GATEWAY_PORT="8080"
export MCP_GATEWAY_DOMAIN="host.docker.internal"
+ export MCP_GATEWAY_HOST_DOMAIN="localhost"
MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
echo "::add-mask::${MCP_GATEWAY_API_KEY}"
export MCP_GATEWAY_API_KEY
@@ -663,15 +706,19 @@ jobs:
export DEBUG="*"
export GH_AW_ENGINE="copilot"
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.19'
+ MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
+ MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
+ DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 2>/dev/null || echo '0')
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.6'
mkdir -p /home/runner/.copilot
- cat << GH_AW_MCP_CONFIG_03f014fbed5a3560_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh"
+ GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
+ cat << GH_AW_MCP_CONFIG_03f014fbed5a3560_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v0.32.0",
+ "container": "ghcr.io/github/github-mcp-server:v1.0.3",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -708,14 +755,27 @@ jobs:
}
}
GH_AW_MCP_CONFIG_03f014fbed5a3560_EOF
- - name: Download activation artifact
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ - name: Mount MCP servers as CLIs
+ id: mount-mcp-clis
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+ MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
- name: activation
- path: /tmp/gh-aw
- - name: Clean git credentials
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs');
+ await main();
+ - name: Clean credentials
continue-on-error: true
run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
+ - name: Audit pre-agent workspace
+ id: pre_agent_audit
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
- name: Execute GitHub Copilot CLI
id: agentic_execution
# Copilot CLI tool arguments (sorted):
@@ -723,21 +783,26 @@ jobs:
run: |
set -o pipefail
touch /tmp/gh-aw/agent-step-summary.md
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
+ export GH_AW_NODE_BIN
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.40/awf-config.schema.json","network":{"allowDomains":["*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","lfs.github.com","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"models":{"auto":["large"],"deep-research":["copilot/deep-research*","google/deep-research*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash"],"opus":["copilot/*opus*","anthropic/*opus*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"]}},"container":{"imageTag":"0.25.40,squid=sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51,agent=sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504,api-proxy=sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280,cli-proxy=sha256:3e7152911d4b4b7b97beef9d3d7d924ff7902227e86001ef3838fb728d5d514c"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
# shellcheck disable=SC1003
- sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \
- -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || echo node)"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_API_KEY: dummy-byok-key-for-offline-mode
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }}
GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
GH_AW_PHASE: agent
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_VERSION: v0.68.3
+ GH_AW_VERSION: v0.71.5
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
GITHUB_REF_NAME: ${{ github.ref_name }}
@@ -782,7 +847,7 @@ jobs:
bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID"
- name: Redact secrets in logs
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -808,7 +873,7 @@ jobs:
- name: Ingest agent output
id: collect_output
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
@@ -822,7 +887,7 @@ jobs:
await main();
- name: Parse agent logs for step summary
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
with:
@@ -834,7 +899,7 @@ jobs:
- name: Parse MCP Gateway logs for step summary
if: always()
id: parse-mcp-gateway
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -847,9 +912,9 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
- # Fix permissions on firewall logs so they can be uploaded as artifacts
+ # Fix permissions on firewall logs/audit dirs so they can be uploaded as artifacts
# AWF runs with sudo, creating files owned by root
- sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true
+ sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
@@ -859,13 +924,23 @@ jobs:
- name: Parse token usage for step summary
if: always()
continue-on-error: true
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
await main();
+ - name: Print AWF reflect summary
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs');
+ await main();
- name: Write agent output placeholder if missing
if: always()
run: |
@@ -885,14 +960,17 @@ jobs:
/tmp/gh-aw/mcp-logs/
/tmp/gh-aw/agent_usage.json
/tmp/gh-aw/agent-stdio.log
+ /tmp/gh-aw/pre-agent-audit.txt
/tmp/gh-aw/agent/
/tmp/gh-aw/github_rate_limits.jsonl
/tmp/gh-aw/safeoutputs.jsonl
/tmp/gh-aw/agent_output.json
/tmp/gh-aw/aw-*.patch
/tmp/gh-aw/aw-*.bundle
+ /tmp/gh-aw/awf-config.json
/tmp/gh-aw/sandbox/firewall/logs/
/tmp/gh-aw/sandbox/firewall/audit/
+ /tmp/gh-aw/sandbox/firewall/awf-reflect.json
if-no-files-found: ignore
conclusion:
@@ -921,11 +999,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
@@ -942,7 +1024,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Process no-op messages
id: noop
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_NOOP_MAX: "1"
@@ -959,7 +1041,7 @@ jobs:
await main();
- name: Log detection run
id: detection_runs
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_WORKFLOW_NAME: "Reference Implementation Sync"
@@ -975,7 +1057,7 @@ jobs:
await main();
- name: Record missing tool
id: missing_tool
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
@@ -989,7 +1071,7 @@ jobs:
await main();
- name: Record incomplete
id: report_incomplete
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
@@ -1004,13 +1086,14 @@ jobs:
- name: Handle agent failure
id: handle_agent_failure
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_WORKFLOW_NAME: "Reference Implementation Sync"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
GH_AW_WORKFLOW_ID: "reference-impl-sync"
+ GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168"
GH_AW_ENGINE_ID: "copilot"
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
@@ -1018,12 +1101,15 @@ jobs:
GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }}
+ GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
GH_AW_ASSIGNMENT_ERRORS: ${{ needs.safe_outputs.outputs.assign_to_agent_assignment_errors }}
GH_AW_ASSIGNMENT_ERROR_COUNT: ${{ needs.safe_outputs.outputs.assign_to_agent_assignment_error_count }}
GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+ GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
+ GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
GH_AW_TIMEOUT_MINUTES: "20"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -1049,11 +1135,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
@@ -1079,7 +1169,7 @@ jobs:
rm -rf /tmp/gh-aw/sandbox/firewall/logs
rm -rf /tmp/gh-aw/sandbox/firewall/audit
- name: Download container images
- run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.20 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20 ghcr.io/github/gh-aw-firewall/squid:0.25.20
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280 ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1094,10 +1184,10 @@ jobs:
echo "run_detection=false" >> "$GITHUB_OUTPUT"
echo "Detection skipped: no agent outputs or patches to analyze"
fi
- - name: Clear MCP configuration for detection
+ - name: Clear MCP Config for detection
if: always() && steps.detection_guard.outputs.run_detection == 'true'
run: |
- rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
+ rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
rm -f /home/runner/.copilot/mcp-config.json
rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
- name: Prepare threat detection files
@@ -1116,7 +1206,7 @@ jobs:
ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
- name: Setup threat detection
if: always() && steps.detection_guard.outputs.run_detection == 'true'
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
WORKFLOW_NAME: "Reference Implementation Sync"
WORKFLOW_DESCRIPTION: "Reference implementation sync workflow. Checks for new commits in the official\nCopilot SDK (github/copilot-sdk) and assigns to Copilot to port changes."
@@ -1132,33 +1222,44 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/threat-detection
touch /tmp/gh-aw/threat-detection/detection.log
+ - name: Setup Node.js
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version: '24'
+ package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.40
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.20
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.40
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ continue-on-error: true
id: detection_agentic_execution
# Copilot CLI tool arguments (sorted):
timeout-minutes: 20
run: |
set -o pipefail
touch /tmp/gh-aw/agent-step-summary.md
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
+ export GH_AW_NODE_BIN
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.40/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","host.docker.internal","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true},"container":{"imageTag":"0.25.40,squid=sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51,agent=sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504,api-proxy=sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280,cli-proxy=sha256:3e7152911d4b4b7b97beef9d3d7d924ff7902227e86001ef3838fb728d5d514c"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
# shellcheck disable=SC1003
- sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \
- -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || echo node)"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_API_KEY: dummy-byok-key-for-offline-mode
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || 'claude-sonnet-4.6' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
- GH_AW_VERSION: v0.68.3
+ GH_AW_VERSION: v0.71.5
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_SERVER_URL: ${{ github.server_url }}
@@ -1179,16 +1280,33 @@ jobs:
- name: Parse and conclude threat detection
id: detection_conclusion
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
with:
script: |
- const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
- setupGlobals(core, github, context, exec, io, getOctokit);
- const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
- await main();
+ try {
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
+ await main();
+ } catch (loadErr) {
+ const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false';
+ const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr));
+ core.error(msg);
+ core.setOutput('reason', 'parse_error');
+ if (continueOnError) {
+ core.warning('\u26A0\uFE0F ' + msg);
+ core.setOutput('conclusion', 'warning');
+ core.setOutput('success', 'false');
+ } else {
+ core.setOutput('conclusion', 'failure');
+ core.setOutput('success', 'false');
+ core.setFailed(msg);
+ }
+ }
safe_outputs:
needs:
@@ -1210,6 +1328,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
+ GH_AW_ENGINE_VERSION: "1.0.40"
GH_AW_WORKFLOW_ID: "reference-impl-sync"
GH_AW_WORKFLOW_NAME: "Reference Implementation Sync"
outputs:
@@ -1229,11 +1348,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
@@ -1259,7 +1382,7 @@ jobs:
echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
- name: Process Safe Outputs
id: process_safe_outputs
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
From cf023beed70bf091d1ce339416c075efa4b2b971 Mon Sep 17 00:00:00 2001
From: Bruno Borges
Date: Mon, 11 May 2026 16:28:51 -0400
Subject: [PATCH 012/135] fix version
---
jbang-example.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jbang-example.java b/jbang-example.java
index 1609db64cc..2cf75dc869 100644
--- a/jbang-example.java
+++ b/jbang-example.java
@@ -1,5 +1,5 @@
///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.SessionUsageInfoEvent;
From c1b6891bfd6d85d9ea25dbe98a742720baa54d32 Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Mon, 11 May 2026 17:02:27 -0400
Subject: [PATCH 013/135] Keep labels constraint; add --label dependencies to
PR creation
Instead of removing the labels:[dependencies] safety constraint from the
codegen-agentic-fix safe-output, fix the root cause: the PR created by
update-copilot-dependency.yml was missing the label. Now the PR is
created with --label dependencies, matching the safe-output constraint.
Recompile codegen-agentic-fix.lock.yml.
---
.../workflows/codegen-agentic-fix.lock.yml | 301 ++++++++++++------
.github/workflows/codegen-agentic-fix.md | 1 +
.../workflows/update-copilot-dependency.yml | 1 +
3 files changed, 214 insertions(+), 89 deletions(-)
diff --git a/.github/workflows/codegen-agentic-fix.lock.yml b/.github/workflows/codegen-agentic-fix.lock.yml
index 9a75a41537..f5ab2030d5 100644
--- a/.github/workflows/codegen-agentic-fix.lock.yml
+++ b/.github/workflows/codegen-agentic-fix.lock.yml
@@ -1,5 +1,5 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"22995cb1fca1a0e3af19ac8bfc2ab7a114e72bb33cd7bf180b818a28682678ae","compiler_version":"v0.68.3","strict":true,"agent_id":"copilot"}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"ba90f2186d7ad780ec640f364005fa24e797b360","version":"v0.68.3"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.19"},{"image":"ghcr.io/github/github-mcp-server:v0.32.0"},{"image":"node:lts-alpine"}]}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"70880e5fb9ec78342cf56974b2414d8cf0a516533e201e437835164543ef58c0","compiler_version":"v0.71.5","strict":true,"agent_id":"copilot"}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"b8068426813005612b960b5ab0b8bd2c27142323","version":"v0.71.5"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.40","digest":"sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40","digest":"sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.40","digest":"sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
# ___ _ _
# / _ \ | | (_)
# | |_| | __ _ ___ _ __ | |_ _ ___
@@ -14,7 +14,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
-# This file was automatically generated by gh-aw (v0.68.3). DO NOT EDIT.
+# This file was automatically generated by gh-aw (v0.71.5). DO NOT EDIT.
#
# To update this file, edit the corresponding .md file and run:
# gh aw compile
@@ -36,16 +36,18 @@
# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+# - github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.25.20
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20
-# - ghcr.io/github/gh-aw-firewall/squid:0.25.20
-# - ghcr.io/github/gh-aw-mcpg:v0.2.19
-# - ghcr.io/github/github-mcp-server:v0.32.0
-# - node:lts-alpine
+# - ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280
+# - ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51
+# - ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c
+# - ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959
+# - node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
name: "Codegen Agentic Fix"
"on":
@@ -85,6 +87,7 @@ jobs:
outputs:
comment_id: ""
comment_repo: ""
+ engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
model: ${{ steps.generate_aw_info.outputs.model }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
@@ -93,30 +96,34 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Codegen Agentic Fix"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/codegen-agentic-fix.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Generate agentic run info
id: generate_aw_info
env:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
- GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }}
- GH_AW_INFO_VERSION: "1.0.21"
- GH_AW_INFO_AGENT_VERSION: "1.0.21"
- GH_AW_INFO_CLI_VERSION: "v0.68.3"
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_INFO_VERSION: "1.0.40"
+ GH_AW_INFO_AGENT_VERSION: "1.0.40"
+ GH_AW_INFO_CLI_VERSION: "v0.71.5"
GH_AW_INFO_WORKFLOW_NAME: "Codegen Agentic Fix"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.25.20"
+ GH_AW_INFO_AWF_VERSION: "v0.25.40"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -135,11 +142,23 @@ jobs:
sparse-checkout: |
.github
.agents
+ .claude
+ .codex
+ .crush
+ .gemini
+ .opencode
+ .pi
sparse-checkout-cone-mode: true
fetch-depth: 1
+ - name: Save agent config folders for base branch restoration
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ # poutine:ignore untrusted_checkout_exec
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
- name: Check workflow lock file
id: check-lock-file
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_WORKFLOW_FILE: "codegen-agentic-fix.lock.yml"
GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
@@ -150,9 +169,9 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
await main();
- name: Check compile-agentic version
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.68.3"
+ GH_AW_COMPILED_VERSION: "v0.71.5"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -178,20 +197,23 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_0adaf9d66984c7fc_EOF'
+ cat << 'GH_AW_PROMPT_d94a435f1fbdc38f_EOF'
- GH_AW_PROMPT_0adaf9d66984c7fc_EOF
+ GH_AW_PROMPT_d94a435f1fbdc38f_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_0adaf9d66984c7fc_EOF'
+ cat << 'GH_AW_PROMPT_d94a435f1fbdc38f_EOF'
Tools: add_comment(max:5), push_to_pull_request_branch, missing_tool, missing_data, noop
- GH_AW_PROMPT_0adaf9d66984c7fc_EOF
+ GH_AW_PROMPT_d94a435f1fbdc38f_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md"
- cat << 'GH_AW_PROMPT_0adaf9d66984c7fc_EOF'
+ cat << 'GH_AW_PROMPT_d94a435f1fbdc38f_EOF'
+ GH_AW_PROMPT_d94a435f1fbdc38f_EOF
+ cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
+ cat << 'GH_AW_PROMPT_d94a435f1fbdc38f_EOF'
The following GitHub context information is available for this workflow:
{{#if __GH_AW_GITHUB_ACTOR__ }}
@@ -220,17 +242,18 @@ jobs:
{{/if}}
- GH_AW_PROMPT_0adaf9d66984c7fc_EOF
+ GH_AW_PROMPT_d94a435f1fbdc38f_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_0adaf9d66984c7fc_EOF'
+ cat << 'GH_AW_PROMPT_d94a435f1fbdc38f_EOF'
{{#runtime-import .github/workflows/codegen-agentic-fix.md}}
- GH_AW_PROMPT_0adaf9d66984c7fc_EOF
+ GH_AW_PROMPT_d94a435f1fbdc38f_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_ENGINE_ID: "copilot"
GH_AW_INPUTS_BRANCH: ${{ inputs.branch }}
GH_AW_INPUTS_ERROR_SUMMARY: ${{ inputs.error_summary }}
GH_AW_INPUTS_PR_NUMBER: ${{ inputs.pr_number }}
@@ -241,7 +264,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
await main();
- name: Substitute placeholders
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_GITHUB_ACTOR: ${{ github.actor }}
@@ -255,6 +278,7 @@ jobs:
GH_AW_INPUTS_BRANCH: ${{ inputs.branch }}
GH_AW_INPUTS_ERROR_SUMMARY: ${{ inputs.error_summary }}
GH_AW_INPUTS_PR_NUMBER: ${{ inputs.pr_number }}
+ GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -276,7 +300,8 @@ jobs:
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
GH_AW_INPUTS_BRANCH: process.env.GH_AW_INPUTS_BRANCH,
GH_AW_INPUTS_ERROR_SUMMARY: process.env.GH_AW_INPUTS_ERROR_SUMMARY,
- GH_AW_INPUTS_PR_NUMBER: process.env.GH_AW_INPUTS_PR_NUMBER
+ GH_AW_INPUTS_PR_NUMBER: process.env.GH_AW_INPUTS_PR_NUMBER,
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
}
});
- name: Validate prompt placeholders
@@ -294,10 +319,12 @@ jobs:
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: activation
+ include-hidden-files: true
path: |
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/aw-prompts/prompt.txt
/tmp/gh-aw/github_rate_limits.jsonl
+ /tmp/gh-aw/base
if-no-files-found: ignore
retention-days: 1
@@ -329,11 +356,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Codegen Agentic Fix"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/codegen-agentic-fix.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Set runtime paths
id: set-runtime-paths
run: |
@@ -369,7 +400,7 @@ jobs:
id: checkout-pr
if: |
github.event.pull_request || github.event.issue.pull_request
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
with:
@@ -380,11 +411,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.40
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.20
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.40
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -395,17 +426,28 @@ jobs:
script: |
const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
await determineAutomaticLockdown(github, context, core);
+ - name: Download activation artifact
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ with:
+ name: activation
+ path: /tmp/gh-aw
+ - name: Restore agent config folders from base branch
+ if: steps.checkout-pr.outcome == 'success'
+ env:
+ GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi"
+ GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
- name: Download container images
- run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.20 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20 ghcr.io/github/gh-aw-firewall/squid:0.25.20 ghcr.io/github/gh-aw-mcpg:v0.2.19 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
- - name: Write Safe Outputs Config
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280 ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51 ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
+ - name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_3142db99d39a4285_EOF'
- {"add_comment":{"max":5,"target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"push_to_pull_request_branch":{"if_no_changes":"warn","max_patch_size":1024,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS"],"protected_path_prefixes":[".github/",".agents/"],"target":"*"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_3142db99d39a4285_EOF
- - name: Write Safe Outputs Tools
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_b6e7bb90508de076_EOF'
+ {"add_comment":{"max":5,"target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"push_to_pull_request_branch":{"if_no_changes":"warn","labels":["dependencies"],"max_patch_size":1024,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"target":"*"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_b6e7bb90508de076_EOF
+ - name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
{
@@ -533,7 +575,7 @@ jobs:
}
}
}
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -591,11 +633,12 @@ jobs:
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
- mkdir -p /tmp/gh-aw/mcp-config
+ mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
# Export gateway environment variables for MCP config and gateway script
- export MCP_GATEWAY_PORT="80"
+ export MCP_GATEWAY_PORT="8080"
export MCP_GATEWAY_DOMAIN="host.docker.internal"
+ export MCP_GATEWAY_HOST_DOMAIN="localhost"
MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
echo "::add-mask::${MCP_GATEWAY_API_KEY}"
export MCP_GATEWAY_API_KEY
@@ -605,15 +648,19 @@ jobs:
export DEBUG="*"
export GH_AW_ENGINE="copilot"
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.19'
+ MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
+ MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
+ DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 2>/dev/null || echo '0')
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.6'
mkdir -p /home/runner/.copilot
- cat << GH_AW_MCP_CONFIG_47ddd2dcd9c136d7_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh"
+ GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
+ cat << GH_AW_MCP_CONFIG_f8f308e27510535f_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v0.32.0",
+ "container": "ghcr.io/github/github-mcp-server:v1.0.3",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -649,15 +696,28 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_47ddd2dcd9c136d7_EOF
- - name: Download activation artifact
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ GH_AW_MCP_CONFIG_f8f308e27510535f_EOF
+ - name: Mount MCP servers as CLIs
+ id: mount-mcp-clis
+ continue-on-error: true
+ env:
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
+ MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
- name: activation
- path: /tmp/gh-aw
- - name: Clean git credentials
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs');
+ await main();
+ - name: Clean credentials
continue-on-error: true
run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
+ - name: Audit pre-agent workspace
+ id: pre_agent_audit
+ continue-on-error: true
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
- name: Execute GitHub Copilot CLI
id: agentic_execution
# Copilot CLI tool arguments (sorted):
@@ -665,21 +725,26 @@ jobs:
run: |
set -o pipefail
touch /tmp/gh-aw/agent-step-summary.md
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
+ export GH_AW_NODE_BIN
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.40/awf-config.schema.json","network":{"allowDomains":["*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","lfs.github.com","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"models":{"auto":["large"],"deep-research":["copilot/deep-research*","google/deep-research*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash"],"opus":["copilot/*opus*","anthropic/*opus*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"]}},"container":{"imageTag":"0.25.40,squid=sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51,agent=sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504,api-proxy=sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280,cli-proxy=sha256:3e7152911d4b4b7b97beef9d3d7d924ff7902227e86001ef3838fb728d5d514c"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
# shellcheck disable=SC1003
- sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \
- -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || echo node)"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_API_KEY: dummy-byok-key-for-offline-mode
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }}
GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
GH_AW_PHASE: agent
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_VERSION: v0.68.3
+ GH_AW_VERSION: v0.71.5
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
GITHUB_REF_NAME: ${{ github.ref_name }}
@@ -724,7 +789,7 @@ jobs:
bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID"
- name: Redact secrets in logs
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -750,7 +815,7 @@ jobs:
- name: Ingest agent output
id: collect_output
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
@@ -764,7 +829,7 @@ jobs:
await main();
- name: Parse agent logs for step summary
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
with:
@@ -776,7 +841,7 @@ jobs:
- name: Parse MCP Gateway logs for step summary
if: always()
id: parse-mcp-gateway
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -789,9 +854,9 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
- # Fix permissions on firewall logs so they can be uploaded as artifacts
+ # Fix permissions on firewall logs/audit dirs so they can be uploaded as artifacts
# AWF runs with sudo, creating files owned by root
- sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true
+ sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
@@ -801,13 +866,23 @@ jobs:
- name: Parse token usage for step summary
if: always()
continue-on-error: true
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
await main();
+ - name: Print AWF reflect summary
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs');
+ await main();
- name: Write agent output placeholder if missing
if: always()
run: |
@@ -827,14 +902,17 @@ jobs:
/tmp/gh-aw/mcp-logs/
/tmp/gh-aw/agent_usage.json
/tmp/gh-aw/agent-stdio.log
+ /tmp/gh-aw/pre-agent-audit.txt
/tmp/gh-aw/agent/
/tmp/gh-aw/github_rate_limits.jsonl
/tmp/gh-aw/safeoutputs.jsonl
/tmp/gh-aw/agent_output.json
/tmp/gh-aw/aw-*.patch
/tmp/gh-aw/aw-*.bundle
+ /tmp/gh-aw/awf-config.json
/tmp/gh-aw/sandbox/firewall/logs/
/tmp/gh-aw/sandbox/firewall/audit/
+ /tmp/gh-aw/sandbox/firewall/awf-reflect.json
if-no-files-found: ignore
conclusion:
@@ -863,11 +941,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Codegen Agentic Fix"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/codegen-agentic-fix.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
@@ -884,7 +966,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Process no-op messages
id: noop
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_NOOP_MAX: "1"
@@ -901,7 +983,7 @@ jobs:
await main();
- name: Log detection run
id: detection_runs
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_WORKFLOW_NAME: "Codegen Agentic Fix"
@@ -917,7 +999,7 @@ jobs:
await main();
- name: Record missing tool
id: missing_tool
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
@@ -931,7 +1013,7 @@ jobs:
await main();
- name: Record incomplete
id: report_incomplete
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
@@ -946,13 +1028,14 @@ jobs:
- name: Handle agent failure
id: handle_agent_failure
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_WORKFLOW_NAME: "Codegen Agentic Fix"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
GH_AW_WORKFLOW_ID: "codegen-agentic-fix"
+ GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168"
GH_AW_ENGINE_ID: "copilot"
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
@@ -960,12 +1043,15 @@ jobs:
GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }}
+ GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }}
GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
+ GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
+ GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
GH_AW_TIMEOUT_MINUTES: "60"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -991,11 +1077,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Codegen Agentic Fix"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/codegen-agentic-fix.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
@@ -1021,7 +1111,7 @@ jobs:
rm -rf /tmp/gh-aw/sandbox/firewall/logs
rm -rf /tmp/gh-aw/sandbox/firewall/audit
- name: Download container images
- run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.20 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20 ghcr.io/github/gh-aw-firewall/squid:0.25.20
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280 ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1036,10 +1126,10 @@ jobs:
echo "run_detection=false" >> "$GITHUB_OUTPUT"
echo "Detection skipped: no agent outputs or patches to analyze"
fi
- - name: Clear MCP configuration for detection
+ - name: Clear MCP Config for detection
if: always() && steps.detection_guard.outputs.run_detection == 'true'
run: |
- rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
+ rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
rm -f /home/runner/.copilot/mcp-config.json
rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
- name: Prepare threat detection files
@@ -1058,7 +1148,7 @@ jobs:
ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
- name: Setup threat detection
if: always() && steps.detection_guard.outputs.run_detection == 'true'
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
WORKFLOW_NAME: "Codegen Agentic Fix"
WORKFLOW_DESCRIPTION: "Agentic fix for codegen-related build/test failures. Invoked when\nmvn verify fails after code generation changes."
@@ -1074,33 +1164,44 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/threat-detection
touch /tmp/gh-aw/threat-detection/detection.log
+ - name: Setup Node.js
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ with:
+ node-version: '24'
+ package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.40
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.20
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.40
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
+ continue-on-error: true
id: detection_agentic_execution
# Copilot CLI tool arguments (sorted):
timeout-minutes: 20
run: |
set -o pipefail
touch /tmp/gh-aw/agent-step-summary.md
+ GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
+ export GH_AW_NODE_BIN
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.40/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","host.docker.internal","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true},"container":{"imageTag":"0.25.40,squid=sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51,agent=sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504,api-proxy=sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280,cli-proxy=sha256:3e7152911d4b4b7b97beef9d3d7d924ff7902227e86001ef3838fb728d5d514c"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
# shellcheck disable=SC1003
- sudo -E awf --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --allow-domains api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,telemetry.enterprise.githubcopilot.com --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.20 --skip-pull --enable-api-proxy \
- -- /bin/bash -c 'node ${RUNNER_TEMP}/gh-aw/actions/copilot_driver.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || echo node)"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
+ COPILOT_API_KEY: dummy-byok-key-for-offline-mode
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || 'claude-sonnet-4.6' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
- GH_AW_VERSION: v0.68.3
+ GH_AW_VERSION: v0.71.5
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
+ GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_SERVER_URL: ${{ github.server_url }}
@@ -1121,16 +1222,33 @@ jobs:
- name: Parse and conclude threat detection
id: detection_conclusion
if: always()
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
with:
script: |
- const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
- setupGlobals(core, github, context, exec, io, getOctokit);
- const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
- await main();
+ try {
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
+ await main();
+ } catch (loadErr) {
+ const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false';
+ const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr));
+ core.error(msg);
+ core.setOutput('reason', 'parse_error');
+ if (continueOnError) {
+ core.warning('\u26A0\uFE0F ' + msg);
+ core.setOutput('conclusion', 'warning');
+ core.setOutput('success', 'false');
+ } else {
+ core.setOutput('conclusion', 'failure');
+ core.setOutput('success', 'false');
+ core.setFailed(msg);
+ }
+ }
safe_outputs:
needs:
@@ -1152,6 +1270,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
+ GH_AW_ENGINE_VERSION: "1.0.40"
GH_AW_WORKFLOW_ID: "codegen-agentic-fix"
GH_AW_WORKFLOW_NAME: "Codegen Agentic Fix"
outputs:
@@ -1168,11 +1287,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@ba90f2186d7ad780ec640f364005fa24e797b360 # v0.68.3
+ uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Codegen Agentic Fix"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/codegen-agentic-fix.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.40"
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
@@ -1226,13 +1349,13 @@ jobs:
echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
- name: Process Safe Outputs
id: process_safe_outputs
- uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":5,\"target\":\"*\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"push_to_pull_request_branch\":{\"if_no_changes\":\"warn\",\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"target\":\"*\"},\"report_incomplete\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":5,\"target\":\"*\"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"push_to_pull_request_branch\":{\"if_no_changes\":\"warn\",\"labels\":[\"dependencies\"],\"max_patch_size\":1024,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"target\":\"*\"},\"report_incomplete\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/codegen-agentic-fix.md b/.github/workflows/codegen-agentic-fix.md
index ea6913f8d3..b4aa0a8f20 100644
--- a/.github/workflows/codegen-agentic-fix.md
+++ b/.github/workflows/codegen-agentic-fix.md
@@ -37,6 +37,7 @@ tools:
safe-outputs:
push-to-pull-request-branch:
target: "*"
+ labels: [dependencies]
add-comment:
target: "*"
max: 5
diff --git a/.github/workflows/update-copilot-dependency.yml b/.github/workflows/update-copilot-dependency.yml
index f7faee073a..854661d5bd 100644
--- a/.github/workflows/update-copilot-dependency.yml
+++ b/.github/workflows/update-copilot-dependency.yml
@@ -157,6 +157,7 @@ jobs:
- Re-ran Java code generator (\`scripts/codegen\`)
> Created by the **Update @github/copilot Dependency** workflow." \
+ --label dependencies \
--base main \
--head "$BRANCH" \
| grep -oE '[0-9]+$' || gh pr view "$BRANCH" --json number --jq .number)
From 2a3e7a564d92bf6aede5a98b880b7b999b0b0fb9 Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Mon, 11 May 2026 16:00:41 -0700
Subject: [PATCH 014/135] Centralize `requestId` parsing to fix
`NumberFormatException` risks across all RPC handlers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Prompted by github-code-quality review comments on PR #185
(https://github.com/github/copilot-sdk-java/pull/185#discussion_r3221146107).
The bot flagged four instances of uncaught `NumberFormatException` from
`Long.parseLong(requestId)` in the new `handleExitPlanModeRequest` and
`handleAutoModeSwitchRequest` handlers. The recommended fix was to parse
`requestId` once, catch `NumberFormatException`, and reuse the parsed `long`.
Assessment: The `NumberFormatException` comments (r3221146107, r3221146111,
r3221146120, r3221146133) are fully addressed and exceeded — the fix
applies the pattern to ALL seven handlers in the class, not just the two
new ones. A shared `parseRequestId(String, String)` utility method replaces
both the flagged inline calls and an existing ad-hoc try/catch in
`handleSystemMessageTransform`.
Two additional comments (r3221146142, r3221146149) flagged the `invocation`
parameter as unused in `AutoModeSwitchHandler` and `ExitPlanModeHandler`. These
are intentionally not addressed: the parameter is part of the consistent
two-arg handler API contract shared by all handler functional interfaces
in the SDK.
--- Per-file manifest ---
`src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java`
- Add `private static parseRequestId(String, String)` utility that wraps
`Long.parseLong` in a try/catch for `NumberFormatException`, logs on
failure, and returns `-1` as a sentinel.
- `handleToolCall`: parse `requestId` upfront via `parseRequestId`; replace
five `Long.parseLong(requestId)` call sites with `requestIdLong`.
- `handlePermissionRequest`: same pattern; replace three call sites.
- `handleUserInputRequest`: same pattern; replace three call sites.
- `handleExitPlanModeRequest`: same pattern; replace three call sites.
(Directly addresses the linked review comment.)
- `handleAutoModeSwitchRequest`: same pattern; replace three call sites.
- `handleHooksInvoke`: same pattern; replace three call sites.
- `handleSystemMessageTransform`: replace existing inline try/catch NFE
block with the shared `parseRequestId` call, removing duplicated logic.
`src/site/markdown/advanced.md`
- Add `.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)` to the
exit-plan-mode and auto-mode-switch code examples so they compile
and run without a missing-handler error.
`src/test/java/com/github/copilot/sdk/ModeHandlersTest.java`
- Parameterize `configureAuthenticatedUser(String testName)` to call
`ctx.configureForTest("mode_handlers", testName)` with per-test
snapshot names.
- `shouldInvokeAutoModeSwitchHandlerWhenRateLimited`: switch from
`sendAndWait` to `send`, add assertions on the returned `messageId`.
`src/test/java/com/github/copilot/sdk/SessionEventHandlingTest.java`
- Update `SessionStartEventData` constructor calls (arity 10 -> 11) for
new `detachedFromSpawningParentSessionId` field.
- Update `AssistantMessageEventData` constructor calls (arity 12 -> 15)
for new `anthropicAdvisorModel`, `turnId`, `parentToolCallId` fields;
adjust positional `null` arguments accordingly.
Signed-off-by: Ed Burns
---
.../copilot/sdk/RpcHandlerDispatcher.java | 97 +++++++++++++------
src/site/markdown/advanced.md | 2 +
.../github/copilot/sdk/ModeHandlersTest.java | 12 ++-
.../copilot/sdk/SessionEventHandlingTest.java | 8 +-
4 files changed, 81 insertions(+), 38 deletions(-)
diff --git a/src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java b/src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java
index 2f9657132c..1d76d8b88a 100644
--- a/src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java
+++ b/src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java
@@ -131,6 +131,10 @@ private void handleLifecycleEvent(JsonNode params) {
private void handleToolCall(JsonRpcClient rpc, String requestId, JsonNode params) {
runAsync(() -> {
+ final long requestIdLong = parseRequestId(requestId, "tool.call");
+ if (requestIdLong == -1) {
+ return;
+ }
try {
String sessionId = params.get("sessionId").asText();
String toolCallId = params.get("toolCallId").asText();
@@ -139,7 +143,7 @@ private void handleToolCall(JsonRpcClient rpc, String requestId, JsonNode params
CopilotSession session = sessions.get(sessionId);
if (session == null) {
- rpc.sendErrorResponse(Long.parseLong(requestId), -32602, "Unknown session " + sessionId);
+ rpc.sendErrorResponse(requestIdLong, -32602, "Unknown session " + sessionId);
return;
}
@@ -147,7 +151,7 @@ private void handleToolCall(JsonRpcClient rpc, String requestId, JsonNode params
if (tool == null || tool.handler() == null) {
var result = ToolResultObject.failure("Tool '" + toolName + "' is not supported.",
"tool '" + toolName + "' not supported");
- rpc.sendResponse(Long.parseLong(requestId), Map.of("result", result));
+ rpc.sendResponse(requestIdLong, Map.of("result", result));
return;
}
@@ -163,7 +167,7 @@ private void handleToolCall(JsonRpcClient rpc, String requestId, JsonNode params
toolResult = ToolResultObject
.success(result instanceof String s ? s : MAPPER.writeValueAsString(result));
}
- rpc.sendResponse(Long.parseLong(requestId), Map.of("result", toolResult));
+ rpc.sendResponse(requestIdLong, Map.of("result", toolResult));
} catch (Exception e) {
LOG.log(Level.SEVERE, "Error sending tool result", e);
}
@@ -172,7 +176,7 @@ private void handleToolCall(JsonRpcClient rpc, String requestId, JsonNode params
var result = ToolResultObject.failure(
"Invoking this tool produced an error. Detailed information is not available.",
ex.getMessage());
- rpc.sendResponse(Long.parseLong(requestId), Map.of("result", result));
+ rpc.sendResponse(requestIdLong, Map.of("result", result));
} catch (Exception e) {
LOG.log(Level.SEVERE, "Error sending tool error", e);
}
@@ -181,7 +185,7 @@ private void handleToolCall(JsonRpcClient rpc, String requestId, JsonNode params
} catch (Exception e) {
LOG.log(Level.SEVERE, "Error handling tool call", e);
try {
- rpc.sendErrorResponse(Long.parseLong(requestId), -32603, e.getMessage());
+ rpc.sendErrorResponse(requestIdLong, -32603, e.getMessage());
} catch (IOException ioe) {
LOG.log(Level.SEVERE, "Failed to send error response", ioe);
}
@@ -191,6 +195,10 @@ private void handleToolCall(JsonRpcClient rpc, String requestId, JsonNode params
private void handlePermissionRequest(JsonRpcClient rpc, String requestId, JsonNode params) {
runAsync(() -> {
+ final long requestIdLong = parseRequestId(requestId, "permission.request");
+ if (requestIdLong == -1) {
+ return;
+ }
try {
String sessionId = params.get("sessionId").asText();
JsonNode permissionRequest = params.get("permissionRequest");
@@ -199,7 +207,7 @@ private void handlePermissionRequest(JsonRpcClient rpc, String requestId, JsonNo
if (session == null) {
var result = new PermissionRequestResult()
.setKind(PermissionRequestResultKind.DENIED_COULD_NOT_REQUEST_FROM_USER);
- rpc.sendResponse(Long.parseLong(requestId), Map.of("result", result));
+ rpc.sendResponse(requestIdLong, Map.of("result", result));
return;
}
@@ -212,7 +220,7 @@ private void handlePermissionRequest(JsonRpcClient rpc, String requestId, JsonNo
throw new IllegalStateException(
"Permission handlers cannot return 'no-result' when connected to a protocol v2 server.");
}
- rpc.sendResponse(Long.parseLong(requestId), Map.of("result", result));
+ rpc.sendResponse(requestIdLong, Map.of("result", result));
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending permission result", e);
}
@@ -220,7 +228,7 @@ private void handlePermissionRequest(JsonRpcClient rpc, String requestId, JsonNo
try {
var result = new PermissionRequestResult()
.setKind(PermissionRequestResultKind.DENIED_COULD_NOT_REQUEST_FROM_USER);
- rpc.sendResponse(Long.parseLong(requestId), Map.of("result", result));
+ rpc.sendResponse(requestIdLong, Map.of("result", result));
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending permission denied", e);
}
@@ -235,6 +243,10 @@ private void handlePermissionRequest(JsonRpcClient rpc, String requestId, JsonNo
private void handleUserInputRequest(JsonRpcClient rpc, String requestId, JsonNode params) {
LOG.fine("Received userInput.request: " + params);
runAsync(() -> {
+ final long requestIdLong = parseRequestId(requestId, "userInput.request");
+ if (requestIdLong == -1) {
+ return;
+ }
try {
String sessionId = params.get("sessionId").asText();
String question = params.get("question").asText();
@@ -246,7 +258,7 @@ private void handleUserInputRequest(JsonRpcClient rpc, String requestId, JsonNod
LOG.fine("Found session: " + (session != null));
if (session == null) {
LOG.fine("Session not found, sending error");
- rpc.sendErrorResponse(Long.parseLong(requestId), -32602, "Unknown session " + sessionId);
+ rpc.sendErrorResponse(requestIdLong, -32602, "Unknown session " + sessionId);
return;
}
@@ -268,7 +280,7 @@ private void handleUserInputRequest(JsonRpcClient rpc, String requestId, JsonNod
String answer = response.getAnswer() != null ? response.getAnswer() : "";
LOG.fine("Sending userInput response: answer=" + answer + ", wasFreeform="
+ response.isWasFreeform());
- rpc.sendResponse(Long.parseLong(requestId),
+ rpc.sendResponse(requestIdLong,
Map.of("answer", answer, "wasFreeform", response.isWasFreeform()));
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending user input response", e);
@@ -276,8 +288,7 @@ private void handleUserInputRequest(JsonRpcClient rpc, String requestId, JsonNod
}).exceptionally(ex -> {
LOG.log(Level.WARNING, "User input handler exception", ex);
try {
- rpc.sendErrorResponse(Long.parseLong(requestId), -32603,
- "User input handler error: " + ex.getMessage());
+ rpc.sendErrorResponse(requestIdLong, -32603, "User input handler error: " + ex.getMessage());
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending user input error", e);
}
@@ -291,12 +302,16 @@ private void handleUserInputRequest(JsonRpcClient rpc, String requestId, JsonNod
private void handleExitPlanModeRequest(JsonRpcClient rpc, String requestId, JsonNode params) {
runAsync(() -> {
+ final long requestIdLong = parseRequestId(requestId, "exitPlanMode.request");
+ if (requestIdLong == -1) {
+ return;
+ }
try {
String sessionId = params.get("sessionId").asText();
CopilotSession session = sessions.get(sessionId);
if (session == null) {
- rpc.sendErrorResponse(Long.parseLong(requestId), -32602, "Unknown session " + sessionId);
+ rpc.sendErrorResponse(requestIdLong, -32602, "Unknown session " + sessionId);
return;
}
@@ -320,13 +335,13 @@ private void handleExitPlanModeRequest(JsonRpcClient rpc, String requestId, Json
session.handleExitPlanModeRequest(request).thenAccept(result -> {
try {
- rpc.sendResponse(Long.parseLong(requestId), MAPPER.valueToTree(result));
+ rpc.sendResponse(requestIdLong, MAPPER.valueToTree(result));
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending exit plan mode response", e);
}
}).exceptionally(ex -> {
try {
- rpc.sendErrorResponse(Long.parseLong(requestId), -32603,
+ rpc.sendErrorResponse(requestIdLong, -32603,
"Exit plan mode handler error: " + ex.getMessage());
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending exit plan mode error", e);
@@ -341,12 +356,16 @@ private void handleExitPlanModeRequest(JsonRpcClient rpc, String requestId, Json
private void handleAutoModeSwitchRequest(JsonRpcClient rpc, String requestId, JsonNode params) {
runAsync(() -> {
+ final long requestIdLong = parseRequestId(requestId, "autoModeSwitch.request");
+ if (requestIdLong == -1) {
+ return;
+ }
try {
String sessionId = params.get("sessionId").asText();
CopilotSession session = sessions.get(sessionId);
if (session == null) {
- rpc.sendErrorResponse(Long.parseLong(requestId), -32602, "Unknown session " + sessionId);
+ rpc.sendErrorResponse(requestIdLong, -32602, "Unknown session " + sessionId);
return;
}
@@ -360,13 +379,13 @@ private void handleAutoModeSwitchRequest(JsonRpcClient rpc, String requestId, Js
session.handleAutoModeSwitchRequest(request).thenAccept(response -> {
try {
- rpc.sendResponse(Long.parseLong(requestId), Map.of("response", response));
+ rpc.sendResponse(requestIdLong, Map.of("response", response));
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending auto mode switch response", e);
}
}).exceptionally(ex -> {
try {
- rpc.sendErrorResponse(Long.parseLong(requestId), -32603,
+ rpc.sendErrorResponse(requestIdLong, -32603,
"Auto mode switch handler error: " + ex.getMessage());
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending auto mode switch error", e);
@@ -381,6 +400,10 @@ private void handleAutoModeSwitchRequest(JsonRpcClient rpc, String requestId, Js
private void handleHooksInvoke(JsonRpcClient rpc, String requestId, JsonNode params) {
runAsync(() -> {
+ final long requestIdLong = parseRequestId(requestId, "hooks.invoke");
+ if (requestIdLong == -1) {
+ return;
+ }
try {
String sessionId = params.get("sessionId").asText();
String hookType = params.get("hookType").asText();
@@ -388,20 +411,19 @@ private void handleHooksInvoke(JsonRpcClient rpc, String requestId, JsonNode par
CopilotSession session = sessions.get(sessionId);
if (session == null) {
- rpc.sendErrorResponse(Long.parseLong(requestId), -32602, "Unknown session " + sessionId);
+ rpc.sendErrorResponse(requestIdLong, -32602, "Unknown session " + sessionId);
return;
}
session.handleHooksInvoke(hookType, input).thenAccept(output -> {
try {
- rpc.sendResponse(Long.parseLong(requestId), Collections.singletonMap("output", output));
+ rpc.sendResponse(requestIdLong, Collections.singletonMap("output", output));
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending hooks response", e);
}
}).exceptionally(ex -> {
try {
- rpc.sendErrorResponse(Long.parseLong(requestId), -32603,
- "Hooks handler error: " + ex.getMessage());
+ rpc.sendErrorResponse(requestIdLong, -32603, "Hooks handler error: " + ex.getMessage());
} catch (IOException e) {
LOG.log(Level.SEVERE, "Error sending hooks error", e);
}
@@ -424,15 +446,11 @@ interface LifecycleEventDispatcher {
private void handleSystemMessageTransform(JsonRpcClient rpc, String requestId, JsonNode params) {
runAsync(() -> {
+ final long requestIdLong = parseRequestId(requestId, "systemMessage.transform");
+ if (requestIdLong == -1) {
+ return;
+ }
try {
- final long requestIdLong;
- try {
- requestIdLong = Long.parseLong(requestId);
- } catch (NumberFormatException nfe) {
- LOG.log(Level.SEVERE, "Invalid requestId for systemMessage.transform: " + requestId, nfe);
- return;
- }
-
String sessionId = params.has("sessionId") ? params.get("sessionId").asText() : null;
JsonNode sections = params.get("sections");
@@ -462,6 +480,25 @@ private void handleSystemMessageTransform(JsonRpcClient rpc, String requestId, J
});
}
+ /**
+ * Parses a JSON-RPC request ID string into a {@code long}.
+ *
+ * @param requestId
+ * the request ID string received from the JSON-RPC layer
+ * @param methodName
+ * the RPC method name, used in the log message on failure
+ * @return the parsed request ID, or {@code -1} if the string is not a valid
+ * long
+ */
+ private static long parseRequestId(String requestId, String methodName) {
+ try {
+ return Long.parseLong(requestId);
+ } catch (NumberFormatException nfe) {
+ LOG.log(Level.SEVERE, "Invalid requestId for " + methodName + ": " + requestId, nfe);
+ return -1;
+ }
+ }
+
private void runAsync(Runnable task) {
try {
if (executor != null) {
diff --git a/src/site/markdown/advanced.md b/src/site/markdown/advanced.md
index 5c46313569..9b5d00c5ac 100644
--- a/src/site/markdown/advanced.md
+++ b/src/site/markdown/advanced.md
@@ -1280,6 +1280,7 @@ When the model finishes creating a plan and wants to transition out of plan mode
```java
var session = client.createSession(new SessionConfig()
+ .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
.setOnExitPlanMode((request, invocation) -> {
System.out.println("Plan summary: " + request.getSummary());
System.out.println("Available actions: " + request.getActions());
@@ -1308,6 +1309,7 @@ When the model encounters a rate limit or similar constraint, it may request to
```java
var session = client.createSession(new SessionConfig()
+ .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
.setOnAutoModeSwitch((request, invocation) -> {
System.out.println("Error: " + request.getErrorCode());
System.out.println("Retry after: " + request.getRetryAfterSeconds() + "s");
diff --git a/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java b/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java
index 1c2da5d094..fc0790be9b 100644
--- a/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java
+++ b/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java
@@ -59,7 +59,8 @@ private CopilotClient createAuthenticatedClient() {
return ctx.createClient(new CopilotClientOptions().setEnvironment(env));
}
- private void configureAuthenticatedUser() throws Exception {
+ private void configureAuthenticatedUser(String testName) throws Exception {
+ ctx.configureForTest("mode_handlers", testName);
ctx.setCopilotUserByToken(TOKEN, "mode-handler-user", "individual_pro", ctx.getProxyUrl(),
"https://localhost:1/telemetry", "mode-handler-tracking-id");
}
@@ -67,7 +68,7 @@ private void configureAuthenticatedUser() throws Exception {
@Test
void shouldInvokeExitPlanModeHandlerWhenModelUsesTool() throws Exception {
final String summary = "Greeting file implementation plan";
- configureAuthenticatedUser();
+ configureAuthenticatedUser("should_invoke_exit_plan_mode_handler_when_model_uses_tool");
var handlerCalled = new CompletableFuture();
@@ -118,7 +119,7 @@ void shouldInvokeExitPlanModeHandlerWhenModelUsesTool() throws Exception {
@Test
void shouldInvokeAutoModeSwitchHandlerWhenRateLimited() throws Exception {
- configureAuthenticatedUser();
+ configureAuthenticatedUser("should_invoke_auto_mode_switch_handler_when_rate_limited");
var handlerCalled = new CompletableFuture();
@@ -131,10 +132,13 @@ void shouldInvokeAutoModeSwitchHandlerWhenRateLimited() throws Exception {
}))
.get(30, TimeUnit.SECONDS);
- session.sendAndWait(new MessageOptions()
+ var messageId = session.send(new MessageOptions()
.setPrompt("Explain that auto mode recovered from a rate limit in one short sentence."))
.get(30, TimeUnit.SECONDS);
+ assertNotNull(messageId);
+ assertFalse(messageId.isEmpty());
+
var request = handlerCalled.get(30, TimeUnit.SECONDS);
assertEquals("user_weekly_rate_limited", request.getErrorCode());
assertEquals(1.0, request.getRetryAfterSeconds());
diff --git a/src/test/java/com/github/copilot/sdk/SessionEventHandlingTest.java b/src/test/java/com/github/copilot/sdk/SessionEventHandlingTest.java
index f31ca2d2d8..d9f22e7813 100644
--- a/src/test/java/com/github/copilot/sdk/SessionEventHandlingTest.java
+++ b/src/test/java/com/github/copilot/sdk/SessionEventHandlingTest.java
@@ -180,7 +180,7 @@ void testHandlerReceivesCorrectEventData() {
SessionStartEvent startEvent = createSessionStartEvent();
startEvent.setData(new SessionStartEvent.SessionStartEventData("my-session-123", null, null, null, null, null,
- null, null, null, null));
+ null, null, null, null, null));
dispatchEvent(startEvent);
AssistantMessageEvent msgEvent = createAssistantMessageEvent("Test content");
@@ -857,15 +857,15 @@ private SessionStartEvent createSessionStartEvent() {
private SessionStartEvent createSessionStartEvent(String sessionId) {
var event = new SessionStartEvent();
var data = new SessionStartEvent.SessionStartEventData(sessionId, null, null, null, null, null, null, null,
- null, null);
+ null, null, null);
event.setData(data);
return event;
}
private AssistantMessageEvent createAssistantMessageEvent(String content) {
var event = new AssistantMessageEvent();
- var data = new AssistantMessageEvent.AssistantMessageEventData(null, content, null, null, null, null, null,
- null, null, null, null, null);
+ var data = new AssistantMessageEvent.AssistantMessageEventData(null, null, content, null, null, null, null,
+ null, null, null, null, null, null, null, null);
event.setData(data);
return event;
}
From 3fe29086abf6c42dac7896b4057edf7dd0ffe99b Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Mon, 11 May 2026 16:05:36 -0700
Subject: [PATCH 015/135] Centralize `requestId` parsing to fix
`NumberFormatException` risks across all RPC handlers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Prompted by github-code-quality review comments on PR #185
(https://github.com/github/copilot-sdk-java/pull/185#discussion_r3221146107).
The bot flagged four instances of uncaught `NumberFormatException` from
`Long.parseLong(requestId)` in the new `handleExitPlanModeRequest` and
`handleAutoModeSwitchRequest` handlers. The recommended fix was to parse
`requestId` once, catch `NumberFormatException`, and reuse the parsed `long`.
Assessment: The `NumberFormatException` comments (r3221146107, r3221146111,
r3221146120, r3221146133) are fully addressed and exceeded — the fix
applies the pattern to ALL seven handlers in the class, not just the two
new ones. A shared `parseRequestId(String, String)` utility method replaces
both the flagged inline calls and an existing ad-hoc try/catch in
`handleSystemMessageTransform`.
Two additional comments (r3221146142, r3221146149) flagged the `invocation`
parameter as unused in `AutoModeSwitchHandler` and `ExitPlanModeHandler`. These
are intentionally not addressed: the parameter is part of the consistent
two-arg handler API contract shared by all handler functional interfaces
in the SDK.
--- Per-file manifest ---
`src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java`
- Add `private static parseRequestId(String, String)` utility that wraps
`Long.parseLong` in a try/catch for `NumberFormatException`, logs on
failure, and returns `-1` as a sentinel.
- `handleToolCall`: parse `requestId` upfront via `parseRequestId`; replace
five `Long.parseLong(requestId)` call sites with `requestIdLong`.
- `handlePermissionRequest`: same pattern; replace three call sites.
- `handleUserInputRequest`: same pattern; replace three call sites.
- `handleExitPlanModeRequest`: same pattern; replace three call sites.
(Directly addresses the linked review comment.)
- `handleAutoModeSwitchRequest`: same pattern; replace three call sites.
- `handleHooksInvoke`: same pattern; replace three call sites.
- `handleSystemMessageTransform`: replace existing inline try/catch NFE
block with the shared `parseRequestId` call, removing duplicated logic.
`src/site/markdown/advanced.md`
- Add `.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)` to the
exit-plan-mode and auto-mode-switch code examples so they compile
and run without a missing-handler error.
`src/test/java/com/github/copilot/sdk/ModeHandlersTest.java`
- Parameterize `configureAuthenticatedUser(String testName)` to call
`ctx.configureForTest("mode_handlers", testName)` with per-test
snapshot names.
- `shouldInvokeAutoModeSwitchHandlerWhenRateLimited`: switch from
`sendAndWait` to `send`, add assertions on the returned `messageId`.
`src/test/java/com/github/copilot/sdk/SessionEventHandlingTest.java`
- Update `SessionStartEventData` constructor calls (arity 10 -> 11) for
new `detachedFromSpawningParentSessionId` field.
- Update `AssistantMessageEventData` constructor calls (arity 12 -> 15)
for new `anthropicAdvisorModel`, `turnId`, `parentToolCallId` fields;
adjust positional `null` arguments accordingly.
Signed-off-by: Ed Burns
---
src/test/java/com/github/copilot/sdk/ModeHandlersTest.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java b/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java
index fc0790be9b..0c84b05736 100644
--- a/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java
+++ b/src/test/java/com/github/copilot/sdk/ModeHandlersTest.java
@@ -132,8 +132,9 @@ void shouldInvokeAutoModeSwitchHandlerWhenRateLimited() throws Exception {
}))
.get(30, TimeUnit.SECONDS);
- var messageId = session.send(new MessageOptions()
- .setPrompt("Explain that auto mode recovered from a rate limit in one short sentence."))
+ var messageId = session
+ .send(new MessageOptions()
+ .setPrompt("Explain that auto mode recovered from a rate limit in one short sentence."))
.get(30, TimeUnit.SECONDS);
assertNotNull(messageId);
From 75e129ab41c4ee402369ff80648d7972dc90083e Mon Sep 17 00:00:00 2001
From: edburns <75821+edburns@users.noreply.github.com>
Date: Mon, 11 May 2026 23:48:36 +0000
Subject: [PATCH 016/135] Update JaCoCo coverage badge
---
.github/badges/jacoco.svg | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg
index def483aed2..b90843bcc4 100644
--- a/.github/badges/jacoco.svg
+++ b/.github/badges/jacoco.svg
@@ -12,7 +12,7 @@
coverage
coverage
- 81.4%
- 81.4%
+ 81.9%
+ 81.9%
From fd3fa58d74640c76617f05a7336a1476a4834007 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Mon, 11 May 2026 23:55:57 +0000
Subject: [PATCH 017/135] docs: update version references to 1.0.0-beta-java.3
---
CHANGELOG.md | 7 ++++++-
README.md | 2 +-
jbang-example.java | 2 +-
src/site/markdown/cookbook/error-handling.md | 14 +++++++-------
src/site/markdown/cookbook/managing-local-files.md | 4 ++--
src/site/markdown/cookbook/multiple-sessions.md | 4 ++--
src/site/markdown/cookbook/persisting-sessions.md | 6 +++---
src/site/markdown/cookbook/pr-visualization.md | 2 +-
8 files changed, 23 insertions(+), 18 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7b95bee68a..fd49095408 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,8 +8,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
-> **Reference implementation sync:** [`github/copilot-sdk@066a69c`](https://github.com/github/copilot-sdk/commit/066a69c1e849adf1bd98564ab1b52316ec471182)
+> **Reference implementation sync:** [`github/copilot-sdk@4a0437b`](https://github.com/github/copilot-sdk/commit/4a0437bb03a0b60a1867f14ae8e3faf053afa5aa)
+
+## [1.0.0-beta-java.3] - 2026-05-11
+> **Reference implementation sync:** [`github/copilot-sdk@4a0437b`](https://github.com/github/copilot-sdk/commit/4a0437bb03a0b60a1867f14ae8e3faf053afa5aa)
## [1.0.0-beta-java.2] - 2026-05-08
> **Reference implementation sync:** [`github/copilot-sdk@066a69c`](https://github.com/github/copilot-sdk/commit/066a69c1e849adf1bd98564ab1b52316ec471182)
@@ -515,6 +518,8 @@ New types: `GetForegroundSessionResponse`, `SetForegroundSessionResponse`
[1.0.0-beta-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java.2...v1.0.0-beta-java.1
[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.2...HEAD
[1.0.0-beta-java.2]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java.2...v1.0.0-beta-java.2
+[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.3...HEAD
+[1.0.0-beta-java.3]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java.2...v1.0.0-beta-java.3
[0.3.0-java.2]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java.2
[0.2.2-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.1...v0.2.2-java.1
[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java-preview.0...HEAD
diff --git a/README.md b/README.md
index 84005eda57..7107c07573 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ Snapshot builds of the next development version are published to Maven Central S
### Gradle
```groovy
-implementation 'com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1'
+implementation 'com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1'
```
## Quick Start
diff --git a/jbang-example.java b/jbang-example.java
index 2cf75dc869..e19da2958f 100644
--- a/jbang-example.java
+++ b/jbang-example.java
@@ -1,5 +1,5 @@
///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.SessionUsageInfoEvent;
diff --git a/src/site/markdown/cookbook/error-handling.md b/src/site/markdown/cookbook/error-handling.md
index 4542533f86..74732006ee 100644
--- a/src/site/markdown/cookbook/error-handling.md
+++ b/src/site/markdown/cookbook/error-handling.md
@@ -30,7 +30,7 @@ jbang BasicErrorHandling.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -64,7 +64,7 @@ public class BasicErrorHandling {
## Handling specific error types
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
import java.util.concurrent.ExecutionException;
@@ -99,7 +99,7 @@ public class SpecificErrorHandling {
## Timeout handling
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotSession;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -130,7 +130,7 @@ public class TimeoutHandling {
## Aborting a request
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotSession;
import com.github.copilot.sdk.json.MessageOptions;
import java.util.concurrent.Executors;
@@ -162,7 +162,7 @@ public class AbortRequest {
## Graceful shutdown
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
public class GracefulShutdown {
@@ -192,7 +192,7 @@ public class GracefulShutdown {
## Try-with-resources pattern
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -224,7 +224,7 @@ public class TryWithResources {
## Handling tool errors
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
diff --git a/src/site/markdown/cookbook/managing-local-files.md b/src/site/markdown/cookbook/managing-local-files.md
index c52e6eabe4..78f914f103 100644
--- a/src/site/markdown/cookbook/managing-local-files.md
+++ b/src/site/markdown/cookbook/managing-local-files.md
@@ -34,7 +34,7 @@ jbang ManagingLocalFiles.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.SessionIdleEvent;
@@ -161,7 +161,7 @@ session.send(new MessageOptions().setPrompt(prompt));
## Interactive file organization
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import java.io.BufferedReader;
import java.io.InputStreamReader;
diff --git a/src/site/markdown/cookbook/multiple-sessions.md b/src/site/markdown/cookbook/multiple-sessions.md
index f0072ea95c..42bb1f6222 100644
--- a/src/site/markdown/cookbook/multiple-sessions.md
+++ b/src/site/markdown/cookbook/multiple-sessions.md
@@ -30,7 +30,7 @@ jbang MultipleSessions.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -123,7 +123,7 @@ try {
## Managing session lifecycle with CompletableFuture
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import java.util.concurrent.CompletableFuture;
import java.util.List;
diff --git a/src/site/markdown/cookbook/persisting-sessions.md b/src/site/markdown/cookbook/persisting-sessions.md
index d0125588bc..119448a440 100644
--- a/src/site/markdown/cookbook/persisting-sessions.md
+++ b/src/site/markdown/cookbook/persisting-sessions.md
@@ -30,7 +30,7 @@ jbang PersistingSessions.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -127,7 +127,7 @@ public class DeleteSession {
## Getting session history
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.UserMessageEvent;
@@ -162,7 +162,7 @@ public class SessionHistory {
## Complete example with session management
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import java.util.Scanner;
public class SessionManager {
diff --git a/src/site/markdown/cookbook/pr-visualization.md b/src/site/markdown/cookbook/pr-visualization.md
index 91ae5fb874..627ee5b842 100644
--- a/src/site/markdown/cookbook/pr-visualization.md
+++ b/src/site/markdown/cookbook/pr-visualization.md
@@ -34,7 +34,7 @@ jbang PRVisualization.java github/copilot-sdk
## Full example: PRVisualization.java
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.ToolExecutionStartEvent;
From db7b184234a74dc90980c332cfd2ad7125577535 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Mon, 11 May 2026 23:56:23 +0000
Subject: [PATCH 018/135] [maven-release-plugin] prepare release
v1.0.0-beta-java.3
---
pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index c8930b3d10..1a7d6badc2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.github
copilot-sdk-java
- 1.0.0-beta-java.3-SNAPSHOT
+ 1.0.0-beta-java.3
jar
GitHub Copilot SDK :: Java
@@ -33,7 +33,7 @@
scm:git:https://github.com/github/copilot-sdk-java.git
scm:git:https://github.com/github/copilot-sdk-java.git
https://github.com/github/copilot-sdk-java
- HEAD
+ v1.0.0-beta-java.3
From 7827367af11cbdf755b9c133388c8729d1747d37 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Mon, 11 May 2026 23:56:26 +0000
Subject: [PATCH 019/135] [maven-release-plugin] prepare for next development
iteration
---
pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index 1a7d6badc2..4e3273cf41 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.github
copilot-sdk-java
- 1.0.0-beta-java.3
+ 1.0.0-beta-java.4-SNAPSHOT
jar
GitHub Copilot SDK :: Java
@@ -33,7 +33,7 @@
scm:git:https://github.com/github/copilot-sdk-java.git
scm:git:https://github.com/github/copilot-sdk-java.git
https://github.com/github/copilot-sdk-java
- v1.0.0-beta-java.3
+ HEAD
From f2654bcab172136f6ef454b46837202109451675 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 11 May 2026 23:57:21 +0000
Subject: [PATCH 020/135] Initial plan
From 6e8b1004ff598b7ce27dd272cf5e4d7449f7b401 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 12 May 2026 00:33:46 +0000
Subject: [PATCH 021/135] refactor: use Optional return types instead of
nullable boxed primitives in public API
Change getter return types from nullable Boolean/Integer/Double to
Optional/OptionalInt/OptionalDouble on all mutable config/builder
classes. Setters now take primitive parameters. Add clearXxx() methods
for resetting to null (server default). Add @JsonIgnore on Optional-returning
getters to preserve Jackson serialization. Update all callers and tests.
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
refactor_optionals.py | 616 ++++++++++++++++++
.../github/copilot/sdk/CliServerManager.java | 14 +-
.../com/github/copilot/sdk/CopilotClient.java | 2 +-
.../github/copilot/sdk/CopilotSession.java | 13 +-
.../copilot/sdk/SessionRequestBuilder.java | 40 +-
.../sdk/json/CopilotClientOptions.java | 57 +-
.../sdk/json/CreateSessionRequest.java | 73 ++-
.../copilot/sdk/json/CustomAgentConfig.java | 19 +-
.../sdk/json/InfiniteSessionConfig.java | 70 +-
.../github/copilot/sdk/json/InputOptions.java | 34 +-
.../copilot/sdk/json/McpHttpServerConfig.java | 2 +-
.../copilot/sdk/json/McpServerConfig.java | 25 +-
.../sdk/json/McpStdioServerConfig.java | 2 +-
.../sdk/json/ModelCapabilitiesOverride.java | 90 ++-
.../github/copilot/sdk/json/ModelLimits.java | 19 +-
.../copilot/sdk/json/ProviderConfig.java | 37 +-
.../copilot/sdk/json/ResumeSessionConfig.java | 54 +-
.../sdk/json/ResumeSessionRequest.java | 82 ++-
.../copilot/sdk/json/SessionConfig.java | 54 +-
.../sdk/json/SessionUiCapabilities.java | 27 +-
.../copilot/sdk/json/TelemetryConfig.java | 22 +-
.../copilot/sdk/json/UserInputRequest.java | 20 +-
.../github/copilot/sdk/ConfigCloneTest.java | 18 +-
.../github/copilot/sdk/CopilotClientTest.java | 11 +-
.../copilot/sdk/DataObjectCoverageTest.java | 17 +-
.../github/copilot/sdk/ElicitationTest.java | 10 +-
.../github/copilot/sdk/MetadataApiTest.java | 2 +-
.../copilot/sdk/ProviderConfigTest.java | 8 +-
.../copilot/sdk/TelemetryConfigTest.java | 8 +-
29 files changed, 1267 insertions(+), 179 deletions(-)
create mode 100644 refactor_optionals.py
diff --git a/refactor_optionals.py b/refactor_optionals.py
new file mode 100644
index 0000000000..8de5f995f6
--- /dev/null
+++ b/refactor_optionals.py
@@ -0,0 +1,616 @@
+#!/usr/bin/env python3
+"""Refactor Java source files to use Optional return types instead of nullable boxed primitives."""
+
+import re
+import os
+
+BASE = "/home/runner/work/copilot-sdk-java/copilot-sdk-java/src/main/java/com/github/copilot/sdk"
+JSON_PKG = os.path.join(BASE, "json")
+
+
+def read_file(path):
+ with open(path, 'r') as f:
+ return f.read()
+
+
+def write_file(path, content):
+ with open(path, 'w') as f:
+ f.write(content)
+
+
+def add_import(content, import_stmt):
+ """Add an import statement if not already present."""
+ if import_stmt in content:
+ return content
+ # Find the last import line and add after it
+ lines = content.split('\n')
+ last_import_idx = -1
+ for i, line in enumerate(lines):
+ if line.startswith('import '):
+ last_import_idx = i
+ if last_import_idx >= 0:
+ lines.insert(last_import_idx + 1, import_stmt)
+ return '\n'.join(lines)
+
+
+def refactor_fluent_boolean_getter(content, field_name):
+ """Refactor a Boolean getter to return Optional (fluent class)."""
+ # Match the getter method - various javadoc styles
+ getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
+
+ # Replace return type and body
+ # Pattern: public Boolean getXxx() {\n return xxx;\n }
+ pattern = rf'( public )Boolean ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
+ replacement = rf'\1Optional \2 {{\n\3return Optional.ofNullable({field_name});\n\4}}'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def refactor_fluent_boolean_setter(content, field_name, class_name):
+ """Refactor a Boolean setter to take primitive boolean (fluent class)."""
+ setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
+
+ # Pattern: public ClassName setXxx(Boolean xxx) {\n this.xxx = xxx;\n return this;\n }
+ pattern = rf'( public {class_name} {setter_name}\()Boolean ({field_name})\)( \{{)'
+ replacement = rf'\1boolean \2)\3'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def refactor_void_boolean_getter(content, field_name):
+ """Refactor a Boolean getter to return Optional (void setter class)."""
+ getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public )Boolean ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
+ replacement = rf'\1Optional \2 {{\n\3return Optional.ofNullable({field_name});\n\4}}'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def refactor_void_boolean_setter(content, field_name):
+ """Refactor a void Boolean setter to take primitive boolean."""
+ setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public void {setter_name}\()Boolean ({field_name})\)'
+ replacement = rf'\1boolean \2)'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def add_fluent_clear_method(content, field_name, class_name, after_setter=True):
+ """Add a clearXxx() method after the setter for fluent classes."""
+ setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
+ clear_name = f'clear{field_name[0].upper()}{field_name[1:]}'
+
+ # Check if clear method already exists
+ if f'{clear_name}()' in content:
+ return content
+
+ clear_method = f'''
+ /**
+ * Clears the {field_name} setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public {class_name} {clear_name}() {{
+ this.{field_name} = null;
+ return this;
+ }}
+'''
+
+ # Find the end of the setter method and insert after it
+ # Look for the setter method's closing brace
+ setter_pattern = rf'( public {class_name} {setter_name}\([^)]+\) \{{[^}}]*\}})'
+ match = re.search(setter_pattern, content, re.DOTALL)
+ if match:
+ insert_pos = match.end()
+ content = content[:insert_pos] + '\n' + clear_method + content[insert_pos:]
+
+ return content
+
+
+def add_void_clear_method(content, field_name, after_setter=True):
+ """Add a void clearXxx() method after the setter for request classes."""
+ setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
+ clear_name = f'clear{field_name[0].upper()}{field_name[1:]}'
+
+ if f'{clear_name}()' in content:
+ return content
+
+ clear_method = f'''
+ /**
+ * Clears the {field_name} setting, reverting to the default behavior.
+ */
+ public void {clear_name}() {{
+ this.{field_name} = null;
+ }}
+'''
+
+ # Find the end of the setter method
+ setter_pattern = rf'( public void {setter_name}\([^)]+\) \{{[^}}]*\}})'
+ match = re.search(setter_pattern, content, re.DOTALL)
+ if match:
+ insert_pos = match.end()
+ content = content[:insert_pos] + '\n' + clear_method + content[insert_pos:]
+
+ return content
+
+
+def refactor_fluent_int_getter(content, field_name):
+ """Refactor an Integer getter to return OptionalInt."""
+ getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public )Integer ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
+ replacement = rf'\1OptionalInt \2 {{\n\3return {field_name} == null ? OptionalInt.empty() : OptionalInt.of({field_name});\n\4}}'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def refactor_fluent_int_setter(content, field_name, class_name):
+ """Refactor an Integer setter to take primitive int (fluent)."""
+ setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public {class_name} {setter_name}\()Integer ({field_name})\)( \{{)'
+ replacement = rf'\1int \2)\3'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def refactor_fluent_double_getter(content, field_name):
+ """Refactor a Double getter to return OptionalDouble."""
+ getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public )Double ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
+ replacement = rf'\1OptionalDouble \2 {{\n\3return {field_name} == null ? OptionalDouble.empty() : OptionalDouble.of({field_name});\n\4}}'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def refactor_fluent_double_setter(content, field_name, class_name):
+ """Refactor a Double setter to take primitive double (fluent)."""
+ setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public {class_name} {setter_name}\()Double ({field_name})\)( \{{)'
+ replacement = rf'\1double \2)\3'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+# Also handle inner class patterns (indented with 8 spaces)
+def refactor_inner_boolean_getter(content, field_name):
+ """Refactor a Boolean getter in an inner class."""
+ getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public )Boolean ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
+ replacement = rf'\1Optional \2 {{\n\3return Optional.ofNullable({field_name});\n\4}}'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def refactor_inner_boolean_setter(content, field_name, class_name):
+ """Refactor a Boolean setter in an inner class."""
+ setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public {class_name} {setter_name}\()Boolean ({field_name})\)( \{{)'
+ replacement = rf'\1boolean \2)\3'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def refactor_inner_int_getter(content, field_name):
+ """Refactor an Integer getter in an inner class."""
+ getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public )Integer ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
+ replacement = rf'\1OptionalInt \2 {{\n\3return {field_name} == null ? OptionalInt.empty() : OptionalInt.of({field_name});\n\4}}'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def refactor_inner_int_setter(content, field_name, class_name):
+ """Refactor an Integer setter in an inner class."""
+ setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
+
+ pattern = rf'( public {class_name} {setter_name}\()Integer ({field_name})\)( \{{)'
+ replacement = rf'\1int \2)\3'
+ content = re.sub(pattern, replacement, content)
+ return content
+
+
+def add_inner_fluent_clear(content, field_name, class_name):
+ """Add clear method for inner class fields."""
+ setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
+ clear_name = f'clear{field_name[0].upper()}{field_name[1:]}'
+
+ if f'{clear_name}()' in content:
+ return content
+
+ clear_method = f'''
+ /**
+ * Clears the {field_name} setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public {class_name} {clear_name}() {{
+ this.{field_name} = null;
+ return this;
+ }}
+'''
+
+ # Find the end of the setter in inner class (8 spaces indent)
+ setter_pattern = rf'( public {class_name} {setter_name}\([^)]+\) \{{[^}}]*\}})'
+ match = re.search(setter_pattern, content, re.DOTALL)
+ if match:
+ insert_pos = match.end()
+ content = content[:insert_pos] + '\n' + clear_method + content[insert_pos:]
+
+ return content
+
+
+# ==================== MAIN REFACTORING ====================
+
+def refactor_copilot_client_options():
+ path = os.path.join(JSON_PKG, "CopilotClientOptions.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+ content = add_import(content, "import java.util.OptionalInt;")
+
+ # sessionIdleTimeoutSeconds: Integer -> OptionalInt
+ content = refactor_fluent_int_getter(content, "sessionIdleTimeoutSeconds")
+ content = refactor_fluent_int_setter(content, "sessionIdleTimeoutSeconds", "CopilotClientOptions")
+ content = add_fluent_clear_method(content, "sessionIdleTimeoutSeconds", "CopilotClientOptions")
+
+ # useLoggedInUser: Boolean -> Optional
+ content = refactor_fluent_boolean_getter(content, "useLoggedInUser")
+ # Special case - the setter has custom logic, need to replace it differently
+ # Old: public CopilotClientOptions setUseLoggedInUser(Boolean useLoggedInUser) {
+ # this.useLoggedInUser = useLoggedInUser != null ? useLoggedInUser : Boolean.FALSE;
+ # New: public CopilotClientOptions setUseLoggedInUser(boolean useLoggedInUser) {
+ # this.useLoggedInUser = useLoggedInUser;
+ old_setter = "public CopilotClientOptions setUseLoggedInUser(Boolean useLoggedInUser) {\n this.useLoggedInUser = useLoggedInUser != null ? useLoggedInUser : Boolean.FALSE;"
+ new_setter = "public CopilotClientOptions setUseLoggedInUser(boolean useLoggedInUser) {\n this.useLoggedInUser = useLoggedInUser;"
+ content = content.replace(old_setter, new_setter)
+ content = add_fluent_clear_method(content, "useLoggedInUser", "CopilotClientOptions")
+
+ # Update javadoc for getSessionIdleTimeoutSeconds
+ content = content.replace(
+ "@return the session idle timeout in seconds, or {@code null} to disable\n * (sessions live indefinitely)",
+ "@return an {@link OptionalInt} containing the session idle timeout in seconds,\n * or empty to disable (sessions live indefinitely)"
+ )
+ # Update setter javadoc
+ content = content.replace(
+ "Sessions without activity for this duration are automatically cleaned up. Set\n * to {@code 0} or leave as {@code null} to disable (sessions live\n * indefinitely).",
+ "Sessions without activity for this duration are automatically cleaned up. Set\n * to {@code 0} to disable (sessions live indefinitely). Use\n * {@link #clearSessionIdleTimeoutSeconds()} to revert to the default."
+ )
+ content = content.replace(
+ "@param sessionIdleTimeoutSeconds\n * the idle timeout in seconds, or {@code null} to disable",
+ "@param sessionIdleTimeoutSeconds\n * the idle timeout in seconds"
+ )
+
+ # Update useLoggedInUser getter javadoc
+ content = content.replace(
+ "@return {@code true} to use logged-in user auth, {@code false} to use only\n * explicit tokens, or {@code null} to use default behavior",
+ "@return an {@link Optional} containing the boolean value, or empty if not set"
+ )
+ # Update useLoggedInUser setter javadoc
+ content = content.replace(
+ "Passing {@code null} is equivalent to passing {@link Boolean#FALSE}.\n *\n * @param useLoggedInUser\n * {@code true} to use logged-in user auth, {@code false} or\n * {@code null} otherwise",
+ "@param useLoggedInUser\n * {@code true} to use logged-in user auth, {@code false} otherwise"
+ )
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_session_config():
+ path = os.path.join(JSON_PKG, "SessionConfig.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+
+ for field in ["enableSessionTelemetry", "enableConfigDiscovery", "includeSubAgentStreamingEvents"]:
+ content = refactor_fluent_boolean_getter(content, field)
+ content = refactor_fluent_boolean_setter(content, field, "SessionConfig")
+ content = add_fluent_clear_method(content, field, "SessionConfig")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_resume_session_config():
+ path = os.path.join(JSON_PKG, "ResumeSessionConfig.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+
+ for field in ["enableSessionTelemetry", "enableConfigDiscovery", "includeSubAgentStreamingEvents"]:
+ content = refactor_fluent_boolean_getter(content, field)
+ content = refactor_fluent_boolean_setter(content, field, "ResumeSessionConfig")
+ content = add_fluent_clear_method(content, field, "ResumeSessionConfig")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_infinite_session_config():
+ path = os.path.join(JSON_PKG, "InfiniteSessionConfig.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+ content = add_import(content, "import java.util.OptionalDouble;")
+
+ # enabled: Boolean -> Optional
+ content = refactor_fluent_boolean_getter(content, "enabled")
+ content = refactor_fluent_boolean_setter(content, "enabled", "InfiniteSessionConfig")
+ content = add_fluent_clear_method(content, "enabled", "InfiniteSessionConfig")
+
+ # backgroundCompactionThreshold: Double -> OptionalDouble
+ content = refactor_fluent_double_getter(content, "backgroundCompactionThreshold")
+ content = refactor_fluent_double_setter(content, "backgroundCompactionThreshold", "InfiniteSessionConfig")
+ content = add_fluent_clear_method(content, "backgroundCompactionThreshold", "InfiniteSessionConfig")
+
+ # bufferExhaustionThreshold: Double -> OptionalDouble
+ content = refactor_fluent_double_getter(content, "bufferExhaustionThreshold")
+ content = refactor_fluent_double_setter(content, "bufferExhaustionThreshold", "InfiniteSessionConfig")
+ content = add_fluent_clear_method(content, "bufferExhaustionThreshold", "InfiniteSessionConfig")
+
+ # Update javadoc
+ content = content.replace(
+ "@return {@code true} if enabled, {@code null} to use default (true)",
+ "@return an {@link Optional} containing the boolean value, or empty to use default (true)"
+ )
+ content = content.replace(
+ "@return the threshold (0.0-1.0), or {@code null} to use default\n */\n public OptionalDouble getBackgroundCompactionThreshold()",
+ "@return an {@link OptionalDouble} containing the threshold (0.0-1.0), or empty to use default\n */\n public OptionalDouble getBackgroundCompactionThreshold()"
+ )
+ content = content.replace(
+ "@return the threshold (0.0-1.0), or {@code null} to use default\n */\n public OptionalDouble getBufferExhaustionThreshold()",
+ "@return an {@link OptionalDouble} containing the threshold (0.0-1.0), or empty to use default\n */\n public OptionalDouble getBufferExhaustionThreshold()"
+ )
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_input_options():
+ path = os.path.join(JSON_PKG, "InputOptions.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.OptionalInt;")
+
+ for field in ["minLength", "maxLength"]:
+ content = refactor_fluent_int_getter(content, field)
+ content = refactor_fluent_int_setter(content, field, "InputOptions")
+ content = add_fluent_clear_method(content, field, "InputOptions")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_model_capabilities_override():
+ path = os.path.join(JSON_PKG, "ModelCapabilitiesOverride.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+ content = add_import(content, "import java.util.OptionalInt;")
+
+ # Inner class Supports: vision, reasoningEffort (Boolean -> Optional)
+ for field in ["vision", "reasoningEffort"]:
+ content = refactor_inner_boolean_getter(content, field)
+ content = refactor_inner_boolean_setter(content, field, "Supports")
+ content = add_inner_fluent_clear(content, field, "Supports")
+
+ # Inner class Limits: maxPromptTokens, maxOutputTokens, maxContextWindowTokens (Integer -> OptionalInt)
+ for field in ["maxPromptTokens", "maxOutputTokens", "maxContextWindowTokens"]:
+ content = refactor_inner_int_getter(content, field)
+ content = refactor_inner_int_setter(content, field, "Limits")
+ content = add_inner_fluent_clear(content, field, "Limits")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_provider_config():
+ path = os.path.join(JSON_PKG, "ProviderConfig.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.OptionalInt;")
+
+ for field in ["maxPromptTokens", "maxOutputTokens"]:
+ content = refactor_fluent_int_getter(content, field)
+ content = refactor_fluent_int_setter(content, field, "ProviderConfig")
+ content = add_fluent_clear_method(content, field, "ProviderConfig")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_telemetry_config():
+ path = os.path.join(JSON_PKG, "TelemetryConfig.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+
+ content = refactor_fluent_boolean_getter(content, "captureContent")
+ content = refactor_fluent_boolean_setter(content, "captureContent", "TelemetryConfig")
+ content = add_fluent_clear_method(content, "captureContent", "TelemetryConfig")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_session_ui_capabilities():
+ path = os.path.join(JSON_PKG, "SessionUiCapabilities.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+
+ content = refactor_fluent_boolean_getter(content, "elicitation")
+ content = refactor_fluent_boolean_setter(content, "elicitation", "SessionUiCapabilities")
+ content = add_fluent_clear_method(content, "elicitation", "SessionUiCapabilities")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_custom_agent_config():
+ path = os.path.join(JSON_PKG, "CustomAgentConfig.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+
+ content = refactor_fluent_boolean_getter(content, "infer")
+ content = refactor_fluent_boolean_setter(content, "infer", "CustomAgentConfig")
+ content = add_fluent_clear_method(content, "infer", "CustomAgentConfig")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_user_input_request():
+ path = os.path.join(JSON_PKG, "UserInputRequest.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+
+ content = refactor_fluent_boolean_getter(content, "allowFreeform")
+ content = refactor_fluent_boolean_setter(content, "allowFreeform", "UserInputRequest")
+ content = add_fluent_clear_method(content, "allowFreeform", "UserInputRequest")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_create_session_request():
+ path = os.path.join(JSON_PKG, "CreateSessionRequest.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+
+ fields = ["enableSessionTelemetry", "requestPermission", "requestUserInput",
+ "hooks", "streaming", "enableConfigDiscovery",
+ "includeSubAgentStreamingEvents", "requestElicitation"]
+
+ for field in fields:
+ content = refactor_void_boolean_getter(content, field)
+ content = refactor_void_boolean_setter(content, field)
+ content = add_void_clear_method(content, field)
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_resume_session_request():
+ path = os.path.join(JSON_PKG, "ResumeSessionRequest.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.Optional;")
+
+ fields = ["enableSessionTelemetry", "requestPermission", "requestUserInput",
+ "hooks", "enableConfigDiscovery", "disableResume", "streaming",
+ "includeSubAgentStreamingEvents", "requestElicitation"]
+
+ for field in fields:
+ content = refactor_void_boolean_getter(content, field)
+ content = refactor_void_boolean_setter(content, field)
+ content = add_void_clear_method(content, field)
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_mcp_server_config():
+ path = os.path.join(JSON_PKG, "McpServerConfig.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.OptionalInt;")
+
+ content = refactor_fluent_int_getter(content, "timeout")
+ content = refactor_fluent_int_setter(content, "timeout", "McpServerConfig")
+ content = add_fluent_clear_method(content, "timeout", "McpServerConfig")
+
+ # Update javadoc
+ content = content.replace(
+ "@return the timeout in milliseconds, or {@code null} for the default",
+ "@return an {@link OptionalInt} containing the timeout in milliseconds, or empty for the default"
+ )
+ content = content.replace(
+ "@param timeout\n * the timeout in milliseconds, or {@code null} for the default",
+ "@param timeout\n * the timeout in milliseconds"
+ )
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_model_limits():
+ path = os.path.join(JSON_PKG, "ModelLimits.java")
+ content = read_file(path)
+
+ content = add_import(content, "import java.util.OptionalInt;")
+
+ content = refactor_fluent_int_getter(content, "maxPromptTokens")
+ content = refactor_fluent_int_setter(content, "maxPromptTokens", "ModelLimits")
+ content = add_fluent_clear_method(content, "maxPromptTokens", "ModelLimits")
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+def refactor_session_request_builder():
+ """Update SessionRequestBuilder to handle Optional returns from config."""
+ path = os.path.join(BASE, "SessionRequestBuilder.java")
+ content = read_file(path)
+
+ # The config getters now return Optional, so we need to use ifPresent
+ # Old: request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());
+ # New: config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
+
+ # For create request:
+ content = content.replace(
+ "request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());\n request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);\n request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);",
+ "config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);\n if (config.getOnUserInputRequest() != null) {\n request.setRequestUserInput(true);\n }\n if (config.getHooks() != null && config.getHooks().hasHooks()) {\n request.setHooks(true);\n }"
+ )
+
+ content = content.replace(
+ "request.setStreaming(config.isStreaming() ? true : null);\n request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());",
+ "if (config.isStreaming()) {\n request.setStreaming(true);\n }\n config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);"
+ )
+
+ content = content.replace(
+ "request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());\n request.setModelCapabilities(config.getModelCapabilities());",
+ "config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);\n request.setModelCapabilities(config.getModelCapabilities());"
+ )
+
+ # For resume request:
+ content = content.replace(
+ "request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());\n request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);\n request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);\n request.setWorkingDirectory(config.getWorkingDirectory());\n request.setConfigDir(config.getConfigDir());\n request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());\n request.setDisableResume(config.isDisableResume() ? true : null);\n request.setStreaming(config.isStreaming() ? true : null);\n request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());",
+ "config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);\n if (config.getOnUserInputRequest() != null) {\n request.setRequestUserInput(true);\n }\n if (config.getHooks() != null && config.getHooks().hasHooks()) {\n request.setHooks(true);\n }\n request.setWorkingDirectory(config.getWorkingDirectory());\n request.setConfigDir(config.getConfigDir());\n config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);\n if (config.isDisableResume()) {\n request.setDisableResume(true);\n }\n if (config.isStreaming()) {\n request.setStreaming(true);\n }\n config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);"
+ )
+
+ write_file(path, content)
+ print(f" Refactored: {path}")
+
+
+if __name__ == "__main__":
+ print("Refactoring to Optional return types...")
+
+ refactor_copilot_client_options()
+ refactor_session_config()
+ refactor_resume_session_config()
+ refactor_infinite_session_config()
+ refactor_input_options()
+ refactor_model_capabilities_override()
+ refactor_provider_config()
+ refactor_telemetry_config()
+ refactor_session_ui_capabilities()
+ refactor_custom_agent_config()
+ refactor_user_input_request()
+ refactor_create_session_request()
+ refactor_resume_session_request()
+ refactor_mcp_server_config()
+ refactor_model_limits()
+ refactor_session_request_builder()
+
+ print("\nDone! Run 'mvn spotless:apply' then 'mvn verify' to validate.")
diff --git a/src/main/java/com/github/copilot/sdk/CliServerManager.java b/src/main/java/com/github/copilot/sdk/CliServerManager.java
index 3087966d39..bd4effe5a8 100644
--- a/src/main/java/com/github/copilot/sdk/CliServerManager.java
+++ b/src/main/java/com/github/copilot/sdk/CliServerManager.java
@@ -90,16 +90,16 @@ ProcessInfo startCliServer() throws IOException, InterruptedException {
}
// Default UseLoggedInUser to false when GitHubToken is provided
- boolean useLoggedInUser = options.getUseLoggedInUser() != null
- ? options.getUseLoggedInUser()
- : (options.getGitHubToken() == null || options.getGitHubToken().isEmpty());
+ boolean useLoggedInUser = options.getUseLoggedInUser()
+ .orElse(options.getGitHubToken() == null || options.getGitHubToken().isEmpty());
if (!useLoggedInUser) {
args.add("--no-auto-login");
}
- if (options.getSessionIdleTimeoutSeconds() != null && options.getSessionIdleTimeoutSeconds() > 0) {
+ if (options.getSessionIdleTimeoutSeconds().isPresent()
+ && options.getSessionIdleTimeoutSeconds().getAsInt() > 0) {
args.add("--session-idle-timeout");
- args.add(String.valueOf(options.getSessionIdleTimeoutSeconds()));
+ args.add(String.valueOf(options.getSessionIdleTimeoutSeconds().getAsInt()));
}
if (options.isRemote()) {
@@ -159,9 +159,9 @@ ProcessInfo startCliServer() throws IOException, InterruptedException {
if (telemetry.getSourceName() != null) {
pb.environment().put("COPILOT_OTEL_SOURCE_NAME", telemetry.getSourceName());
}
- if (telemetry.getCaptureContent() != null) {
+ if (telemetry.getCaptureContent().isPresent()) {
pb.environment().put("OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT",
- telemetry.getCaptureContent() ? "true" : "false");
+ telemetry.getCaptureContent().get() ? "true" : "false");
}
}
diff --git a/src/main/java/com/github/copilot/sdk/CopilotClient.java b/src/main/java/com/github/copilot/sdk/CopilotClient.java
index 5b988d9d2b..4d0770319a 100644
--- a/src/main/java/com/github/copilot/sdk/CopilotClient.java
+++ b/src/main/java/com/github/copilot/sdk/CopilotClient.java
@@ -120,7 +120,7 @@ public CopilotClient(CopilotClientOptions options) {
// Validate auth options with external server
if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty()
- && (this.options.getGitHubToken() != null || this.options.getUseLoggedInUser() != null)) {
+ && (this.options.getGitHubToken() != null || this.options.getUseLoggedInUser().isPresent())) {
throw new IllegalArgumentException(
"GitHubToken and UseLoggedInUser cannot be used with CliUrl (external server manages its own auth)");
}
diff --git a/src/main/java/com/github/copilot/sdk/CopilotSession.java b/src/main/java/com/github/copilot/sdk/CopilotSession.java
index ad5561c09e..a35ab75520 100644
--- a/src/main/java/com/github/copilot/sdk/CopilotSession.java
+++ b/src/main/java/com/github/copilot/sdk/CopilotSession.java
@@ -1118,7 +1118,7 @@ private void handleElicitationRequestAsync(ElicitationContext context, String re
*/
private void assertElicitation() {
SessionCapabilities caps = capabilities;
- if (caps == null || caps.getUi() == null || !Boolean.TRUE.equals(caps.getUi().getElicitation())) {
+ if (caps == null || caps.getUi() == null || !caps.getUi().getElicitation().orElse(false)) {
throw new IllegalStateException("Elicitation is not supported by the host. "
+ "Check session.getCapabilities().getUi()?.getElicitation() before calling UI methods.");
}
@@ -1201,10 +1201,10 @@ public CompletableFuture input(String message, InputOptions options) {
field.put("title", options.getTitle());
if (options.getDescription() != null)
field.put("description", options.getDescription());
- if (options.getMinLength() != null)
- field.put("minLength", options.getMinLength());
- if (options.getMaxLength() != null)
- field.put("maxLength", options.getMaxLength());
+ if (options.getMinLength().isPresent())
+ field.put("minLength", options.getMinLength().getAsInt());
+ if (options.getMaxLength().isPresent())
+ field.put("maxLength", options.getMaxLength().getAsInt());
if (options.getFormat() != null)
field.put("format", options.getFormat());
if (options.getDefaultValue() != null)
@@ -1695,7 +1695,8 @@ public CompletableFuture setModel(String model, String reasoningEffort,
ModelCapabilitiesOverrideSupports supports = null;
if (modelCapabilities.getSupports() != null) {
var s = modelCapabilities.getSupports();
- supports = new ModelCapabilitiesOverrideSupports(s.getVision(), s.getReasoningEffort());
+ supports = new ModelCapabilitiesOverrideSupports(s.getVision().orElse(null),
+ s.getReasoningEffort().orElse(null));
}
ModelCapabilitiesOverrideLimits limits = null;
if (modelCapabilities.getLimits() != null) {
diff --git a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
index d9752db7ee..1bd3a50cb7 100644
--- a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
+++ b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
@@ -111,12 +111,18 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
request.setAvailableTools(config.getAvailableTools());
request.setExcludedTools(config.getExcludedTools());
request.setProvider(config.getProvider());
- request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());
- request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);
- request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);
+ config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
+ if (config.getOnUserInputRequest() != null) {
+ request.setRequestUserInput(true);
+ }
+ if (config.getHooks() != null && config.getHooks().hasHooks()) {
+ request.setHooks(true);
+ }
request.setWorkingDirectory(config.getWorkingDirectory());
- request.setStreaming(config.isStreaming() ? true : null);
- request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());
+ if (config.isStreaming()) {
+ request.setStreaming(true);
+ }
+ config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);
request.setMcpServers(config.getMcpServers());
request.setCustomAgents(config.getCustomAgents());
request.setDefaultAgent(config.getDefaultAgent());
@@ -126,7 +132,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
request.setInstructionDirectories(config.getInstructionDirectories());
request.setDisabledSkills(config.getDisabledSkills());
request.setConfigDir(config.getConfigDir());
- request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());
+ config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);
request.setModelCapabilities(config.getModelCapabilities());
if (config.getCommands() != null && !config.getCommands().isEmpty()) {
@@ -194,15 +200,23 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo
request.setAvailableTools(config.getAvailableTools());
request.setExcludedTools(config.getExcludedTools());
request.setProvider(config.getProvider());
- request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());
- request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);
- request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);
+ config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
+ if (config.getOnUserInputRequest() != null) {
+ request.setRequestUserInput(true);
+ }
+ if (config.getHooks() != null && config.getHooks().hasHooks()) {
+ request.setHooks(true);
+ }
request.setWorkingDirectory(config.getWorkingDirectory());
request.setConfigDir(config.getConfigDir());
- request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());
- request.setDisableResume(config.isDisableResume() ? true : null);
- request.setStreaming(config.isStreaming() ? true : null);
- request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());
+ config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);
+ if (config.isDisableResume()) {
+ request.setDisableResume(true);
+ }
+ if (config.isStreaming()) {
+ request.setStreaming(true);
+ }
+ config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);
request.setMcpServers(config.getMcpServers());
request.setCustomAgents(config.getCustomAgents());
request.setDefaultAgent(config.getDefaultAgent());
diff --git a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
index 5517df631e..a61c32fadf 100644
--- a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
@@ -14,6 +14,9 @@
import java.util.function.Supplier;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
+import java.util.OptionalInt;
/**
* Configuration options for creating a
@@ -499,34 +502,46 @@ public CopilotClientOptions setTelemetry(TelemetryConfig telemetry) {
/**
* Gets the server-wide idle timeout for sessions in seconds.
*
- * @return the session idle timeout in seconds, or {@code null} to disable
- * (sessions live indefinitely)
+ * @return an {@link OptionalInt} containing the session idle timeout in
+ * seconds, or empty to disable (sessions live indefinitely)
* @since 1.3.0
*/
- public Integer getSessionIdleTimeoutSeconds() {
- return sessionIdleTimeoutSeconds;
+ @JsonIgnore
+ public OptionalInt getSessionIdleTimeoutSeconds() {
+ return sessionIdleTimeoutSeconds == null ? OptionalInt.empty() : OptionalInt.of(sessionIdleTimeoutSeconds);
}
/**
* Sets the server-wide idle timeout for sessions in seconds.
*
* Sessions without activity for this duration are automatically cleaned up. Set
- * to {@code 0} or leave as {@code null} to disable (sessions live
- * indefinitely).
+ * to {@code 0} to disable (sessions live indefinitely). Use
+ * {@link #clearSessionIdleTimeoutSeconds()} to revert to the default.
*
* This option is only used when the SDK spawns the CLI process; it is ignored
* when connecting to an external server via {@link #setCliUrl(String)}.
*
* @param sessionIdleTimeoutSeconds
- * the idle timeout in seconds, or {@code null} to disable
+ * the idle timeout in seconds
* @return this options instance for method chaining
* @since 1.3.0
*/
- public CopilotClientOptions setSessionIdleTimeoutSeconds(Integer sessionIdleTimeoutSeconds) {
+ public CopilotClientOptions setSessionIdleTimeoutSeconds(int sessionIdleTimeoutSeconds) {
this.sessionIdleTimeoutSeconds = sessionIdleTimeoutSeconds;
return this;
}
+ /**
+ * Clears the sessionIdleTimeoutSeconds setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public CopilotClientOptions clearSessionIdleTimeoutSeconds() {
+ this.sessionIdleTimeoutSeconds = null;
+ return this;
+ }
+
/**
* Gets the connection token for the headless CLI server (TCP only).
*
@@ -555,11 +570,11 @@ public CopilotClientOptions setTcpConnectionToken(String tcpConnectionToken) {
/**
* Returns whether to use the logged-in user for authentication.
*
- * @return {@code true} to use logged-in user auth, {@code false} to use only
- * explicit tokens, or {@code null} to use default behavior
+ * @return an {@link Optional} containing the boolean value, or empty if not set
*/
- public Boolean getUseLoggedInUser() {
- return useLoggedInUser;
+ @JsonIgnore
+ public Optional getUseLoggedInUser() {
+ return Optional.ofNullable(useLoggedInUser);
}
/**
@@ -569,15 +584,23 @@ public Boolean getUseLoggedInUser() {
* auth. When false, only explicit tokens (gitHubToken or environment variables)
* are used. Default: true (but defaults to false when gitHubToken is provided).
*
- * Passing {@code null} is equivalent to passing {@link Boolean#FALSE}.
*
* @param useLoggedInUser
- * {@code true} to use logged-in user auth, {@code false} or
- * {@code null} otherwise
+ * {@code true} to use logged-in user auth, {@code false} otherwise
* @return this options instance for method chaining
*/
- public CopilotClientOptions setUseLoggedInUser(Boolean useLoggedInUser) {
- this.useLoggedInUser = useLoggedInUser != null ? useLoggedInUser : Boolean.FALSE;
+ public CopilotClientOptions setUseLoggedInUser(boolean useLoggedInUser) {
+ this.useLoggedInUser = useLoggedInUser;
+ return this;
+ }
+
+ /**
+ * Clears the useLoggedInUser setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public CopilotClientOptions clearUseLoggedInUser() {
+ this.useLoggedInUser = null;
return this;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
index 12bab4154c..0160724bef 100644
--- a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
@@ -224,40 +224,68 @@ public Boolean getEnableSessionTelemetry() {
/**
* Sets enable session telemetry flag. @param enableSessionTelemetry the flag
*/
- public void setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
+ public void setEnableSessionTelemetry(boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
}
+ /**
+ * Clears the enableSessionTelemetry setting, reverting to the default behavior.
+ */
+ public void clearEnableSessionTelemetry() {
+ this.enableSessionTelemetry = null;
+ }
+
/** Gets request permission flag. @return the flag */
public Boolean getRequestPermission() {
return requestPermission;
}
/** Sets request permission flag. @param requestPermission the flag */
- public void setRequestPermission(Boolean requestPermission) {
+ public void setRequestPermission(boolean requestPermission) {
this.requestPermission = requestPermission;
}
+ /**
+ * Clears the requestPermission setting, reverting to the default behavior.
+ */
+ public void clearRequestPermission() {
+ this.requestPermission = null;
+ }
+
/** Gets request user input flag. @return the flag */
public Boolean getRequestUserInput() {
return requestUserInput;
}
/** Sets request user input flag. @param requestUserInput the flag */
- public void setRequestUserInput(Boolean requestUserInput) {
+ public void setRequestUserInput(boolean requestUserInput) {
this.requestUserInput = requestUserInput;
}
+ /**
+ * Clears the requestUserInput setting, reverting to the default behavior.
+ */
+ public void clearRequestUserInput() {
+ this.requestUserInput = null;
+ }
+
/** Gets hooks flag. @return the flag */
public Boolean getHooks() {
return hooks;
}
/** Sets hooks flag. @param hooks the flag */
- public void setHooks(Boolean hooks) {
+ public void setHooks(boolean hooks) {
this.hooks = hooks;
}
+ /**
+ * Clears the hooks setting, reverting to the default behavior.
+ */
+ public void clearHooks() {
+ this.hooks = null;
+ }
+
/** Gets working directory. @return the working directory */
public String getWorkingDirectory() {
return workingDirectory;
@@ -274,10 +302,17 @@ public Boolean getStreaming() {
}
/** Sets streaming flag. @param streaming the flag */
- public void setStreaming(Boolean streaming) {
+ public void setStreaming(boolean streaming) {
this.streaming = streaming;
}
+ /**
+ * Clears the streaming setting, reverting to the default behavior.
+ */
+ public void clearStreaming() {
+ this.streaming = null;
+ }
+
/** Gets MCP servers. @return the servers map */
public Map getMcpServers() {
return mcpServers == null ? null : Collections.unmodifiableMap(mcpServers);
@@ -388,10 +423,17 @@ public Boolean getEnableConfigDiscovery() {
}
/** Sets enable config discovery flag. @param enableConfigDiscovery the flag */
- public void setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
+ public void setEnableConfigDiscovery(boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
}
+ /**
+ * Clears the enableConfigDiscovery setting, reverting to the default behavior.
+ */
+ public void clearEnableConfigDiscovery() {
+ this.enableConfigDiscovery = null;
+ }
+
/** Gets include sub-agent streaming events flag. @return the flag */
public Boolean getIncludeSubAgentStreamingEvents() {
return includeSubAgentStreamingEvents;
@@ -401,10 +443,18 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* Sets include sub-agent streaming events flag. @param
* includeSubAgentStreamingEvents the flag
*/
- public void setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
+ public void setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
}
+ /**
+ * Clears the includeSubAgentStreamingEvents setting, reverting to the default
+ * behavior.
+ */
+ public void clearIncludeSubAgentStreamingEvents() {
+ this.includeSubAgentStreamingEvents = null;
+ }
+
/** Gets the commands wire definitions. @return the commands */
public List getCommands() {
return commands == null ? null : Collections.unmodifiableList(commands);
@@ -421,10 +471,17 @@ public Boolean getRequestElicitation() {
}
/** Sets the requestElicitation flag. @param requestElicitation the flag */
- public void setRequestElicitation(Boolean requestElicitation) {
+ public void setRequestElicitation(boolean requestElicitation) {
this.requestElicitation = requestElicitation;
}
+ /**
+ * Clears the requestElicitation setting, reverting to the default behavior.
+ */
+ public void clearRequestElicitation() {
+ this.requestElicitation = null;
+ }
+
/** Gets the requestExitPlanMode flag. @return the flag */
public Boolean getRequestExitPlanMode() {
return requestExitPlanMode;
diff --git a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
index 1421db603f..c40d1b3c50 100644
--- a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
@@ -10,6 +10,8 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
/**
* Configuration for a custom agent in a Copilot session.
@@ -199,8 +201,9 @@ public CustomAgentConfig setMcpServers(Map mcpServers)
*
* @return the infer flag, or {@code null} if not set
*/
- public Boolean getInfer() {
- return infer;
+ @JsonIgnore
+ public Optional getInfer() {
+ return Optional.ofNullable(infer);
}
/**
@@ -210,11 +213,21 @@ public Boolean getInfer() {
* {@code true} to enable inference mode
* @return this config for method chaining
*/
- public CustomAgentConfig setInfer(Boolean infer) {
+ public CustomAgentConfig setInfer(boolean infer) {
this.infer = infer;
return this;
}
+ /**
+ * Clears the infer setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public CustomAgentConfig clearInfer() {
+ this.infer = null;
+ return this;
+ }
+
/**
* Gets the list of skill names to preload into this agent's context.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java
index d45851f8a1..561796ede7 100644
--- a/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java
@@ -6,6 +6,9 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
+import java.util.OptionalDouble;
/**
* Configuration for infinite sessions with automatic context compaction and
@@ -43,10 +46,12 @@ public class InfiniteSessionConfig {
/**
* Gets whether infinite sessions are enabled.
*
- * @return {@code true} if enabled, {@code null} to use default (true)
+ * @return an {@link Optional} containing the boolean value, or empty to use
+ * default (true)
*/
- public Boolean getEnabled() {
- return enabled;
+ @JsonIgnore
+ public Optional getEnabled() {
+ return Optional.ofNullable(enabled);
}
/**
@@ -58,18 +63,32 @@ public Boolean getEnabled() {
* {@code true} to enable infinite sessions
* @return this config instance for method chaining
*/
- public InfiniteSessionConfig setEnabled(Boolean enabled) {
+ public InfiniteSessionConfig setEnabled(boolean enabled) {
this.enabled = enabled;
return this;
}
+ /**
+ * Clears the enabled setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InfiniteSessionConfig clearEnabled() {
+ this.enabled = null;
+ return this;
+ }
+
/**
* Gets the background compaction threshold.
*
- * @return the threshold (0.0-1.0), or {@code null} to use default
+ * @return an {@link OptionalDouble} containing the threshold (0.0-1.0), or
+ * empty to use default
*/
- public Double getBackgroundCompactionThreshold() {
- return backgroundCompactionThreshold;
+ @JsonIgnore
+ public OptionalDouble getBackgroundCompactionThreshold() {
+ return backgroundCompactionThreshold == null
+ ? OptionalDouble.empty()
+ : OptionalDouble.of(backgroundCompactionThreshold);
}
/**
@@ -82,18 +101,33 @@ public Double getBackgroundCompactionThreshold() {
* the threshold (0.0-1.0)
* @return this config instance for method chaining
*/
- public InfiniteSessionConfig setBackgroundCompactionThreshold(Double backgroundCompactionThreshold) {
+ public InfiniteSessionConfig setBackgroundCompactionThreshold(double backgroundCompactionThreshold) {
this.backgroundCompactionThreshold = backgroundCompactionThreshold;
return this;
}
+ /**
+ * Clears the backgroundCompactionThreshold setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InfiniteSessionConfig clearBackgroundCompactionThreshold() {
+ this.backgroundCompactionThreshold = null;
+ return this;
+ }
+
/**
* Gets the buffer exhaustion threshold.
*
- * @return the threshold (0.0-1.0), or {@code null} to use default
+ * @return an {@link OptionalDouble} containing the threshold (0.0-1.0), or
+ * empty to use default
*/
- public Double getBufferExhaustionThreshold() {
- return bufferExhaustionThreshold;
+ @JsonIgnore
+ public OptionalDouble getBufferExhaustionThreshold() {
+ return bufferExhaustionThreshold == null
+ ? OptionalDouble.empty()
+ : OptionalDouble.of(bufferExhaustionThreshold);
}
/**
@@ -107,8 +141,20 @@ public Double getBufferExhaustionThreshold() {
* the threshold (0.0-1.0)
* @return this config instance for method chaining
*/
- public InfiniteSessionConfig setBufferExhaustionThreshold(Double bufferExhaustionThreshold) {
+ public InfiniteSessionConfig setBufferExhaustionThreshold(double bufferExhaustionThreshold) {
this.bufferExhaustionThreshold = bufferExhaustionThreshold;
return this;
}
+
+ /**
+ * Clears the bufferExhaustionThreshold setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InfiniteSessionConfig clearBufferExhaustionThreshold() {
+ this.bufferExhaustionThreshold = null;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/github/copilot/sdk/json/InputOptions.java b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
index 9b0b6c8dd8..3b66476a18 100644
--- a/src/main/java/com/github/copilot/sdk/json/InputOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
@@ -4,6 +4,8 @@
package com.github.copilot.sdk.json;
+import java.util.OptionalInt;
+
/**
* Options for the {@link SessionUiApi#input(String, InputOptions)} convenience
* method.
@@ -47,33 +49,53 @@ public InputOptions setDescription(String description) {
}
/** Gets the minimum character length. @return the min length */
- public Integer getMinLength() {
- return minLength;
+ public OptionalInt getMinLength() {
+ return minLength == null ? OptionalInt.empty() : OptionalInt.of(minLength);
}
/**
* Sets the minimum character length. @param minLength the min length @return
* this
*/
- public InputOptions setMinLength(Integer minLength) {
+ public InputOptions setMinLength(int minLength) {
this.minLength = minLength;
return this;
}
+ /**
+ * Clears the minLength setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InputOptions clearMinLength() {
+ this.minLength = null;
+ return this;
+ }
+
/** Gets the maximum character length. @return the max length */
- public Integer getMaxLength() {
- return maxLength;
+ public OptionalInt getMaxLength() {
+ return maxLength == null ? OptionalInt.empty() : OptionalInt.of(maxLength);
}
/**
* Sets the maximum character length. @param maxLength the max length @return
* this
*/
- public InputOptions setMaxLength(Integer maxLength) {
+ public InputOptions setMaxLength(int maxLength) {
this.maxLength = maxLength;
return this;
}
+ /**
+ * Clears the maxLength setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InputOptions clearMaxLength() {
+ this.maxLength = null;
+ return this;
+ }
+
/**
* Gets the semantic format hint (e.g., {@code "email"}, {@code "uri"},
* {@code "date"}, {@code "date-time"}).
diff --git a/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java b/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java
index 7017db3d2d..9c5b8dbedc 100644
--- a/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java
@@ -99,7 +99,7 @@ public McpHttpServerConfig setTools(List tools) {
}
@Override
- public McpHttpServerConfig setTimeout(Integer timeout) {
+ public McpHttpServerConfig setTimeout(int timeout) {
super.setTimeout(timeout);
return this;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/McpServerConfig.java b/src/main/java/com/github/copilot/sdk/json/McpServerConfig.java
index 7cf39af6b6..b7f56b05a8 100644
--- a/src/main/java/com/github/copilot/sdk/json/McpServerConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/McpServerConfig.java
@@ -11,6 +11,8 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.OptionalInt;
/**
* Abstract base class for MCP (Model Context Protocol) server configurations.
@@ -68,21 +70,34 @@ public McpServerConfig setTools(List tools) {
/**
* Gets the optional timeout in milliseconds for tool calls to this server.
*
- * @return the timeout in milliseconds, or {@code null} for the default
+ * @return an {@link OptionalInt} containing the timeout in milliseconds, or
+ * empty for the default
*/
- public Integer getTimeout() {
- return timeout;
+ @JsonIgnore
+ public OptionalInt getTimeout() {
+ return timeout == null ? OptionalInt.empty() : OptionalInt.of(timeout);
}
/**
* Sets an optional timeout in milliseconds for tool calls to this server.
*
* @param timeout
- * the timeout in milliseconds, or {@code null} for the default
+ * the timeout in milliseconds
* @return this config for method chaining
*/
- public McpServerConfig setTimeout(Integer timeout) {
+ public McpServerConfig setTimeout(int timeout) {
this.timeout = timeout;
return this;
}
+
+ /**
+ * Clears the timeout setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public McpServerConfig clearTimeout() {
+ this.timeout = null;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/github/copilot/sdk/json/McpStdioServerConfig.java b/src/main/java/com/github/copilot/sdk/json/McpStdioServerConfig.java
index 900034be61..eef4d1e7d5 100644
--- a/src/main/java/com/github/copilot/sdk/json/McpStdioServerConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/McpStdioServerConfig.java
@@ -148,7 +148,7 @@ public McpStdioServerConfig setTools(List tools) {
}
@Override
- public McpStdioServerConfig setTimeout(Integer timeout) {
+ public McpStdioServerConfig setTimeout(int timeout) {
super.setTimeout(timeout);
return this;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java b/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
index 18701ad671..ab242d83de 100644
--- a/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
+++ b/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
@@ -7,6 +7,9 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
+import java.util.OptionalInt;
/**
* Per-property overrides for model capabilities, deep-merged over runtime
@@ -109,8 +112,9 @@ public static class Supports {
* @return {@code true} to enable vision, {@code false} to disable, or
* {@code null} to use the runtime default
*/
- public Boolean getVision() {
- return vision;
+ @JsonIgnore
+ public Optional getVision() {
+ return Optional.ofNullable(vision);
}
/**
@@ -121,19 +125,30 @@ public Boolean getVision() {
* to use the runtime default
* @return this instance for method chaining
*/
- public Supports setVision(Boolean vision) {
+ public Supports setVision(boolean vision) {
this.vision = vision;
return this;
}
+ /**
+ * Clears the vision setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Supports clearVision() {
+ this.vision = null;
+ return this;
+ }
+
/**
* Gets the reasoning effort override.
*
* @return {@code true} to enable reasoning effort, {@code false} to disable, or
* {@code null} to use the runtime default
*/
- public Boolean getReasoningEffort() {
- return reasoningEffort;
+ @JsonIgnore
+ public Optional getReasoningEffort() {
+ return Optional.ofNullable(reasoningEffort);
}
/**
@@ -144,10 +159,21 @@ public Boolean getReasoningEffort() {
* to use the runtime default
* @return this instance for method chaining
*/
- public Supports setReasoningEffort(Boolean reasoningEffort) {
+ public Supports setReasoningEffort(boolean reasoningEffort) {
this.reasoningEffort = reasoningEffort;
return this;
}
+
+ /**
+ * Clears the reasoningEffort setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Supports clearReasoningEffort() {
+ this.reasoningEffort = null;
+ return this;
+ }
+
}
/**
@@ -174,8 +200,9 @@ public static class Limits {
*
* @return the override value, or {@code null} to use the runtime default
*/
- public Integer getMaxPromptTokens() {
- return maxPromptTokens;
+ @JsonIgnore
+ public OptionalInt getMaxPromptTokens() {
+ return maxPromptTokens == null ? OptionalInt.empty() : OptionalInt.of(maxPromptTokens);
}
/**
@@ -185,18 +212,29 @@ public Integer getMaxPromptTokens() {
* the override value, or {@code null} to use the runtime default
* @return this instance for method chaining
*/
- public Limits setMaxPromptTokens(Integer maxPromptTokens) {
+ public Limits setMaxPromptTokens(int maxPromptTokens) {
this.maxPromptTokens = maxPromptTokens;
return this;
}
+ /**
+ * Clears the maxPromptTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Limits clearMaxPromptTokens() {
+ this.maxPromptTokens = null;
+ return this;
+ }
+
/**
* Gets the maximum output tokens override.
*
* @return the override value, or {@code null} to use the runtime default
*/
- public Integer getMaxOutputTokens() {
- return maxOutputTokens;
+ @JsonIgnore
+ public OptionalInt getMaxOutputTokens() {
+ return maxOutputTokens == null ? OptionalInt.empty() : OptionalInt.of(maxOutputTokens);
}
/**
@@ -206,18 +244,29 @@ public Integer getMaxOutputTokens() {
* the override value, or {@code null} to use the runtime default
* @return this instance for method chaining
*/
- public Limits setMaxOutputTokens(Integer maxOutputTokens) {
+ public Limits setMaxOutputTokens(int maxOutputTokens) {
this.maxOutputTokens = maxOutputTokens;
return this;
}
+ /**
+ * Clears the maxOutputTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Limits clearMaxOutputTokens() {
+ this.maxOutputTokens = null;
+ return this;
+ }
+
/**
* Gets the maximum context window tokens override.
*
* @return the override value, or {@code null} to use the runtime default
*/
- public Integer getMaxContextWindowTokens() {
- return maxContextWindowTokens;
+ @JsonIgnore
+ public OptionalInt getMaxContextWindowTokens() {
+ return maxContextWindowTokens == null ? OptionalInt.empty() : OptionalInt.of(maxContextWindowTokens);
}
/**
@@ -227,9 +276,20 @@ public Integer getMaxContextWindowTokens() {
* the override value, or {@code null} to use the runtime default
* @return this instance for method chaining
*/
- public Limits setMaxContextWindowTokens(Integer maxContextWindowTokens) {
+ public Limits setMaxContextWindowTokens(int maxContextWindowTokens) {
this.maxContextWindowTokens = maxContextWindowTokens;
return this;
}
+
+ /**
+ * Clears the maxContextWindowTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Limits clearMaxContextWindowTokens() {
+ this.maxContextWindowTokens = null;
+ return this;
+ }
+
}
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ModelLimits.java b/src/main/java/com/github/copilot/sdk/json/ModelLimits.java
index 734a50deda..fedecd6d36 100644
--- a/src/main/java/com/github/copilot/sdk/json/ModelLimits.java
+++ b/src/main/java/com/github/copilot/sdk/json/ModelLimits.java
@@ -6,6 +6,8 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.OptionalInt;
/**
* Model limits.
@@ -24,15 +26,26 @@ public class ModelLimits {
@JsonProperty("vision")
private ModelVisionLimits vision;
- public Integer getMaxPromptTokens() {
- return maxPromptTokens;
+ @JsonIgnore
+ public OptionalInt getMaxPromptTokens() {
+ return maxPromptTokens == null ? OptionalInt.empty() : OptionalInt.of(maxPromptTokens);
}
- public ModelLimits setMaxPromptTokens(Integer maxPromptTokens) {
+ public ModelLimits setMaxPromptTokens(int maxPromptTokens) {
this.maxPromptTokens = maxPromptTokens;
return this;
}
+ /**
+ * Clears the maxPromptTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ModelLimits clearMaxPromptTokens() {
+ this.maxPromptTokens = null;
+ return this;
+ }
+
public int getMaxContextWindowTokens() {
return maxContextWindowTokens;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java b/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
index 8947696c9a..3826f9dd83 100644
--- a/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
@@ -9,6 +9,8 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.OptionalInt;
/**
* Configuration for a custom API provider (BYOK - Bring Your Own Key).
@@ -298,8 +300,9 @@ public ProviderConfig setWireModel(String wireModel) {
*
* @return the max prompt tokens, or {@code null} if not set
*/
- public Integer getMaxPromptTokens() {
- return maxPromptTokens;
+ @JsonIgnore
+ public OptionalInt getMaxPromptTokens() {
+ return maxPromptTokens == null ? OptionalInt.empty() : OptionalInt.of(maxPromptTokens);
}
/**
@@ -314,18 +317,29 @@ public Integer getMaxPromptTokens() {
* the max prompt tokens
* @return this config for method chaining
*/
- public ProviderConfig setMaxPromptTokens(Integer maxPromptTokens) {
+ public ProviderConfig setMaxPromptTokens(int maxPromptTokens) {
this.maxPromptTokens = maxPromptTokens;
return this;
}
+ /**
+ * Clears the maxPromptTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ProviderConfig clearMaxPromptTokens() {
+ this.maxPromptTokens = null;
+ return this;
+ }
+
/**
* Gets the maximum output token override.
*
* @return the max output tokens, or {@code null} if not set
*/
- public Integer getMaxOutputTokens() {
- return maxOutputTokens;
+ @JsonIgnore
+ public OptionalInt getMaxOutputTokens() {
+ return maxOutputTokens == null ? OptionalInt.empty() : OptionalInt.of(maxOutputTokens);
}
/**
@@ -338,8 +352,19 @@ public Integer getMaxOutputTokens() {
* the max output tokens
* @return this config for method chaining
*/
- public ProviderConfig setMaxOutputTokens(Integer maxOutputTokens) {
+ public ProviderConfig setMaxOutputTokens(int maxOutputTokens) {
this.maxOutputTokens = maxOutputTokens;
return this;
}
+
+ /**
+ * Clears the maxOutputTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ProviderConfig clearMaxOutputTokens() {
+ this.maxOutputTokens = null;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
index f2caad7710..9d76212140 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
@@ -11,8 +11,10 @@
import java.util.function.Consumer;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.copilot.sdk.generated.SessionEvent;
+import java.util.Optional;
/**
* Configuration for resuming an existing Copilot session.
@@ -244,8 +246,9 @@ public ResumeSessionConfig setProvider(ProviderConfig provider) {
*
* @return whether session telemetry is enabled
*/
- public Boolean getEnableSessionTelemetry() {
- return enableSessionTelemetry;
+ @JsonIgnore
+ public Optional getEnableSessionTelemetry() {
+ return Optional.ofNullable(enableSessionTelemetry);
}
/**
@@ -259,11 +262,21 @@ public Boolean getEnableSessionTelemetry() {
* whether to enable session telemetry
* @return this config for method chaining
*/
- public ResumeSessionConfig setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
+ public ResumeSessionConfig setEnableSessionTelemetry(boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
return this;
}
+ /**
+ * Clears the enableSessionTelemetry setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ResumeSessionConfig clearEnableSessionTelemetry() {
+ this.enableSessionTelemetry = null;
+ return this;
+ }
+
/**
* Gets the reasoning effort level.
*
@@ -403,8 +416,9 @@ public ResumeSessionConfig setConfigDir(String configDir) {
* @return {@code true} to enable discovery, {@code false} to disable, or
* {@code null} to use the runtime default
*/
- public Boolean getEnableConfigDiscovery() {
- return enableConfigDiscovery;
+ @JsonIgnore
+ public Optional getEnableConfigDiscovery() {
+ return Optional.ofNullable(enableConfigDiscovery);
}
/**
@@ -420,19 +434,30 @@ public Boolean getEnableConfigDiscovery() {
* {@code null} to use the runtime default
* @return this config for method chaining
*/
- public ResumeSessionConfig setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
+ public ResumeSessionConfig setEnableConfigDiscovery(boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
return this;
}
+ /**
+ * Clears the enableConfigDiscovery setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ResumeSessionConfig clearEnableConfigDiscovery() {
+ this.enableConfigDiscovery = null;
+ return this;
+ }
+
/**
* Gets whether sub-agent streaming events are included.
*
* @return {@code true} to include sub-agent streaming events, {@code false} to
* suppress them, or {@code null} to use the runtime default
*/
- public Boolean getIncludeSubAgentStreamingEvents() {
- return includeSubAgentStreamingEvents;
+ @JsonIgnore
+ public Optional getIncludeSubAgentStreamingEvents() {
+ return Optional.ofNullable(includeSubAgentStreamingEvents);
}
/**
@@ -443,11 +468,22 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* suppress
* @return this config for method chaining
*/
- public ResumeSessionConfig setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
+ public ResumeSessionConfig setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
return this;
}
+ /**
+ * Clears the includeSubAgentStreamingEvents setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ResumeSessionConfig clearIncludeSubAgentStreamingEvents() {
+ this.includeSubAgentStreamingEvents = null;
+ return this;
+ }
+
/**
* Gets the model capabilities override.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
index a1af269700..054fc8fba9 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
@@ -231,40 +231,68 @@ public Boolean getEnableSessionTelemetry() {
/**
* Sets enable session telemetry flag. @param enableSessionTelemetry the flag
*/
- public void setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
+ public void setEnableSessionTelemetry(boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
}
+ /**
+ * Clears the enableSessionTelemetry setting, reverting to the default behavior.
+ */
+ public void clearEnableSessionTelemetry() {
+ this.enableSessionTelemetry = null;
+ }
+
/** Gets request permission flag. @return the flag */
public Boolean getRequestPermission() {
return requestPermission;
}
/** Sets request permission flag. @param requestPermission the flag */
- public void setRequestPermission(Boolean requestPermission) {
+ public void setRequestPermission(boolean requestPermission) {
this.requestPermission = requestPermission;
}
+ /**
+ * Clears the requestPermission setting, reverting to the default behavior.
+ */
+ public void clearRequestPermission() {
+ this.requestPermission = null;
+ }
+
/** Gets request user input flag. @return the flag */
public Boolean getRequestUserInput() {
return requestUserInput;
}
/** Sets request user input flag. @param requestUserInput the flag */
- public void setRequestUserInput(Boolean requestUserInput) {
+ public void setRequestUserInput(boolean requestUserInput) {
this.requestUserInput = requestUserInput;
}
+ /**
+ * Clears the requestUserInput setting, reverting to the default behavior.
+ */
+ public void clearRequestUserInput() {
+ this.requestUserInput = null;
+ }
+
/** Gets hooks flag. @return the flag */
public Boolean getHooks() {
return hooks;
}
/** Sets hooks flag. @param hooks the flag */
- public void setHooks(Boolean hooks) {
+ public void setHooks(boolean hooks) {
this.hooks = hooks;
}
+ /**
+ * Clears the hooks setting, reverting to the default behavior.
+ */
+ public void clearHooks() {
+ this.hooks = null;
+ }
+
/** Gets working directory. @return the working directory */
public String getWorkingDirectory() {
return workingDirectory;
@@ -291,30 +319,51 @@ public Boolean getEnableConfigDiscovery() {
}
/** Sets enable config discovery flag. @param enableConfigDiscovery the flag */
- public void setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
+ public void setEnableConfigDiscovery(boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
}
+ /**
+ * Clears the enableConfigDiscovery setting, reverting to the default behavior.
+ */
+ public void clearEnableConfigDiscovery() {
+ this.enableConfigDiscovery = null;
+ }
+
/** Gets disable resume flag. @return the flag */
public Boolean getDisableResume() {
return disableResume;
}
/** Sets disable resume flag. @param disableResume the flag */
- public void setDisableResume(Boolean disableResume) {
+ public void setDisableResume(boolean disableResume) {
this.disableResume = disableResume;
}
+ /**
+ * Clears the disableResume setting, reverting to the default behavior.
+ */
+ public void clearDisableResume() {
+ this.disableResume = null;
+ }
+
/** Gets streaming flag. @return the flag */
public Boolean getStreaming() {
return streaming;
}
/** Sets streaming flag. @param streaming the flag */
- public void setStreaming(Boolean streaming) {
+ public void setStreaming(boolean streaming) {
this.streaming = streaming;
}
+ /**
+ * Clears the streaming setting, reverting to the default behavior.
+ */
+ public void clearStreaming() {
+ this.streaming = null;
+ }
+
/** Gets include sub-agent streaming events flag. @return the flag */
public Boolean getIncludeSubAgentStreamingEvents() {
return includeSubAgentStreamingEvents;
@@ -324,10 +373,18 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* Sets include sub-agent streaming events flag. @param
* includeSubAgentStreamingEvents the flag
*/
- public void setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
+ public void setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
}
+ /**
+ * Clears the includeSubAgentStreamingEvents setting, reverting to the default
+ * behavior.
+ */
+ public void clearIncludeSubAgentStreamingEvents() {
+ this.includeSubAgentStreamingEvents = null;
+ }
+
/** Gets MCP servers. @return the servers map */
public Map getMcpServers() {
return mcpServers == null ? null : Collections.unmodifiableMap(mcpServers);
@@ -441,10 +498,17 @@ public Boolean getRequestElicitation() {
}
/** Sets the requestElicitation flag. @param requestElicitation the flag */
- public void setRequestElicitation(Boolean requestElicitation) {
+ public void setRequestElicitation(boolean requestElicitation) {
this.requestElicitation = requestElicitation;
}
+ /**
+ * Clears the requestElicitation setting, reverting to the default behavior.
+ */
+ public void clearRequestElicitation() {
+ this.requestElicitation = null;
+ }
+
/** Gets the requestExitPlanMode flag. @return the flag */
public Boolean getRequestExitPlanMode() {
return requestExitPlanMode;
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
index 51cad884ed..c83aa00fca 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
@@ -11,8 +11,10 @@
import java.util.function.Consumer;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.copilot.sdk.generated.SessionEvent;
+import java.util.Optional;
/**
* Configuration for creating a new Copilot session.
@@ -298,8 +300,9 @@ public SessionConfig setProvider(ProviderConfig provider) {
*
* @return whether session telemetry is enabled
*/
- public Boolean getEnableSessionTelemetry() {
- return enableSessionTelemetry;
+ @JsonIgnore
+ public Optional getEnableSessionTelemetry() {
+ return Optional.ofNullable(enableSessionTelemetry);
}
/**
@@ -313,11 +316,21 @@ public Boolean getEnableSessionTelemetry() {
* whether to enable session telemetry
* @return this config instance for method chaining
*/
- public SessionConfig setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
+ public SessionConfig setEnableSessionTelemetry(boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
return this;
}
+ /**
+ * Clears the enableSessionTelemetry setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public SessionConfig clearEnableSessionTelemetry() {
+ this.enableSessionTelemetry = null;
+ return this;
+ }
+
/**
* Gets the permission request handler.
*
@@ -661,8 +674,9 @@ public SessionConfig setConfigDir(String configDir) {
* @return {@code true} to enable discovery, {@code false} to disable, or
* {@code null} to use the runtime default
*/
- public Boolean getEnableConfigDiscovery() {
- return enableConfigDiscovery;
+ @JsonIgnore
+ public Optional getEnableConfigDiscovery() {
+ return Optional.ofNullable(enableConfigDiscovery);
}
/**
@@ -680,19 +694,30 @@ public Boolean getEnableConfigDiscovery() {
* {@code null} to use the runtime default
* @return this config instance for method chaining
*/
- public SessionConfig setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
+ public SessionConfig setEnableConfigDiscovery(boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
return this;
}
+ /**
+ * Clears the enableConfigDiscovery setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public SessionConfig clearEnableConfigDiscovery() {
+ this.enableConfigDiscovery = null;
+ return this;
+ }
+
/**
* Gets whether sub-agent streaming events are included.
*
* @return {@code true} to include sub-agent streaming events, {@code false} to
* suppress them, or {@code null} to use the runtime default
*/
- public Boolean getIncludeSubAgentStreamingEvents() {
- return includeSubAgentStreamingEvents;
+ @JsonIgnore
+ public Optional getIncludeSubAgentStreamingEvents() {
+ return Optional.ofNullable(includeSubAgentStreamingEvents);
}
/**
@@ -709,11 +734,22 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* suppress
* @return this config instance for method chaining
*/
- public SessionConfig setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
+ public SessionConfig setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
return this;
}
+ /**
+ * Clears the includeSubAgentStreamingEvents setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public SessionConfig clearIncludeSubAgentStreamingEvents() {
+ this.includeSubAgentStreamingEvents = null;
+ return this;
+ }
+
/**
* Gets the model capabilities override.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java b/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
index 9b8e0b5872..06ddfc760d 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
@@ -4,6 +4,11 @@
package com.github.copilot.sdk.json;
+import java.util.Optional;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
/**
* UI-specific capability flags for a session.
*
@@ -11,16 +16,17 @@
*/
public class SessionUiCapabilities {
+ @JsonProperty("elicitation")
private Boolean elicitation;
/**
* Returns whether the host supports interactive elicitation dialogs.
*
- * @return {@code true} if elicitation is supported, {@code false} or
- * {@code null} otherwise
+ * @return an {@link Optional} containing the boolean value, or empty if not set
*/
- public Boolean getElicitation() {
- return elicitation;
+ @JsonIgnore
+ public Optional getElicitation() {
+ return Optional.ofNullable(elicitation);
}
/**
@@ -30,8 +36,19 @@ public Boolean getElicitation() {
* {@code true} if elicitation is supported
* @return this instance for method chaining
*/
- public SessionUiCapabilities setElicitation(Boolean elicitation) {
+ public SessionUiCapabilities setElicitation(boolean elicitation) {
this.elicitation = elicitation;
return this;
}
+
+ /**
+ * Clears the elicitation setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public SessionUiCapabilities clearElicitation() {
+ this.elicitation = null;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
index 8407ab6098..9b28a3150a 100644
--- a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
@@ -4,6 +4,10 @@
package com.github.copilot.sdk.json;
+import java.util.Optional;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
/**
* OpenTelemetry configuration for the Copilot CLI server.
*
@@ -131,8 +135,9 @@ public TelemetryConfig setSourceName(String sourceName) {
* @return {@code true} to capture content, {@code false} to suppress it, or
* {@code null} to use the default
*/
- public Boolean getCaptureContent() {
- return captureContent;
+ @JsonIgnore
+ public Optional getCaptureContent() {
+ return Optional.ofNullable(captureContent);
}
/**
@@ -142,8 +147,19 @@ public Boolean getCaptureContent() {
* {@code true} to capture content, {@code false} to suppress it
* @return this config for method chaining
*/
- public TelemetryConfig setCaptureContent(Boolean captureContent) {
+ public TelemetryConfig setCaptureContent(boolean captureContent) {
this.captureContent = captureContent;
return this;
}
+
+ /**
+ * Clears the captureContent setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public TelemetryConfig clearCaptureContent() {
+ this.captureContent = null;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
index 9b466f866c..dfbb1b6da3 100644
--- a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
@@ -9,6 +9,8 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
/**
* Request for user input from the agent.
@@ -78,8 +80,9 @@ public UserInputRequest setChoices(List choices) {
* @return {@code true} if freeform input is allowed, {@code null} if not
* specified
*/
- public Boolean getAllowFreeform() {
- return allowFreeform;
+ @JsonIgnore
+ public Optional getAllowFreeform() {
+ return Optional.ofNullable(allowFreeform);
}
/**
@@ -89,8 +92,19 @@ public Boolean getAllowFreeform() {
* {@code true} to allow freeform input
* @return this instance for method chaining
*/
- public UserInputRequest setAllowFreeform(Boolean allowFreeform) {
+ public UserInputRequest setAllowFreeform(boolean allowFreeform) {
this.allowFreeform = allowFreeform;
return this;
}
+
+ /**
+ * Clears the allowFreeform setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public UserInputRequest clearAllowFreeform() {
+ this.allowFreeform = null;
+ return this;
+ }
+
}
diff --git a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
index 7abc47e4a4..af92baa7e2 100644
--- a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
+++ b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
@@ -203,7 +203,7 @@ void sessionConfigEnableSessionTelemetryCopied() {
SessionConfig cloned = original.clone();
- assertFalse(cloned.getEnableSessionTelemetry());
+ assertFalse(cloned.getEnableSessionTelemetry().orElse(true));
}
@Test
@@ -212,7 +212,7 @@ void sessionConfigEnableSessionTelemetryDefaultIsNull() {
SessionConfig cloned = original.clone();
- assertNull(cloned.getEnableSessionTelemetry());
+ assertTrue(cloned.getEnableSessionTelemetry().isEmpty());
}
@Test
@@ -222,7 +222,7 @@ void resumeSessionConfigEnableSessionTelemetryCopied() {
ResumeSessionConfig cloned = original.clone();
- assertFalse(cloned.getEnableSessionTelemetry());
+ assertFalse(cloned.getEnableSessionTelemetry().orElse(true));
}
@Test
@@ -231,7 +231,7 @@ void resumeSessionConfigEnableSessionTelemetryDefaultIsNull() {
ResumeSessionConfig cloned = original.clone();
- assertNull(cloned.getEnableSessionTelemetry());
+ assertTrue(cloned.getEnableSessionTelemetry().isEmpty());
}
@Test
@@ -301,11 +301,11 @@ void copilotClientOptionsSetTelemetry() {
}
@Test
- void copilotClientOptionsSetUseLoggedInUserNull() {
+ void copilotClientOptionsSetUseLoggedInUserClear() {
var opts = new CopilotClientOptions();
- opts.setUseLoggedInUser(null);
- // null → Boolean.FALSE
- assertEquals(Boolean.FALSE, opts.getUseLoggedInUser());
+ opts.setUseLoggedInUser(true);
+ opts.clearUseLoggedInUser();
+ assertTrue(opts.getUseLoggedInUser().isEmpty());
}
@Test
@@ -375,7 +375,7 @@ void copilotClientOptionsSessionIdleTimeoutCloned() {
CopilotClientOptions cloned = original.clone();
- assertEquals(600, cloned.getSessionIdleTimeoutSeconds());
+ assertEquals(600, cloned.getSessionIdleTimeoutSeconds().getAsInt());
}
@Test
diff --git a/src/test/java/com/github/copilot/sdk/CopilotClientTest.java b/src/test/java/com/github/copilot/sdk/CopilotClientTest.java
index b0430959b9..14ed8ca89e 100644
--- a/src/test/java/com/github/copilot/sdk/CopilotClientTest.java
+++ b/src/test/java/com/github/copilot/sdk/CopilotClientTest.java
@@ -20,6 +20,7 @@
import java.util.concurrent.ExecutionException;
import static org.junit.jupiter.api.Assertions.*;
+import java.util.Optional;
/**
* Tests for CopilotClient.
@@ -153,14 +154,14 @@ void testGitHubTokenOptionAccepted() {
void testUseLoggedInUserDefaultsToNull() {
var options = new CopilotClientOptions().setCliPath("/path/to/cli");
- assertNull(options.getUseLoggedInUser());
+ assertTrue(options.getUseLoggedInUser().isEmpty());
}
@Test
void testExplicitUseLoggedInUserFalse() {
var options = new CopilotClientOptions().setCliPath("/path/to/cli").setUseLoggedInUser(false);
- assertEquals(false, options.getUseLoggedInUser());
+ assertEquals(Optional.of(false), options.getUseLoggedInUser());
}
@Test
@@ -168,7 +169,7 @@ void testExplicitUseLoggedInUserTrueWithGitHubToken() {
var options = new CopilotClientOptions().setCliPath("/path/to/cli").setGitHubToken("gho_test_token")
.setUseLoggedInUser(true);
- assertEquals(true, options.getUseLoggedInUser());
+ assertEquals(Optional.of(true), options.getUseLoggedInUser());
}
@Test
@@ -189,14 +190,14 @@ void testUseLoggedInUserWithCliUrlThrows() {
void testSessionIdleTimeoutSecondsDefaultsToNull() {
var options = new CopilotClientOptions();
- assertNull(options.getSessionIdleTimeoutSeconds());
+ assertTrue(options.getSessionIdleTimeoutSeconds().isEmpty());
}
@Test
void testSessionIdleTimeoutSecondsOptionAccepted() {
var options = new CopilotClientOptions().setSessionIdleTimeoutSeconds(600);
- assertEquals(600, options.getSessionIdleTimeoutSeconds());
+ assertEquals(600, options.getSessionIdleTimeoutSeconds().getAsInt());
}
@Test
diff --git a/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java b/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
index b61c93559b..e8e983a4ca 100644
--- a/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
+++ b/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
@@ -194,7 +194,7 @@ void mcpHttpServerConfigCoversGettersAndFluentSetters() {
assertEquals("https://mcp.example.com/sse", cfg.getUrl());
assertEquals("Bearer token", cfg.getHeaders().get("Authorization"));
assertEquals(tools, cfg.getTools());
- assertEquals(45, cfg.getTimeout());
+ assertEquals(45, cfg.getTimeout().getAsInt());
}
@Test
@@ -212,22 +212,21 @@ void mcpStdioServerConfigCoversGettersAndFluentSetters() {
assertEquals("1", cfg.getEnv().get("DEBUG"));
assertEquals("/tmp", cfg.getWorkingDirectory());
assertEquals(tools, cfg.getTools());
- assertEquals(30, cfg.getTimeout());
+ assertEquals(30, cfg.getTimeout().getAsInt());
}
@Test
void modelCapabilitiesOverrideCoversNestedSupportsAndLimits() {
- var supports = new ModelCapabilitiesOverride.Supports().setVision(Boolean.TRUE)
- .setReasoningEffort(Boolean.FALSE);
+ var supports = new ModelCapabilitiesOverride.Supports().setVision(true).setReasoningEffort(false);
var limits = new ModelCapabilitiesOverride.Limits().setMaxPromptTokens(2048).setMaxOutputTokens(512)
.setMaxContextWindowTokens(8192);
var override = new ModelCapabilitiesOverride().setSupports(supports).setLimits(limits);
- assertTrue(override.getSupports().getVision());
- assertFalse(override.getSupports().getReasoningEffort());
- assertEquals(2048, override.getLimits().getMaxPromptTokens());
- assertEquals(512, override.getLimits().getMaxOutputTokens());
- assertEquals(8192, override.getLimits().getMaxContextWindowTokens());
+ assertTrue(override.getSupports().getVision().orElse(false));
+ assertFalse(override.getSupports().getReasoningEffort().orElse(true));
+ assertEquals(2048, override.getLimits().getMaxPromptTokens().getAsInt());
+ assertEquals(512, override.getLimits().getMaxOutputTokens().getAsInt());
+ assertEquals(8192, override.getLimits().getMaxContextWindowTokens().getAsInt());
}
}
diff --git a/src/test/java/com/github/copilot/sdk/ElicitationTest.java b/src/test/java/com/github/copilot/sdk/ElicitationTest.java
index 6b748b4cc2..bf3c0bfb29 100644
--- a/src/test/java/com/github/copilot/sdk/ElicitationTest.java
+++ b/src/test/java/com/github/copilot/sdk/ElicitationTest.java
@@ -40,7 +40,7 @@ void sessionCapabilitiesTypesAreProperlyStructured() {
var capabilities = new SessionCapabilities().setUi(new SessionUiCapabilities().setElicitation(true));
assertNotNull(capabilities.getUi());
- assertTrue(capabilities.getUi().getElicitation());
+ assertTrue(capabilities.getUi().getElicitation().get());
// Test with null UI
var emptyCapabilities = new SessionCapabilities();
@@ -119,8 +119,8 @@ void inputOptionsHasAllFields() {
assertEquals("My Title", opts.getTitle());
assertEquals("My Desc", opts.getDescription());
- assertEquals(1, opts.getMinLength());
- assertEquals(100, opts.getMaxLength());
+ assertEquals(1, opts.getMinLength().getAsInt());
+ assertEquals(100, opts.getMaxLength().getAsInt());
assertEquals("email", opts.getFormat());
assertEquals("default@example.com", opts.getDefaultValue());
}
@@ -164,7 +164,7 @@ void buildCreateRequestSetsRequestElicitationWhenHandlerPresent() {
var request = SessionRequestBuilder.buildCreateRequest(config);
- assertTrue(Boolean.TRUE.equals(request.getRequestElicitation()));
+ assertTrue(request.getRequestElicitation());
}
@Test
@@ -186,6 +186,6 @@ void buildResumeRequestSetsRequestElicitationWhenHandlerPresent() {
var request = SessionRequestBuilder.buildResumeRequest("session-1", config);
- assertTrue(Boolean.TRUE.equals(request.getRequestElicitation()));
+ assertTrue(request.getRequestElicitation());
}
}
diff --git a/src/test/java/com/github/copilot/sdk/MetadataApiTest.java b/src/test/java/com/github/copilot/sdk/MetadataApiTest.java
index 3a9120a525..91ab628435 100644
--- a/src/test/java/com/github/copilot/sdk/MetadataApiTest.java
+++ b/src/test/java/com/github/copilot/sdk/MetadataApiTest.java
@@ -156,7 +156,7 @@ void testModelInfoDeserialization() throws Exception {
// Capabilities
assertNotNull(model.getCapabilities());
assertTrue(model.getCapabilities().getSupports().isVision());
- assertEquals(8192, model.getCapabilities().getLimits().getMaxPromptTokens());
+ assertEquals(8192, model.getCapabilities().getLimits().getMaxPromptTokens().getAsInt());
assertEquals(128000, model.getCapabilities().getLimits().getMaxContextWindowTokens());
// Vision limits
diff --git a/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java b/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java
index e7602619ca..6bbb3ae284 100644
--- a/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java
+++ b/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java
@@ -410,8 +410,8 @@ void testProviderModelIdAndWireModelSerialization() throws Exception {
ProviderConfig deserialized = MAPPER.readValue(MAPPER.writeValueAsString(provider), ProviderConfig.class);
assertEquals("gpt-4o", deserialized.getModelId());
assertEquals("my-finetune-v3", deserialized.getWireModel());
- assertEquals(100_000, deserialized.getMaxPromptTokens());
- assertEquals(4096, deserialized.getMaxOutputTokens());
+ assertEquals(100_000, deserialized.getMaxPromptTokens().getAsInt());
+ assertEquals(4096, deserialized.getMaxOutputTokens().getAsInt());
}
@Test
@@ -419,8 +419,8 @@ void testProviderModelFieldsDefaultToNull() {
var provider = new ProviderConfig();
assertNull(provider.getModelId());
assertNull(provider.getWireModel());
- assertNull(provider.getMaxPromptTokens());
- assertNull(provider.getMaxOutputTokens());
+ assertTrue(provider.getMaxPromptTokens().isEmpty());
+ assertTrue(provider.getMaxOutputTokens().isEmpty());
}
@Test
diff --git a/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java b/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java
index 99b360d2db..278777ce13 100644
--- a/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java
+++ b/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java
@@ -22,7 +22,7 @@ void defaultValuesAreNull() {
assertNull(config.getFilePath());
assertNull(config.getExporterType());
assertNull(config.getSourceName());
- assertNull(config.getCaptureContent());
+ assertTrue(config.getCaptureContent().isEmpty());
}
@Test
@@ -57,10 +57,10 @@ void sourceNameGetterSetter() {
void captureContentGetterSetter() {
var config = new TelemetryConfig();
config.setCaptureContent(true);
- assertTrue(config.getCaptureContent());
+ assertTrue(config.getCaptureContent().get());
config.setCaptureContent(false);
- assertFalse(config.getCaptureContent());
+ assertFalse(config.getCaptureContent().get());
}
@Test
@@ -72,6 +72,6 @@ void fluentChainingReturnsThis() {
assertEquals("/tmp/spans.json", config.getFilePath());
assertEquals("file", config.getExporterType());
assertEquals("sdk-test", config.getSourceName());
- assertTrue(config.getCaptureContent());
+ assertTrue(config.getCaptureContent().get());
}
}
From c708aa2305f408a1e23f7f2941c214b70044a043 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 12 May 2026 00:36:41 +0000
Subject: [PATCH 022/135] fix: remove accidentally committed temp file and
rename test method
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
refactor_optionals.py | 616 ------------------
.../github/copilot/sdk/ConfigCloneTest.java | 2 +-
2 files changed, 1 insertion(+), 617 deletions(-)
delete mode 100644 refactor_optionals.py
diff --git a/refactor_optionals.py b/refactor_optionals.py
deleted file mode 100644
index 8de5f995f6..0000000000
--- a/refactor_optionals.py
+++ /dev/null
@@ -1,616 +0,0 @@
-#!/usr/bin/env python3
-"""Refactor Java source files to use Optional return types instead of nullable boxed primitives."""
-
-import re
-import os
-
-BASE = "/home/runner/work/copilot-sdk-java/copilot-sdk-java/src/main/java/com/github/copilot/sdk"
-JSON_PKG = os.path.join(BASE, "json")
-
-
-def read_file(path):
- with open(path, 'r') as f:
- return f.read()
-
-
-def write_file(path, content):
- with open(path, 'w') as f:
- f.write(content)
-
-
-def add_import(content, import_stmt):
- """Add an import statement if not already present."""
- if import_stmt in content:
- return content
- # Find the last import line and add after it
- lines = content.split('\n')
- last_import_idx = -1
- for i, line in enumerate(lines):
- if line.startswith('import '):
- last_import_idx = i
- if last_import_idx >= 0:
- lines.insert(last_import_idx + 1, import_stmt)
- return '\n'.join(lines)
-
-
-def refactor_fluent_boolean_getter(content, field_name):
- """Refactor a Boolean getter to return Optional (fluent class)."""
- # Match the getter method - various javadoc styles
- getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
-
- # Replace return type and body
- # Pattern: public Boolean getXxx() {\n return xxx;\n }
- pattern = rf'( public )Boolean ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
- replacement = rf'\1Optional \2 {{\n\3return Optional.ofNullable({field_name});\n\4}}'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def refactor_fluent_boolean_setter(content, field_name, class_name):
- """Refactor a Boolean setter to take primitive boolean (fluent class)."""
- setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
-
- # Pattern: public ClassName setXxx(Boolean xxx) {\n this.xxx = xxx;\n return this;\n }
- pattern = rf'( public {class_name} {setter_name}\()Boolean ({field_name})\)( \{{)'
- replacement = rf'\1boolean \2)\3'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def refactor_void_boolean_getter(content, field_name):
- """Refactor a Boolean getter to return Optional (void setter class)."""
- getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public )Boolean ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
- replacement = rf'\1Optional \2 {{\n\3return Optional.ofNullable({field_name});\n\4}}'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def refactor_void_boolean_setter(content, field_name):
- """Refactor a void Boolean setter to take primitive boolean."""
- setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public void {setter_name}\()Boolean ({field_name})\)'
- replacement = rf'\1boolean \2)'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def add_fluent_clear_method(content, field_name, class_name, after_setter=True):
- """Add a clearXxx() method after the setter for fluent classes."""
- setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
- clear_name = f'clear{field_name[0].upper()}{field_name[1:]}'
-
- # Check if clear method already exists
- if f'{clear_name}()' in content:
- return content
-
- clear_method = f'''
- /**
- * Clears the {field_name} setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public {class_name} {clear_name}() {{
- this.{field_name} = null;
- return this;
- }}
-'''
-
- # Find the end of the setter method and insert after it
- # Look for the setter method's closing brace
- setter_pattern = rf'( public {class_name} {setter_name}\([^)]+\) \{{[^}}]*\}})'
- match = re.search(setter_pattern, content, re.DOTALL)
- if match:
- insert_pos = match.end()
- content = content[:insert_pos] + '\n' + clear_method + content[insert_pos:]
-
- return content
-
-
-def add_void_clear_method(content, field_name, after_setter=True):
- """Add a void clearXxx() method after the setter for request classes."""
- setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
- clear_name = f'clear{field_name[0].upper()}{field_name[1:]}'
-
- if f'{clear_name}()' in content:
- return content
-
- clear_method = f'''
- /**
- * Clears the {field_name} setting, reverting to the default behavior.
- */
- public void {clear_name}() {{
- this.{field_name} = null;
- }}
-'''
-
- # Find the end of the setter method
- setter_pattern = rf'( public void {setter_name}\([^)]+\) \{{[^}}]*\}})'
- match = re.search(setter_pattern, content, re.DOTALL)
- if match:
- insert_pos = match.end()
- content = content[:insert_pos] + '\n' + clear_method + content[insert_pos:]
-
- return content
-
-
-def refactor_fluent_int_getter(content, field_name):
- """Refactor an Integer getter to return OptionalInt."""
- getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public )Integer ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
- replacement = rf'\1OptionalInt \2 {{\n\3return {field_name} == null ? OptionalInt.empty() : OptionalInt.of({field_name});\n\4}}'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def refactor_fluent_int_setter(content, field_name, class_name):
- """Refactor an Integer setter to take primitive int (fluent)."""
- setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public {class_name} {setter_name}\()Integer ({field_name})\)( \{{)'
- replacement = rf'\1int \2)\3'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def refactor_fluent_double_getter(content, field_name):
- """Refactor a Double getter to return OptionalDouble."""
- getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public )Double ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
- replacement = rf'\1OptionalDouble \2 {{\n\3return {field_name} == null ? OptionalDouble.empty() : OptionalDouble.of({field_name});\n\4}}'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def refactor_fluent_double_setter(content, field_name, class_name):
- """Refactor a Double setter to take primitive double (fluent)."""
- setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public {class_name} {setter_name}\()Double ({field_name})\)( \{{)'
- replacement = rf'\1double \2)\3'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-# Also handle inner class patterns (indented with 8 spaces)
-def refactor_inner_boolean_getter(content, field_name):
- """Refactor a Boolean getter in an inner class."""
- getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public )Boolean ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
- replacement = rf'\1Optional \2 {{\n\3return Optional.ofNullable({field_name});\n\4}}'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def refactor_inner_boolean_setter(content, field_name, class_name):
- """Refactor a Boolean setter in an inner class."""
- setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public {class_name} {setter_name}\()Boolean ({field_name})\)( \{{)'
- replacement = rf'\1boolean \2)\3'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def refactor_inner_int_getter(content, field_name):
- """Refactor an Integer getter in an inner class."""
- getter_name = f'get{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public )Integer ({getter_name}\(\)) \{{\n(\s+)return {field_name};\n(\s+)\}}'
- replacement = rf'\1OptionalInt \2 {{\n\3return {field_name} == null ? OptionalInt.empty() : OptionalInt.of({field_name});\n\4}}'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def refactor_inner_int_setter(content, field_name, class_name):
- """Refactor an Integer setter in an inner class."""
- setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
-
- pattern = rf'( public {class_name} {setter_name}\()Integer ({field_name})\)( \{{)'
- replacement = rf'\1int \2)\3'
- content = re.sub(pattern, replacement, content)
- return content
-
-
-def add_inner_fluent_clear(content, field_name, class_name):
- """Add clear method for inner class fields."""
- setter_name = f'set{field_name[0].upper()}{field_name[1:]}'
- clear_name = f'clear{field_name[0].upper()}{field_name[1:]}'
-
- if f'{clear_name}()' in content:
- return content
-
- clear_method = f'''
- /**
- * Clears the {field_name} setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public {class_name} {clear_name}() {{
- this.{field_name} = null;
- return this;
- }}
-'''
-
- # Find the end of the setter in inner class (8 spaces indent)
- setter_pattern = rf'( public {class_name} {setter_name}\([^)]+\) \{{[^}}]*\}})'
- match = re.search(setter_pattern, content, re.DOTALL)
- if match:
- insert_pos = match.end()
- content = content[:insert_pos] + '\n' + clear_method + content[insert_pos:]
-
- return content
-
-
-# ==================== MAIN REFACTORING ====================
-
-def refactor_copilot_client_options():
- path = os.path.join(JSON_PKG, "CopilotClientOptions.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
- content = add_import(content, "import java.util.OptionalInt;")
-
- # sessionIdleTimeoutSeconds: Integer -> OptionalInt
- content = refactor_fluent_int_getter(content, "sessionIdleTimeoutSeconds")
- content = refactor_fluent_int_setter(content, "sessionIdleTimeoutSeconds", "CopilotClientOptions")
- content = add_fluent_clear_method(content, "sessionIdleTimeoutSeconds", "CopilotClientOptions")
-
- # useLoggedInUser: Boolean -> Optional
- content = refactor_fluent_boolean_getter(content, "useLoggedInUser")
- # Special case - the setter has custom logic, need to replace it differently
- # Old: public CopilotClientOptions setUseLoggedInUser(Boolean useLoggedInUser) {
- # this.useLoggedInUser = useLoggedInUser != null ? useLoggedInUser : Boolean.FALSE;
- # New: public CopilotClientOptions setUseLoggedInUser(boolean useLoggedInUser) {
- # this.useLoggedInUser = useLoggedInUser;
- old_setter = "public CopilotClientOptions setUseLoggedInUser(Boolean useLoggedInUser) {\n this.useLoggedInUser = useLoggedInUser != null ? useLoggedInUser : Boolean.FALSE;"
- new_setter = "public CopilotClientOptions setUseLoggedInUser(boolean useLoggedInUser) {\n this.useLoggedInUser = useLoggedInUser;"
- content = content.replace(old_setter, new_setter)
- content = add_fluent_clear_method(content, "useLoggedInUser", "CopilotClientOptions")
-
- # Update javadoc for getSessionIdleTimeoutSeconds
- content = content.replace(
- "@return the session idle timeout in seconds, or {@code null} to disable\n * (sessions live indefinitely)",
- "@return an {@link OptionalInt} containing the session idle timeout in seconds,\n * or empty to disable (sessions live indefinitely)"
- )
- # Update setter javadoc
- content = content.replace(
- "Sessions without activity for this duration are automatically cleaned up. Set\n * to {@code 0} or leave as {@code null} to disable (sessions live\n * indefinitely).",
- "Sessions without activity for this duration are automatically cleaned up. Set\n * to {@code 0} to disable (sessions live indefinitely). Use\n * {@link #clearSessionIdleTimeoutSeconds()} to revert to the default."
- )
- content = content.replace(
- "@param sessionIdleTimeoutSeconds\n * the idle timeout in seconds, or {@code null} to disable",
- "@param sessionIdleTimeoutSeconds\n * the idle timeout in seconds"
- )
-
- # Update useLoggedInUser getter javadoc
- content = content.replace(
- "@return {@code true} to use logged-in user auth, {@code false} to use only\n * explicit tokens, or {@code null} to use default behavior",
- "@return an {@link Optional} containing the boolean value, or empty if not set"
- )
- # Update useLoggedInUser setter javadoc
- content = content.replace(
- "Passing {@code null} is equivalent to passing {@link Boolean#FALSE}.\n *\n * @param useLoggedInUser\n * {@code true} to use logged-in user auth, {@code false} or\n * {@code null} otherwise",
- "@param useLoggedInUser\n * {@code true} to use logged-in user auth, {@code false} otherwise"
- )
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_session_config():
- path = os.path.join(JSON_PKG, "SessionConfig.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
-
- for field in ["enableSessionTelemetry", "enableConfigDiscovery", "includeSubAgentStreamingEvents"]:
- content = refactor_fluent_boolean_getter(content, field)
- content = refactor_fluent_boolean_setter(content, field, "SessionConfig")
- content = add_fluent_clear_method(content, field, "SessionConfig")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_resume_session_config():
- path = os.path.join(JSON_PKG, "ResumeSessionConfig.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
-
- for field in ["enableSessionTelemetry", "enableConfigDiscovery", "includeSubAgentStreamingEvents"]:
- content = refactor_fluent_boolean_getter(content, field)
- content = refactor_fluent_boolean_setter(content, field, "ResumeSessionConfig")
- content = add_fluent_clear_method(content, field, "ResumeSessionConfig")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_infinite_session_config():
- path = os.path.join(JSON_PKG, "InfiniteSessionConfig.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
- content = add_import(content, "import java.util.OptionalDouble;")
-
- # enabled: Boolean -> Optional
- content = refactor_fluent_boolean_getter(content, "enabled")
- content = refactor_fluent_boolean_setter(content, "enabled", "InfiniteSessionConfig")
- content = add_fluent_clear_method(content, "enabled", "InfiniteSessionConfig")
-
- # backgroundCompactionThreshold: Double -> OptionalDouble
- content = refactor_fluent_double_getter(content, "backgroundCompactionThreshold")
- content = refactor_fluent_double_setter(content, "backgroundCompactionThreshold", "InfiniteSessionConfig")
- content = add_fluent_clear_method(content, "backgroundCompactionThreshold", "InfiniteSessionConfig")
-
- # bufferExhaustionThreshold: Double -> OptionalDouble
- content = refactor_fluent_double_getter(content, "bufferExhaustionThreshold")
- content = refactor_fluent_double_setter(content, "bufferExhaustionThreshold", "InfiniteSessionConfig")
- content = add_fluent_clear_method(content, "bufferExhaustionThreshold", "InfiniteSessionConfig")
-
- # Update javadoc
- content = content.replace(
- "@return {@code true} if enabled, {@code null} to use default (true)",
- "@return an {@link Optional} containing the boolean value, or empty to use default (true)"
- )
- content = content.replace(
- "@return the threshold (0.0-1.0), or {@code null} to use default\n */\n public OptionalDouble getBackgroundCompactionThreshold()",
- "@return an {@link OptionalDouble} containing the threshold (0.0-1.0), or empty to use default\n */\n public OptionalDouble getBackgroundCompactionThreshold()"
- )
- content = content.replace(
- "@return the threshold (0.0-1.0), or {@code null} to use default\n */\n public OptionalDouble getBufferExhaustionThreshold()",
- "@return an {@link OptionalDouble} containing the threshold (0.0-1.0), or empty to use default\n */\n public OptionalDouble getBufferExhaustionThreshold()"
- )
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_input_options():
- path = os.path.join(JSON_PKG, "InputOptions.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.OptionalInt;")
-
- for field in ["minLength", "maxLength"]:
- content = refactor_fluent_int_getter(content, field)
- content = refactor_fluent_int_setter(content, field, "InputOptions")
- content = add_fluent_clear_method(content, field, "InputOptions")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_model_capabilities_override():
- path = os.path.join(JSON_PKG, "ModelCapabilitiesOverride.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
- content = add_import(content, "import java.util.OptionalInt;")
-
- # Inner class Supports: vision, reasoningEffort (Boolean -> Optional)
- for field in ["vision", "reasoningEffort"]:
- content = refactor_inner_boolean_getter(content, field)
- content = refactor_inner_boolean_setter(content, field, "Supports")
- content = add_inner_fluent_clear(content, field, "Supports")
-
- # Inner class Limits: maxPromptTokens, maxOutputTokens, maxContextWindowTokens (Integer -> OptionalInt)
- for field in ["maxPromptTokens", "maxOutputTokens", "maxContextWindowTokens"]:
- content = refactor_inner_int_getter(content, field)
- content = refactor_inner_int_setter(content, field, "Limits")
- content = add_inner_fluent_clear(content, field, "Limits")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_provider_config():
- path = os.path.join(JSON_PKG, "ProviderConfig.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.OptionalInt;")
-
- for field in ["maxPromptTokens", "maxOutputTokens"]:
- content = refactor_fluent_int_getter(content, field)
- content = refactor_fluent_int_setter(content, field, "ProviderConfig")
- content = add_fluent_clear_method(content, field, "ProviderConfig")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_telemetry_config():
- path = os.path.join(JSON_PKG, "TelemetryConfig.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
-
- content = refactor_fluent_boolean_getter(content, "captureContent")
- content = refactor_fluent_boolean_setter(content, "captureContent", "TelemetryConfig")
- content = add_fluent_clear_method(content, "captureContent", "TelemetryConfig")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_session_ui_capabilities():
- path = os.path.join(JSON_PKG, "SessionUiCapabilities.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
-
- content = refactor_fluent_boolean_getter(content, "elicitation")
- content = refactor_fluent_boolean_setter(content, "elicitation", "SessionUiCapabilities")
- content = add_fluent_clear_method(content, "elicitation", "SessionUiCapabilities")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_custom_agent_config():
- path = os.path.join(JSON_PKG, "CustomAgentConfig.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
-
- content = refactor_fluent_boolean_getter(content, "infer")
- content = refactor_fluent_boolean_setter(content, "infer", "CustomAgentConfig")
- content = add_fluent_clear_method(content, "infer", "CustomAgentConfig")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_user_input_request():
- path = os.path.join(JSON_PKG, "UserInputRequest.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
-
- content = refactor_fluent_boolean_getter(content, "allowFreeform")
- content = refactor_fluent_boolean_setter(content, "allowFreeform", "UserInputRequest")
- content = add_fluent_clear_method(content, "allowFreeform", "UserInputRequest")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_create_session_request():
- path = os.path.join(JSON_PKG, "CreateSessionRequest.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
-
- fields = ["enableSessionTelemetry", "requestPermission", "requestUserInput",
- "hooks", "streaming", "enableConfigDiscovery",
- "includeSubAgentStreamingEvents", "requestElicitation"]
-
- for field in fields:
- content = refactor_void_boolean_getter(content, field)
- content = refactor_void_boolean_setter(content, field)
- content = add_void_clear_method(content, field)
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_resume_session_request():
- path = os.path.join(JSON_PKG, "ResumeSessionRequest.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.Optional;")
-
- fields = ["enableSessionTelemetry", "requestPermission", "requestUserInput",
- "hooks", "enableConfigDiscovery", "disableResume", "streaming",
- "includeSubAgentStreamingEvents", "requestElicitation"]
-
- for field in fields:
- content = refactor_void_boolean_getter(content, field)
- content = refactor_void_boolean_setter(content, field)
- content = add_void_clear_method(content, field)
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_mcp_server_config():
- path = os.path.join(JSON_PKG, "McpServerConfig.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.OptionalInt;")
-
- content = refactor_fluent_int_getter(content, "timeout")
- content = refactor_fluent_int_setter(content, "timeout", "McpServerConfig")
- content = add_fluent_clear_method(content, "timeout", "McpServerConfig")
-
- # Update javadoc
- content = content.replace(
- "@return the timeout in milliseconds, or {@code null} for the default",
- "@return an {@link OptionalInt} containing the timeout in milliseconds, or empty for the default"
- )
- content = content.replace(
- "@param timeout\n * the timeout in milliseconds, or {@code null} for the default",
- "@param timeout\n * the timeout in milliseconds"
- )
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_model_limits():
- path = os.path.join(JSON_PKG, "ModelLimits.java")
- content = read_file(path)
-
- content = add_import(content, "import java.util.OptionalInt;")
-
- content = refactor_fluent_int_getter(content, "maxPromptTokens")
- content = refactor_fluent_int_setter(content, "maxPromptTokens", "ModelLimits")
- content = add_fluent_clear_method(content, "maxPromptTokens", "ModelLimits")
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-def refactor_session_request_builder():
- """Update SessionRequestBuilder to handle Optional returns from config."""
- path = os.path.join(BASE, "SessionRequestBuilder.java")
- content = read_file(path)
-
- # The config getters now return Optional, so we need to use ifPresent
- # Old: request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());
- # New: config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
-
- # For create request:
- content = content.replace(
- "request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());\n request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);\n request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);",
- "config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);\n if (config.getOnUserInputRequest() != null) {\n request.setRequestUserInput(true);\n }\n if (config.getHooks() != null && config.getHooks().hasHooks()) {\n request.setHooks(true);\n }"
- )
-
- content = content.replace(
- "request.setStreaming(config.isStreaming() ? true : null);\n request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());",
- "if (config.isStreaming()) {\n request.setStreaming(true);\n }\n config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);"
- )
-
- content = content.replace(
- "request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());\n request.setModelCapabilities(config.getModelCapabilities());",
- "config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);\n request.setModelCapabilities(config.getModelCapabilities());"
- )
-
- # For resume request:
- content = content.replace(
- "request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());\n request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);\n request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);\n request.setWorkingDirectory(config.getWorkingDirectory());\n request.setConfigDir(config.getConfigDir());\n request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());\n request.setDisableResume(config.isDisableResume() ? true : null);\n request.setStreaming(config.isStreaming() ? true : null);\n request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());",
- "config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);\n if (config.getOnUserInputRequest() != null) {\n request.setRequestUserInput(true);\n }\n if (config.getHooks() != null && config.getHooks().hasHooks()) {\n request.setHooks(true);\n }\n request.setWorkingDirectory(config.getWorkingDirectory());\n request.setConfigDir(config.getConfigDir());\n config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);\n if (config.isDisableResume()) {\n request.setDisableResume(true);\n }\n if (config.isStreaming()) {\n request.setStreaming(true);\n }\n config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);"
- )
-
- write_file(path, content)
- print(f" Refactored: {path}")
-
-
-if __name__ == "__main__":
- print("Refactoring to Optional return types...")
-
- refactor_copilot_client_options()
- refactor_session_config()
- refactor_resume_session_config()
- refactor_infinite_session_config()
- refactor_input_options()
- refactor_model_capabilities_override()
- refactor_provider_config()
- refactor_telemetry_config()
- refactor_session_ui_capabilities()
- refactor_custom_agent_config()
- refactor_user_input_request()
- refactor_create_session_request()
- refactor_resume_session_request()
- refactor_mcp_server_config()
- refactor_model_limits()
- refactor_session_request_builder()
-
- print("\nDone! Run 'mvn spotless:apply' then 'mvn verify' to validate.")
diff --git a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
index af92baa7e2..09bd3ee385 100644
--- a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
+++ b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
@@ -301,7 +301,7 @@ void copilotClientOptionsSetTelemetry() {
}
@Test
- void copilotClientOptionsSetUseLoggedInUserClear() {
+ void copilotClientOptionsClearUseLoggedInUser() {
var opts = new CopilotClientOptions();
opts.setUseLoggedInUser(true);
opts.clearUseLoggedInUser();
From 9e86db79561a060d503bca9516717a5dd2089304 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 12 May 2026 20:33:39 +0000
Subject: [PATCH 023/135] Initial plan
From befdd933a7b9600871316ecb00d5b59fdb2d7753 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 12 May 2026 20:47:33 +0000
Subject: [PATCH 024/135] fix: fix release version replacement for -beta-java.N
qualifier format
- Fix sed patterns in publish-maven.yml to use general qualifier regex
`\(-[a-z][a-z0-9-]*\.[0-9][0-9]*\)*` that matches any version qualifier
format (-java.N, -java-preview.N, -beta-java.N) and also handles
previously-chained invalid versions
- Fix awk regex patterns in update-changelog.sh to recognize -beta-java.N
in [Unreleased] and version link patterns (-(beta-)?java(-preview)?.N)
- Fix duplicate [Unreleased] link bug: track unreleased_link_handled flag
so the first-version-link insertion block only fires when there is no
existing [Unreleased] link to update
- Move [Unreleased] handler before first-version-link handler in awk so
the flag is set before the later block evaluates it
- Update version validation regex to accept -beta-java.N format
- Fix CHANGELOG.md: remove duplicate [Unreleased] links and fix incorrect
predecessor version references for 1.0.0-beta-java.2 and .3
- Fix README.md, jbang-example.java, and cookbook markdown files:
replace chained invalid versions with correct 1.0.0-beta-java.3
- Fix test-update-changelog.sh: replace ((passed++)) with
passed=$((passed+1)) to avoid set -e triggering on arithmetic result 0;
add two new tests for beta-java format and no-duplicate-links guarantee
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
---
.../scripts/release/test-update-changelog.sh | 71 ++++++++++++++++++-
.github/scripts/release/update-changelog.sh | 31 ++++----
.github/workflows/publish-maven.yml | 16 ++---
CHANGELOG.md | 35 ++-------
README.md | 4 +-
jbang-example.java | 2 +-
src/site/markdown/cookbook/error-handling.md | 14 ++--
.../markdown/cookbook/managing-local-files.md | 4 +-
.../markdown/cookbook/multiple-sessions.md | 4 +-
.../markdown/cookbook/persisting-sessions.md | 6 +-
.../markdown/cookbook/pr-visualization.md | 2 +-
11 files changed, 116 insertions(+), 73 deletions(-)
diff --git a/.github/scripts/release/test-update-changelog.sh b/.github/scripts/release/test-update-changelog.sh
index ade87d6a94..b5fc8486b7 100755
--- a/.github/scripts/release/test-update-changelog.sh
+++ b/.github/scripts/release/test-update-changelog.sh
@@ -33,10 +33,10 @@ run_test() {
if $test_func; then
echo -e "${GREEN}PASSED${NC}"
- ((passed++))
+ passed=$((passed + 1))
else
echo -e "${RED}FAILED${NC}"
- ((failed++))
+ failed=$((failed + 1))
fi
}
@@ -180,6 +180,71 @@ EOF
fi
}
+# Test 6: Beta-java version format (e.g., 1.0.0-beta-java.N)
+test_beta_java_version() {
+ local test_file="${TEST_DIR}/test6.md"
+ cat > "$test_file" << 'EOF'
+# Changelog
+
+## [Unreleased]
+
+### Added
+- New feature
+
+## [1.0.0-beta-java.1] - 2026-05-01
+
+[Unreleased]: https://github.com/test/repo/compare/v1.0.0-beta-java.1...HEAD
+[1.0.0-beta-java.1]: https://github.com/test/repo/compare/v0.3.0-java.2...v1.0.0-beta-java.1
+[0.3.0-java.2]: https://github.com/test/repo/releases/tag/0.3.0-java.2
+EOF
+
+ CHANGELOG_FILE="$test_file" bash "$UPDATE_SCRIPT" 1.0.0-beta-java.2 > /dev/null 2>&1
+
+ # The [Unreleased] link should now point to v1.0.0-beta-java.2
+ # [1.0.0-beta-java.2] should compare from v1.0.0-beta-java.1
+ if grep -q "\[Unreleased\]: https://github.com/test/repo/compare/v1.0.0-beta-java.2...HEAD" "$test_file" && \
+ grep -q "\[1.0.0-beta-java.2\]: https://github.com/test/repo/compare/v1.0.0-beta-java.1...v1.0.0-beta-java.2" "$test_file"; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# Test 7: No duplicate [Unreleased] links when existing [Unreleased] link is present
+test_no_duplicate_unreleased_links() {
+ local test_file="${TEST_DIR}/test7.md"
+ cat > "$test_file" << 'EOF'
+# Changelog
+
+## [Unreleased]
+
+### Added
+- New feature
+
+## [1.0.0-beta-java.2] - 2026-05-08
+
+## [1.0.0-beta-java.1] - 2026-05-05
+
+[Unreleased]: https://github.com/test/repo/compare/v1.0.0-beta-java.2...HEAD
+[1.0.0-beta-java.2]: https://github.com/test/repo/compare/v1.0.0-beta-java.1...v1.0.0-beta-java.2
+[1.0.0-beta-java.1]: https://github.com/test/repo/compare/v0.3.0-java.2...v1.0.0-beta-java.1
+[0.3.0-java.2]: https://github.com/test/repo/releases/tag/0.3.0-java.2
+EOF
+
+ CHANGELOG_FILE="$test_file" bash "$UPDATE_SCRIPT" 1.0.0-beta-java.3 > /dev/null 2>&1
+
+ # Count [Unreleased] link definitions - there should be exactly one
+ local unreleased_count
+ unreleased_count=$(grep -c "^\[Unreleased\]:" "$test_file")
+ if [ "$unreleased_count" -eq 1 ] && \
+ grep -q "\[Unreleased\]: https://github.com/test/repo/compare/v1.0.0-beta-java.3...HEAD" "$test_file" && \
+ grep -q "\[1.0.0-beta-java.3\]: https://github.com/test/repo/compare/v1.0.0-beta-java.2...v1.0.0-beta-java.3" "$test_file"; then
+ return 0
+ else
+ return 1
+ fi
+}
+
# Run all tests
echo "Running CHANGELOG update script tests..."
echo ""
@@ -189,6 +254,8 @@ run_test "Handle CHANGELOG without Unreleased link" test_no_unreleased_link
run_test "Preserve content structure" test_preserve_content
run_test "Error handling - no Unreleased section" test_no_unreleased_section
run_test "Multiple version handling" test_multiple_versions
+run_test "Beta-java version format (e.g., 1.0.0-beta-java.N)" test_beta_java_version
+run_test "No duplicate [Unreleased] links when existing link is present" test_no_duplicate_unreleased_links
echo ""
echo "=========================================="
diff --git a/.github/scripts/release/update-changelog.sh b/.github/scripts/release/update-changelog.sh
index ff35dec722..e21d03774e 100755
--- a/.github/scripts/release/update-changelog.sh
+++ b/.github/scripts/release/update-changelog.sh
@@ -45,6 +45,7 @@ BEGIN {
links_section = 0
first_version_link = ""
repo_url = ""
+ unreleased_link_handled = 0
}
# Track if we are in the links section at the bottom
@@ -53,7 +54,7 @@ BEGIN {
}
# Capture the repository URL from the first version link
-links_section && repo_url == "" && /^\[[0-9]+\.[0-9]+\.[0-9]+(-java\.[0-9]+)?\]:/ {
+links_section && repo_url == "" && /^\[[0-9]+\.[0-9]+\.[0-9]+(-(beta-)?java(-preview)?\.[0-9]+)?\]:/ {
match($0, /(https:\/\/github\.com\/[^\/]+\/[^\/]+)\//, arr)
if (arr[1] != "") {
repo_url = arr[1]
@@ -86,28 +87,30 @@ skip_old_reference_impl && /^[[:space:]]*$/ { next }
skip_old_reference_impl && /^> \*\*Reference implementation sync:\*\*/ { next }
skip_old_reference_impl && !/^[[:space:]]*$/ && !/^> \*\*Reference implementation sync:\*\*/ { skip_old_reference_impl = 0 }
-# Capture the first version link to get the previous version
-links_section && first_version_link == "" && /^\[[0-9]+\.[0-9]+\.[0-9]+(-java\.[0-9]+)?\]:/ {
- match($0, /\[([0-9]+\.[0-9]+\.[0-9]+(-java\.[0-9]+)?)\]:/, arr)
- if (arr[1] != "" && repo_url != "") {
- first_version_link = arr[1]
- # Insert Unreleased and new version links before first version link
- print "[Unreleased]: " repo_url "/compare/v" version "...HEAD"
- print "[" version "]: " repo_url "/compare/v" arr[1] "...v" version
- }
-}
-
-# Update existing [Unreleased] link if present
+# Update existing [Unreleased] link if present (must be checked before the first-version-link block)
links_section && /^\[Unreleased\]:/ {
# Get the previous version and repo URL from the existing link
- match($0, /(https:\/\/github\.com\/[^\/]+\/[^\/]+)\/compare\/v([0-9]+\.[0-9]+\.[0-9]+(-java\.[0-9]+)?)\.\.\.HEAD/, arr)
+ match($0, /(https:\/\/github\.com\/[^\/]+\/[^\/]+)\/compare\/v([0-9]+\.[0-9]+\.[0-9]+(-(beta-)?java(-preview)?\.[0-9]+)?)\.\.\.HEAD/, arr)
if (arr[1] != "" && arr[2] != "") {
print "[Unreleased]: " arr[1] "/compare/v" version "...HEAD"
print "[" version "]: " arr[1] "/compare/v" arr[2] "...v" version
+ unreleased_link_handled = 1
next
}
}
+# Capture the first version link to get the previous version
+# Only fires if the [Unreleased] link was not already handled above
+links_section && first_version_link == "" && !unreleased_link_handled && /^\[[0-9]+\.[0-9]+\.[0-9]+(-(beta-)?java(-preview)?\.[0-9]+)?\]:/ {
+ match($0, /\[([0-9]+\.[0-9]+\.[0-9]+(-(beta-)?java(-preview)?\.[0-9]+)?)\]:/, arr)
+ if (arr[1] != "" && repo_url != "") {
+ first_version_link = arr[1]
+ # Insert Unreleased and new version links before first version link
+ print "[Unreleased]: " repo_url "/compare/v" version "...HEAD"
+ print "[" version "]: " repo_url "/compare/v" arr[1] "...v" version
+ }
+}
+
# Print all other lines unchanged
{ print }
' "$CHANGELOG_FILE" > "$TEMP_FILE"
diff --git a/.github/workflows/publish-maven.yml b/.github/workflows/publish-maven.yml
index 99e61ac18f..f14987176a 100644
--- a/.github/workflows/publish-maven.yml
+++ b/.github/workflows/publish-maven.yml
@@ -87,8 +87,8 @@ jobs:
else
# Split version: supports "0.1.32", "0.1.32-java.0", and "0.1.32-java-preview.0" formats
# Validate RELEASE_VERSION format explicitly to provide clear errors
- if ! echo "$RELEASE_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-java(-preview)?\.[0-9]+)?$'; then
- echo "Error: RELEASE_VERSION '$RELEASE_VERSION' is invalid. Expected format: M.M.P, M.M.P-java.N, or M.M.P-java-preview.N (e.g., 1.2.3, 1.2.3-java.0, or 1.2.3-java-preview.0)." >&2
+ if ! echo "$RELEASE_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-(beta-)?java(-preview)?\.[0-9]+)?$'; then
+ echo "Error: RELEASE_VERSION '$RELEASE_VERSION' is invalid. Expected format: M.M.P, M.M.P-java.N, M.M.P-java-preview.N, or M.M.P-beta-java.N (e.g., 1.2.3, 1.2.3-java.0, 1.2.3-java-preview.0, or 1.2.3-beta-java.0)." >&2
exit 1
fi
# Extract the base M.M.P portion (before any qualifier)
@@ -121,21 +121,21 @@ jobs:
# Update CHANGELOG.md with release version and Reference implementation sync hash
./.github/scripts/release/update-changelog.sh "${VERSION}" "${REFERENCE_IMPL_HASH}"
- # Update version in README.md (supports versions like 1.0.0, 0.1.32-java.0, and 0.3.0-java-preview.0)
- sed -i "s|[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-java\(-preview\)\{0,1\}\.[0-9][0-9]*\)\{0,1\} |${VERSION} |g" README.md
- sed -i "s|copilot-sdk-java:[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-java\(-preview\)\{0,1\}\.[0-9][0-9]*\)\{0,1\}|copilot-sdk-java:${VERSION}|g" README.md
+ # Update version in README.md (supports any version qualifier like -java.N, -java-preview.N, -beta-java.N)
+ sed -i "s|[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-[a-z][a-z0-9-]*\.[0-9][0-9]*\)* |${VERSION} |g" README.md
+ sed -i "s|copilot-sdk-java:[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-[a-z][a-z0-9-]*\.[0-9][0-9]*\)*|copilot-sdk-java:${VERSION}|g" README.md
# Update snapshot version in README.md
DEV_VERSION="${{ steps.versions.outputs.dev_version }}"
- sed -i "s|[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-java\(-preview\)\{0,1\}\.[0-9][0-9]*\)\{0,1\}-SNAPSHOT |${DEV_VERSION} |g" README.md
+ sed -i "s|[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-[a-z][a-z0-9-]*\.[0-9][0-9]*\)*-SNAPSHOT |${DEV_VERSION} |g" README.md
# Update version in jbang-example.java
- sed -i "s|copilot-sdk-java:[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-java\(-preview\)\{0,1\}\.[0-9][0-9]*\)\{0,1\}|copilot-sdk-java:${VERSION}|g" jbang-example.java
+ sed -i "s|copilot-sdk-java:[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-[a-z][a-z0-9-]*\.[0-9][0-9]*\)*|copilot-sdk-java:${VERSION}|g" jbang-example.java
sed -i 's|copilot-sdk-java:${project\.version}|copilot-sdk-java:'"${VERSION}"'|g' jbang-example.java
# Update version in cookbook files (hardcoded for direct GitHub browsing and JBang usage)
find src/site/markdown/cookbook -name "*.md" -type f -exec \
- sed -i "s|copilot-sdk-java:[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-java\(-preview\)\{0,1\}\.[0-9][0-9]*\)\{0,1\}|copilot-sdk-java:${VERSION}|g" {} \;
+ sed -i "s|copilot-sdk-java:[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\(-[a-z][a-z0-9-]*\.[0-9][0-9]*\)*|copilot-sdk-java:${VERSION}|g" {} \;
# Commit the documentation changes before release:prepare (requires clean working directory)
git add CHANGELOG.md README.md jbang-example.java src/site/markdown/cookbook/
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd49095408..5eb0397d56 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -506,38 +506,12 @@ New types: `GetForegroundSessionResponse`, `SetForegroundSessionResponse`
- Pre-commit hook for Spotless code formatting
- Comprehensive API documentation
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java-preview.0...HEAD
-[0.3.0-java-preview.0]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java-preview.0
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java-preview.0...HEAD
-[0.3.0-java-preview.0]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java-preview.0
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java-preview.1...HEAD
-[0.3.0-java-preview.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java-preview.1
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.1...HEAD
-[1.0.0-beta-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java.2...v1.0.0-beta-java.1
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.1...HEAD
-[1.0.0-beta-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java.2...v1.0.0-beta-java.1
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.2...HEAD
-[1.0.0-beta-java.2]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java.2...v1.0.0-beta-java.2
[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.3...HEAD
-[1.0.0-beta-java.3]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java.2...v1.0.0-beta-java.3
+[1.0.0-beta-java.3]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.2...v1.0.0-beta-java.3
+[1.0.0-beta-java.2]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.1...v1.0.0-beta-java.2
+[1.0.0-beta-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java.2...v1.0.0-beta-java.1
[0.3.0-java.2]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java.2
-[0.2.2-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.1...v0.2.2-java.1
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java-preview.0...HEAD
-[0.3.0-java-preview.0]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java-preview.0
-[0.2.2-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.1...v0.2.2-java.1
-[0.2.1-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.0...v0.2.1-java.1
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java-preview.0...HEAD
-[0.3.0-java-preview.0]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java-preview.0
-[0.2.2-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.1...v0.2.2-java.1
-[0.2.1-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.0...v0.2.1-java.1
-[0.2.1-java.0]: https://github.com/github/copilot-sdk-java/compare/v0.1.32-java.0...v0.2.1-java.0
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java-preview.0...HEAD
-[0.3.0-java-preview.0]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java-preview.0
-[0.2.2-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.1...v0.2.2-java.1
-[0.2.1-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.0...v0.2.1-java.1
-[0.2.1-java.0]: https://github.com/github/copilot-sdk-java/compare/v0.1.32-java.0...v0.2.1-java.0
-[0.1.32-java.0]: https://github.com/github/copilot-sdk-java/compare/v1.0.11...v0.1.32-java.0
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java-preview.0...HEAD
+[0.3.0-java-preview.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java-preview.1
[0.3.0-java-preview.0]: https://github.com/github/copilot-sdk-java/compare/v0.2.2-java.1...v0.3.0-java-preview.0
[0.2.2-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.1...v0.2.2-java.1
[0.2.1-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.2.1-java.0...v0.2.1-java.1
@@ -555,4 +529,3 @@ New types: `GetForegroundSessionResponse`, `SetForegroundSessionResponse`
[1.0.2]: https://github.com/github/copilot-sdk-java/compare/v1.0.1...v1.0.2
[1.0.1]: https://github.com/github/copilot-sdk-java/compare/1.0.0...v1.0.1
[1.0.0]: https://github.com/github/copilot-sdk-java/releases/tag/1.0.0
-
diff --git a/README.md b/README.md
index 7107c07573..c1aac6a5ab 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ Java SDK for programmatic control of GitHub Copilot CLI, enabling you to build A
com.github
copilot-sdk-java
- 1.0.0-beta-java.1
+ 1.0.0-beta-java.3
```
@@ -60,7 +60,7 @@ Snapshot builds of the next development version are published to Maven Central S
### Gradle
```groovy
-implementation 'com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1'
+implementation 'com.github:copilot-sdk-java:1.0.0-beta-java.3'
```
## Quick Start
diff --git a/jbang-example.java b/jbang-example.java
index e19da2958f..78763bea9c 100644
--- a/jbang-example.java
+++ b/jbang-example.java
@@ -1,5 +1,5 @@
///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.SessionUsageInfoEvent;
diff --git a/src/site/markdown/cookbook/error-handling.md b/src/site/markdown/cookbook/error-handling.md
index 74732006ee..42c9e3a9c6 100644
--- a/src/site/markdown/cookbook/error-handling.md
+++ b/src/site/markdown/cookbook/error-handling.md
@@ -30,7 +30,7 @@ jbang BasicErrorHandling.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -64,7 +64,7 @@ public class BasicErrorHandling {
## Handling specific error types
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import java.util.concurrent.ExecutionException;
@@ -99,7 +99,7 @@ public class SpecificErrorHandling {
## Timeout handling
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotSession;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -130,7 +130,7 @@ public class TimeoutHandling {
## Aborting a request
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotSession;
import com.github.copilot.sdk.json.MessageOptions;
import java.util.concurrent.Executors;
@@ -162,7 +162,7 @@ public class AbortRequest {
## Graceful shutdown
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
public class GracefulShutdown {
@@ -192,7 +192,7 @@ public class GracefulShutdown {
## Try-with-resources pattern
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -224,7 +224,7 @@ public class TryWithResources {
## Handling tool errors
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
diff --git a/src/site/markdown/cookbook/managing-local-files.md b/src/site/markdown/cookbook/managing-local-files.md
index 78f914f103..788a712b60 100644
--- a/src/site/markdown/cookbook/managing-local-files.md
+++ b/src/site/markdown/cookbook/managing-local-files.md
@@ -34,7 +34,7 @@ jbang ManagingLocalFiles.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.SessionIdleEvent;
@@ -161,7 +161,7 @@ session.send(new MessageOptions().setPrompt(prompt));
## Interactive file organization
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import java.io.BufferedReader;
import java.io.InputStreamReader;
diff --git a/src/site/markdown/cookbook/multiple-sessions.md b/src/site/markdown/cookbook/multiple-sessions.md
index 42bb1f6222..c6f9666779 100644
--- a/src/site/markdown/cookbook/multiple-sessions.md
+++ b/src/site/markdown/cookbook/multiple-sessions.md
@@ -30,7 +30,7 @@ jbang MultipleSessions.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -123,7 +123,7 @@ try {
## Managing session lifecycle with CompletableFuture
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import java.util.concurrent.CompletableFuture;
import java.util.List;
diff --git a/src/site/markdown/cookbook/persisting-sessions.md b/src/site/markdown/cookbook/persisting-sessions.md
index 119448a440..6c9440a510 100644
--- a/src/site/markdown/cookbook/persisting-sessions.md
+++ b/src/site/markdown/cookbook/persisting-sessions.md
@@ -30,7 +30,7 @@ jbang PersistingSessions.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -127,7 +127,7 @@ public class DeleteSession {
## Getting session history
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.UserMessageEvent;
@@ -162,7 +162,7 @@ public class SessionHistory {
## Complete example with session management
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import java.util.Scanner;
public class SessionManager {
diff --git a/src/site/markdown/cookbook/pr-visualization.md b/src/site/markdown/cookbook/pr-visualization.md
index 627ee5b842..d193e4487e 100644
--- a/src/site/markdown/cookbook/pr-visualization.md
+++ b/src/site/markdown/cookbook/pr-visualization.md
@@ -34,7 +34,7 @@ jbang PRVisualization.java github/copilot-sdk
## Full example: PRVisualization.java
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3-beta-java.2-beta-java.1
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.ToolExecutionStartEvent;
From 7a4b7ace904d9ac841a593acce06a6a48b8e9a10 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 13 May 2026 00:13:35 +0000
Subject: [PATCH 025/135] fix: add @JsonIgnore to InputOptions, rollback
McpServerConfig/ModelLimits changes
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.../github/copilot/sdk/json/InputOptions.java | 3 +++
.../copilot/sdk/json/McpHttpServerConfig.java | 2 +-
.../copilot/sdk/json/McpServerConfig.java | 25 ++++---------------
.../sdk/json/McpStdioServerConfig.java | 2 +-
.../github/copilot/sdk/json/ModelLimits.java | 19 +++-----------
.../copilot/sdk/DataObjectCoverageTest.java | 4 +--
6 files changed, 15 insertions(+), 40 deletions(-)
diff --git a/src/main/java/com/github/copilot/sdk/json/InputOptions.java b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
index 3b66476a18..73e6411dfa 100644
--- a/src/main/java/com/github/copilot/sdk/json/InputOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
@@ -4,6 +4,7 @@
package com.github.copilot.sdk.json;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.OptionalInt;
/**
@@ -49,6 +50,7 @@ public InputOptions setDescription(String description) {
}
/** Gets the minimum character length. @return the min length */
+ @JsonIgnore
public OptionalInt getMinLength() {
return minLength == null ? OptionalInt.empty() : OptionalInt.of(minLength);
}
@@ -73,6 +75,7 @@ public InputOptions clearMinLength() {
}
/** Gets the maximum character length. @return the max length */
+ @JsonIgnore
public OptionalInt getMaxLength() {
return maxLength == null ? OptionalInt.empty() : OptionalInt.of(maxLength);
}
diff --git a/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java b/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java
index 9c5b8dbedc..7017db3d2d 100644
--- a/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/McpHttpServerConfig.java
@@ -99,7 +99,7 @@ public McpHttpServerConfig setTools(List tools) {
}
@Override
- public McpHttpServerConfig setTimeout(int timeout) {
+ public McpHttpServerConfig setTimeout(Integer timeout) {
super.setTimeout(timeout);
return this;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/McpServerConfig.java b/src/main/java/com/github/copilot/sdk/json/McpServerConfig.java
index b7f56b05a8..7cf39af6b6 100644
--- a/src/main/java/com/github/copilot/sdk/json/McpServerConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/McpServerConfig.java
@@ -11,8 +11,6 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.OptionalInt;
/**
* Abstract base class for MCP (Model Context Protocol) server configurations.
@@ -70,34 +68,21 @@ public McpServerConfig setTools(List tools) {
/**
* Gets the optional timeout in milliseconds for tool calls to this server.
*
- * @return an {@link OptionalInt} containing the timeout in milliseconds, or
- * empty for the default
+ * @return the timeout in milliseconds, or {@code null} for the default
*/
- @JsonIgnore
- public OptionalInt getTimeout() {
- return timeout == null ? OptionalInt.empty() : OptionalInt.of(timeout);
+ public Integer getTimeout() {
+ return timeout;
}
/**
* Sets an optional timeout in milliseconds for tool calls to this server.
*
* @param timeout
- * the timeout in milliseconds
+ * the timeout in milliseconds, or {@code null} for the default
* @return this config for method chaining
*/
- public McpServerConfig setTimeout(int timeout) {
+ public McpServerConfig setTimeout(Integer timeout) {
this.timeout = timeout;
return this;
}
-
- /**
- * Clears the timeout setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public McpServerConfig clearTimeout() {
- this.timeout = null;
- return this;
- }
-
}
diff --git a/src/main/java/com/github/copilot/sdk/json/McpStdioServerConfig.java b/src/main/java/com/github/copilot/sdk/json/McpStdioServerConfig.java
index eef4d1e7d5..900034be61 100644
--- a/src/main/java/com/github/copilot/sdk/json/McpStdioServerConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/McpStdioServerConfig.java
@@ -148,7 +148,7 @@ public McpStdioServerConfig setTools(List tools) {
}
@Override
- public McpStdioServerConfig setTimeout(int timeout) {
+ public McpStdioServerConfig setTimeout(Integer timeout) {
super.setTimeout(timeout);
return this;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ModelLimits.java b/src/main/java/com/github/copilot/sdk/json/ModelLimits.java
index fedecd6d36..734a50deda 100644
--- a/src/main/java/com/github/copilot/sdk/json/ModelLimits.java
+++ b/src/main/java/com/github/copilot/sdk/json/ModelLimits.java
@@ -6,8 +6,6 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.OptionalInt;
/**
* Model limits.
@@ -26,26 +24,15 @@ public class ModelLimits {
@JsonProperty("vision")
private ModelVisionLimits vision;
- @JsonIgnore
- public OptionalInt getMaxPromptTokens() {
- return maxPromptTokens == null ? OptionalInt.empty() : OptionalInt.of(maxPromptTokens);
+ public Integer getMaxPromptTokens() {
+ return maxPromptTokens;
}
- public ModelLimits setMaxPromptTokens(int maxPromptTokens) {
+ public ModelLimits setMaxPromptTokens(Integer maxPromptTokens) {
this.maxPromptTokens = maxPromptTokens;
return this;
}
- /**
- * Clears the maxPromptTokens setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public ModelLimits clearMaxPromptTokens() {
- this.maxPromptTokens = null;
- return this;
- }
-
public int getMaxContextWindowTokens() {
return maxContextWindowTokens;
}
diff --git a/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java b/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
index e8e983a4ca..2ff3600200 100644
--- a/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
+++ b/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
@@ -194,7 +194,7 @@ void mcpHttpServerConfigCoversGettersAndFluentSetters() {
assertEquals("https://mcp.example.com/sse", cfg.getUrl());
assertEquals("Bearer token", cfg.getHeaders().get("Authorization"));
assertEquals(tools, cfg.getTools());
- assertEquals(45, cfg.getTimeout().getAsInt());
+ assertEquals(45, cfg.getTimeout());
}
@Test
@@ -212,7 +212,7 @@ void mcpStdioServerConfigCoversGettersAndFluentSetters() {
assertEquals("1", cfg.getEnv().get("DEBUG"));
assertEquals("/tmp", cfg.getWorkingDirectory());
assertEquals(tools, cfg.getTools());
- assertEquals(30, cfg.getTimeout().getAsInt());
+ assertEquals(30, cfg.getTimeout());
}
@Test
From a82938c57d552751512ab2e2235ebfb86b32db64 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 13 May 2026 00:22:14 +0000
Subject: [PATCH 026/135] test: add comprehensive clearXxx() and Jackson
serialization roundtrip tests
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.../github/copilot/sdk/MetadataApiTest.java | 2 +-
.../sdk/OptionalApiAndJacksonTest.java | 372 ++++++++++++++++++
2 files changed, 373 insertions(+), 1 deletion(-)
create mode 100644 src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
diff --git a/src/test/java/com/github/copilot/sdk/MetadataApiTest.java b/src/test/java/com/github/copilot/sdk/MetadataApiTest.java
index 91ab628435..3a9120a525 100644
--- a/src/test/java/com/github/copilot/sdk/MetadataApiTest.java
+++ b/src/test/java/com/github/copilot/sdk/MetadataApiTest.java
@@ -156,7 +156,7 @@ void testModelInfoDeserialization() throws Exception {
// Capabilities
assertNotNull(model.getCapabilities());
assertTrue(model.getCapabilities().getSupports().isVision());
- assertEquals(8192, model.getCapabilities().getLimits().getMaxPromptTokens().getAsInt());
+ assertEquals(8192, model.getCapabilities().getLimits().getMaxPromptTokens());
assertEquals(128000, model.getCapabilities().getLimits().getMaxContextWindowTokens());
// Vision limits
diff --git a/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java b/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
new file mode 100644
index 0000000000..a22fb32e73
--- /dev/null
+++ b/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
@@ -0,0 +1,372 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.copilot.sdk.json.CopilotClientOptions;
+import com.github.copilot.sdk.json.CustomAgentConfig;
+import com.github.copilot.sdk.json.InfiniteSessionConfig;
+import com.github.copilot.sdk.json.InputOptions;
+import com.github.copilot.sdk.json.ModelCapabilitiesOverride;
+import com.github.copilot.sdk.json.ProviderConfig;
+import com.github.copilot.sdk.json.ResumeSessionConfig;
+import com.github.copilot.sdk.json.SessionConfig;
+import com.github.copilot.sdk.json.SessionUiCapabilities;
+import com.github.copilot.sdk.json.TelemetryConfig;
+import com.github.copilot.sdk.json.UserInputRequest;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Validates that every {@code clearXxx()} method resets its field to absent,
+ * that Optional-returning getters report the correct state, and that Jackson
+ * omits cleared fields from serialized output.
+ */
+class OptionalApiAndJacksonTest {
+
+ private static final ObjectMapper MAPPER = JsonRpcClient.getObjectMapper();
+
+ // ── CopilotClientOptions ──────────────────────────────────────────
+
+ @Test
+ void copilotClientOptions_clearSessionIdleTimeoutSeconds() {
+ var opts = new CopilotClientOptions();
+ opts.setSessionIdleTimeoutSeconds(120);
+ assertFalse(opts.getSessionIdleTimeoutSeconds().isEmpty());
+
+ opts.clearSessionIdleTimeoutSeconds();
+ assertTrue(opts.getSessionIdleTimeoutSeconds().isEmpty());
+ }
+
+ @Test
+ void copilotClientOptions_clearUseLoggedInUser() {
+ var opts = new CopilotClientOptions();
+ opts.setUseLoggedInUser(true);
+ assertTrue(opts.getUseLoggedInUser().isPresent());
+
+ opts.clearUseLoggedInUser();
+ assertTrue(opts.getUseLoggedInUser().isEmpty());
+ }
+
+ // ── SessionConfig ─────────────────────────────────────────────────
+
+ @Test
+ void sessionConfig_clearEnableSessionTelemetry() {
+ var cfg = new SessionConfig();
+ cfg.setEnableSessionTelemetry(true);
+ assertTrue(cfg.getEnableSessionTelemetry().isPresent());
+
+ cfg.clearEnableSessionTelemetry();
+ assertTrue(cfg.getEnableSessionTelemetry().isEmpty());
+ }
+
+ @Test
+ void sessionConfig_clearEnableConfigDiscovery() {
+ var cfg = new SessionConfig();
+ cfg.setEnableConfigDiscovery(false);
+ assertTrue(cfg.getEnableConfigDiscovery().isPresent());
+
+ cfg.clearEnableConfigDiscovery();
+ assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
+ }
+
+ @Test
+ void sessionConfig_clearIncludeSubAgentStreamingEvents() {
+ var cfg = new SessionConfig();
+ cfg.setIncludeSubAgentStreamingEvents(true);
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isPresent());
+
+ cfg.clearIncludeSubAgentStreamingEvents();
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
+ }
+
+ // ── ResumeSessionConfig ───────────────────────────────────────────
+
+ @Test
+ void resumeSessionConfig_clearEnableSessionTelemetry() {
+ var cfg = new ResumeSessionConfig();
+ cfg.setEnableSessionTelemetry(false);
+ assertTrue(cfg.getEnableSessionTelemetry().isPresent());
+
+ cfg.clearEnableSessionTelemetry();
+ assertTrue(cfg.getEnableSessionTelemetry().isEmpty());
+ }
+
+ @Test
+ void resumeSessionConfig_clearEnableConfigDiscovery() {
+ var cfg = new ResumeSessionConfig();
+ cfg.setEnableConfigDiscovery(true);
+ assertTrue(cfg.getEnableConfigDiscovery().isPresent());
+
+ cfg.clearEnableConfigDiscovery();
+ assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
+ }
+
+ @Test
+ void resumeSessionConfig_clearIncludeSubAgentStreamingEvents() {
+ var cfg = new ResumeSessionConfig();
+ cfg.setIncludeSubAgentStreamingEvents(false);
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isPresent());
+
+ cfg.clearIncludeSubAgentStreamingEvents();
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
+ }
+
+ // ── InfiniteSessionConfig ─────────────────────────────────────────
+
+ @Test
+ void infiniteSessionConfig_clearEnabled() {
+ var cfg = new InfiniteSessionConfig();
+ cfg.setEnabled(true);
+ assertTrue(cfg.getEnabled().isPresent());
+
+ cfg.clearEnabled();
+ assertTrue(cfg.getEnabled().isEmpty());
+ }
+
+ @Test
+ void infiniteSessionConfig_clearBackgroundCompactionThreshold() {
+ var cfg = new InfiniteSessionConfig();
+ cfg.setBackgroundCompactionThreshold(0.75);
+ assertFalse(cfg.getBackgroundCompactionThreshold().isEmpty());
+
+ cfg.clearBackgroundCompactionThreshold();
+ assertTrue(cfg.getBackgroundCompactionThreshold().isEmpty());
+ }
+
+ @Test
+ void infiniteSessionConfig_clearBufferExhaustionThreshold() {
+ var cfg = new InfiniteSessionConfig();
+ cfg.setBufferExhaustionThreshold(0.9);
+ assertFalse(cfg.getBufferExhaustionThreshold().isEmpty());
+
+ cfg.clearBufferExhaustionThreshold();
+ assertTrue(cfg.getBufferExhaustionThreshold().isEmpty());
+ }
+
+ // ── InputOptions ──────────────────────────────────────────────────
+
+ @Test
+ void inputOptions_clearMinLength() {
+ var opts = new InputOptions();
+ opts.setMinLength(5);
+ assertFalse(opts.getMinLength().isEmpty());
+
+ opts.clearMinLength();
+ assertTrue(opts.getMinLength().isEmpty());
+ }
+
+ @Test
+ void inputOptions_clearMaxLength() {
+ var opts = new InputOptions();
+ opts.setMaxLength(100);
+ assertFalse(opts.getMaxLength().isEmpty());
+
+ opts.clearMaxLength();
+ assertTrue(opts.getMaxLength().isEmpty());
+ }
+
+ // ── ModelCapabilitiesOverride.Supports ─────────────────────────────
+
+ @Test
+ void supports_clearVision() {
+ var s = new ModelCapabilitiesOverride.Supports();
+ s.setVision(true);
+ assertTrue(s.getVision().isPresent());
+
+ s.clearVision();
+ assertTrue(s.getVision().isEmpty());
+ }
+
+ @Test
+ void supports_clearReasoningEffort() {
+ var s = new ModelCapabilitiesOverride.Supports();
+ s.setReasoningEffort(false);
+ assertTrue(s.getReasoningEffort().isPresent());
+
+ s.clearReasoningEffort();
+ assertTrue(s.getReasoningEffort().isEmpty());
+ }
+
+ // ── ModelCapabilitiesOverride.Limits ───────────────────────────────
+
+ @Test
+ void limits_clearMaxPromptTokens() {
+ var l = new ModelCapabilitiesOverride.Limits();
+ l.setMaxPromptTokens(4096);
+ assertFalse(l.getMaxPromptTokens().isEmpty());
+
+ l.clearMaxPromptTokens();
+ assertTrue(l.getMaxPromptTokens().isEmpty());
+ }
+
+ @Test
+ void limits_clearMaxOutputTokens() {
+ var l = new ModelCapabilitiesOverride.Limits();
+ l.setMaxOutputTokens(1024);
+ assertFalse(l.getMaxOutputTokens().isEmpty());
+
+ l.clearMaxOutputTokens();
+ assertTrue(l.getMaxOutputTokens().isEmpty());
+ }
+
+ @Test
+ void limits_clearMaxContextWindowTokens() {
+ var l = new ModelCapabilitiesOverride.Limits();
+ l.setMaxContextWindowTokens(16384);
+ assertFalse(l.getMaxContextWindowTokens().isEmpty());
+
+ l.clearMaxContextWindowTokens();
+ assertTrue(l.getMaxContextWindowTokens().isEmpty());
+ }
+
+ // ── ProviderConfig ────────────────────────────────────────────────
+
+ @Test
+ void providerConfig_clearMaxPromptTokens() {
+ var cfg = new ProviderConfig();
+ cfg.setMaxPromptTokens(2048);
+ assertFalse(cfg.getMaxPromptTokens().isEmpty());
+
+ cfg.clearMaxPromptTokens();
+ assertTrue(cfg.getMaxPromptTokens().isEmpty());
+ }
+
+ @Test
+ void providerConfig_clearMaxOutputTokens() {
+ var cfg = new ProviderConfig();
+ cfg.setMaxOutputTokens(512);
+ assertFalse(cfg.getMaxOutputTokens().isEmpty());
+
+ cfg.clearMaxOutputTokens();
+ assertTrue(cfg.getMaxOutputTokens().isEmpty());
+ }
+
+ // ── TelemetryConfig ───────────────────────────────────────────────
+
+ @Test
+ void telemetryConfig_clearCaptureContent() {
+ var cfg = new TelemetryConfig();
+ cfg.setCaptureContent(true);
+ assertTrue(cfg.getCaptureContent().isPresent());
+
+ cfg.clearCaptureContent();
+ assertTrue(cfg.getCaptureContent().isEmpty());
+ }
+
+ // ── SessionUiCapabilities ─────────────────────────────────────────
+
+ @Test
+ void sessionUiCapabilities_clearElicitation() {
+ var caps = new SessionUiCapabilities();
+ caps.setElicitation(true);
+ assertTrue(caps.getElicitation().isPresent());
+
+ caps.clearElicitation();
+ assertTrue(caps.getElicitation().isEmpty());
+ }
+
+ // ── CustomAgentConfig ─────────────────────────────────────────────
+
+ @Test
+ void customAgentConfig_clearInfer() {
+ var cfg = new CustomAgentConfig();
+ cfg.setInfer(true);
+ assertTrue(cfg.getInfer().isPresent());
+
+ cfg.clearInfer();
+ assertTrue(cfg.getInfer().isEmpty());
+ }
+
+ // ── UserInputRequest ──────────────────────────────────────────────
+
+ @Test
+ void userInputRequest_clearAllowFreeform() {
+ var req = new UserInputRequest();
+ req.setAllowFreeform(false);
+ assertTrue(req.getAllowFreeform().isPresent());
+
+ req.clearAllowFreeform();
+ assertTrue(req.getAllowFreeform().isEmpty());
+ }
+
+ // ── Jackson serialization roundtrip ───────────────────────────────
+
+ // ── Jackson serialization roundtrip ───────────────────────────────
+ //
+ // Classes whose fields carry @JsonProperty (InfiniteSessionConfig,
+ // ModelCapabilitiesOverride inner classes) are serialized via field
+ // access: Jackson writes the field when set and omits it when cleared.
+ //
+ // Classes without @JsonProperty on fields (SessionConfig,
+ // CopilotClientOptions, TelemetryConfig, ProviderConfig) are not
+ // directly serialized — their values are copied to wire DTOs by
+ // SessionRequestBuilder. The @JsonIgnore on their Optional-returning
+ // getters prevents Jackson from attempting to serialize Optional
+ // wrappers if the class is ever processed.
+
+ @Test
+ void jackson_infiniteSessionConfigClearedFieldsOmitted() throws Exception {
+ var cfg = new InfiniteSessionConfig();
+ cfg.setEnabled(true);
+ cfg.setBackgroundCompactionThreshold(0.75);
+ cfg.setBufferExhaustionThreshold(0.9);
+
+ String withFields = MAPPER.writeValueAsString(cfg);
+ assertTrue(withFields.contains("enabled"));
+ assertTrue(withFields.contains("backgroundCompactionThreshold"));
+ assertTrue(withFields.contains("bufferExhaustionThreshold"));
+
+ cfg.clearEnabled();
+ cfg.clearBackgroundCompactionThreshold();
+ cfg.clearBufferExhaustionThreshold();
+
+ String cleared = MAPPER.writeValueAsString(cfg);
+ assertFalse(cleared.contains("enabled"));
+ assertFalse(cleared.contains("backgroundCompactionThreshold"));
+ assertFalse(cleared.contains("bufferExhaustionThreshold"));
+ }
+
+ @Test
+ void jackson_modelCapabilitiesOverrideSupportsClearedFieldsOmitted() throws Exception {
+ var supports = new ModelCapabilitiesOverride.Supports();
+ supports.setVision(true);
+ supports.setReasoningEffort(false);
+
+ String withFields = MAPPER.writeValueAsString(supports);
+ assertTrue(withFields.contains("vision"));
+ assertTrue(withFields.contains("reasoningEffort"));
+
+ supports.clearVision();
+ supports.clearReasoningEffort();
+
+ String cleared = MAPPER.writeValueAsString(supports);
+ assertFalse(cleared.contains("vision"));
+ assertFalse(cleared.contains("reasoningEffort"));
+ }
+
+ @Test
+ void jackson_modelCapabilitiesOverrideLimitsClearedFieldsOmitted() throws Exception {
+ var limits = new ModelCapabilitiesOverride.Limits();
+ limits.setMaxPromptTokens(2048);
+ limits.setMaxOutputTokens(512);
+ limits.setMaxContextWindowTokens(16384);
+
+ String withFields = MAPPER.writeValueAsString(limits);
+ assertTrue(withFields.contains("max_prompt_tokens"));
+ assertTrue(withFields.contains("max_output_tokens"));
+ assertTrue(withFields.contains("max_context_window_tokens"));
+
+ limits.clearMaxPromptTokens();
+ limits.clearMaxOutputTokens();
+ limits.clearMaxContextWindowTokens();
+
+ String cleared = MAPPER.writeValueAsString(limits);
+ assertFalse(cleared.contains("max_prompt_tokens"));
+ assertFalse(cleared.contains("max_output_tokens"));
+ assertFalse(cleared.contains("max_context_window_tokens"));
+ }
+}
From 116781160c9a2b997ec9eb9058a65417d93e0f64 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 13 May 2026 00:23:02 +0000
Subject: [PATCH 027/135] fix: remove duplicate comment block in
OptionalApiAndJacksonTest
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.../java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java b/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
index a22fb32e73..c2ff8bf060 100644
--- a/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
+++ b/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
@@ -293,8 +293,6 @@ void userInputRequest_clearAllowFreeform() {
assertTrue(req.getAllowFreeform().isEmpty());
}
- // ── Jackson serialization roundtrip ───────────────────────────────
-
// ── Jackson serialization roundtrip ───────────────────────────────
//
// Classes whose fields carry @JsonProperty (InfiniteSessionConfig,
From feae21b180d9813645034d6c4de3ba928e837747 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 13 May 2026 21:10:55 +0000
Subject: [PATCH 028/135] fix: update Javadoc for Optional-based API and fix
test assertions
- Update @return tags to describe Optional.empty()/OptionalInt.empty() instead of null
- Update @param tags to remove null references on primitive setters
- Fix exception message in CopilotSession to use valid Java syntax
- Fix ElicitationTest to use assertEquals(Boolean.TRUE, ...) to avoid NPE
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.../github/copilot/sdk/CopilotSession.java | 2 +-
.../sdk/json/CopilotClientOptions.java | 3 ++-
.../copilot/sdk/json/CustomAgentConfig.java | 3 ++-
.../github/copilot/sdk/json/InputOptions.java | 14 ++++++++++--
.../sdk/json/ModelCapabilitiesOverride.java | 22 ++++++++++---------
.../copilot/sdk/json/ProviderConfig.java | 6 +++--
.../copilot/sdk/json/ResumeSessionConfig.java | 7 +++---
.../copilot/sdk/json/SessionConfig.java | 20 +++++++++--------
.../copilot/sdk/json/TelemetryConfig.java | 5 +++--
.../copilot/sdk/json/UserInputRequest.java | 3 ++-
.../github/copilot/sdk/ElicitationTest.java | 4 ++--
11 files changed, 55 insertions(+), 34 deletions(-)
diff --git a/src/main/java/com/github/copilot/sdk/CopilotSession.java b/src/main/java/com/github/copilot/sdk/CopilotSession.java
index a35ab75520..79a7f343b7 100644
--- a/src/main/java/com/github/copilot/sdk/CopilotSession.java
+++ b/src/main/java/com/github/copilot/sdk/CopilotSession.java
@@ -1120,7 +1120,7 @@ private void assertElicitation() {
SessionCapabilities caps = capabilities;
if (caps == null || caps.getUi() == null || !caps.getUi().getElicitation().orElse(false)) {
throw new IllegalStateException("Elicitation is not supported by the host. "
- + "Check session.getCapabilities().getUi()?.getElicitation() before calling UI methods.");
+ + "Check session.getCapabilities().getUi().getElicitation().orElse(false) before calling UI methods.");
}
}
diff --git a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
index a61c32fadf..e4605ffe10 100644
--- a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
@@ -503,7 +503,8 @@ public CopilotClientOptions setTelemetry(TelemetryConfig telemetry) {
* Gets the server-wide idle timeout for sessions in seconds.
*
* @return an {@link OptionalInt} containing the session idle timeout in
- * seconds, or empty to disable (sessions live indefinitely)
+ * seconds, or {@link java.util.OptionalInt#empty()} if not set. Use
+ * {@link #clearSessionIdleTimeoutSeconds()} to revert to the default.
* @since 1.3.0
*/
@JsonIgnore
diff --git a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
index c40d1b3c50..bb9520055e 100644
--- a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
@@ -199,7 +199,8 @@ public CustomAgentConfig setMcpServers(Map mcpServers)
/**
* Gets whether inference mode is enabled.
*
- * @return the infer flag, or {@code null} if not set
+ * @return an {@link java.util.Optional} containing the infer flag, or
+ * {@link java.util.Optional#empty()} if not set
*/
@JsonIgnore
public Optional getInfer() {
diff --git a/src/main/java/com/github/copilot/sdk/json/InputOptions.java b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
index 73e6411dfa..4f209bf6fa 100644
--- a/src/main/java/com/github/copilot/sdk/json/InputOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
@@ -49,7 +49,12 @@ public InputOptions setDescription(String description) {
return this;
}
- /** Gets the minimum character length. @return the min length */
+ /**
+ * Gets the minimum character length.
+ *
+ * @return an {@link java.util.OptionalInt} containing the min length, or
+ * {@link java.util.OptionalInt#empty()} if not set
+ */
@JsonIgnore
public OptionalInt getMinLength() {
return minLength == null ? OptionalInt.empty() : OptionalInt.of(minLength);
@@ -74,7 +79,12 @@ public InputOptions clearMinLength() {
return this;
}
- /** Gets the maximum character length. @return the max length */
+ /**
+ * Gets the maximum character length.
+ *
+ * @return an {@link java.util.OptionalInt} containing the max length, or
+ * {@link java.util.OptionalInt#empty()} if not set
+ */
@JsonIgnore
public OptionalInt getMaxLength() {
return maxLength == null ? OptionalInt.empty() : OptionalInt.of(maxLength);
diff --git a/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java b/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
index ab242d83de..02727d4b5c 100644
--- a/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
+++ b/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
@@ -109,8 +109,9 @@ public static class Supports {
/**
* Gets the vision override.
*
- * @return {@code true} to enable vision, {@code false} to disable, or
- * {@code null} to use the runtime default
+ * @return an {@link java.util.Optional} containing {@code true} to enable
+ * vision or {@code false} to disable, or
+ * {@link java.util.Optional#empty()} to use the runtime default
*/
@JsonIgnore
public Optional getVision() {
@@ -118,11 +119,11 @@ public Optional getVision() {
}
/**
- * Sets whether vision (image input) is enabled.
+ * Sets whether vision (image input) is enabled. Use {@link #clearVision()} to
+ * revert to the runtime default.
*
* @param vision
- * {@code true} to enable, {@code false} to disable, or {@code null}
- * to use the runtime default
+ * {@code true} to enable, {@code false} to disable
* @return this instance for method chaining
*/
public Supports setVision(boolean vision) {
@@ -143,8 +144,9 @@ public Supports clearVision() {
/**
* Gets the reasoning effort override.
*
- * @return {@code true} to enable reasoning effort, {@code false} to disable, or
- * {@code null} to use the runtime default
+ * @return an {@link java.util.Optional} containing {@code true} to enable
+ * reasoning effort or {@code false} to disable, or
+ * {@link java.util.Optional#empty()} to use the runtime default
*/
@JsonIgnore
public Optional getReasoningEffort() {
@@ -152,11 +154,11 @@ public Optional getReasoningEffort() {
}
/**
- * Sets whether reasoning effort configuration is enabled.
+ * Sets whether reasoning effort configuration is enabled. Use
+ * {@link #clearReasoningEffort()} to revert to the runtime default.
*
* @param reasoningEffort
- * {@code true} to enable, {@code false} to disable, or {@code null}
- * to use the runtime default
+ * {@code true} to enable, {@code false} to disable
* @return this instance for method chaining
*/
public Supports setReasoningEffort(boolean reasoningEffort) {
diff --git a/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java b/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
index 3826f9dd83..1c5e6fcc7f 100644
--- a/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
@@ -298,7 +298,8 @@ public ProviderConfig setWireModel(String wireModel) {
/**
* Gets the maximum prompt token override.
*
- * @return the max prompt tokens, or {@code null} if not set
+ * @return an {@link java.util.OptionalInt} containing the max prompt tokens, or
+ * {@link java.util.OptionalInt#empty()} if not set
*/
@JsonIgnore
public OptionalInt getMaxPromptTokens() {
@@ -335,7 +336,8 @@ public ProviderConfig clearMaxPromptTokens() {
/**
* Gets the maximum output token override.
*
- * @return the max output tokens, or {@code null} if not set
+ * @return an {@link java.util.OptionalInt} containing the max output tokens, or
+ * {@link java.util.OptionalInt#empty()} if not set
*/
@JsonIgnore
public OptionalInt getMaxOutputTokens() {
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
index 9d76212140..d8c3bf43b1 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
@@ -236,7 +236,7 @@ public ResumeSessionConfig setProvider(ProviderConfig provider) {
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When {@code null} (the default) or
+ * {@code false}, disables session telemetry. When unset (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting. This is independent of
@@ -244,7 +244,8 @@ public ResumeSessionConfig setProvider(ProviderConfig provider) {
* CopilotClientOptions.TelemetryConfig}, which configures OpenTelemetry export
* for observability.
*
- * @return whether session telemetry is enabled
+ * @return an {@link java.util.Optional} containing whether session telemetry is
+ * enabled, or {@link java.util.Optional#empty()} for the default
*/
@JsonIgnore
public Optional getEnableSessionTelemetry() {
@@ -253,7 +254,7 @@ public Optional getEnableSessionTelemetry() {
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When {@code null} (the default) or
+ * {@code false}, disables session telemetry. When unset (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting.
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
index c83aa00fca..53a84aa721 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
@@ -290,7 +290,7 @@ public SessionConfig setProvider(ProviderConfig provider) {
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When {@code null} (the default) or
+ * {@code false}, disables session telemetry. When unset (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting. This is independent of
@@ -298,7 +298,8 @@ public SessionConfig setProvider(ProviderConfig provider) {
* CopilotClientOptions.TelemetryConfig}, which configures OpenTelemetry export
* for observability.
*
- * @return whether session telemetry is enabled
+ * @return an {@link java.util.Optional} containing whether session telemetry is
+ * enabled, or {@link java.util.Optional#empty()} for the default
*/
@JsonIgnore
public Optional getEnableSessionTelemetry() {
@@ -307,7 +308,7 @@ public Optional getEnableSessionTelemetry() {
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When {@code null} (the default) or
+ * {@code false}, disables session telemetry. When unset (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting.
@@ -671,8 +672,9 @@ public SessionConfig setConfigDir(String configDir) {
/**
* Gets whether automatic configuration discovery is enabled.
*
- * @return {@code true} to enable discovery, {@code false} to disable, or
- * {@code null} to use the runtime default
+ * @return an {@link java.util.Optional} containing {@code true} to enable
+ * discovery or {@code false} to disable, or
+ * {@link java.util.Optional#empty()} to use the runtime default
*/
@JsonIgnore
public Optional getEnableConfigDiscovery() {
@@ -690,8 +692,7 @@ public Optional getEnableConfigDiscovery() {
* name collision.
*
* @param enableConfigDiscovery
- * {@code true} to enable discovery, {@code false} to disable, or
- * {@code null} to use the runtime default
+ * {@code true} to enable discovery, {@code false} to disable
* @return this config instance for method chaining
*/
public SessionConfig setEnableConfigDiscovery(boolean enableConfigDiscovery) {
@@ -712,8 +713,9 @@ public SessionConfig clearEnableConfigDiscovery() {
/**
* Gets whether sub-agent streaming events are included.
*
- * @return {@code true} to include sub-agent streaming events, {@code false} to
- * suppress them, or {@code null} to use the runtime default
+ * @return an {@link java.util.Optional} containing {@code true} to include
+ * sub-agent streaming events or {@code false} to suppress them, or
+ * {@link java.util.Optional#empty()} to use the runtime default
*/
@JsonIgnore
public Optional getIncludeSubAgentStreamingEvents() {
diff --git a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
index 9b28a3150a..af00454477 100644
--- a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
@@ -132,8 +132,9 @@ public TelemetryConfig setSourceName(String sourceName) {
* Maps to the {@code OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT}
* environment variable.
*
- * @return {@code true} to capture content, {@code false} to suppress it, or
- * {@code null} to use the default
+ * @return an {@link java.util.Optional} containing {@code true} to capture
+ * content or {@code false} to suppress it, or
+ * {@link java.util.Optional#empty()} to use the default
*/
@JsonIgnore
public Optional getCaptureContent() {
diff --git a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
index dfbb1b6da3..6003c86df2 100644
--- a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
@@ -77,7 +77,8 @@ public UserInputRequest setChoices(List choices) {
/**
* Returns whether freeform text input is allowed.
*
- * @return {@code true} if freeform input is allowed, {@code null} if not
+ * @return an {@link java.util.Optional} containing {@code true} if freeform
+ * input is allowed, or {@link java.util.Optional#empty()} if not
* specified
*/
@JsonIgnore
diff --git a/src/test/java/com/github/copilot/sdk/ElicitationTest.java b/src/test/java/com/github/copilot/sdk/ElicitationTest.java
index bf3c0bfb29..1f62451276 100644
--- a/src/test/java/com/github/copilot/sdk/ElicitationTest.java
+++ b/src/test/java/com/github/copilot/sdk/ElicitationTest.java
@@ -164,7 +164,7 @@ void buildCreateRequestSetsRequestElicitationWhenHandlerPresent() {
var request = SessionRequestBuilder.buildCreateRequest(config);
- assertTrue(request.getRequestElicitation());
+ assertEquals(Boolean.TRUE, request.getRequestElicitation());
}
@Test
@@ -186,6 +186,6 @@ void buildResumeRequestSetsRequestElicitationWhenHandlerPresent() {
var request = SessionRequestBuilder.buildResumeRequest("session-1", config);
- assertTrue(request.getRequestElicitation());
+ assertEquals(Boolean.TRUE, request.getRequestElicitation());
}
}
From acd5c4a52603428d8f46bb5d5de4b3a9e6f21042 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 13 May 2026 21:13:18 +0000
Subject: [PATCH 029/135] test: add Optional value retrieval and JSON
deserialization tests
Adds tests for getAsInt/get/orElse value retrieval on all Optional-returning
getters, and JSON deserialization round-trip tests for ModelCapabilitiesOverride
inner classes and InfiniteSessionConfig to keep coverage above 83%.
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.../sdk/OptionalApiAndJacksonTest.java | 265 ++++++++++++++++++
1 file changed, 265 insertions(+)
diff --git a/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java b/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
index c2ff8bf060..2a9770e2e2 100644
--- a/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
+++ b/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
@@ -293,6 +293,271 @@ void userInputRequest_clearAllowFreeform() {
assertTrue(req.getAllowFreeform().isEmpty());
}
+ // ── Value retrieval through Optional getters ────────────────────────
+
+ @Test
+ void copilotClientOptions_sessionIdleTimeoutSecondsValue() {
+ var opts = new CopilotClientOptions();
+ assertTrue(opts.getSessionIdleTimeoutSeconds().isEmpty());
+
+ opts.setSessionIdleTimeoutSeconds(300);
+ assertEquals(300, opts.getSessionIdleTimeoutSeconds().getAsInt());
+
+ opts.setSessionIdleTimeoutSeconds(0);
+ assertTrue(opts.getSessionIdleTimeoutSeconds().isPresent());
+ assertEquals(0, opts.getSessionIdleTimeoutSeconds().getAsInt());
+ }
+
+ @Test
+ void copilotClientOptions_useLoggedInUserValue() {
+ var opts = new CopilotClientOptions();
+ assertTrue(opts.getUseLoggedInUser().isEmpty());
+
+ opts.setUseLoggedInUser(true);
+ assertEquals(Boolean.TRUE, opts.getUseLoggedInUser().get());
+
+ opts.setUseLoggedInUser(false);
+ assertEquals(Boolean.FALSE, opts.getUseLoggedInUser().get());
+ }
+
+ @Test
+ void sessionConfig_enableSessionTelemetryValue() {
+ var cfg = new SessionConfig();
+ assertFalse(cfg.getEnableSessionTelemetry().orElse(false));
+
+ cfg.setEnableSessionTelemetry(true);
+ assertTrue(cfg.getEnableSessionTelemetry().orElse(false));
+
+ cfg.setEnableSessionTelemetry(false);
+ assertFalse(cfg.getEnableSessionTelemetry().orElse(true));
+ }
+
+ @Test
+ void sessionConfig_enableConfigDiscoveryValue() {
+ var cfg = new SessionConfig();
+ assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
+
+ cfg.setEnableConfigDiscovery(true);
+ assertTrue(cfg.getEnableConfigDiscovery().get());
+
+ cfg.setEnableConfigDiscovery(false);
+ assertFalse(cfg.getEnableConfigDiscovery().get());
+ }
+
+ @Test
+ void sessionConfig_includeSubAgentStreamingEventsValue() {
+ var cfg = new SessionConfig();
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
+
+ cfg.setIncludeSubAgentStreamingEvents(true);
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().get());
+ }
+
+ @Test
+ void resumeSessionConfig_enableSessionTelemetryValue() {
+ var cfg = new ResumeSessionConfig();
+ assertTrue(cfg.getEnableSessionTelemetry().isEmpty());
+
+ cfg.setEnableSessionTelemetry(true);
+ assertTrue(cfg.getEnableSessionTelemetry().get());
+
+ cfg.setEnableSessionTelemetry(false);
+ assertFalse(cfg.getEnableSessionTelemetry().get());
+ }
+
+ @Test
+ void resumeSessionConfig_enableConfigDiscoveryValue() {
+ var cfg = new ResumeSessionConfig();
+ assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
+
+ cfg.setEnableConfigDiscovery(true);
+ assertTrue(cfg.getEnableConfigDiscovery().get());
+ }
+
+ @Test
+ void resumeSessionConfig_includeSubAgentStreamingEventsValue() {
+ var cfg = new ResumeSessionConfig();
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
+
+ cfg.setIncludeSubAgentStreamingEvents(false);
+ assertFalse(cfg.getIncludeSubAgentStreamingEvents().get());
+ }
+
+ @Test
+ void infiniteSessionConfig_thresholdValues() {
+ var cfg = new InfiniteSessionConfig();
+ assertTrue(cfg.getBackgroundCompactionThreshold().isEmpty());
+ assertTrue(cfg.getBufferExhaustionThreshold().isEmpty());
+
+ cfg.setBackgroundCompactionThreshold(0.6);
+ cfg.setBufferExhaustionThreshold(0.85);
+ assertEquals(0.6, cfg.getBackgroundCompactionThreshold().getAsDouble(), 0.001);
+ assertEquals(0.85, cfg.getBufferExhaustionThreshold().getAsDouble(), 0.001);
+ }
+
+ @Test
+ void infiniteSessionConfig_enabledValue() {
+ var cfg = new InfiniteSessionConfig();
+ assertTrue(cfg.getEnabled().isEmpty());
+
+ cfg.setEnabled(true);
+ assertTrue(cfg.getEnabled().get());
+
+ cfg.setEnabled(false);
+ assertFalse(cfg.getEnabled().get());
+ }
+
+ @Test
+ void inputOptions_minAndMaxLengthValues() {
+ var opts = new InputOptions();
+ assertTrue(opts.getMinLength().isEmpty());
+ assertTrue(opts.getMaxLength().isEmpty());
+
+ opts.setMinLength(1);
+ opts.setMaxLength(255);
+ assertEquals(1, opts.getMinLength().getAsInt());
+ assertEquals(255, opts.getMaxLength().getAsInt());
+ }
+
+ @Test
+ void supports_visionAndReasoningEffortValues() {
+ var s = new ModelCapabilitiesOverride.Supports();
+ assertTrue(s.getVision().isEmpty());
+ assertTrue(s.getReasoningEffort().isEmpty());
+
+ s.setVision(true);
+ s.setReasoningEffort(false);
+ assertTrue(s.getVision().get());
+ assertFalse(s.getReasoningEffort().get());
+ }
+
+ @Test
+ void limits_tokenValues() {
+ var l = new ModelCapabilitiesOverride.Limits();
+ assertTrue(l.getMaxPromptTokens().isEmpty());
+ assertTrue(l.getMaxOutputTokens().isEmpty());
+ assertTrue(l.getMaxContextWindowTokens().isEmpty());
+
+ l.setMaxPromptTokens(4096);
+ l.setMaxOutputTokens(1024);
+ l.setMaxContextWindowTokens(16384);
+ assertEquals(4096, l.getMaxPromptTokens().getAsInt());
+ assertEquals(1024, l.getMaxOutputTokens().getAsInt());
+ assertEquals(16384, l.getMaxContextWindowTokens().getAsInt());
+ }
+
+ @Test
+ void providerConfig_tokenValues() {
+ var cfg = new ProviderConfig();
+ assertTrue(cfg.getMaxPromptTokens().isEmpty());
+ assertTrue(cfg.getMaxOutputTokens().isEmpty());
+
+ cfg.setMaxPromptTokens(8192);
+ cfg.setMaxOutputTokens(2048);
+ assertEquals(8192, cfg.getMaxPromptTokens().getAsInt());
+ assertEquals(2048, cfg.getMaxOutputTokens().getAsInt());
+ }
+
+ @Test
+ void telemetryConfig_captureContentValue() {
+ var cfg = new TelemetryConfig();
+ assertTrue(cfg.getCaptureContent().isEmpty());
+
+ cfg.setCaptureContent(true);
+ assertTrue(cfg.getCaptureContent().get());
+
+ cfg.setCaptureContent(false);
+ assertFalse(cfg.getCaptureContent().get());
+ }
+
+ @Test
+ void sessionUiCapabilities_elicitationValue() {
+ var caps = new SessionUiCapabilities();
+ assertTrue(caps.getElicitation().isEmpty());
+ assertFalse(caps.getElicitation().orElse(false));
+
+ caps.setElicitation(true);
+ assertTrue(caps.getElicitation().orElse(false));
+ }
+
+ @Test
+ void customAgentConfig_inferValue() {
+ var cfg = new CustomAgentConfig();
+ assertTrue(cfg.getInfer().isEmpty());
+
+ cfg.setInfer(true);
+ assertTrue(cfg.getInfer().get());
+
+ cfg.setInfer(false);
+ assertFalse(cfg.getInfer().get());
+ }
+
+ @Test
+ void userInputRequest_allowFreeformValue() {
+ var req = new UserInputRequest();
+ assertTrue(req.getAllowFreeform().isEmpty());
+
+ req.setAllowFreeform(true);
+ assertTrue(req.getAllowFreeform().get());
+
+ req.setAllowFreeform(false);
+ assertFalse(req.getAllowFreeform().get());
+ }
+
+ // ── JSON deserialization into Optional-returning classes ───────────
+
+ @Test
+ void jackson_deserializeSupportsWithFields() throws Exception {
+ String json = "{\"vision\":true,\"reasoningEffort\":false}";
+ var supports = MAPPER.readValue(json, ModelCapabilitiesOverride.Supports.class);
+ assertTrue(supports.getVision().get());
+ assertFalse(supports.getReasoningEffort().get());
+ }
+
+ @Test
+ void jackson_deserializeSupportsEmpty() throws Exception {
+ String json = "{}";
+ var supports = MAPPER.readValue(json, ModelCapabilitiesOverride.Supports.class);
+ assertTrue(supports.getVision().isEmpty());
+ assertTrue(supports.getReasoningEffort().isEmpty());
+ }
+
+ @Test
+ void jackson_deserializeLimitsWithFields() throws Exception {
+ String json = "{\"max_prompt_tokens\":4096,\"max_output_tokens\":1024,\"max_context_window_tokens\":16384}";
+ var limits = MAPPER.readValue(json, ModelCapabilitiesOverride.Limits.class);
+ assertEquals(4096, limits.getMaxPromptTokens().getAsInt());
+ assertEquals(1024, limits.getMaxOutputTokens().getAsInt());
+ assertEquals(16384, limits.getMaxContextWindowTokens().getAsInt());
+ }
+
+ @Test
+ void jackson_deserializeLimitsEmpty() throws Exception {
+ String json = "{}";
+ var limits = MAPPER.readValue(json, ModelCapabilitiesOverride.Limits.class);
+ assertTrue(limits.getMaxPromptTokens().isEmpty());
+ assertTrue(limits.getMaxOutputTokens().isEmpty());
+ assertTrue(limits.getMaxContextWindowTokens().isEmpty());
+ }
+
+ @Test
+ void jackson_deserializeInfiniteSessionConfigWithFields() throws Exception {
+ String json = "{\"enabled\":true,\"backgroundCompactionThreshold\":0.7,\"bufferExhaustionThreshold\":0.9}";
+ var cfg = MAPPER.readValue(json, InfiniteSessionConfig.class);
+ assertTrue(cfg.getEnabled().get());
+ assertEquals(0.7, cfg.getBackgroundCompactionThreshold().getAsDouble(), 0.001);
+ assertEquals(0.9, cfg.getBufferExhaustionThreshold().getAsDouble(), 0.001);
+ }
+
+ @Test
+ void jackson_deserializeInfiniteSessionConfigEmpty() throws Exception {
+ String json = "{}";
+ var cfg = MAPPER.readValue(json, InfiniteSessionConfig.class);
+ assertTrue(cfg.getEnabled().isEmpty());
+ assertTrue(cfg.getBackgroundCompactionThreshold().isEmpty());
+ assertTrue(cfg.getBufferExhaustionThreshold().isEmpty());
+ }
+
// ── Jackson serialization roundtrip ───────────────────────────────
//
// Classes whose fields carry @JsonProperty (InfiniteSessionConfig,
From e22533773582423092b552b3f21c4f4def3b4152 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 13 May 2026 23:12:55 +0000
Subject: [PATCH 030/135] Bump github/gh-aw from 0.71.5 to 0.73.0 in the
github-actions group
Bumps the github-actions group with 1 update: [github/gh-aw](https://github.com/github/gh-aw).
Updates `github/gh-aw` from 0.71.5 to 0.73.0
- [Release notes](https://github.com/github/gh-aw/releases)
- [Changelog](https://github.com/github/gh-aw/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/gh-aw/compare/19ac811a4a85389c33b15128e1d7b7d4507f814a...4d44d0e89851a877f4ddc0cb6c0197e42b1016c5)
---
updated-dependencies:
- dependency-name: github/gh-aw
dependency-version: 0.73.0
dependency-type: direct:production
update-type: version-update:semver-minor
dependency-group: github-actions
...
Signed-off-by: dependabot[bot]
---
.github/workflows/copilot-setup-steps.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml
index 0d7e4f9a6c..9522a64923 100644
--- a/.github/workflows/copilot-setup-steps.yml
+++ b/.github/workflows/copilot-setup-steps.yml
@@ -24,7 +24,7 @@ jobs:
# Install GitHub CLI and gh-aw extension for Copilot Agent interaction
- name: Install gh-aw extension
- uses: github/gh-aw/actions/setup-cli@19ac811a4a85389c33b15128e1d7b7d4507f814a # v0.71.5
+ uses: github/gh-aw/actions/setup-cli@4d44d0e89851a877f4ddc0cb6c0197e42b1016c5 # v0.73.0
with:
version: v0.68.3
From 89ab0fe8405d13f594a5a070f7ef8549a69f66df Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Thu, 14 May 2026 10:12:29 -0700
Subject: [PATCH 031/135] Per
https://github.com/github/copilot-sdk-partners/issues/89 no per-language
teams
---
.github/CODEOWNERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 0c213e61c0..c6959d3089 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @github/copilot-sdk-java
+* @github/copilot-sdk
From 8e0eeeb9832f2f113b8a4ec5c4accc05ca1f6e6a Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 14 May 2026 18:44:37 +0000
Subject: [PATCH 032/135] refactor: revert Optional usage, use plain nullable
fields with @JsonInclude(NON_NULL)
Remove all Optional/OptionalInt/OptionalDouble usage from DTOs.
Revert to plain nullable boxed fields (Boolean, Integer, Double) per
Java DTO conventions and reference implementation parity.
Add @JsonInclude(JsonInclude.Include.NON_NULL) to classes that were
missing it: InputOptions, TelemetryConfig, SessionUiCapabilities,
UserInputRequest.
Add JsonIncludeNonNullTest verifying annotation presence and
serialization behavior (null fields omitted, set fields included).
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.../github/copilot/sdk/CliServerManager.java | 14 +-
.../com/github/copilot/sdk/CopilotClient.java | 2 +-
.../github/copilot/sdk/CopilotSession.java | 15 +-
.../copilot/sdk/SessionRequestBuilder.java | 40 +-
.../sdk/json/CopilotClientOptions.java | 58 +-
.../sdk/json/CreateSessionRequest.java | 73 +-
.../copilot/sdk/json/CustomAgentConfig.java | 22 +-
.../sdk/json/InfiniteSessionConfig.java | 70 +-
.../github/copilot/sdk/json/InputOptions.java | 52 +-
.../sdk/json/ModelCapabilitiesOverride.java | 112 +--
.../copilot/sdk/json/ProviderConfig.java | 43 +-
.../copilot/sdk/json/ResumeSessionConfig.java | 61 +-
.../sdk/json/ResumeSessionRequest.java | 82 +--
.../copilot/sdk/json/SessionConfig.java | 74 +-
.../sdk/json/SessionUiCapabilities.java | 28 +-
.../copilot/sdk/json/TelemetryConfig.java | 28 +-
.../copilot/sdk/json/UserInputRequest.java | 25 +-
.../github/copilot/sdk/ConfigCloneTest.java | 18 +-
.../github/copilot/sdk/CopilotClientTest.java | 11 +-
.../copilot/sdk/DataObjectCoverageTest.java | 13 +-
.../github/copilot/sdk/ElicitationTest.java | 10 +-
.../copilot/sdk/JsonIncludeNonNullTest.java | 159 +++++
.../sdk/OptionalApiAndJacksonTest.java | 635 ------------------
.../copilot/sdk/ProviderConfigTest.java | 8 +-
.../copilot/sdk/TelemetryConfigTest.java | 8 +-
25 files changed, 364 insertions(+), 1297 deletions(-)
create mode 100644 src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java
delete mode 100644 src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
diff --git a/src/main/java/com/github/copilot/sdk/CliServerManager.java b/src/main/java/com/github/copilot/sdk/CliServerManager.java
index bd4effe5a8..3087966d39 100644
--- a/src/main/java/com/github/copilot/sdk/CliServerManager.java
+++ b/src/main/java/com/github/copilot/sdk/CliServerManager.java
@@ -90,16 +90,16 @@ ProcessInfo startCliServer() throws IOException, InterruptedException {
}
// Default UseLoggedInUser to false when GitHubToken is provided
- boolean useLoggedInUser = options.getUseLoggedInUser()
- .orElse(options.getGitHubToken() == null || options.getGitHubToken().isEmpty());
+ boolean useLoggedInUser = options.getUseLoggedInUser() != null
+ ? options.getUseLoggedInUser()
+ : (options.getGitHubToken() == null || options.getGitHubToken().isEmpty());
if (!useLoggedInUser) {
args.add("--no-auto-login");
}
- if (options.getSessionIdleTimeoutSeconds().isPresent()
- && options.getSessionIdleTimeoutSeconds().getAsInt() > 0) {
+ if (options.getSessionIdleTimeoutSeconds() != null && options.getSessionIdleTimeoutSeconds() > 0) {
args.add("--session-idle-timeout");
- args.add(String.valueOf(options.getSessionIdleTimeoutSeconds().getAsInt()));
+ args.add(String.valueOf(options.getSessionIdleTimeoutSeconds()));
}
if (options.isRemote()) {
@@ -159,9 +159,9 @@ ProcessInfo startCliServer() throws IOException, InterruptedException {
if (telemetry.getSourceName() != null) {
pb.environment().put("COPILOT_OTEL_SOURCE_NAME", telemetry.getSourceName());
}
- if (telemetry.getCaptureContent().isPresent()) {
+ if (telemetry.getCaptureContent() != null) {
pb.environment().put("OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT",
- telemetry.getCaptureContent().get() ? "true" : "false");
+ telemetry.getCaptureContent() ? "true" : "false");
}
}
diff --git a/src/main/java/com/github/copilot/sdk/CopilotClient.java b/src/main/java/com/github/copilot/sdk/CopilotClient.java
index 4d0770319a..5b988d9d2b 100644
--- a/src/main/java/com/github/copilot/sdk/CopilotClient.java
+++ b/src/main/java/com/github/copilot/sdk/CopilotClient.java
@@ -120,7 +120,7 @@ public CopilotClient(CopilotClientOptions options) {
// Validate auth options with external server
if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty()
- && (this.options.getGitHubToken() != null || this.options.getUseLoggedInUser().isPresent())) {
+ && (this.options.getGitHubToken() != null || this.options.getUseLoggedInUser() != null)) {
throw new IllegalArgumentException(
"GitHubToken and UseLoggedInUser cannot be used with CliUrl (external server manages its own auth)");
}
diff --git a/src/main/java/com/github/copilot/sdk/CopilotSession.java b/src/main/java/com/github/copilot/sdk/CopilotSession.java
index 79a7f343b7..ad5561c09e 100644
--- a/src/main/java/com/github/copilot/sdk/CopilotSession.java
+++ b/src/main/java/com/github/copilot/sdk/CopilotSession.java
@@ -1118,9 +1118,9 @@ private void handleElicitationRequestAsync(ElicitationContext context, String re
*/
private void assertElicitation() {
SessionCapabilities caps = capabilities;
- if (caps == null || caps.getUi() == null || !caps.getUi().getElicitation().orElse(false)) {
+ if (caps == null || caps.getUi() == null || !Boolean.TRUE.equals(caps.getUi().getElicitation())) {
throw new IllegalStateException("Elicitation is not supported by the host. "
- + "Check session.getCapabilities().getUi().getElicitation().orElse(false) before calling UI methods.");
+ + "Check session.getCapabilities().getUi()?.getElicitation() before calling UI methods.");
}
}
@@ -1201,10 +1201,10 @@ public CompletableFuture input(String message, InputOptions options) {
field.put("title", options.getTitle());
if (options.getDescription() != null)
field.put("description", options.getDescription());
- if (options.getMinLength().isPresent())
- field.put("minLength", options.getMinLength().getAsInt());
- if (options.getMaxLength().isPresent())
- field.put("maxLength", options.getMaxLength().getAsInt());
+ if (options.getMinLength() != null)
+ field.put("minLength", options.getMinLength());
+ if (options.getMaxLength() != null)
+ field.put("maxLength", options.getMaxLength());
if (options.getFormat() != null)
field.put("format", options.getFormat());
if (options.getDefaultValue() != null)
@@ -1695,8 +1695,7 @@ public CompletableFuture setModel(String model, String reasoningEffort,
ModelCapabilitiesOverrideSupports supports = null;
if (modelCapabilities.getSupports() != null) {
var s = modelCapabilities.getSupports();
- supports = new ModelCapabilitiesOverrideSupports(s.getVision().orElse(null),
- s.getReasoningEffort().orElse(null));
+ supports = new ModelCapabilitiesOverrideSupports(s.getVision(), s.getReasoningEffort());
}
ModelCapabilitiesOverrideLimits limits = null;
if (modelCapabilities.getLimits() != null) {
diff --git a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
index 1bd3a50cb7..d9752db7ee 100644
--- a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
+++ b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
@@ -111,18 +111,12 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
request.setAvailableTools(config.getAvailableTools());
request.setExcludedTools(config.getExcludedTools());
request.setProvider(config.getProvider());
- config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
- if (config.getOnUserInputRequest() != null) {
- request.setRequestUserInput(true);
- }
- if (config.getHooks() != null && config.getHooks().hasHooks()) {
- request.setHooks(true);
- }
+ request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());
+ request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);
+ request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);
request.setWorkingDirectory(config.getWorkingDirectory());
- if (config.isStreaming()) {
- request.setStreaming(true);
- }
- config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);
+ request.setStreaming(config.isStreaming() ? true : null);
+ request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());
request.setMcpServers(config.getMcpServers());
request.setCustomAgents(config.getCustomAgents());
request.setDefaultAgent(config.getDefaultAgent());
@@ -132,7 +126,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
request.setInstructionDirectories(config.getInstructionDirectories());
request.setDisabledSkills(config.getDisabledSkills());
request.setConfigDir(config.getConfigDir());
- config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);
+ request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());
request.setModelCapabilities(config.getModelCapabilities());
if (config.getCommands() != null && !config.getCommands().isEmpty()) {
@@ -200,23 +194,15 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo
request.setAvailableTools(config.getAvailableTools());
request.setExcludedTools(config.getExcludedTools());
request.setProvider(config.getProvider());
- config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
- if (config.getOnUserInputRequest() != null) {
- request.setRequestUserInput(true);
- }
- if (config.getHooks() != null && config.getHooks().hasHooks()) {
- request.setHooks(true);
- }
+ request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());
+ request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);
+ request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);
request.setWorkingDirectory(config.getWorkingDirectory());
request.setConfigDir(config.getConfigDir());
- config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);
- if (config.isDisableResume()) {
- request.setDisableResume(true);
- }
- if (config.isStreaming()) {
- request.setStreaming(true);
- }
- config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);
+ request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());
+ request.setDisableResume(config.isDisableResume() ? true : null);
+ request.setStreaming(config.isStreaming() ? true : null);
+ request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());
request.setMcpServers(config.getMcpServers());
request.setCustomAgents(config.getCustomAgents());
request.setDefaultAgent(config.getDefaultAgent());
diff --git a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
index e4605ffe10..5517df631e 100644
--- a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
@@ -14,9 +14,6 @@
import java.util.function.Supplier;
import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.Optional;
-import java.util.OptionalInt;
/**
* Configuration options for creating a
@@ -502,47 +499,34 @@ public CopilotClientOptions setTelemetry(TelemetryConfig telemetry) {
/**
* Gets the server-wide idle timeout for sessions in seconds.
*
- * @return an {@link OptionalInt} containing the session idle timeout in
- * seconds, or {@link java.util.OptionalInt#empty()} if not set. Use
- * {@link #clearSessionIdleTimeoutSeconds()} to revert to the default.
+ * @return the session idle timeout in seconds, or {@code null} to disable
+ * (sessions live indefinitely)
* @since 1.3.0
*/
- @JsonIgnore
- public OptionalInt getSessionIdleTimeoutSeconds() {
- return sessionIdleTimeoutSeconds == null ? OptionalInt.empty() : OptionalInt.of(sessionIdleTimeoutSeconds);
+ public Integer getSessionIdleTimeoutSeconds() {
+ return sessionIdleTimeoutSeconds;
}
/**
* Sets the server-wide idle timeout for sessions in seconds.
*
* Sessions without activity for this duration are automatically cleaned up. Set
- * to {@code 0} to disable (sessions live indefinitely). Use
- * {@link #clearSessionIdleTimeoutSeconds()} to revert to the default.
+ * to {@code 0} or leave as {@code null} to disable (sessions live
+ * indefinitely).
*
* This option is only used when the SDK spawns the CLI process; it is ignored
* when connecting to an external server via {@link #setCliUrl(String)}.
*
* @param sessionIdleTimeoutSeconds
- * the idle timeout in seconds
+ * the idle timeout in seconds, or {@code null} to disable
* @return this options instance for method chaining
* @since 1.3.0
*/
- public CopilotClientOptions setSessionIdleTimeoutSeconds(int sessionIdleTimeoutSeconds) {
+ public CopilotClientOptions setSessionIdleTimeoutSeconds(Integer sessionIdleTimeoutSeconds) {
this.sessionIdleTimeoutSeconds = sessionIdleTimeoutSeconds;
return this;
}
- /**
- * Clears the sessionIdleTimeoutSeconds setting, reverting to the default
- * behavior.
- *
- * @return this instance for method chaining
- */
- public CopilotClientOptions clearSessionIdleTimeoutSeconds() {
- this.sessionIdleTimeoutSeconds = null;
- return this;
- }
-
/**
* Gets the connection token for the headless CLI server (TCP only).
*
@@ -571,11 +555,11 @@ public CopilotClientOptions setTcpConnectionToken(String tcpConnectionToken) {
/**
* Returns whether to use the logged-in user for authentication.
*
- * @return an {@link Optional} containing the boolean value, or empty if not set
+ * @return {@code true} to use logged-in user auth, {@code false} to use only
+ * explicit tokens, or {@code null} to use default behavior
*/
- @JsonIgnore
- public Optional getUseLoggedInUser() {
- return Optional.ofNullable(useLoggedInUser);
+ public Boolean getUseLoggedInUser() {
+ return useLoggedInUser;
}
/**
@@ -585,23 +569,15 @@ public Optional getUseLoggedInUser() {
* auth. When false, only explicit tokens (gitHubToken or environment variables)
* are used. Default: true (but defaults to false when gitHubToken is provided).
*
+ * Passing {@code null} is equivalent to passing {@link Boolean#FALSE}.
*
* @param useLoggedInUser
- * {@code true} to use logged-in user auth, {@code false} otherwise
+ * {@code true} to use logged-in user auth, {@code false} or
+ * {@code null} otherwise
* @return this options instance for method chaining
*/
- public CopilotClientOptions setUseLoggedInUser(boolean useLoggedInUser) {
- this.useLoggedInUser = useLoggedInUser;
- return this;
- }
-
- /**
- * Clears the useLoggedInUser setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public CopilotClientOptions clearUseLoggedInUser() {
- this.useLoggedInUser = null;
+ public CopilotClientOptions setUseLoggedInUser(Boolean useLoggedInUser) {
+ this.useLoggedInUser = useLoggedInUser != null ? useLoggedInUser : Boolean.FALSE;
return this;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
index 0160724bef..12bab4154c 100644
--- a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
@@ -224,68 +224,40 @@ public Boolean getEnableSessionTelemetry() {
/**
* Sets enable session telemetry flag. @param enableSessionTelemetry the flag
*/
- public void setEnableSessionTelemetry(boolean enableSessionTelemetry) {
+ public void setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
}
- /**
- * Clears the enableSessionTelemetry setting, reverting to the default behavior.
- */
- public void clearEnableSessionTelemetry() {
- this.enableSessionTelemetry = null;
- }
-
/** Gets request permission flag. @return the flag */
public Boolean getRequestPermission() {
return requestPermission;
}
/** Sets request permission flag. @param requestPermission the flag */
- public void setRequestPermission(boolean requestPermission) {
+ public void setRequestPermission(Boolean requestPermission) {
this.requestPermission = requestPermission;
}
- /**
- * Clears the requestPermission setting, reverting to the default behavior.
- */
- public void clearRequestPermission() {
- this.requestPermission = null;
- }
-
/** Gets request user input flag. @return the flag */
public Boolean getRequestUserInput() {
return requestUserInput;
}
/** Sets request user input flag. @param requestUserInput the flag */
- public void setRequestUserInput(boolean requestUserInput) {
+ public void setRequestUserInput(Boolean requestUserInput) {
this.requestUserInput = requestUserInput;
}
- /**
- * Clears the requestUserInput setting, reverting to the default behavior.
- */
- public void clearRequestUserInput() {
- this.requestUserInput = null;
- }
-
/** Gets hooks flag. @return the flag */
public Boolean getHooks() {
return hooks;
}
/** Sets hooks flag. @param hooks the flag */
- public void setHooks(boolean hooks) {
+ public void setHooks(Boolean hooks) {
this.hooks = hooks;
}
- /**
- * Clears the hooks setting, reverting to the default behavior.
- */
- public void clearHooks() {
- this.hooks = null;
- }
-
/** Gets working directory. @return the working directory */
public String getWorkingDirectory() {
return workingDirectory;
@@ -302,17 +274,10 @@ public Boolean getStreaming() {
}
/** Sets streaming flag. @param streaming the flag */
- public void setStreaming(boolean streaming) {
+ public void setStreaming(Boolean streaming) {
this.streaming = streaming;
}
- /**
- * Clears the streaming setting, reverting to the default behavior.
- */
- public void clearStreaming() {
- this.streaming = null;
- }
-
/** Gets MCP servers. @return the servers map */
public Map getMcpServers() {
return mcpServers == null ? null : Collections.unmodifiableMap(mcpServers);
@@ -423,17 +388,10 @@ public Boolean getEnableConfigDiscovery() {
}
/** Sets enable config discovery flag. @param enableConfigDiscovery the flag */
- public void setEnableConfigDiscovery(boolean enableConfigDiscovery) {
+ public void setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
}
- /**
- * Clears the enableConfigDiscovery setting, reverting to the default behavior.
- */
- public void clearEnableConfigDiscovery() {
- this.enableConfigDiscovery = null;
- }
-
/** Gets include sub-agent streaming events flag. @return the flag */
public Boolean getIncludeSubAgentStreamingEvents() {
return includeSubAgentStreamingEvents;
@@ -443,18 +401,10 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* Sets include sub-agent streaming events flag. @param
* includeSubAgentStreamingEvents the flag
*/
- public void setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
+ public void setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
}
- /**
- * Clears the includeSubAgentStreamingEvents setting, reverting to the default
- * behavior.
- */
- public void clearIncludeSubAgentStreamingEvents() {
- this.includeSubAgentStreamingEvents = null;
- }
-
/** Gets the commands wire definitions. @return the commands */
public List getCommands() {
return commands == null ? null : Collections.unmodifiableList(commands);
@@ -471,17 +421,10 @@ public Boolean getRequestElicitation() {
}
/** Sets the requestElicitation flag. @param requestElicitation the flag */
- public void setRequestElicitation(boolean requestElicitation) {
+ public void setRequestElicitation(Boolean requestElicitation) {
this.requestElicitation = requestElicitation;
}
- /**
- * Clears the requestElicitation setting, reverting to the default behavior.
- */
- public void clearRequestElicitation() {
- this.requestElicitation = null;
- }
-
/** Gets the requestExitPlanMode flag. @return the flag */
public Boolean getRequestExitPlanMode() {
return requestExitPlanMode;
diff --git a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
index bb9520055e..1421db603f 100644
--- a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
@@ -10,8 +10,6 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.Optional;
/**
* Configuration for a custom agent in a Copilot session.
@@ -199,12 +197,10 @@ public CustomAgentConfig setMcpServers(Map mcpServers)
/**
* Gets whether inference mode is enabled.
*
- * @return an {@link java.util.Optional} containing the infer flag, or
- * {@link java.util.Optional#empty()} if not set
+ * @return the infer flag, or {@code null} if not set
*/
- @JsonIgnore
- public Optional getInfer() {
- return Optional.ofNullable(infer);
+ public Boolean getInfer() {
+ return infer;
}
/**
@@ -214,21 +210,11 @@ public Optional getInfer() {
* {@code true} to enable inference mode
* @return this config for method chaining
*/
- public CustomAgentConfig setInfer(boolean infer) {
+ public CustomAgentConfig setInfer(Boolean infer) {
this.infer = infer;
return this;
}
- /**
- * Clears the infer setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public CustomAgentConfig clearInfer() {
- this.infer = null;
- return this;
- }
-
/**
* Gets the list of skill names to preload into this agent's context.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java
index 561796ede7..d45851f8a1 100644
--- a/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java
@@ -6,9 +6,6 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.Optional;
-import java.util.OptionalDouble;
/**
* Configuration for infinite sessions with automatic context compaction and
@@ -46,12 +43,10 @@ public class InfiniteSessionConfig {
/**
* Gets whether infinite sessions are enabled.
*
- * @return an {@link Optional} containing the boolean value, or empty to use
- * default (true)
+ * @return {@code true} if enabled, {@code null} to use default (true)
*/
- @JsonIgnore
- public Optional getEnabled() {
- return Optional.ofNullable(enabled);
+ public Boolean getEnabled() {
+ return enabled;
}
/**
@@ -63,32 +58,18 @@ public Optional getEnabled() {
* {@code true} to enable infinite sessions
* @return this config instance for method chaining
*/
- public InfiniteSessionConfig setEnabled(boolean enabled) {
+ public InfiniteSessionConfig setEnabled(Boolean enabled) {
this.enabled = enabled;
return this;
}
- /**
- * Clears the enabled setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public InfiniteSessionConfig clearEnabled() {
- this.enabled = null;
- return this;
- }
-
/**
* Gets the background compaction threshold.
*
- * @return an {@link OptionalDouble} containing the threshold (0.0-1.0), or
- * empty to use default
+ * @return the threshold (0.0-1.0), or {@code null} to use default
*/
- @JsonIgnore
- public OptionalDouble getBackgroundCompactionThreshold() {
- return backgroundCompactionThreshold == null
- ? OptionalDouble.empty()
- : OptionalDouble.of(backgroundCompactionThreshold);
+ public Double getBackgroundCompactionThreshold() {
+ return backgroundCompactionThreshold;
}
/**
@@ -101,33 +82,18 @@ public OptionalDouble getBackgroundCompactionThreshold() {
* the threshold (0.0-1.0)
* @return this config instance for method chaining
*/
- public InfiniteSessionConfig setBackgroundCompactionThreshold(double backgroundCompactionThreshold) {
+ public InfiniteSessionConfig setBackgroundCompactionThreshold(Double backgroundCompactionThreshold) {
this.backgroundCompactionThreshold = backgroundCompactionThreshold;
return this;
}
- /**
- * Clears the backgroundCompactionThreshold setting, reverting to the default
- * behavior.
- *
- * @return this instance for method chaining
- */
- public InfiniteSessionConfig clearBackgroundCompactionThreshold() {
- this.backgroundCompactionThreshold = null;
- return this;
- }
-
/**
* Gets the buffer exhaustion threshold.
*
- * @return an {@link OptionalDouble} containing the threshold (0.0-1.0), or
- * empty to use default
+ * @return the threshold (0.0-1.0), or {@code null} to use default
*/
- @JsonIgnore
- public OptionalDouble getBufferExhaustionThreshold() {
- return bufferExhaustionThreshold == null
- ? OptionalDouble.empty()
- : OptionalDouble.of(bufferExhaustionThreshold);
+ public Double getBufferExhaustionThreshold() {
+ return bufferExhaustionThreshold;
}
/**
@@ -141,20 +107,8 @@ public OptionalDouble getBufferExhaustionThreshold() {
* the threshold (0.0-1.0)
* @return this config instance for method chaining
*/
- public InfiniteSessionConfig setBufferExhaustionThreshold(double bufferExhaustionThreshold) {
+ public InfiniteSessionConfig setBufferExhaustionThreshold(Double bufferExhaustionThreshold) {
this.bufferExhaustionThreshold = bufferExhaustionThreshold;
return this;
}
-
- /**
- * Clears the bufferExhaustionThreshold setting, reverting to the default
- * behavior.
- *
- * @return this instance for method chaining
- */
- public InfiniteSessionConfig clearBufferExhaustionThreshold() {
- this.bufferExhaustionThreshold = null;
- return this;
- }
-
}
diff --git a/src/main/java/com/github/copilot/sdk/json/InputOptions.java b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
index 4f209bf6fa..43b29c53b9 100644
--- a/src/main/java/com/github/copilot/sdk/json/InputOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
@@ -4,8 +4,7 @@
package com.github.copilot.sdk.json;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.OptionalInt;
+import com.fasterxml.jackson.annotation.JsonInclude;
/**
* Options for the {@link SessionUiApi#input(String, InputOptions)} convenience
@@ -13,6 +12,7 @@
*
* @since 1.0.0
*/
+@JsonInclude(JsonInclude.Include.NON_NULL)
public class InputOptions {
private String title;
@@ -49,66 +49,34 @@ public InputOptions setDescription(String description) {
return this;
}
- /**
- * Gets the minimum character length.
- *
- * @return an {@link java.util.OptionalInt} containing the min length, or
- * {@link java.util.OptionalInt#empty()} if not set
- */
- @JsonIgnore
- public OptionalInt getMinLength() {
- return minLength == null ? OptionalInt.empty() : OptionalInt.of(minLength);
+ /** Gets the minimum character length. @return the min length */
+ public Integer getMinLength() {
+ return minLength;
}
/**
* Sets the minimum character length. @param minLength the min length @return
* this
*/
- public InputOptions setMinLength(int minLength) {
+ public InputOptions setMinLength(Integer minLength) {
this.minLength = minLength;
return this;
}
- /**
- * Clears the minLength setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public InputOptions clearMinLength() {
- this.minLength = null;
- return this;
- }
-
- /**
- * Gets the maximum character length.
- *
- * @return an {@link java.util.OptionalInt} containing the max length, or
- * {@link java.util.OptionalInt#empty()} if not set
- */
- @JsonIgnore
- public OptionalInt getMaxLength() {
- return maxLength == null ? OptionalInt.empty() : OptionalInt.of(maxLength);
+ /** Gets the maximum character length. @return the max length */
+ public Integer getMaxLength() {
+ return maxLength;
}
/**
* Sets the maximum character length. @param maxLength the max length @return
* this
*/
- public InputOptions setMaxLength(int maxLength) {
+ public InputOptions setMaxLength(Integer maxLength) {
this.maxLength = maxLength;
return this;
}
- /**
- * Clears the maxLength setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public InputOptions clearMaxLength() {
- this.maxLength = null;
- return this;
- }
-
/**
* Gets the semantic format hint (e.g., {@code "email"}, {@code "uri"},
* {@code "date"}, {@code "date-time"}).
diff --git a/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java b/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
index 02727d4b5c..18701ad671 100644
--- a/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
+++ b/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
@@ -7,9 +7,6 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.Optional;
-import java.util.OptionalInt;
/**
* Per-property overrides for model capabilities, deep-merged over runtime
@@ -109,73 +106,48 @@ public static class Supports {
/**
* Gets the vision override.
*
- * @return an {@link java.util.Optional} containing {@code true} to enable
- * vision or {@code false} to disable, or
- * {@link java.util.Optional#empty()} to use the runtime default
+ * @return {@code true} to enable vision, {@code false} to disable, or
+ * {@code null} to use the runtime default
*/
- @JsonIgnore
- public Optional getVision() {
- return Optional.ofNullable(vision);
+ public Boolean getVision() {
+ return vision;
}
/**
- * Sets whether vision (image input) is enabled. Use {@link #clearVision()} to
- * revert to the runtime default.
+ * Sets whether vision (image input) is enabled.
*
* @param vision
- * {@code true} to enable, {@code false} to disable
+ * {@code true} to enable, {@code false} to disable, or {@code null}
+ * to use the runtime default
* @return this instance for method chaining
*/
- public Supports setVision(boolean vision) {
+ public Supports setVision(Boolean vision) {
this.vision = vision;
return this;
}
- /**
- * Clears the vision setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public Supports clearVision() {
- this.vision = null;
- return this;
- }
-
/**
* Gets the reasoning effort override.
*
- * @return an {@link java.util.Optional} containing {@code true} to enable
- * reasoning effort or {@code false} to disable, or
- * {@link java.util.Optional#empty()} to use the runtime default
+ * @return {@code true} to enable reasoning effort, {@code false} to disable, or
+ * {@code null} to use the runtime default
*/
- @JsonIgnore
- public Optional getReasoningEffort() {
- return Optional.ofNullable(reasoningEffort);
+ public Boolean getReasoningEffort() {
+ return reasoningEffort;
}
/**
- * Sets whether reasoning effort configuration is enabled. Use
- * {@link #clearReasoningEffort()} to revert to the runtime default.
+ * Sets whether reasoning effort configuration is enabled.
*
* @param reasoningEffort
- * {@code true} to enable, {@code false} to disable
+ * {@code true} to enable, {@code false} to disable, or {@code null}
+ * to use the runtime default
* @return this instance for method chaining
*/
- public Supports setReasoningEffort(boolean reasoningEffort) {
+ public Supports setReasoningEffort(Boolean reasoningEffort) {
this.reasoningEffort = reasoningEffort;
return this;
}
-
- /**
- * Clears the reasoningEffort setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public Supports clearReasoningEffort() {
- this.reasoningEffort = null;
- return this;
- }
-
}
/**
@@ -202,9 +174,8 @@ public static class Limits {
*
* @return the override value, or {@code null} to use the runtime default
*/
- @JsonIgnore
- public OptionalInt getMaxPromptTokens() {
- return maxPromptTokens == null ? OptionalInt.empty() : OptionalInt.of(maxPromptTokens);
+ public Integer getMaxPromptTokens() {
+ return maxPromptTokens;
}
/**
@@ -214,29 +185,18 @@ public OptionalInt getMaxPromptTokens() {
* the override value, or {@code null} to use the runtime default
* @return this instance for method chaining
*/
- public Limits setMaxPromptTokens(int maxPromptTokens) {
+ public Limits setMaxPromptTokens(Integer maxPromptTokens) {
this.maxPromptTokens = maxPromptTokens;
return this;
}
- /**
- * Clears the maxPromptTokens setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public Limits clearMaxPromptTokens() {
- this.maxPromptTokens = null;
- return this;
- }
-
/**
* Gets the maximum output tokens override.
*
* @return the override value, or {@code null} to use the runtime default
*/
- @JsonIgnore
- public OptionalInt getMaxOutputTokens() {
- return maxOutputTokens == null ? OptionalInt.empty() : OptionalInt.of(maxOutputTokens);
+ public Integer getMaxOutputTokens() {
+ return maxOutputTokens;
}
/**
@@ -246,29 +206,18 @@ public OptionalInt getMaxOutputTokens() {
* the override value, or {@code null} to use the runtime default
* @return this instance for method chaining
*/
- public Limits setMaxOutputTokens(int maxOutputTokens) {
+ public Limits setMaxOutputTokens(Integer maxOutputTokens) {
this.maxOutputTokens = maxOutputTokens;
return this;
}
- /**
- * Clears the maxOutputTokens setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public Limits clearMaxOutputTokens() {
- this.maxOutputTokens = null;
- return this;
- }
-
/**
* Gets the maximum context window tokens override.
*
* @return the override value, or {@code null} to use the runtime default
*/
- @JsonIgnore
- public OptionalInt getMaxContextWindowTokens() {
- return maxContextWindowTokens == null ? OptionalInt.empty() : OptionalInt.of(maxContextWindowTokens);
+ public Integer getMaxContextWindowTokens() {
+ return maxContextWindowTokens;
}
/**
@@ -278,20 +227,9 @@ public OptionalInt getMaxContextWindowTokens() {
* the override value, or {@code null} to use the runtime default
* @return this instance for method chaining
*/
- public Limits setMaxContextWindowTokens(int maxContextWindowTokens) {
+ public Limits setMaxContextWindowTokens(Integer maxContextWindowTokens) {
this.maxContextWindowTokens = maxContextWindowTokens;
return this;
}
-
- /**
- * Clears the maxContextWindowTokens setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public Limits clearMaxContextWindowTokens() {
- this.maxContextWindowTokens = null;
- return this;
- }
-
}
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java b/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
index 1c5e6fcc7f..8947696c9a 100644
--- a/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
@@ -9,8 +9,6 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.OptionalInt;
/**
* Configuration for a custom API provider (BYOK - Bring Your Own Key).
@@ -298,12 +296,10 @@ public ProviderConfig setWireModel(String wireModel) {
/**
* Gets the maximum prompt token override.
*
- * @return an {@link java.util.OptionalInt} containing the max prompt tokens, or
- * {@link java.util.OptionalInt#empty()} if not set
+ * @return the max prompt tokens, or {@code null} if not set
*/
- @JsonIgnore
- public OptionalInt getMaxPromptTokens() {
- return maxPromptTokens == null ? OptionalInt.empty() : OptionalInt.of(maxPromptTokens);
+ public Integer getMaxPromptTokens() {
+ return maxPromptTokens;
}
/**
@@ -318,30 +314,18 @@ public OptionalInt getMaxPromptTokens() {
* the max prompt tokens
* @return this config for method chaining
*/
- public ProviderConfig setMaxPromptTokens(int maxPromptTokens) {
+ public ProviderConfig setMaxPromptTokens(Integer maxPromptTokens) {
this.maxPromptTokens = maxPromptTokens;
return this;
}
- /**
- * Clears the maxPromptTokens setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public ProviderConfig clearMaxPromptTokens() {
- this.maxPromptTokens = null;
- return this;
- }
-
/**
* Gets the maximum output token override.
*
- * @return an {@link java.util.OptionalInt} containing the max output tokens, or
- * {@link java.util.OptionalInt#empty()} if not set
+ * @return the max output tokens, or {@code null} if not set
*/
- @JsonIgnore
- public OptionalInt getMaxOutputTokens() {
- return maxOutputTokens == null ? OptionalInt.empty() : OptionalInt.of(maxOutputTokens);
+ public Integer getMaxOutputTokens() {
+ return maxOutputTokens;
}
/**
@@ -354,19 +338,8 @@ public OptionalInt getMaxOutputTokens() {
* the max output tokens
* @return this config for method chaining
*/
- public ProviderConfig setMaxOutputTokens(int maxOutputTokens) {
+ public ProviderConfig setMaxOutputTokens(Integer maxOutputTokens) {
this.maxOutputTokens = maxOutputTokens;
return this;
}
-
- /**
- * Clears the maxOutputTokens setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public ProviderConfig clearMaxOutputTokens() {
- this.maxOutputTokens = null;
- return this;
- }
-
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
index d8c3bf43b1..f2caad7710 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
@@ -11,10 +11,8 @@
import java.util.function.Consumer;
import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.copilot.sdk.generated.SessionEvent;
-import java.util.Optional;
/**
* Configuration for resuming an existing Copilot session.
@@ -236,7 +234,7 @@ public ResumeSessionConfig setProvider(ProviderConfig provider) {
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When unset (the default) or
+ * {@code false}, disables session telemetry. When {@code null} (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting. This is independent of
@@ -244,17 +242,15 @@ public ResumeSessionConfig setProvider(ProviderConfig provider) {
* CopilotClientOptions.TelemetryConfig}, which configures OpenTelemetry export
* for observability.
*
- * @return an {@link java.util.Optional} containing whether session telemetry is
- * enabled, or {@link java.util.Optional#empty()} for the default
+ * @return whether session telemetry is enabled
*/
- @JsonIgnore
- public Optional getEnableSessionTelemetry() {
- return Optional.ofNullable(enableSessionTelemetry);
+ public Boolean getEnableSessionTelemetry() {
+ return enableSessionTelemetry;
}
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When unset (the default) or
+ * {@code false}, disables session telemetry. When {@code null} (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting.
@@ -263,21 +259,11 @@ public Optional getEnableSessionTelemetry() {
* whether to enable session telemetry
* @return this config for method chaining
*/
- public ResumeSessionConfig setEnableSessionTelemetry(boolean enableSessionTelemetry) {
+ public ResumeSessionConfig setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
return this;
}
- /**
- * Clears the enableSessionTelemetry setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public ResumeSessionConfig clearEnableSessionTelemetry() {
- this.enableSessionTelemetry = null;
- return this;
- }
-
/**
* Gets the reasoning effort level.
*
@@ -417,9 +403,8 @@ public ResumeSessionConfig setConfigDir(String configDir) {
* @return {@code true} to enable discovery, {@code false} to disable, or
* {@code null} to use the runtime default
*/
- @JsonIgnore
- public Optional getEnableConfigDiscovery() {
- return Optional.ofNullable(enableConfigDiscovery);
+ public Boolean getEnableConfigDiscovery() {
+ return enableConfigDiscovery;
}
/**
@@ -435,30 +420,19 @@ public Optional getEnableConfigDiscovery() {
* {@code null} to use the runtime default
* @return this config for method chaining
*/
- public ResumeSessionConfig setEnableConfigDiscovery(boolean enableConfigDiscovery) {
+ public ResumeSessionConfig setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
return this;
}
- /**
- * Clears the enableConfigDiscovery setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public ResumeSessionConfig clearEnableConfigDiscovery() {
- this.enableConfigDiscovery = null;
- return this;
- }
-
/**
* Gets whether sub-agent streaming events are included.
*
* @return {@code true} to include sub-agent streaming events, {@code false} to
* suppress them, or {@code null} to use the runtime default
*/
- @JsonIgnore
- public Optional getIncludeSubAgentStreamingEvents() {
- return Optional.ofNullable(includeSubAgentStreamingEvents);
+ public Boolean getIncludeSubAgentStreamingEvents() {
+ return includeSubAgentStreamingEvents;
}
/**
@@ -469,22 +443,11 @@ public Optional getIncludeSubAgentStreamingEvents() {
* suppress
* @return this config for method chaining
*/
- public ResumeSessionConfig setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
+ public ResumeSessionConfig setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
return this;
}
- /**
- * Clears the includeSubAgentStreamingEvents setting, reverting to the default
- * behavior.
- *
- * @return this instance for method chaining
- */
- public ResumeSessionConfig clearIncludeSubAgentStreamingEvents() {
- this.includeSubAgentStreamingEvents = null;
- return this;
- }
-
/**
* Gets the model capabilities override.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
index 054fc8fba9..a1af269700 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
@@ -231,68 +231,40 @@ public Boolean getEnableSessionTelemetry() {
/**
* Sets enable session telemetry flag. @param enableSessionTelemetry the flag
*/
- public void setEnableSessionTelemetry(boolean enableSessionTelemetry) {
+ public void setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
}
- /**
- * Clears the enableSessionTelemetry setting, reverting to the default behavior.
- */
- public void clearEnableSessionTelemetry() {
- this.enableSessionTelemetry = null;
- }
-
/** Gets request permission flag. @return the flag */
public Boolean getRequestPermission() {
return requestPermission;
}
/** Sets request permission flag. @param requestPermission the flag */
- public void setRequestPermission(boolean requestPermission) {
+ public void setRequestPermission(Boolean requestPermission) {
this.requestPermission = requestPermission;
}
- /**
- * Clears the requestPermission setting, reverting to the default behavior.
- */
- public void clearRequestPermission() {
- this.requestPermission = null;
- }
-
/** Gets request user input flag. @return the flag */
public Boolean getRequestUserInput() {
return requestUserInput;
}
/** Sets request user input flag. @param requestUserInput the flag */
- public void setRequestUserInput(boolean requestUserInput) {
+ public void setRequestUserInput(Boolean requestUserInput) {
this.requestUserInput = requestUserInput;
}
- /**
- * Clears the requestUserInput setting, reverting to the default behavior.
- */
- public void clearRequestUserInput() {
- this.requestUserInput = null;
- }
-
/** Gets hooks flag. @return the flag */
public Boolean getHooks() {
return hooks;
}
/** Sets hooks flag. @param hooks the flag */
- public void setHooks(boolean hooks) {
+ public void setHooks(Boolean hooks) {
this.hooks = hooks;
}
- /**
- * Clears the hooks setting, reverting to the default behavior.
- */
- public void clearHooks() {
- this.hooks = null;
- }
-
/** Gets working directory. @return the working directory */
public String getWorkingDirectory() {
return workingDirectory;
@@ -319,51 +291,30 @@ public Boolean getEnableConfigDiscovery() {
}
/** Sets enable config discovery flag. @param enableConfigDiscovery the flag */
- public void setEnableConfigDiscovery(boolean enableConfigDiscovery) {
+ public void setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
}
- /**
- * Clears the enableConfigDiscovery setting, reverting to the default behavior.
- */
- public void clearEnableConfigDiscovery() {
- this.enableConfigDiscovery = null;
- }
-
/** Gets disable resume flag. @return the flag */
public Boolean getDisableResume() {
return disableResume;
}
/** Sets disable resume flag. @param disableResume the flag */
- public void setDisableResume(boolean disableResume) {
+ public void setDisableResume(Boolean disableResume) {
this.disableResume = disableResume;
}
- /**
- * Clears the disableResume setting, reverting to the default behavior.
- */
- public void clearDisableResume() {
- this.disableResume = null;
- }
-
/** Gets streaming flag. @return the flag */
public Boolean getStreaming() {
return streaming;
}
/** Sets streaming flag. @param streaming the flag */
- public void setStreaming(boolean streaming) {
+ public void setStreaming(Boolean streaming) {
this.streaming = streaming;
}
- /**
- * Clears the streaming setting, reverting to the default behavior.
- */
- public void clearStreaming() {
- this.streaming = null;
- }
-
/** Gets include sub-agent streaming events flag. @return the flag */
public Boolean getIncludeSubAgentStreamingEvents() {
return includeSubAgentStreamingEvents;
@@ -373,18 +324,10 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* Sets include sub-agent streaming events flag. @param
* includeSubAgentStreamingEvents the flag
*/
- public void setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
+ public void setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
}
- /**
- * Clears the includeSubAgentStreamingEvents setting, reverting to the default
- * behavior.
- */
- public void clearIncludeSubAgentStreamingEvents() {
- this.includeSubAgentStreamingEvents = null;
- }
-
/** Gets MCP servers. @return the servers map */
public Map getMcpServers() {
return mcpServers == null ? null : Collections.unmodifiableMap(mcpServers);
@@ -498,17 +441,10 @@ public Boolean getRequestElicitation() {
}
/** Sets the requestElicitation flag. @param requestElicitation the flag */
- public void setRequestElicitation(boolean requestElicitation) {
+ public void setRequestElicitation(Boolean requestElicitation) {
this.requestElicitation = requestElicitation;
}
- /**
- * Clears the requestElicitation setting, reverting to the default behavior.
- */
- public void clearRequestElicitation() {
- this.requestElicitation = null;
- }
-
/** Gets the requestExitPlanMode flag. @return the flag */
public Boolean getRequestExitPlanMode() {
return requestExitPlanMode;
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
index 53a84aa721..51cad884ed 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
@@ -11,10 +11,8 @@
import java.util.function.Consumer;
import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.copilot.sdk.generated.SessionEvent;
-import java.util.Optional;
/**
* Configuration for creating a new Copilot session.
@@ -290,7 +288,7 @@ public SessionConfig setProvider(ProviderConfig provider) {
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When unset (the default) or
+ * {@code false}, disables session telemetry. When {@code null} (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting. This is independent of
@@ -298,17 +296,15 @@ public SessionConfig setProvider(ProviderConfig provider) {
* CopilotClientOptions.TelemetryConfig}, which configures OpenTelemetry export
* for observability.
*
- * @return an {@link java.util.Optional} containing whether session telemetry is
- * enabled, or {@link java.util.Optional#empty()} for the default
+ * @return whether session telemetry is enabled
*/
- @JsonIgnore
- public Optional getEnableSessionTelemetry() {
- return Optional.ofNullable(enableSessionTelemetry);
+ public Boolean getEnableSessionTelemetry() {
+ return enableSessionTelemetry;
}
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When unset (the default) or
+ * {@code false}, disables session telemetry. When {@code null} (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting.
@@ -317,21 +313,11 @@ public Optional getEnableSessionTelemetry() {
* whether to enable session telemetry
* @return this config instance for method chaining
*/
- public SessionConfig setEnableSessionTelemetry(boolean enableSessionTelemetry) {
+ public SessionConfig setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
return this;
}
- /**
- * Clears the enableSessionTelemetry setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public SessionConfig clearEnableSessionTelemetry() {
- this.enableSessionTelemetry = null;
- return this;
- }
-
/**
* Gets the permission request handler.
*
@@ -672,13 +658,11 @@ public SessionConfig setConfigDir(String configDir) {
/**
* Gets whether automatic configuration discovery is enabled.
*
- * @return an {@link java.util.Optional} containing {@code true} to enable
- * discovery or {@code false} to disable, or
- * {@link java.util.Optional#empty()} to use the runtime default
+ * @return {@code true} to enable discovery, {@code false} to disable, or
+ * {@code null} to use the runtime default
*/
- @JsonIgnore
- public Optional getEnableConfigDiscovery() {
- return Optional.ofNullable(enableConfigDiscovery);
+ public Boolean getEnableConfigDiscovery() {
+ return enableConfigDiscovery;
}
/**
@@ -692,34 +676,23 @@ public Optional getEnableConfigDiscovery() {
* name collision.
*
* @param enableConfigDiscovery
- * {@code true} to enable discovery, {@code false} to disable
+ * {@code true} to enable discovery, {@code false} to disable, or
+ * {@code null} to use the runtime default
* @return this config instance for method chaining
*/
- public SessionConfig setEnableConfigDiscovery(boolean enableConfigDiscovery) {
+ public SessionConfig setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
return this;
}
- /**
- * Clears the enableConfigDiscovery setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public SessionConfig clearEnableConfigDiscovery() {
- this.enableConfigDiscovery = null;
- return this;
- }
-
/**
* Gets whether sub-agent streaming events are included.
*
- * @return an {@link java.util.Optional} containing {@code true} to include
- * sub-agent streaming events or {@code false} to suppress them, or
- * {@link java.util.Optional#empty()} to use the runtime default
+ * @return {@code true} to include sub-agent streaming events, {@code false} to
+ * suppress them, or {@code null} to use the runtime default
*/
- @JsonIgnore
- public Optional getIncludeSubAgentStreamingEvents() {
- return Optional.ofNullable(includeSubAgentStreamingEvents);
+ public Boolean getIncludeSubAgentStreamingEvents() {
+ return includeSubAgentStreamingEvents;
}
/**
@@ -736,22 +709,11 @@ public Optional getIncludeSubAgentStreamingEvents() {
* suppress
* @return this config instance for method chaining
*/
- public SessionConfig setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
+ public SessionConfig setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
return this;
}
- /**
- * Clears the includeSubAgentStreamingEvents setting, reverting to the default
- * behavior.
- *
- * @return this instance for method chaining
- */
- public SessionConfig clearIncludeSubAgentStreamingEvents() {
- this.includeSubAgentStreamingEvents = null;
- return this;
- }
-
/**
* Gets the model capabilities override.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java b/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
index 06ddfc760d..8df70c0502 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
@@ -4,29 +4,26 @@
package com.github.copilot.sdk.json;
-import java.util.Optional;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonInclude;
/**
* UI-specific capability flags for a session.
*
* @since 1.0.0
*/
+@JsonInclude(JsonInclude.Include.NON_NULL)
public class SessionUiCapabilities {
- @JsonProperty("elicitation")
private Boolean elicitation;
/**
* Returns whether the host supports interactive elicitation dialogs.
*
- * @return an {@link Optional} containing the boolean value, or empty if not set
+ * @return {@code true} if elicitation is supported, {@code false} or
+ * {@code null} otherwise
*/
- @JsonIgnore
- public Optional getElicitation() {
- return Optional.ofNullable(elicitation);
+ public Boolean getElicitation() {
+ return elicitation;
}
/**
@@ -36,19 +33,8 @@ public Optional getElicitation() {
* {@code true} if elicitation is supported
* @return this instance for method chaining
*/
- public SessionUiCapabilities setElicitation(boolean elicitation) {
+ public SessionUiCapabilities setElicitation(Boolean elicitation) {
this.elicitation = elicitation;
return this;
}
-
- /**
- * Clears the elicitation setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public SessionUiCapabilities clearElicitation() {
- this.elicitation = null;
- return this;
- }
-
}
diff --git a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
index af00454477..d387128696 100644
--- a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
@@ -4,9 +4,7 @@
package com.github.copilot.sdk.json;
-import java.util.Optional;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
/**
* OpenTelemetry configuration for the Copilot CLI server.
@@ -25,6 +23,7 @@
* @see CopilotClientOptions#setTelemetry(TelemetryConfig)
* @since 1.2.0
*/
+@JsonInclude(JsonInclude.Include.NON_NULL)
public class TelemetryConfig {
private String otlpEndpoint;
@@ -132,13 +131,11 @@ public TelemetryConfig setSourceName(String sourceName) {
* Maps to the {@code OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT}
* environment variable.
*
- * @return an {@link java.util.Optional} containing {@code true} to capture
- * content or {@code false} to suppress it, or
- * {@link java.util.Optional#empty()} to use the default
+ * @return {@code true} to capture content, {@code false} to suppress it, or
+ * {@code null} to use the default
*/
- @JsonIgnore
- public Optional getCaptureContent() {
- return Optional.ofNullable(captureContent);
+ public Boolean getCaptureContent() {
+ return captureContent;
}
/**
@@ -148,19 +145,8 @@ public Optional getCaptureContent() {
* {@code true} to capture content, {@code false} to suppress it
* @return this config for method chaining
*/
- public TelemetryConfig setCaptureContent(boolean captureContent) {
+ public TelemetryConfig setCaptureContent(Boolean captureContent) {
this.captureContent = captureContent;
return this;
}
-
- /**
- * Clears the captureContent setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public TelemetryConfig clearCaptureContent() {
- this.captureContent = null;
- return this;
- }
-
}
diff --git a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
index 6003c86df2..85e0b26bdc 100644
--- a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
@@ -8,9 +8,8 @@
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import java.util.Optional;
/**
* Request for user input from the agent.
@@ -21,6 +20,7 @@
* @since 1.0.6
*/
@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserInputRequest {
@JsonProperty("question")
@@ -77,13 +77,11 @@ public UserInputRequest setChoices(List choices) {
/**
* Returns whether freeform text input is allowed.
*
- * @return an {@link java.util.Optional} containing {@code true} if freeform
- * input is allowed, or {@link java.util.Optional#empty()} if not
+ * @return {@code true} if freeform input is allowed, {@code null} if not
* specified
*/
- @JsonIgnore
- public Optional getAllowFreeform() {
- return Optional.ofNullable(allowFreeform);
+ public Boolean getAllowFreeform() {
+ return allowFreeform;
}
/**
@@ -93,19 +91,8 @@ public Optional getAllowFreeform() {
* {@code true} to allow freeform input
* @return this instance for method chaining
*/
- public UserInputRequest setAllowFreeform(boolean allowFreeform) {
+ public UserInputRequest setAllowFreeform(Boolean allowFreeform) {
this.allowFreeform = allowFreeform;
return this;
}
-
- /**
- * Clears the allowFreeform setting, reverting to the default behavior.
- *
- * @return this instance for method chaining
- */
- public UserInputRequest clearAllowFreeform() {
- this.allowFreeform = null;
- return this;
- }
-
}
diff --git a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
index 09bd3ee385..7abc47e4a4 100644
--- a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
+++ b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
@@ -203,7 +203,7 @@ void sessionConfigEnableSessionTelemetryCopied() {
SessionConfig cloned = original.clone();
- assertFalse(cloned.getEnableSessionTelemetry().orElse(true));
+ assertFalse(cloned.getEnableSessionTelemetry());
}
@Test
@@ -212,7 +212,7 @@ void sessionConfigEnableSessionTelemetryDefaultIsNull() {
SessionConfig cloned = original.clone();
- assertTrue(cloned.getEnableSessionTelemetry().isEmpty());
+ assertNull(cloned.getEnableSessionTelemetry());
}
@Test
@@ -222,7 +222,7 @@ void resumeSessionConfigEnableSessionTelemetryCopied() {
ResumeSessionConfig cloned = original.clone();
- assertFalse(cloned.getEnableSessionTelemetry().orElse(true));
+ assertFalse(cloned.getEnableSessionTelemetry());
}
@Test
@@ -231,7 +231,7 @@ void resumeSessionConfigEnableSessionTelemetryDefaultIsNull() {
ResumeSessionConfig cloned = original.clone();
- assertTrue(cloned.getEnableSessionTelemetry().isEmpty());
+ assertNull(cloned.getEnableSessionTelemetry());
}
@Test
@@ -301,11 +301,11 @@ void copilotClientOptionsSetTelemetry() {
}
@Test
- void copilotClientOptionsClearUseLoggedInUser() {
+ void copilotClientOptionsSetUseLoggedInUserNull() {
var opts = new CopilotClientOptions();
- opts.setUseLoggedInUser(true);
- opts.clearUseLoggedInUser();
- assertTrue(opts.getUseLoggedInUser().isEmpty());
+ opts.setUseLoggedInUser(null);
+ // null → Boolean.FALSE
+ assertEquals(Boolean.FALSE, opts.getUseLoggedInUser());
}
@Test
@@ -375,7 +375,7 @@ void copilotClientOptionsSessionIdleTimeoutCloned() {
CopilotClientOptions cloned = original.clone();
- assertEquals(600, cloned.getSessionIdleTimeoutSeconds().getAsInt());
+ assertEquals(600, cloned.getSessionIdleTimeoutSeconds());
}
@Test
diff --git a/src/test/java/com/github/copilot/sdk/CopilotClientTest.java b/src/test/java/com/github/copilot/sdk/CopilotClientTest.java
index 14ed8ca89e..b0430959b9 100644
--- a/src/test/java/com/github/copilot/sdk/CopilotClientTest.java
+++ b/src/test/java/com/github/copilot/sdk/CopilotClientTest.java
@@ -20,7 +20,6 @@
import java.util.concurrent.ExecutionException;
import static org.junit.jupiter.api.Assertions.*;
-import java.util.Optional;
/**
* Tests for CopilotClient.
@@ -154,14 +153,14 @@ void testGitHubTokenOptionAccepted() {
void testUseLoggedInUserDefaultsToNull() {
var options = new CopilotClientOptions().setCliPath("/path/to/cli");
- assertTrue(options.getUseLoggedInUser().isEmpty());
+ assertNull(options.getUseLoggedInUser());
}
@Test
void testExplicitUseLoggedInUserFalse() {
var options = new CopilotClientOptions().setCliPath("/path/to/cli").setUseLoggedInUser(false);
- assertEquals(Optional.of(false), options.getUseLoggedInUser());
+ assertEquals(false, options.getUseLoggedInUser());
}
@Test
@@ -169,7 +168,7 @@ void testExplicitUseLoggedInUserTrueWithGitHubToken() {
var options = new CopilotClientOptions().setCliPath("/path/to/cli").setGitHubToken("gho_test_token")
.setUseLoggedInUser(true);
- assertEquals(Optional.of(true), options.getUseLoggedInUser());
+ assertEquals(true, options.getUseLoggedInUser());
}
@Test
@@ -190,14 +189,14 @@ void testUseLoggedInUserWithCliUrlThrows() {
void testSessionIdleTimeoutSecondsDefaultsToNull() {
var options = new CopilotClientOptions();
- assertTrue(options.getSessionIdleTimeoutSeconds().isEmpty());
+ assertNull(options.getSessionIdleTimeoutSeconds());
}
@Test
void testSessionIdleTimeoutSecondsOptionAccepted() {
var options = new CopilotClientOptions().setSessionIdleTimeoutSeconds(600);
- assertEquals(600, options.getSessionIdleTimeoutSeconds().getAsInt());
+ assertEquals(600, options.getSessionIdleTimeoutSeconds());
}
@Test
diff --git a/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java b/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
index 2ff3600200..b61c93559b 100644
--- a/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
+++ b/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
@@ -217,16 +217,17 @@ void mcpStdioServerConfigCoversGettersAndFluentSetters() {
@Test
void modelCapabilitiesOverrideCoversNestedSupportsAndLimits() {
- var supports = new ModelCapabilitiesOverride.Supports().setVision(true).setReasoningEffort(false);
+ var supports = new ModelCapabilitiesOverride.Supports().setVision(Boolean.TRUE)
+ .setReasoningEffort(Boolean.FALSE);
var limits = new ModelCapabilitiesOverride.Limits().setMaxPromptTokens(2048).setMaxOutputTokens(512)
.setMaxContextWindowTokens(8192);
var override = new ModelCapabilitiesOverride().setSupports(supports).setLimits(limits);
- assertTrue(override.getSupports().getVision().orElse(false));
- assertFalse(override.getSupports().getReasoningEffort().orElse(true));
- assertEquals(2048, override.getLimits().getMaxPromptTokens().getAsInt());
- assertEquals(512, override.getLimits().getMaxOutputTokens().getAsInt());
- assertEquals(8192, override.getLimits().getMaxContextWindowTokens().getAsInt());
+ assertTrue(override.getSupports().getVision());
+ assertFalse(override.getSupports().getReasoningEffort());
+ assertEquals(2048, override.getLimits().getMaxPromptTokens());
+ assertEquals(512, override.getLimits().getMaxOutputTokens());
+ assertEquals(8192, override.getLimits().getMaxContextWindowTokens());
}
}
diff --git a/src/test/java/com/github/copilot/sdk/ElicitationTest.java b/src/test/java/com/github/copilot/sdk/ElicitationTest.java
index 1f62451276..6b748b4cc2 100644
--- a/src/test/java/com/github/copilot/sdk/ElicitationTest.java
+++ b/src/test/java/com/github/copilot/sdk/ElicitationTest.java
@@ -40,7 +40,7 @@ void sessionCapabilitiesTypesAreProperlyStructured() {
var capabilities = new SessionCapabilities().setUi(new SessionUiCapabilities().setElicitation(true));
assertNotNull(capabilities.getUi());
- assertTrue(capabilities.getUi().getElicitation().get());
+ assertTrue(capabilities.getUi().getElicitation());
// Test with null UI
var emptyCapabilities = new SessionCapabilities();
@@ -119,8 +119,8 @@ void inputOptionsHasAllFields() {
assertEquals("My Title", opts.getTitle());
assertEquals("My Desc", opts.getDescription());
- assertEquals(1, opts.getMinLength().getAsInt());
- assertEquals(100, opts.getMaxLength().getAsInt());
+ assertEquals(1, opts.getMinLength());
+ assertEquals(100, opts.getMaxLength());
assertEquals("email", opts.getFormat());
assertEquals("default@example.com", opts.getDefaultValue());
}
@@ -164,7 +164,7 @@ void buildCreateRequestSetsRequestElicitationWhenHandlerPresent() {
var request = SessionRequestBuilder.buildCreateRequest(config);
- assertEquals(Boolean.TRUE, request.getRequestElicitation());
+ assertTrue(Boolean.TRUE.equals(request.getRequestElicitation()));
}
@Test
@@ -186,6 +186,6 @@ void buildResumeRequestSetsRequestElicitationWhenHandlerPresent() {
var request = SessionRequestBuilder.buildResumeRequest("session-1", config);
- assertEquals(Boolean.TRUE, request.getRequestElicitation());
+ assertTrue(Boolean.TRUE.equals(request.getRequestElicitation()));
}
}
diff --git a/src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java b/src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java
new file mode 100644
index 0000000000..7465507f50
--- /dev/null
+++ b/src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java
@@ -0,0 +1,159 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.junit.jupiter.api.Test;
+
+import com.github.copilot.sdk.json.CopilotClientOptions;
+import com.github.copilot.sdk.json.CustomAgentConfig;
+import com.github.copilot.sdk.json.InfiniteSessionConfig;
+import com.github.copilot.sdk.json.InputOptions;
+import com.github.copilot.sdk.json.ModelCapabilitiesOverride;
+import com.github.copilot.sdk.json.ProviderConfig;
+import com.github.copilot.sdk.json.ResumeSessionConfig;
+import com.github.copilot.sdk.json.SessionConfig;
+import com.github.copilot.sdk.json.SessionUiCapabilities;
+import com.github.copilot.sdk.json.TelemetryConfig;
+import com.github.copilot.sdk.json.UserInputRequest;
+
+/**
+ * Verifies that public DTO classes in the {@code com.github.copilot.sdk.json}
+ * package are annotated with {@code @JsonInclude(JsonInclude.Include.NON_NULL)}
+ * so that null-valued fields are omitted during JSON serialization.
+ */
+class JsonIncludeNonNullTest {
+
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ // --- Annotation presence checks ---
+
+ @Test
+ void copilotClientOptionsHasNonNullAnnotation() {
+ assertHasNonNullInclude(CopilotClientOptions.class);
+ }
+
+ @Test
+ void sessionConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(SessionConfig.class);
+ }
+
+ @Test
+ void resumeSessionConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(ResumeSessionConfig.class);
+ }
+
+ @Test
+ void infiniteSessionConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(InfiniteSessionConfig.class);
+ }
+
+ @Test
+ void inputOptionsHasNonNullAnnotation() {
+ assertHasNonNullInclude(InputOptions.class);
+ }
+
+ @Test
+ void modelCapabilitiesOverrideHasNonNullAnnotation() {
+ assertHasNonNullInclude(ModelCapabilitiesOverride.class);
+ }
+
+ @Test
+ void providerConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(ProviderConfig.class);
+ }
+
+ @Test
+ void telemetryConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(TelemetryConfig.class);
+ }
+
+ @Test
+ void sessionUiCapabilitiesHasNonNullAnnotation() {
+ assertHasNonNullInclude(SessionUiCapabilities.class);
+ }
+
+ @Test
+ void customAgentConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(CustomAgentConfig.class);
+ }
+
+ @Test
+ void userInputRequestHasNonNullAnnotation() {
+ assertHasNonNullInclude(UserInputRequest.class);
+ }
+
+ // --- Serialization tests: null fields are omitted ---
+
+ @Test
+ void inputOptionsOmitsNullFieldsInJson() throws JsonProcessingException {
+ var opts = new InputOptions();
+ String json = MAPPER.writeValueAsString(opts);
+ assertEquals("{}", json, "All-null InputOptions should serialize to empty JSON");
+ }
+
+ @Test
+ void telemetryConfigOmitsNullFieldsInJson() throws JsonProcessingException {
+ var config = new TelemetryConfig();
+ String json = MAPPER.writeValueAsString(config);
+ assertEquals("{}", json, "All-null TelemetryConfig should serialize to empty JSON");
+ }
+
+ @Test
+ void sessionUiCapabilitiesOmitsNullFieldsInJson() throws JsonProcessingException {
+ var caps = new SessionUiCapabilities();
+ String json = MAPPER.writeValueAsString(caps);
+ assertEquals("{}", json, "All-null SessionUiCapabilities should serialize to empty JSON");
+ }
+
+ @Test
+ void userInputRequestOmitsNullFieldsInJson() throws JsonProcessingException {
+ var req = new UserInputRequest();
+ String json = MAPPER.writeValueAsString(req);
+ assertFalse(json.contains("null"), "UserInputRequest with no fields set should not contain 'null' values");
+ }
+
+ @Test
+ void inputOptionsIncludesSetFieldsInJson() throws JsonProcessingException {
+ var opts = new InputOptions();
+ opts.setMinLength(5);
+ opts.setMaxLength(100);
+ String json = MAPPER.writeValueAsString(opts);
+ assertTrue(json.contains("\"minLength\":5"), "Set minLength should appear in JSON");
+ assertTrue(json.contains("\"maxLength\":100"), "Set maxLength should appear in JSON");
+ assertFalse(json.contains("\"title\""), "Unset title should be omitted from JSON");
+ }
+
+ @Test
+ void telemetryConfigIncludesSetFieldsInJson() throws JsonProcessingException {
+ var config = new TelemetryConfig();
+ config.setOtlpEndpoint("http://localhost:4318");
+ String json = MAPPER.writeValueAsString(config);
+ assertTrue(json.contains("\"otlpEndpoint\":\"http://localhost:4318\""),
+ "Set otlpEndpoint should appear in JSON");
+ assertFalse(json.contains("\"filePath\""), "Unset filePath should be omitted from JSON");
+ }
+
+ @Test
+ void sessionUiCapabilitiesIncludesSetFieldsInJson() throws JsonProcessingException {
+ var caps = new SessionUiCapabilities();
+ caps.setElicitation(true);
+ String json = MAPPER.writeValueAsString(caps);
+ assertTrue(json.contains("\"elicitation\":true"), "Set elicitation should appear in JSON");
+ }
+
+ private void assertHasNonNullInclude(Class> clazz) {
+ JsonInclude annotation = clazz.getAnnotation(JsonInclude.class);
+ assertNotNull(annotation, clazz.getSimpleName() + " should be annotated with @JsonInclude");
+ assertEquals(JsonInclude.Include.NON_NULL, annotation.value(),
+ clazz.getSimpleName() + " @JsonInclude should use Include.NON_NULL");
+ }
+
+}
diff --git a/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java b/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
deleted file mode 100644
index 2a9770e2e2..0000000000
--- a/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
+++ /dev/null
@@ -1,635 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- *--------------------------------------------------------------------------------------------*/
-
-package com.github.copilot.sdk;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.copilot.sdk.json.CopilotClientOptions;
-import com.github.copilot.sdk.json.CustomAgentConfig;
-import com.github.copilot.sdk.json.InfiniteSessionConfig;
-import com.github.copilot.sdk.json.InputOptions;
-import com.github.copilot.sdk.json.ModelCapabilitiesOverride;
-import com.github.copilot.sdk.json.ProviderConfig;
-import com.github.copilot.sdk.json.ResumeSessionConfig;
-import com.github.copilot.sdk.json.SessionConfig;
-import com.github.copilot.sdk.json.SessionUiCapabilities;
-import com.github.copilot.sdk.json.TelemetryConfig;
-import com.github.copilot.sdk.json.UserInputRequest;
-import org.junit.jupiter.api.Test;
-
-/**
- * Validates that every {@code clearXxx()} method resets its field to absent,
- * that Optional-returning getters report the correct state, and that Jackson
- * omits cleared fields from serialized output.
- */
-class OptionalApiAndJacksonTest {
-
- private static final ObjectMapper MAPPER = JsonRpcClient.getObjectMapper();
-
- // ── CopilotClientOptions ──────────────────────────────────────────
-
- @Test
- void copilotClientOptions_clearSessionIdleTimeoutSeconds() {
- var opts = new CopilotClientOptions();
- opts.setSessionIdleTimeoutSeconds(120);
- assertFalse(opts.getSessionIdleTimeoutSeconds().isEmpty());
-
- opts.clearSessionIdleTimeoutSeconds();
- assertTrue(opts.getSessionIdleTimeoutSeconds().isEmpty());
- }
-
- @Test
- void copilotClientOptions_clearUseLoggedInUser() {
- var opts = new CopilotClientOptions();
- opts.setUseLoggedInUser(true);
- assertTrue(opts.getUseLoggedInUser().isPresent());
-
- opts.clearUseLoggedInUser();
- assertTrue(opts.getUseLoggedInUser().isEmpty());
- }
-
- // ── SessionConfig ─────────────────────────────────────────────────
-
- @Test
- void sessionConfig_clearEnableSessionTelemetry() {
- var cfg = new SessionConfig();
- cfg.setEnableSessionTelemetry(true);
- assertTrue(cfg.getEnableSessionTelemetry().isPresent());
-
- cfg.clearEnableSessionTelemetry();
- assertTrue(cfg.getEnableSessionTelemetry().isEmpty());
- }
-
- @Test
- void sessionConfig_clearEnableConfigDiscovery() {
- var cfg = new SessionConfig();
- cfg.setEnableConfigDiscovery(false);
- assertTrue(cfg.getEnableConfigDiscovery().isPresent());
-
- cfg.clearEnableConfigDiscovery();
- assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
- }
-
- @Test
- void sessionConfig_clearIncludeSubAgentStreamingEvents() {
- var cfg = new SessionConfig();
- cfg.setIncludeSubAgentStreamingEvents(true);
- assertTrue(cfg.getIncludeSubAgentStreamingEvents().isPresent());
-
- cfg.clearIncludeSubAgentStreamingEvents();
- assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
- }
-
- // ── ResumeSessionConfig ───────────────────────────────────────────
-
- @Test
- void resumeSessionConfig_clearEnableSessionTelemetry() {
- var cfg = new ResumeSessionConfig();
- cfg.setEnableSessionTelemetry(false);
- assertTrue(cfg.getEnableSessionTelemetry().isPresent());
-
- cfg.clearEnableSessionTelemetry();
- assertTrue(cfg.getEnableSessionTelemetry().isEmpty());
- }
-
- @Test
- void resumeSessionConfig_clearEnableConfigDiscovery() {
- var cfg = new ResumeSessionConfig();
- cfg.setEnableConfigDiscovery(true);
- assertTrue(cfg.getEnableConfigDiscovery().isPresent());
-
- cfg.clearEnableConfigDiscovery();
- assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
- }
-
- @Test
- void resumeSessionConfig_clearIncludeSubAgentStreamingEvents() {
- var cfg = new ResumeSessionConfig();
- cfg.setIncludeSubAgentStreamingEvents(false);
- assertTrue(cfg.getIncludeSubAgentStreamingEvents().isPresent());
-
- cfg.clearIncludeSubAgentStreamingEvents();
- assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
- }
-
- // ── InfiniteSessionConfig ─────────────────────────────────────────
-
- @Test
- void infiniteSessionConfig_clearEnabled() {
- var cfg = new InfiniteSessionConfig();
- cfg.setEnabled(true);
- assertTrue(cfg.getEnabled().isPresent());
-
- cfg.clearEnabled();
- assertTrue(cfg.getEnabled().isEmpty());
- }
-
- @Test
- void infiniteSessionConfig_clearBackgroundCompactionThreshold() {
- var cfg = new InfiniteSessionConfig();
- cfg.setBackgroundCompactionThreshold(0.75);
- assertFalse(cfg.getBackgroundCompactionThreshold().isEmpty());
-
- cfg.clearBackgroundCompactionThreshold();
- assertTrue(cfg.getBackgroundCompactionThreshold().isEmpty());
- }
-
- @Test
- void infiniteSessionConfig_clearBufferExhaustionThreshold() {
- var cfg = new InfiniteSessionConfig();
- cfg.setBufferExhaustionThreshold(0.9);
- assertFalse(cfg.getBufferExhaustionThreshold().isEmpty());
-
- cfg.clearBufferExhaustionThreshold();
- assertTrue(cfg.getBufferExhaustionThreshold().isEmpty());
- }
-
- // ── InputOptions ──────────────────────────────────────────────────
-
- @Test
- void inputOptions_clearMinLength() {
- var opts = new InputOptions();
- opts.setMinLength(5);
- assertFalse(opts.getMinLength().isEmpty());
-
- opts.clearMinLength();
- assertTrue(opts.getMinLength().isEmpty());
- }
-
- @Test
- void inputOptions_clearMaxLength() {
- var opts = new InputOptions();
- opts.setMaxLength(100);
- assertFalse(opts.getMaxLength().isEmpty());
-
- opts.clearMaxLength();
- assertTrue(opts.getMaxLength().isEmpty());
- }
-
- // ── ModelCapabilitiesOverride.Supports ─────────────────────────────
-
- @Test
- void supports_clearVision() {
- var s = new ModelCapabilitiesOverride.Supports();
- s.setVision(true);
- assertTrue(s.getVision().isPresent());
-
- s.clearVision();
- assertTrue(s.getVision().isEmpty());
- }
-
- @Test
- void supports_clearReasoningEffort() {
- var s = new ModelCapabilitiesOverride.Supports();
- s.setReasoningEffort(false);
- assertTrue(s.getReasoningEffort().isPresent());
-
- s.clearReasoningEffort();
- assertTrue(s.getReasoningEffort().isEmpty());
- }
-
- // ── ModelCapabilitiesOverride.Limits ───────────────────────────────
-
- @Test
- void limits_clearMaxPromptTokens() {
- var l = new ModelCapabilitiesOverride.Limits();
- l.setMaxPromptTokens(4096);
- assertFalse(l.getMaxPromptTokens().isEmpty());
-
- l.clearMaxPromptTokens();
- assertTrue(l.getMaxPromptTokens().isEmpty());
- }
-
- @Test
- void limits_clearMaxOutputTokens() {
- var l = new ModelCapabilitiesOverride.Limits();
- l.setMaxOutputTokens(1024);
- assertFalse(l.getMaxOutputTokens().isEmpty());
-
- l.clearMaxOutputTokens();
- assertTrue(l.getMaxOutputTokens().isEmpty());
- }
-
- @Test
- void limits_clearMaxContextWindowTokens() {
- var l = new ModelCapabilitiesOverride.Limits();
- l.setMaxContextWindowTokens(16384);
- assertFalse(l.getMaxContextWindowTokens().isEmpty());
-
- l.clearMaxContextWindowTokens();
- assertTrue(l.getMaxContextWindowTokens().isEmpty());
- }
-
- // ── ProviderConfig ────────────────────────────────────────────────
-
- @Test
- void providerConfig_clearMaxPromptTokens() {
- var cfg = new ProviderConfig();
- cfg.setMaxPromptTokens(2048);
- assertFalse(cfg.getMaxPromptTokens().isEmpty());
-
- cfg.clearMaxPromptTokens();
- assertTrue(cfg.getMaxPromptTokens().isEmpty());
- }
-
- @Test
- void providerConfig_clearMaxOutputTokens() {
- var cfg = new ProviderConfig();
- cfg.setMaxOutputTokens(512);
- assertFalse(cfg.getMaxOutputTokens().isEmpty());
-
- cfg.clearMaxOutputTokens();
- assertTrue(cfg.getMaxOutputTokens().isEmpty());
- }
-
- // ── TelemetryConfig ───────────────────────────────────────────────
-
- @Test
- void telemetryConfig_clearCaptureContent() {
- var cfg = new TelemetryConfig();
- cfg.setCaptureContent(true);
- assertTrue(cfg.getCaptureContent().isPresent());
-
- cfg.clearCaptureContent();
- assertTrue(cfg.getCaptureContent().isEmpty());
- }
-
- // ── SessionUiCapabilities ─────────────────────────────────────────
-
- @Test
- void sessionUiCapabilities_clearElicitation() {
- var caps = new SessionUiCapabilities();
- caps.setElicitation(true);
- assertTrue(caps.getElicitation().isPresent());
-
- caps.clearElicitation();
- assertTrue(caps.getElicitation().isEmpty());
- }
-
- // ── CustomAgentConfig ─────────────────────────────────────────────
-
- @Test
- void customAgentConfig_clearInfer() {
- var cfg = new CustomAgentConfig();
- cfg.setInfer(true);
- assertTrue(cfg.getInfer().isPresent());
-
- cfg.clearInfer();
- assertTrue(cfg.getInfer().isEmpty());
- }
-
- // ── UserInputRequest ──────────────────────────────────────────────
-
- @Test
- void userInputRequest_clearAllowFreeform() {
- var req = new UserInputRequest();
- req.setAllowFreeform(false);
- assertTrue(req.getAllowFreeform().isPresent());
-
- req.clearAllowFreeform();
- assertTrue(req.getAllowFreeform().isEmpty());
- }
-
- // ── Value retrieval through Optional getters ────────────────────────
-
- @Test
- void copilotClientOptions_sessionIdleTimeoutSecondsValue() {
- var opts = new CopilotClientOptions();
- assertTrue(opts.getSessionIdleTimeoutSeconds().isEmpty());
-
- opts.setSessionIdleTimeoutSeconds(300);
- assertEquals(300, opts.getSessionIdleTimeoutSeconds().getAsInt());
-
- opts.setSessionIdleTimeoutSeconds(0);
- assertTrue(opts.getSessionIdleTimeoutSeconds().isPresent());
- assertEquals(0, opts.getSessionIdleTimeoutSeconds().getAsInt());
- }
-
- @Test
- void copilotClientOptions_useLoggedInUserValue() {
- var opts = new CopilotClientOptions();
- assertTrue(opts.getUseLoggedInUser().isEmpty());
-
- opts.setUseLoggedInUser(true);
- assertEquals(Boolean.TRUE, opts.getUseLoggedInUser().get());
-
- opts.setUseLoggedInUser(false);
- assertEquals(Boolean.FALSE, opts.getUseLoggedInUser().get());
- }
-
- @Test
- void sessionConfig_enableSessionTelemetryValue() {
- var cfg = new SessionConfig();
- assertFalse(cfg.getEnableSessionTelemetry().orElse(false));
-
- cfg.setEnableSessionTelemetry(true);
- assertTrue(cfg.getEnableSessionTelemetry().orElse(false));
-
- cfg.setEnableSessionTelemetry(false);
- assertFalse(cfg.getEnableSessionTelemetry().orElse(true));
- }
-
- @Test
- void sessionConfig_enableConfigDiscoveryValue() {
- var cfg = new SessionConfig();
- assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
-
- cfg.setEnableConfigDiscovery(true);
- assertTrue(cfg.getEnableConfigDiscovery().get());
-
- cfg.setEnableConfigDiscovery(false);
- assertFalse(cfg.getEnableConfigDiscovery().get());
- }
-
- @Test
- void sessionConfig_includeSubAgentStreamingEventsValue() {
- var cfg = new SessionConfig();
- assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
-
- cfg.setIncludeSubAgentStreamingEvents(true);
- assertTrue(cfg.getIncludeSubAgentStreamingEvents().get());
- }
-
- @Test
- void resumeSessionConfig_enableSessionTelemetryValue() {
- var cfg = new ResumeSessionConfig();
- assertTrue(cfg.getEnableSessionTelemetry().isEmpty());
-
- cfg.setEnableSessionTelemetry(true);
- assertTrue(cfg.getEnableSessionTelemetry().get());
-
- cfg.setEnableSessionTelemetry(false);
- assertFalse(cfg.getEnableSessionTelemetry().get());
- }
-
- @Test
- void resumeSessionConfig_enableConfigDiscoveryValue() {
- var cfg = new ResumeSessionConfig();
- assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
-
- cfg.setEnableConfigDiscovery(true);
- assertTrue(cfg.getEnableConfigDiscovery().get());
- }
-
- @Test
- void resumeSessionConfig_includeSubAgentStreamingEventsValue() {
- var cfg = new ResumeSessionConfig();
- assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
-
- cfg.setIncludeSubAgentStreamingEvents(false);
- assertFalse(cfg.getIncludeSubAgentStreamingEvents().get());
- }
-
- @Test
- void infiniteSessionConfig_thresholdValues() {
- var cfg = new InfiniteSessionConfig();
- assertTrue(cfg.getBackgroundCompactionThreshold().isEmpty());
- assertTrue(cfg.getBufferExhaustionThreshold().isEmpty());
-
- cfg.setBackgroundCompactionThreshold(0.6);
- cfg.setBufferExhaustionThreshold(0.85);
- assertEquals(0.6, cfg.getBackgroundCompactionThreshold().getAsDouble(), 0.001);
- assertEquals(0.85, cfg.getBufferExhaustionThreshold().getAsDouble(), 0.001);
- }
-
- @Test
- void infiniteSessionConfig_enabledValue() {
- var cfg = new InfiniteSessionConfig();
- assertTrue(cfg.getEnabled().isEmpty());
-
- cfg.setEnabled(true);
- assertTrue(cfg.getEnabled().get());
-
- cfg.setEnabled(false);
- assertFalse(cfg.getEnabled().get());
- }
-
- @Test
- void inputOptions_minAndMaxLengthValues() {
- var opts = new InputOptions();
- assertTrue(opts.getMinLength().isEmpty());
- assertTrue(opts.getMaxLength().isEmpty());
-
- opts.setMinLength(1);
- opts.setMaxLength(255);
- assertEquals(1, opts.getMinLength().getAsInt());
- assertEquals(255, opts.getMaxLength().getAsInt());
- }
-
- @Test
- void supports_visionAndReasoningEffortValues() {
- var s = new ModelCapabilitiesOverride.Supports();
- assertTrue(s.getVision().isEmpty());
- assertTrue(s.getReasoningEffort().isEmpty());
-
- s.setVision(true);
- s.setReasoningEffort(false);
- assertTrue(s.getVision().get());
- assertFalse(s.getReasoningEffort().get());
- }
-
- @Test
- void limits_tokenValues() {
- var l = new ModelCapabilitiesOverride.Limits();
- assertTrue(l.getMaxPromptTokens().isEmpty());
- assertTrue(l.getMaxOutputTokens().isEmpty());
- assertTrue(l.getMaxContextWindowTokens().isEmpty());
-
- l.setMaxPromptTokens(4096);
- l.setMaxOutputTokens(1024);
- l.setMaxContextWindowTokens(16384);
- assertEquals(4096, l.getMaxPromptTokens().getAsInt());
- assertEquals(1024, l.getMaxOutputTokens().getAsInt());
- assertEquals(16384, l.getMaxContextWindowTokens().getAsInt());
- }
-
- @Test
- void providerConfig_tokenValues() {
- var cfg = new ProviderConfig();
- assertTrue(cfg.getMaxPromptTokens().isEmpty());
- assertTrue(cfg.getMaxOutputTokens().isEmpty());
-
- cfg.setMaxPromptTokens(8192);
- cfg.setMaxOutputTokens(2048);
- assertEquals(8192, cfg.getMaxPromptTokens().getAsInt());
- assertEquals(2048, cfg.getMaxOutputTokens().getAsInt());
- }
-
- @Test
- void telemetryConfig_captureContentValue() {
- var cfg = new TelemetryConfig();
- assertTrue(cfg.getCaptureContent().isEmpty());
-
- cfg.setCaptureContent(true);
- assertTrue(cfg.getCaptureContent().get());
-
- cfg.setCaptureContent(false);
- assertFalse(cfg.getCaptureContent().get());
- }
-
- @Test
- void sessionUiCapabilities_elicitationValue() {
- var caps = new SessionUiCapabilities();
- assertTrue(caps.getElicitation().isEmpty());
- assertFalse(caps.getElicitation().orElse(false));
-
- caps.setElicitation(true);
- assertTrue(caps.getElicitation().orElse(false));
- }
-
- @Test
- void customAgentConfig_inferValue() {
- var cfg = new CustomAgentConfig();
- assertTrue(cfg.getInfer().isEmpty());
-
- cfg.setInfer(true);
- assertTrue(cfg.getInfer().get());
-
- cfg.setInfer(false);
- assertFalse(cfg.getInfer().get());
- }
-
- @Test
- void userInputRequest_allowFreeformValue() {
- var req = new UserInputRequest();
- assertTrue(req.getAllowFreeform().isEmpty());
-
- req.setAllowFreeform(true);
- assertTrue(req.getAllowFreeform().get());
-
- req.setAllowFreeform(false);
- assertFalse(req.getAllowFreeform().get());
- }
-
- // ── JSON deserialization into Optional-returning classes ───────────
-
- @Test
- void jackson_deserializeSupportsWithFields() throws Exception {
- String json = "{\"vision\":true,\"reasoningEffort\":false}";
- var supports = MAPPER.readValue(json, ModelCapabilitiesOverride.Supports.class);
- assertTrue(supports.getVision().get());
- assertFalse(supports.getReasoningEffort().get());
- }
-
- @Test
- void jackson_deserializeSupportsEmpty() throws Exception {
- String json = "{}";
- var supports = MAPPER.readValue(json, ModelCapabilitiesOverride.Supports.class);
- assertTrue(supports.getVision().isEmpty());
- assertTrue(supports.getReasoningEffort().isEmpty());
- }
-
- @Test
- void jackson_deserializeLimitsWithFields() throws Exception {
- String json = "{\"max_prompt_tokens\":4096,\"max_output_tokens\":1024,\"max_context_window_tokens\":16384}";
- var limits = MAPPER.readValue(json, ModelCapabilitiesOverride.Limits.class);
- assertEquals(4096, limits.getMaxPromptTokens().getAsInt());
- assertEquals(1024, limits.getMaxOutputTokens().getAsInt());
- assertEquals(16384, limits.getMaxContextWindowTokens().getAsInt());
- }
-
- @Test
- void jackson_deserializeLimitsEmpty() throws Exception {
- String json = "{}";
- var limits = MAPPER.readValue(json, ModelCapabilitiesOverride.Limits.class);
- assertTrue(limits.getMaxPromptTokens().isEmpty());
- assertTrue(limits.getMaxOutputTokens().isEmpty());
- assertTrue(limits.getMaxContextWindowTokens().isEmpty());
- }
-
- @Test
- void jackson_deserializeInfiniteSessionConfigWithFields() throws Exception {
- String json = "{\"enabled\":true,\"backgroundCompactionThreshold\":0.7,\"bufferExhaustionThreshold\":0.9}";
- var cfg = MAPPER.readValue(json, InfiniteSessionConfig.class);
- assertTrue(cfg.getEnabled().get());
- assertEquals(0.7, cfg.getBackgroundCompactionThreshold().getAsDouble(), 0.001);
- assertEquals(0.9, cfg.getBufferExhaustionThreshold().getAsDouble(), 0.001);
- }
-
- @Test
- void jackson_deserializeInfiniteSessionConfigEmpty() throws Exception {
- String json = "{}";
- var cfg = MAPPER.readValue(json, InfiniteSessionConfig.class);
- assertTrue(cfg.getEnabled().isEmpty());
- assertTrue(cfg.getBackgroundCompactionThreshold().isEmpty());
- assertTrue(cfg.getBufferExhaustionThreshold().isEmpty());
- }
-
- // ── Jackson serialization roundtrip ───────────────────────────────
- //
- // Classes whose fields carry @JsonProperty (InfiniteSessionConfig,
- // ModelCapabilitiesOverride inner classes) are serialized via field
- // access: Jackson writes the field when set and omits it when cleared.
- //
- // Classes without @JsonProperty on fields (SessionConfig,
- // CopilotClientOptions, TelemetryConfig, ProviderConfig) are not
- // directly serialized — their values are copied to wire DTOs by
- // SessionRequestBuilder. The @JsonIgnore on their Optional-returning
- // getters prevents Jackson from attempting to serialize Optional
- // wrappers if the class is ever processed.
-
- @Test
- void jackson_infiniteSessionConfigClearedFieldsOmitted() throws Exception {
- var cfg = new InfiniteSessionConfig();
- cfg.setEnabled(true);
- cfg.setBackgroundCompactionThreshold(0.75);
- cfg.setBufferExhaustionThreshold(0.9);
-
- String withFields = MAPPER.writeValueAsString(cfg);
- assertTrue(withFields.contains("enabled"));
- assertTrue(withFields.contains("backgroundCompactionThreshold"));
- assertTrue(withFields.contains("bufferExhaustionThreshold"));
-
- cfg.clearEnabled();
- cfg.clearBackgroundCompactionThreshold();
- cfg.clearBufferExhaustionThreshold();
-
- String cleared = MAPPER.writeValueAsString(cfg);
- assertFalse(cleared.contains("enabled"));
- assertFalse(cleared.contains("backgroundCompactionThreshold"));
- assertFalse(cleared.contains("bufferExhaustionThreshold"));
- }
-
- @Test
- void jackson_modelCapabilitiesOverrideSupportsClearedFieldsOmitted() throws Exception {
- var supports = new ModelCapabilitiesOverride.Supports();
- supports.setVision(true);
- supports.setReasoningEffort(false);
-
- String withFields = MAPPER.writeValueAsString(supports);
- assertTrue(withFields.contains("vision"));
- assertTrue(withFields.contains("reasoningEffort"));
-
- supports.clearVision();
- supports.clearReasoningEffort();
-
- String cleared = MAPPER.writeValueAsString(supports);
- assertFalse(cleared.contains("vision"));
- assertFalse(cleared.contains("reasoningEffort"));
- }
-
- @Test
- void jackson_modelCapabilitiesOverrideLimitsClearedFieldsOmitted() throws Exception {
- var limits = new ModelCapabilitiesOverride.Limits();
- limits.setMaxPromptTokens(2048);
- limits.setMaxOutputTokens(512);
- limits.setMaxContextWindowTokens(16384);
-
- String withFields = MAPPER.writeValueAsString(limits);
- assertTrue(withFields.contains("max_prompt_tokens"));
- assertTrue(withFields.contains("max_output_tokens"));
- assertTrue(withFields.contains("max_context_window_tokens"));
-
- limits.clearMaxPromptTokens();
- limits.clearMaxOutputTokens();
- limits.clearMaxContextWindowTokens();
-
- String cleared = MAPPER.writeValueAsString(limits);
- assertFalse(cleared.contains("max_prompt_tokens"));
- assertFalse(cleared.contains("max_output_tokens"));
- assertFalse(cleared.contains("max_context_window_tokens"));
- }
-}
diff --git a/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java b/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java
index 6bbb3ae284..e7602619ca 100644
--- a/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java
+++ b/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java
@@ -410,8 +410,8 @@ void testProviderModelIdAndWireModelSerialization() throws Exception {
ProviderConfig deserialized = MAPPER.readValue(MAPPER.writeValueAsString(provider), ProviderConfig.class);
assertEquals("gpt-4o", deserialized.getModelId());
assertEquals("my-finetune-v3", deserialized.getWireModel());
- assertEquals(100_000, deserialized.getMaxPromptTokens().getAsInt());
- assertEquals(4096, deserialized.getMaxOutputTokens().getAsInt());
+ assertEquals(100_000, deserialized.getMaxPromptTokens());
+ assertEquals(4096, deserialized.getMaxOutputTokens());
}
@Test
@@ -419,8 +419,8 @@ void testProviderModelFieldsDefaultToNull() {
var provider = new ProviderConfig();
assertNull(provider.getModelId());
assertNull(provider.getWireModel());
- assertTrue(provider.getMaxPromptTokens().isEmpty());
- assertTrue(provider.getMaxOutputTokens().isEmpty());
+ assertNull(provider.getMaxPromptTokens());
+ assertNull(provider.getMaxOutputTokens());
}
@Test
diff --git a/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java b/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java
index 278777ce13..99b360d2db 100644
--- a/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java
+++ b/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java
@@ -22,7 +22,7 @@ void defaultValuesAreNull() {
assertNull(config.getFilePath());
assertNull(config.getExporterType());
assertNull(config.getSourceName());
- assertTrue(config.getCaptureContent().isEmpty());
+ assertNull(config.getCaptureContent());
}
@Test
@@ -57,10 +57,10 @@ void sourceNameGetterSetter() {
void captureContentGetterSetter() {
var config = new TelemetryConfig();
config.setCaptureContent(true);
- assertTrue(config.getCaptureContent().get());
+ assertTrue(config.getCaptureContent());
config.setCaptureContent(false);
- assertFalse(config.getCaptureContent().get());
+ assertFalse(config.getCaptureContent());
}
@Test
@@ -72,6 +72,6 @@ void fluentChainingReturnsThis() {
assertEquals("/tmp/spans.json", config.getFilePath());
assertEquals("file", config.getExporterType());
assertEquals("sdk-test", config.getSourceName());
- assertTrue(config.getCaptureContent().get());
+ assertTrue(config.getCaptureContent());
}
}
From 6437ddffff975870fa8f916c95a3d78ab991e1a5 Mon Sep 17 00:00:00 2001
From: Bruno Borges
Date: Thu, 14 May 2026 16:04:20 -0400
Subject: [PATCH 033/135] Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
---
.github/workflows/publish-maven.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/publish-maven.yml b/.github/workflows/publish-maven.yml
index f14987176a..cc612389b7 100644
--- a/.github/workflows/publish-maven.yml
+++ b/.github/workflows/publish-maven.yml
@@ -88,7 +88,7 @@ jobs:
# Split version: supports "0.1.32", "0.1.32-java.0", and "0.1.32-java-preview.0" formats
# Validate RELEASE_VERSION format explicitly to provide clear errors
if ! echo "$RELEASE_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-(beta-)?java(-preview)?\.[0-9]+)?$'; then
- echo "Error: RELEASE_VERSION '$RELEASE_VERSION' is invalid. Expected format: M.M.P, M.M.P-java.N, M.M.P-java-preview.N, or M.M.P-beta-java.N (e.g., 1.2.3, 1.2.3-java.0, 1.2.3-java-preview.0, or 1.2.3-beta-java.0)." >&2
+ echo "Error: RELEASE_VERSION '$RELEASE_VERSION' is invalid. Expected format: M.M.P, M.M.P-java.N, M.M.P-java-preview.N, M.M.P-beta-java.N, or M.M.P-beta-java-preview.N (e.g., 1.2.3, 1.2.3-java.0, 1.2.3-java-preview.0, 1.2.3-beta-java.0, or 1.2.3-beta-java-preview.0)." >&2
exit 1
fi
# Extract the base M.M.P portion (before any qualifier)
From a04ea0bedb308da7cef3f3a07783d98993ccb460 Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Thu, 14 May 2026 15:00:43 -0700
Subject: [PATCH 034/135] Revert "refactor: revert Optional usage, use plain
nullable fields with @JsonInclude(NON_NULL)"
This reverts commit 8e0eeeb9832f2f113b8a4ec5c4accc05ca1f6e6a.
---
.../github/copilot/sdk/CliServerManager.java | 14 +-
.../com/github/copilot/sdk/CopilotClient.java | 2 +-
.../github/copilot/sdk/CopilotSession.java | 15 +-
.../copilot/sdk/SessionRequestBuilder.java | 40 +-
.../sdk/json/CopilotClientOptions.java | 58 +-
.../sdk/json/CreateSessionRequest.java | 73 +-
.../copilot/sdk/json/CustomAgentConfig.java | 22 +-
.../sdk/json/InfiniteSessionConfig.java | 70 +-
.../github/copilot/sdk/json/InputOptions.java | 52 +-
.../sdk/json/ModelCapabilitiesOverride.java | 112 ++-
.../copilot/sdk/json/ProviderConfig.java | 43 +-
.../copilot/sdk/json/ResumeSessionConfig.java | 61 +-
.../sdk/json/ResumeSessionRequest.java | 82 ++-
.../copilot/sdk/json/SessionConfig.java | 74 +-
.../sdk/json/SessionUiCapabilities.java | 28 +-
.../copilot/sdk/json/TelemetryConfig.java | 28 +-
.../copilot/sdk/json/UserInputRequest.java | 25 +-
.../github/copilot/sdk/ConfigCloneTest.java | 18 +-
.../github/copilot/sdk/CopilotClientTest.java | 11 +-
.../copilot/sdk/DataObjectCoverageTest.java | 13 +-
.../github/copilot/sdk/ElicitationTest.java | 10 +-
.../copilot/sdk/JsonIncludeNonNullTest.java | 159 -----
.../sdk/OptionalApiAndJacksonTest.java | 635 ++++++++++++++++++
.../copilot/sdk/ProviderConfigTest.java | 8 +-
.../copilot/sdk/TelemetryConfigTest.java | 8 +-
25 files changed, 1297 insertions(+), 364 deletions(-)
delete mode 100644 src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java
create mode 100644 src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
diff --git a/src/main/java/com/github/copilot/sdk/CliServerManager.java b/src/main/java/com/github/copilot/sdk/CliServerManager.java
index 3087966d39..bd4effe5a8 100644
--- a/src/main/java/com/github/copilot/sdk/CliServerManager.java
+++ b/src/main/java/com/github/copilot/sdk/CliServerManager.java
@@ -90,16 +90,16 @@ ProcessInfo startCliServer() throws IOException, InterruptedException {
}
// Default UseLoggedInUser to false when GitHubToken is provided
- boolean useLoggedInUser = options.getUseLoggedInUser() != null
- ? options.getUseLoggedInUser()
- : (options.getGitHubToken() == null || options.getGitHubToken().isEmpty());
+ boolean useLoggedInUser = options.getUseLoggedInUser()
+ .orElse(options.getGitHubToken() == null || options.getGitHubToken().isEmpty());
if (!useLoggedInUser) {
args.add("--no-auto-login");
}
- if (options.getSessionIdleTimeoutSeconds() != null && options.getSessionIdleTimeoutSeconds() > 0) {
+ if (options.getSessionIdleTimeoutSeconds().isPresent()
+ && options.getSessionIdleTimeoutSeconds().getAsInt() > 0) {
args.add("--session-idle-timeout");
- args.add(String.valueOf(options.getSessionIdleTimeoutSeconds()));
+ args.add(String.valueOf(options.getSessionIdleTimeoutSeconds().getAsInt()));
}
if (options.isRemote()) {
@@ -159,9 +159,9 @@ ProcessInfo startCliServer() throws IOException, InterruptedException {
if (telemetry.getSourceName() != null) {
pb.environment().put("COPILOT_OTEL_SOURCE_NAME", telemetry.getSourceName());
}
- if (telemetry.getCaptureContent() != null) {
+ if (telemetry.getCaptureContent().isPresent()) {
pb.environment().put("OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT",
- telemetry.getCaptureContent() ? "true" : "false");
+ telemetry.getCaptureContent().get() ? "true" : "false");
}
}
diff --git a/src/main/java/com/github/copilot/sdk/CopilotClient.java b/src/main/java/com/github/copilot/sdk/CopilotClient.java
index 5b988d9d2b..4d0770319a 100644
--- a/src/main/java/com/github/copilot/sdk/CopilotClient.java
+++ b/src/main/java/com/github/copilot/sdk/CopilotClient.java
@@ -120,7 +120,7 @@ public CopilotClient(CopilotClientOptions options) {
// Validate auth options with external server
if (this.options.getCliUrl() != null && !this.options.getCliUrl().isEmpty()
- && (this.options.getGitHubToken() != null || this.options.getUseLoggedInUser() != null)) {
+ && (this.options.getGitHubToken() != null || this.options.getUseLoggedInUser().isPresent())) {
throw new IllegalArgumentException(
"GitHubToken and UseLoggedInUser cannot be used with CliUrl (external server manages its own auth)");
}
diff --git a/src/main/java/com/github/copilot/sdk/CopilotSession.java b/src/main/java/com/github/copilot/sdk/CopilotSession.java
index ad5561c09e..79a7f343b7 100644
--- a/src/main/java/com/github/copilot/sdk/CopilotSession.java
+++ b/src/main/java/com/github/copilot/sdk/CopilotSession.java
@@ -1118,9 +1118,9 @@ private void handleElicitationRequestAsync(ElicitationContext context, String re
*/
private void assertElicitation() {
SessionCapabilities caps = capabilities;
- if (caps == null || caps.getUi() == null || !Boolean.TRUE.equals(caps.getUi().getElicitation())) {
+ if (caps == null || caps.getUi() == null || !caps.getUi().getElicitation().orElse(false)) {
throw new IllegalStateException("Elicitation is not supported by the host. "
- + "Check session.getCapabilities().getUi()?.getElicitation() before calling UI methods.");
+ + "Check session.getCapabilities().getUi().getElicitation().orElse(false) before calling UI methods.");
}
}
@@ -1201,10 +1201,10 @@ public CompletableFuture input(String message, InputOptions options) {
field.put("title", options.getTitle());
if (options.getDescription() != null)
field.put("description", options.getDescription());
- if (options.getMinLength() != null)
- field.put("minLength", options.getMinLength());
- if (options.getMaxLength() != null)
- field.put("maxLength", options.getMaxLength());
+ if (options.getMinLength().isPresent())
+ field.put("minLength", options.getMinLength().getAsInt());
+ if (options.getMaxLength().isPresent())
+ field.put("maxLength", options.getMaxLength().getAsInt());
if (options.getFormat() != null)
field.put("format", options.getFormat());
if (options.getDefaultValue() != null)
@@ -1695,7 +1695,8 @@ public CompletableFuture setModel(String model, String reasoningEffort,
ModelCapabilitiesOverrideSupports supports = null;
if (modelCapabilities.getSupports() != null) {
var s = modelCapabilities.getSupports();
- supports = new ModelCapabilitiesOverrideSupports(s.getVision(), s.getReasoningEffort());
+ supports = new ModelCapabilitiesOverrideSupports(s.getVision().orElse(null),
+ s.getReasoningEffort().orElse(null));
}
ModelCapabilitiesOverrideLimits limits = null;
if (modelCapabilities.getLimits() != null) {
diff --git a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
index d9752db7ee..1bd3a50cb7 100644
--- a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
+++ b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
@@ -111,12 +111,18 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
request.setAvailableTools(config.getAvailableTools());
request.setExcludedTools(config.getExcludedTools());
request.setProvider(config.getProvider());
- request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());
- request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);
- request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);
+ config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
+ if (config.getOnUserInputRequest() != null) {
+ request.setRequestUserInput(true);
+ }
+ if (config.getHooks() != null && config.getHooks().hasHooks()) {
+ request.setHooks(true);
+ }
request.setWorkingDirectory(config.getWorkingDirectory());
- request.setStreaming(config.isStreaming() ? true : null);
- request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());
+ if (config.isStreaming()) {
+ request.setStreaming(true);
+ }
+ config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);
request.setMcpServers(config.getMcpServers());
request.setCustomAgents(config.getCustomAgents());
request.setDefaultAgent(config.getDefaultAgent());
@@ -126,7 +132,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
request.setInstructionDirectories(config.getInstructionDirectories());
request.setDisabledSkills(config.getDisabledSkills());
request.setConfigDir(config.getConfigDir());
- request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());
+ config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);
request.setModelCapabilities(config.getModelCapabilities());
if (config.getCommands() != null && !config.getCommands().isEmpty()) {
@@ -194,15 +200,23 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo
request.setAvailableTools(config.getAvailableTools());
request.setExcludedTools(config.getExcludedTools());
request.setProvider(config.getProvider());
- request.setEnableSessionTelemetry(config.getEnableSessionTelemetry());
- request.setRequestUserInput(config.getOnUserInputRequest() != null ? true : null);
- request.setHooks(config.getHooks() != null && config.getHooks().hasHooks() ? true : null);
+ config.getEnableSessionTelemetry().ifPresent(request::setEnableSessionTelemetry);
+ if (config.getOnUserInputRequest() != null) {
+ request.setRequestUserInput(true);
+ }
+ if (config.getHooks() != null && config.getHooks().hasHooks()) {
+ request.setHooks(true);
+ }
request.setWorkingDirectory(config.getWorkingDirectory());
request.setConfigDir(config.getConfigDir());
- request.setEnableConfigDiscovery(config.getEnableConfigDiscovery());
- request.setDisableResume(config.isDisableResume() ? true : null);
- request.setStreaming(config.isStreaming() ? true : null);
- request.setIncludeSubAgentStreamingEvents(config.getIncludeSubAgentStreamingEvents());
+ config.getEnableConfigDiscovery().ifPresent(request::setEnableConfigDiscovery);
+ if (config.isDisableResume()) {
+ request.setDisableResume(true);
+ }
+ if (config.isStreaming()) {
+ request.setStreaming(true);
+ }
+ config.getIncludeSubAgentStreamingEvents().ifPresent(request::setIncludeSubAgentStreamingEvents);
request.setMcpServers(config.getMcpServers());
request.setCustomAgents(config.getCustomAgents());
request.setDefaultAgent(config.getDefaultAgent());
diff --git a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
index 5517df631e..e4605ffe10 100644
--- a/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
@@ -14,6 +14,9 @@
import java.util.function.Supplier;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
+import java.util.OptionalInt;
/**
* Configuration options for creating a
@@ -499,34 +502,47 @@ public CopilotClientOptions setTelemetry(TelemetryConfig telemetry) {
/**
* Gets the server-wide idle timeout for sessions in seconds.
*
- * @return the session idle timeout in seconds, or {@code null} to disable
- * (sessions live indefinitely)
+ * @return an {@link OptionalInt} containing the session idle timeout in
+ * seconds, or {@link java.util.OptionalInt#empty()} if not set. Use
+ * {@link #clearSessionIdleTimeoutSeconds()} to revert to the default.
* @since 1.3.0
*/
- public Integer getSessionIdleTimeoutSeconds() {
- return sessionIdleTimeoutSeconds;
+ @JsonIgnore
+ public OptionalInt getSessionIdleTimeoutSeconds() {
+ return sessionIdleTimeoutSeconds == null ? OptionalInt.empty() : OptionalInt.of(sessionIdleTimeoutSeconds);
}
/**
* Sets the server-wide idle timeout for sessions in seconds.
*
* Sessions without activity for this duration are automatically cleaned up. Set
- * to {@code 0} or leave as {@code null} to disable (sessions live
- * indefinitely).
+ * to {@code 0} to disable (sessions live indefinitely). Use
+ * {@link #clearSessionIdleTimeoutSeconds()} to revert to the default.
*
* This option is only used when the SDK spawns the CLI process; it is ignored
* when connecting to an external server via {@link #setCliUrl(String)}.
*
* @param sessionIdleTimeoutSeconds
- * the idle timeout in seconds, or {@code null} to disable
+ * the idle timeout in seconds
* @return this options instance for method chaining
* @since 1.3.0
*/
- public CopilotClientOptions setSessionIdleTimeoutSeconds(Integer sessionIdleTimeoutSeconds) {
+ public CopilotClientOptions setSessionIdleTimeoutSeconds(int sessionIdleTimeoutSeconds) {
this.sessionIdleTimeoutSeconds = sessionIdleTimeoutSeconds;
return this;
}
+ /**
+ * Clears the sessionIdleTimeoutSeconds setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public CopilotClientOptions clearSessionIdleTimeoutSeconds() {
+ this.sessionIdleTimeoutSeconds = null;
+ return this;
+ }
+
/**
* Gets the connection token for the headless CLI server (TCP only).
*
@@ -555,11 +571,11 @@ public CopilotClientOptions setTcpConnectionToken(String tcpConnectionToken) {
/**
* Returns whether to use the logged-in user for authentication.
*
- * @return {@code true} to use logged-in user auth, {@code false} to use only
- * explicit tokens, or {@code null} to use default behavior
+ * @return an {@link Optional} containing the boolean value, or empty if not set
*/
- public Boolean getUseLoggedInUser() {
- return useLoggedInUser;
+ @JsonIgnore
+ public Optional getUseLoggedInUser() {
+ return Optional.ofNullable(useLoggedInUser);
}
/**
@@ -569,15 +585,23 @@ public Boolean getUseLoggedInUser() {
* auth. When false, only explicit tokens (gitHubToken or environment variables)
* are used. Default: true (but defaults to false when gitHubToken is provided).
*
- * Passing {@code null} is equivalent to passing {@link Boolean#FALSE}.
*
* @param useLoggedInUser
- * {@code true} to use logged-in user auth, {@code false} or
- * {@code null} otherwise
+ * {@code true} to use logged-in user auth, {@code false} otherwise
* @return this options instance for method chaining
*/
- public CopilotClientOptions setUseLoggedInUser(Boolean useLoggedInUser) {
- this.useLoggedInUser = useLoggedInUser != null ? useLoggedInUser : Boolean.FALSE;
+ public CopilotClientOptions setUseLoggedInUser(boolean useLoggedInUser) {
+ this.useLoggedInUser = useLoggedInUser;
+ return this;
+ }
+
+ /**
+ * Clears the useLoggedInUser setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public CopilotClientOptions clearUseLoggedInUser() {
+ this.useLoggedInUser = null;
return this;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
index 12bab4154c..0160724bef 100644
--- a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
@@ -224,40 +224,68 @@ public Boolean getEnableSessionTelemetry() {
/**
* Sets enable session telemetry flag. @param enableSessionTelemetry the flag
*/
- public void setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
+ public void setEnableSessionTelemetry(boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
}
+ /**
+ * Clears the enableSessionTelemetry setting, reverting to the default behavior.
+ */
+ public void clearEnableSessionTelemetry() {
+ this.enableSessionTelemetry = null;
+ }
+
/** Gets request permission flag. @return the flag */
public Boolean getRequestPermission() {
return requestPermission;
}
/** Sets request permission flag. @param requestPermission the flag */
- public void setRequestPermission(Boolean requestPermission) {
+ public void setRequestPermission(boolean requestPermission) {
this.requestPermission = requestPermission;
}
+ /**
+ * Clears the requestPermission setting, reverting to the default behavior.
+ */
+ public void clearRequestPermission() {
+ this.requestPermission = null;
+ }
+
/** Gets request user input flag. @return the flag */
public Boolean getRequestUserInput() {
return requestUserInput;
}
/** Sets request user input flag. @param requestUserInput the flag */
- public void setRequestUserInput(Boolean requestUserInput) {
+ public void setRequestUserInput(boolean requestUserInput) {
this.requestUserInput = requestUserInput;
}
+ /**
+ * Clears the requestUserInput setting, reverting to the default behavior.
+ */
+ public void clearRequestUserInput() {
+ this.requestUserInput = null;
+ }
+
/** Gets hooks flag. @return the flag */
public Boolean getHooks() {
return hooks;
}
/** Sets hooks flag. @param hooks the flag */
- public void setHooks(Boolean hooks) {
+ public void setHooks(boolean hooks) {
this.hooks = hooks;
}
+ /**
+ * Clears the hooks setting, reverting to the default behavior.
+ */
+ public void clearHooks() {
+ this.hooks = null;
+ }
+
/** Gets working directory. @return the working directory */
public String getWorkingDirectory() {
return workingDirectory;
@@ -274,10 +302,17 @@ public Boolean getStreaming() {
}
/** Sets streaming flag. @param streaming the flag */
- public void setStreaming(Boolean streaming) {
+ public void setStreaming(boolean streaming) {
this.streaming = streaming;
}
+ /**
+ * Clears the streaming setting, reverting to the default behavior.
+ */
+ public void clearStreaming() {
+ this.streaming = null;
+ }
+
/** Gets MCP servers. @return the servers map */
public Map getMcpServers() {
return mcpServers == null ? null : Collections.unmodifiableMap(mcpServers);
@@ -388,10 +423,17 @@ public Boolean getEnableConfigDiscovery() {
}
/** Sets enable config discovery flag. @param enableConfigDiscovery the flag */
- public void setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
+ public void setEnableConfigDiscovery(boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
}
+ /**
+ * Clears the enableConfigDiscovery setting, reverting to the default behavior.
+ */
+ public void clearEnableConfigDiscovery() {
+ this.enableConfigDiscovery = null;
+ }
+
/** Gets include sub-agent streaming events flag. @return the flag */
public Boolean getIncludeSubAgentStreamingEvents() {
return includeSubAgentStreamingEvents;
@@ -401,10 +443,18 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* Sets include sub-agent streaming events flag. @param
* includeSubAgentStreamingEvents the flag
*/
- public void setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
+ public void setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
}
+ /**
+ * Clears the includeSubAgentStreamingEvents setting, reverting to the default
+ * behavior.
+ */
+ public void clearIncludeSubAgentStreamingEvents() {
+ this.includeSubAgentStreamingEvents = null;
+ }
+
/** Gets the commands wire definitions. @return the commands */
public List getCommands() {
return commands == null ? null : Collections.unmodifiableList(commands);
@@ -421,10 +471,17 @@ public Boolean getRequestElicitation() {
}
/** Sets the requestElicitation flag. @param requestElicitation the flag */
- public void setRequestElicitation(Boolean requestElicitation) {
+ public void setRequestElicitation(boolean requestElicitation) {
this.requestElicitation = requestElicitation;
}
+ /**
+ * Clears the requestElicitation setting, reverting to the default behavior.
+ */
+ public void clearRequestElicitation() {
+ this.requestElicitation = null;
+ }
+
/** Gets the requestExitPlanMode flag. @return the flag */
public Boolean getRequestExitPlanMode() {
return requestExitPlanMode;
diff --git a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
index 1421db603f..bb9520055e 100644
--- a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
@@ -10,6 +10,8 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
/**
* Configuration for a custom agent in a Copilot session.
@@ -197,10 +199,12 @@ public CustomAgentConfig setMcpServers(Map mcpServers)
/**
* Gets whether inference mode is enabled.
*
- * @return the infer flag, or {@code null} if not set
+ * @return an {@link java.util.Optional} containing the infer flag, or
+ * {@link java.util.Optional#empty()} if not set
*/
- public Boolean getInfer() {
- return infer;
+ @JsonIgnore
+ public Optional getInfer() {
+ return Optional.ofNullable(infer);
}
/**
@@ -210,11 +214,21 @@ public Boolean getInfer() {
* {@code true} to enable inference mode
* @return this config for method chaining
*/
- public CustomAgentConfig setInfer(Boolean infer) {
+ public CustomAgentConfig setInfer(boolean infer) {
this.infer = infer;
return this;
}
+ /**
+ * Clears the infer setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public CustomAgentConfig clearInfer() {
+ this.infer = null;
+ return this;
+ }
+
/**
* Gets the list of skill names to preload into this agent's context.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java
index d45851f8a1..561796ede7 100644
--- a/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java
@@ -6,6 +6,9 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
+import java.util.OptionalDouble;
/**
* Configuration for infinite sessions with automatic context compaction and
@@ -43,10 +46,12 @@ public class InfiniteSessionConfig {
/**
* Gets whether infinite sessions are enabled.
*
- * @return {@code true} if enabled, {@code null} to use default (true)
+ * @return an {@link Optional} containing the boolean value, or empty to use
+ * default (true)
*/
- public Boolean getEnabled() {
- return enabled;
+ @JsonIgnore
+ public Optional getEnabled() {
+ return Optional.ofNullable(enabled);
}
/**
@@ -58,18 +63,32 @@ public Boolean getEnabled() {
* {@code true} to enable infinite sessions
* @return this config instance for method chaining
*/
- public InfiniteSessionConfig setEnabled(Boolean enabled) {
+ public InfiniteSessionConfig setEnabled(boolean enabled) {
this.enabled = enabled;
return this;
}
+ /**
+ * Clears the enabled setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InfiniteSessionConfig clearEnabled() {
+ this.enabled = null;
+ return this;
+ }
+
/**
* Gets the background compaction threshold.
*
- * @return the threshold (0.0-1.0), or {@code null} to use default
+ * @return an {@link OptionalDouble} containing the threshold (0.0-1.0), or
+ * empty to use default
*/
- public Double getBackgroundCompactionThreshold() {
- return backgroundCompactionThreshold;
+ @JsonIgnore
+ public OptionalDouble getBackgroundCompactionThreshold() {
+ return backgroundCompactionThreshold == null
+ ? OptionalDouble.empty()
+ : OptionalDouble.of(backgroundCompactionThreshold);
}
/**
@@ -82,18 +101,33 @@ public Double getBackgroundCompactionThreshold() {
* the threshold (0.0-1.0)
* @return this config instance for method chaining
*/
- public InfiniteSessionConfig setBackgroundCompactionThreshold(Double backgroundCompactionThreshold) {
+ public InfiniteSessionConfig setBackgroundCompactionThreshold(double backgroundCompactionThreshold) {
this.backgroundCompactionThreshold = backgroundCompactionThreshold;
return this;
}
+ /**
+ * Clears the backgroundCompactionThreshold setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InfiniteSessionConfig clearBackgroundCompactionThreshold() {
+ this.backgroundCompactionThreshold = null;
+ return this;
+ }
+
/**
* Gets the buffer exhaustion threshold.
*
- * @return the threshold (0.0-1.0), or {@code null} to use default
+ * @return an {@link OptionalDouble} containing the threshold (0.0-1.0), or
+ * empty to use default
*/
- public Double getBufferExhaustionThreshold() {
- return bufferExhaustionThreshold;
+ @JsonIgnore
+ public OptionalDouble getBufferExhaustionThreshold() {
+ return bufferExhaustionThreshold == null
+ ? OptionalDouble.empty()
+ : OptionalDouble.of(bufferExhaustionThreshold);
}
/**
@@ -107,8 +141,20 @@ public Double getBufferExhaustionThreshold() {
* the threshold (0.0-1.0)
* @return this config instance for method chaining
*/
- public InfiniteSessionConfig setBufferExhaustionThreshold(Double bufferExhaustionThreshold) {
+ public InfiniteSessionConfig setBufferExhaustionThreshold(double bufferExhaustionThreshold) {
this.bufferExhaustionThreshold = bufferExhaustionThreshold;
return this;
}
+
+ /**
+ * Clears the bufferExhaustionThreshold setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InfiniteSessionConfig clearBufferExhaustionThreshold() {
+ this.bufferExhaustionThreshold = null;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/github/copilot/sdk/json/InputOptions.java b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
index 43b29c53b9..4f209bf6fa 100644
--- a/src/main/java/com/github/copilot/sdk/json/InputOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
@@ -4,7 +4,8 @@
package com.github.copilot.sdk.json;
-import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.OptionalInt;
/**
* Options for the {@link SessionUiApi#input(String, InputOptions)} convenience
@@ -12,7 +13,6 @@
*
* @since 1.0.0
*/
-@JsonInclude(JsonInclude.Include.NON_NULL)
public class InputOptions {
private String title;
@@ -49,34 +49,66 @@ public InputOptions setDescription(String description) {
return this;
}
- /** Gets the minimum character length. @return the min length */
- public Integer getMinLength() {
- return minLength;
+ /**
+ * Gets the minimum character length.
+ *
+ * @return an {@link java.util.OptionalInt} containing the min length, or
+ * {@link java.util.OptionalInt#empty()} if not set
+ */
+ @JsonIgnore
+ public OptionalInt getMinLength() {
+ return minLength == null ? OptionalInt.empty() : OptionalInt.of(minLength);
}
/**
* Sets the minimum character length. @param minLength the min length @return
* this
*/
- public InputOptions setMinLength(Integer minLength) {
+ public InputOptions setMinLength(int minLength) {
this.minLength = minLength;
return this;
}
- /** Gets the maximum character length. @return the max length */
- public Integer getMaxLength() {
- return maxLength;
+ /**
+ * Clears the minLength setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InputOptions clearMinLength() {
+ this.minLength = null;
+ return this;
+ }
+
+ /**
+ * Gets the maximum character length.
+ *
+ * @return an {@link java.util.OptionalInt} containing the max length, or
+ * {@link java.util.OptionalInt#empty()} if not set
+ */
+ @JsonIgnore
+ public OptionalInt getMaxLength() {
+ return maxLength == null ? OptionalInt.empty() : OptionalInt.of(maxLength);
}
/**
* Sets the maximum character length. @param maxLength the max length @return
* this
*/
- public InputOptions setMaxLength(Integer maxLength) {
+ public InputOptions setMaxLength(int maxLength) {
this.maxLength = maxLength;
return this;
}
+ /**
+ * Clears the maxLength setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public InputOptions clearMaxLength() {
+ this.maxLength = null;
+ return this;
+ }
+
/**
* Gets the semantic format hint (e.g., {@code "email"}, {@code "uri"},
* {@code "date"}, {@code "date-time"}).
diff --git a/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java b/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
index 18701ad671..02727d4b5c 100644
--- a/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
+++ b/src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java
@@ -7,6 +7,9 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
+import java.util.OptionalInt;
/**
* Per-property overrides for model capabilities, deep-merged over runtime
@@ -106,48 +109,73 @@ public static class Supports {
/**
* Gets the vision override.
*
- * @return {@code true} to enable vision, {@code false} to disable, or
- * {@code null} to use the runtime default
+ * @return an {@link java.util.Optional} containing {@code true} to enable
+ * vision or {@code false} to disable, or
+ * {@link java.util.Optional#empty()} to use the runtime default
*/
- public Boolean getVision() {
- return vision;
+ @JsonIgnore
+ public Optional getVision() {
+ return Optional.ofNullable(vision);
}
/**
- * Sets whether vision (image input) is enabled.
+ * Sets whether vision (image input) is enabled. Use {@link #clearVision()} to
+ * revert to the runtime default.
*
* @param vision
- * {@code true} to enable, {@code false} to disable, or {@code null}
- * to use the runtime default
+ * {@code true} to enable, {@code false} to disable
* @return this instance for method chaining
*/
- public Supports setVision(Boolean vision) {
+ public Supports setVision(boolean vision) {
this.vision = vision;
return this;
}
+ /**
+ * Clears the vision setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Supports clearVision() {
+ this.vision = null;
+ return this;
+ }
+
/**
* Gets the reasoning effort override.
*
- * @return {@code true} to enable reasoning effort, {@code false} to disable, or
- * {@code null} to use the runtime default
+ * @return an {@link java.util.Optional} containing {@code true} to enable
+ * reasoning effort or {@code false} to disable, or
+ * {@link java.util.Optional#empty()} to use the runtime default
*/
- public Boolean getReasoningEffort() {
- return reasoningEffort;
+ @JsonIgnore
+ public Optional getReasoningEffort() {
+ return Optional.ofNullable(reasoningEffort);
}
/**
- * Sets whether reasoning effort configuration is enabled.
+ * Sets whether reasoning effort configuration is enabled. Use
+ * {@link #clearReasoningEffort()} to revert to the runtime default.
*
* @param reasoningEffort
- * {@code true} to enable, {@code false} to disable, or {@code null}
- * to use the runtime default
+ * {@code true} to enable, {@code false} to disable
* @return this instance for method chaining
*/
- public Supports setReasoningEffort(Boolean reasoningEffort) {
+ public Supports setReasoningEffort(boolean reasoningEffort) {
this.reasoningEffort = reasoningEffort;
return this;
}
+
+ /**
+ * Clears the reasoningEffort setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Supports clearReasoningEffort() {
+ this.reasoningEffort = null;
+ return this;
+ }
+
}
/**
@@ -174,8 +202,9 @@ public static class Limits {
*
* @return the override value, or {@code null} to use the runtime default
*/
- public Integer getMaxPromptTokens() {
- return maxPromptTokens;
+ @JsonIgnore
+ public OptionalInt getMaxPromptTokens() {
+ return maxPromptTokens == null ? OptionalInt.empty() : OptionalInt.of(maxPromptTokens);
}
/**
@@ -185,18 +214,29 @@ public Integer getMaxPromptTokens() {
* the override value, or {@code null} to use the runtime default
* @return this instance for method chaining
*/
- public Limits setMaxPromptTokens(Integer maxPromptTokens) {
+ public Limits setMaxPromptTokens(int maxPromptTokens) {
this.maxPromptTokens = maxPromptTokens;
return this;
}
+ /**
+ * Clears the maxPromptTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Limits clearMaxPromptTokens() {
+ this.maxPromptTokens = null;
+ return this;
+ }
+
/**
* Gets the maximum output tokens override.
*
* @return the override value, or {@code null} to use the runtime default
*/
- public Integer getMaxOutputTokens() {
- return maxOutputTokens;
+ @JsonIgnore
+ public OptionalInt getMaxOutputTokens() {
+ return maxOutputTokens == null ? OptionalInt.empty() : OptionalInt.of(maxOutputTokens);
}
/**
@@ -206,18 +246,29 @@ public Integer getMaxOutputTokens() {
* the override value, or {@code null} to use the runtime default
* @return this instance for method chaining
*/
- public Limits setMaxOutputTokens(Integer maxOutputTokens) {
+ public Limits setMaxOutputTokens(int maxOutputTokens) {
this.maxOutputTokens = maxOutputTokens;
return this;
}
+ /**
+ * Clears the maxOutputTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Limits clearMaxOutputTokens() {
+ this.maxOutputTokens = null;
+ return this;
+ }
+
/**
* Gets the maximum context window tokens override.
*
* @return the override value, or {@code null} to use the runtime default
*/
- public Integer getMaxContextWindowTokens() {
- return maxContextWindowTokens;
+ @JsonIgnore
+ public OptionalInt getMaxContextWindowTokens() {
+ return maxContextWindowTokens == null ? OptionalInt.empty() : OptionalInt.of(maxContextWindowTokens);
}
/**
@@ -227,9 +278,20 @@ public Integer getMaxContextWindowTokens() {
* the override value, or {@code null} to use the runtime default
* @return this instance for method chaining
*/
- public Limits setMaxContextWindowTokens(Integer maxContextWindowTokens) {
+ public Limits setMaxContextWindowTokens(int maxContextWindowTokens) {
this.maxContextWindowTokens = maxContextWindowTokens;
return this;
}
+
+ /**
+ * Clears the maxContextWindowTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public Limits clearMaxContextWindowTokens() {
+ this.maxContextWindowTokens = null;
+ return this;
+ }
+
}
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java b/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
index 8947696c9a..1c5e6fcc7f 100644
--- a/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ProviderConfig.java
@@ -9,6 +9,8 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.OptionalInt;
/**
* Configuration for a custom API provider (BYOK - Bring Your Own Key).
@@ -296,10 +298,12 @@ public ProviderConfig setWireModel(String wireModel) {
/**
* Gets the maximum prompt token override.
*
- * @return the max prompt tokens, or {@code null} if not set
+ * @return an {@link java.util.OptionalInt} containing the max prompt tokens, or
+ * {@link java.util.OptionalInt#empty()} if not set
*/
- public Integer getMaxPromptTokens() {
- return maxPromptTokens;
+ @JsonIgnore
+ public OptionalInt getMaxPromptTokens() {
+ return maxPromptTokens == null ? OptionalInt.empty() : OptionalInt.of(maxPromptTokens);
}
/**
@@ -314,18 +318,30 @@ public Integer getMaxPromptTokens() {
* the max prompt tokens
* @return this config for method chaining
*/
- public ProviderConfig setMaxPromptTokens(Integer maxPromptTokens) {
+ public ProviderConfig setMaxPromptTokens(int maxPromptTokens) {
this.maxPromptTokens = maxPromptTokens;
return this;
}
+ /**
+ * Clears the maxPromptTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ProviderConfig clearMaxPromptTokens() {
+ this.maxPromptTokens = null;
+ return this;
+ }
+
/**
* Gets the maximum output token override.
*
- * @return the max output tokens, or {@code null} if not set
+ * @return an {@link java.util.OptionalInt} containing the max output tokens, or
+ * {@link java.util.OptionalInt#empty()} if not set
*/
- public Integer getMaxOutputTokens() {
- return maxOutputTokens;
+ @JsonIgnore
+ public OptionalInt getMaxOutputTokens() {
+ return maxOutputTokens == null ? OptionalInt.empty() : OptionalInt.of(maxOutputTokens);
}
/**
@@ -338,8 +354,19 @@ public Integer getMaxOutputTokens() {
* the max output tokens
* @return this config for method chaining
*/
- public ProviderConfig setMaxOutputTokens(Integer maxOutputTokens) {
+ public ProviderConfig setMaxOutputTokens(int maxOutputTokens) {
this.maxOutputTokens = maxOutputTokens;
return this;
}
+
+ /**
+ * Clears the maxOutputTokens setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ProviderConfig clearMaxOutputTokens() {
+ this.maxOutputTokens = null;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
index f2caad7710..d8c3bf43b1 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
@@ -11,8 +11,10 @@
import java.util.function.Consumer;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.copilot.sdk.generated.SessionEvent;
+import java.util.Optional;
/**
* Configuration for resuming an existing Copilot session.
@@ -234,7 +236,7 @@ public ResumeSessionConfig setProvider(ProviderConfig provider) {
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When {@code null} (the default) or
+ * {@code false}, disables session telemetry. When unset (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting. This is independent of
@@ -242,15 +244,17 @@ public ResumeSessionConfig setProvider(ProviderConfig provider) {
* CopilotClientOptions.TelemetryConfig}, which configures OpenTelemetry export
* for observability.
*
- * @return whether session telemetry is enabled
+ * @return an {@link java.util.Optional} containing whether session telemetry is
+ * enabled, or {@link java.util.Optional#empty()} for the default
*/
- public Boolean getEnableSessionTelemetry() {
- return enableSessionTelemetry;
+ @JsonIgnore
+ public Optional getEnableSessionTelemetry() {
+ return Optional.ofNullable(enableSessionTelemetry);
}
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When {@code null} (the default) or
+ * {@code false}, disables session telemetry. When unset (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting.
@@ -259,11 +263,21 @@ public Boolean getEnableSessionTelemetry() {
* whether to enable session telemetry
* @return this config for method chaining
*/
- public ResumeSessionConfig setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
+ public ResumeSessionConfig setEnableSessionTelemetry(boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
return this;
}
+ /**
+ * Clears the enableSessionTelemetry setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ResumeSessionConfig clearEnableSessionTelemetry() {
+ this.enableSessionTelemetry = null;
+ return this;
+ }
+
/**
* Gets the reasoning effort level.
*
@@ -403,8 +417,9 @@ public ResumeSessionConfig setConfigDir(String configDir) {
* @return {@code true} to enable discovery, {@code false} to disable, or
* {@code null} to use the runtime default
*/
- public Boolean getEnableConfigDiscovery() {
- return enableConfigDiscovery;
+ @JsonIgnore
+ public Optional getEnableConfigDiscovery() {
+ return Optional.ofNullable(enableConfigDiscovery);
}
/**
@@ -420,19 +435,30 @@ public Boolean getEnableConfigDiscovery() {
* {@code null} to use the runtime default
* @return this config for method chaining
*/
- public ResumeSessionConfig setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
+ public ResumeSessionConfig setEnableConfigDiscovery(boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
return this;
}
+ /**
+ * Clears the enableConfigDiscovery setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ResumeSessionConfig clearEnableConfigDiscovery() {
+ this.enableConfigDiscovery = null;
+ return this;
+ }
+
/**
* Gets whether sub-agent streaming events are included.
*
* @return {@code true} to include sub-agent streaming events, {@code false} to
* suppress them, or {@code null} to use the runtime default
*/
- public Boolean getIncludeSubAgentStreamingEvents() {
- return includeSubAgentStreamingEvents;
+ @JsonIgnore
+ public Optional getIncludeSubAgentStreamingEvents() {
+ return Optional.ofNullable(includeSubAgentStreamingEvents);
}
/**
@@ -443,11 +469,22 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* suppress
* @return this config for method chaining
*/
- public ResumeSessionConfig setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
+ public ResumeSessionConfig setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
return this;
}
+ /**
+ * Clears the includeSubAgentStreamingEvents setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public ResumeSessionConfig clearIncludeSubAgentStreamingEvents() {
+ this.includeSubAgentStreamingEvents = null;
+ return this;
+ }
+
/**
* Gets the model capabilities override.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
index a1af269700..054fc8fba9 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
@@ -231,40 +231,68 @@ public Boolean getEnableSessionTelemetry() {
/**
* Sets enable session telemetry flag. @param enableSessionTelemetry the flag
*/
- public void setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
+ public void setEnableSessionTelemetry(boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
}
+ /**
+ * Clears the enableSessionTelemetry setting, reverting to the default behavior.
+ */
+ public void clearEnableSessionTelemetry() {
+ this.enableSessionTelemetry = null;
+ }
+
/** Gets request permission flag. @return the flag */
public Boolean getRequestPermission() {
return requestPermission;
}
/** Sets request permission flag. @param requestPermission the flag */
- public void setRequestPermission(Boolean requestPermission) {
+ public void setRequestPermission(boolean requestPermission) {
this.requestPermission = requestPermission;
}
+ /**
+ * Clears the requestPermission setting, reverting to the default behavior.
+ */
+ public void clearRequestPermission() {
+ this.requestPermission = null;
+ }
+
/** Gets request user input flag. @return the flag */
public Boolean getRequestUserInput() {
return requestUserInput;
}
/** Sets request user input flag. @param requestUserInput the flag */
- public void setRequestUserInput(Boolean requestUserInput) {
+ public void setRequestUserInput(boolean requestUserInput) {
this.requestUserInput = requestUserInput;
}
+ /**
+ * Clears the requestUserInput setting, reverting to the default behavior.
+ */
+ public void clearRequestUserInput() {
+ this.requestUserInput = null;
+ }
+
/** Gets hooks flag. @return the flag */
public Boolean getHooks() {
return hooks;
}
/** Sets hooks flag. @param hooks the flag */
- public void setHooks(Boolean hooks) {
+ public void setHooks(boolean hooks) {
this.hooks = hooks;
}
+ /**
+ * Clears the hooks setting, reverting to the default behavior.
+ */
+ public void clearHooks() {
+ this.hooks = null;
+ }
+
/** Gets working directory. @return the working directory */
public String getWorkingDirectory() {
return workingDirectory;
@@ -291,30 +319,51 @@ public Boolean getEnableConfigDiscovery() {
}
/** Sets enable config discovery flag. @param enableConfigDiscovery the flag */
- public void setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
+ public void setEnableConfigDiscovery(boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
}
+ /**
+ * Clears the enableConfigDiscovery setting, reverting to the default behavior.
+ */
+ public void clearEnableConfigDiscovery() {
+ this.enableConfigDiscovery = null;
+ }
+
/** Gets disable resume flag. @return the flag */
public Boolean getDisableResume() {
return disableResume;
}
/** Sets disable resume flag. @param disableResume the flag */
- public void setDisableResume(Boolean disableResume) {
+ public void setDisableResume(boolean disableResume) {
this.disableResume = disableResume;
}
+ /**
+ * Clears the disableResume setting, reverting to the default behavior.
+ */
+ public void clearDisableResume() {
+ this.disableResume = null;
+ }
+
/** Gets streaming flag. @return the flag */
public Boolean getStreaming() {
return streaming;
}
/** Sets streaming flag. @param streaming the flag */
- public void setStreaming(Boolean streaming) {
+ public void setStreaming(boolean streaming) {
this.streaming = streaming;
}
+ /**
+ * Clears the streaming setting, reverting to the default behavior.
+ */
+ public void clearStreaming() {
+ this.streaming = null;
+ }
+
/** Gets include sub-agent streaming events flag. @return the flag */
public Boolean getIncludeSubAgentStreamingEvents() {
return includeSubAgentStreamingEvents;
@@ -324,10 +373,18 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* Sets include sub-agent streaming events flag. @param
* includeSubAgentStreamingEvents the flag
*/
- public void setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
+ public void setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
}
+ /**
+ * Clears the includeSubAgentStreamingEvents setting, reverting to the default
+ * behavior.
+ */
+ public void clearIncludeSubAgentStreamingEvents() {
+ this.includeSubAgentStreamingEvents = null;
+ }
+
/** Gets MCP servers. @return the servers map */
public Map getMcpServers() {
return mcpServers == null ? null : Collections.unmodifiableMap(mcpServers);
@@ -441,10 +498,17 @@ public Boolean getRequestElicitation() {
}
/** Sets the requestElicitation flag. @param requestElicitation the flag */
- public void setRequestElicitation(Boolean requestElicitation) {
+ public void setRequestElicitation(boolean requestElicitation) {
this.requestElicitation = requestElicitation;
}
+ /**
+ * Clears the requestElicitation setting, reverting to the default behavior.
+ */
+ public void clearRequestElicitation() {
+ this.requestElicitation = null;
+ }
+
/** Gets the requestExitPlanMode flag. @return the flag */
public Boolean getRequestExitPlanMode() {
return requestExitPlanMode;
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
index 51cad884ed..53a84aa721 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
@@ -11,8 +11,10 @@
import java.util.function.Consumer;
import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.github.copilot.sdk.generated.SessionEvent;
+import java.util.Optional;
/**
* Configuration for creating a new Copilot session.
@@ -288,7 +290,7 @@ public SessionConfig setProvider(ProviderConfig provider) {
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When {@code null} (the default) or
+ * {@code false}, disables session telemetry. When unset (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting. This is independent of
@@ -296,15 +298,17 @@ public SessionConfig setProvider(ProviderConfig provider) {
* CopilotClientOptions.TelemetryConfig}, which configures OpenTelemetry export
* for observability.
*
- * @return whether session telemetry is enabled
+ * @return an {@link java.util.Optional} containing whether session telemetry is
+ * enabled, or {@link java.util.Optional#empty()} for the default
*/
- public Boolean getEnableSessionTelemetry() {
- return enableSessionTelemetry;
+ @JsonIgnore
+ public Optional getEnableSessionTelemetry() {
+ return Optional.ofNullable(enableSessionTelemetry);
}
/**
* Enables or disables internal session telemetry for this session. When
- * {@code false}, disables session telemetry. When {@code null} (the default) or
+ * {@code false}, disables session telemetry. When unset (the default) or
* {@code true}, telemetry is enabled for GitHub-authenticated sessions. When a
* custom {@link ProviderConfig} (BYOK) is configured, session telemetry is
* always disabled regardless of this setting.
@@ -313,11 +317,21 @@ public Boolean getEnableSessionTelemetry() {
* whether to enable session telemetry
* @return this config instance for method chaining
*/
- public SessionConfig setEnableSessionTelemetry(Boolean enableSessionTelemetry) {
+ public SessionConfig setEnableSessionTelemetry(boolean enableSessionTelemetry) {
this.enableSessionTelemetry = enableSessionTelemetry;
return this;
}
+ /**
+ * Clears the enableSessionTelemetry setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public SessionConfig clearEnableSessionTelemetry() {
+ this.enableSessionTelemetry = null;
+ return this;
+ }
+
/**
* Gets the permission request handler.
*
@@ -658,11 +672,13 @@ public SessionConfig setConfigDir(String configDir) {
/**
* Gets whether automatic configuration discovery is enabled.
*
- * @return {@code true} to enable discovery, {@code false} to disable, or
- * {@code null} to use the runtime default
+ * @return an {@link java.util.Optional} containing {@code true} to enable
+ * discovery or {@code false} to disable, or
+ * {@link java.util.Optional#empty()} to use the runtime default
*/
- public Boolean getEnableConfigDiscovery() {
- return enableConfigDiscovery;
+ @JsonIgnore
+ public Optional getEnableConfigDiscovery() {
+ return Optional.ofNullable(enableConfigDiscovery);
}
/**
@@ -676,23 +692,34 @@ public Boolean getEnableConfigDiscovery() {
* name collision.
*
* @param enableConfigDiscovery
- * {@code true} to enable discovery, {@code false} to disable, or
- * {@code null} to use the runtime default
+ * {@code true} to enable discovery, {@code false} to disable
* @return this config instance for method chaining
*/
- public SessionConfig setEnableConfigDiscovery(Boolean enableConfigDiscovery) {
+ public SessionConfig setEnableConfigDiscovery(boolean enableConfigDiscovery) {
this.enableConfigDiscovery = enableConfigDiscovery;
return this;
}
+ /**
+ * Clears the enableConfigDiscovery setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public SessionConfig clearEnableConfigDiscovery() {
+ this.enableConfigDiscovery = null;
+ return this;
+ }
+
/**
* Gets whether sub-agent streaming events are included.
*
- * @return {@code true} to include sub-agent streaming events, {@code false} to
- * suppress them, or {@code null} to use the runtime default
+ * @return an {@link java.util.Optional} containing {@code true} to include
+ * sub-agent streaming events or {@code false} to suppress them, or
+ * {@link java.util.Optional#empty()} to use the runtime default
*/
- public Boolean getIncludeSubAgentStreamingEvents() {
- return includeSubAgentStreamingEvents;
+ @JsonIgnore
+ public Optional getIncludeSubAgentStreamingEvents() {
+ return Optional.ofNullable(includeSubAgentStreamingEvents);
}
/**
@@ -709,11 +736,22 @@ public Boolean getIncludeSubAgentStreamingEvents() {
* suppress
* @return this config instance for method chaining
*/
- public SessionConfig setIncludeSubAgentStreamingEvents(Boolean includeSubAgentStreamingEvents) {
+ public SessionConfig setIncludeSubAgentStreamingEvents(boolean includeSubAgentStreamingEvents) {
this.includeSubAgentStreamingEvents = includeSubAgentStreamingEvents;
return this;
}
+ /**
+ * Clears the includeSubAgentStreamingEvents setting, reverting to the default
+ * behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public SessionConfig clearIncludeSubAgentStreamingEvents() {
+ this.includeSubAgentStreamingEvents = null;
+ return this;
+ }
+
/**
* Gets the model capabilities override.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java b/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
index 8df70c0502..06ddfc760d 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
@@ -4,26 +4,29 @@
package com.github.copilot.sdk.json;
-import com.fasterxml.jackson.annotation.JsonInclude;
+import java.util.Optional;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
/**
* UI-specific capability flags for a session.
*
* @since 1.0.0
*/
-@JsonInclude(JsonInclude.Include.NON_NULL)
public class SessionUiCapabilities {
+ @JsonProperty("elicitation")
private Boolean elicitation;
/**
* Returns whether the host supports interactive elicitation dialogs.
*
- * @return {@code true} if elicitation is supported, {@code false} or
- * {@code null} otherwise
+ * @return an {@link Optional} containing the boolean value, or empty if not set
*/
- public Boolean getElicitation() {
- return elicitation;
+ @JsonIgnore
+ public Optional getElicitation() {
+ return Optional.ofNullable(elicitation);
}
/**
@@ -33,8 +36,19 @@ public Boolean getElicitation() {
* {@code true} if elicitation is supported
* @return this instance for method chaining
*/
- public SessionUiCapabilities setElicitation(Boolean elicitation) {
+ public SessionUiCapabilities setElicitation(boolean elicitation) {
this.elicitation = elicitation;
return this;
}
+
+ /**
+ * Clears the elicitation setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public SessionUiCapabilities clearElicitation() {
+ this.elicitation = null;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
index d387128696..af00454477 100644
--- a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
@@ -4,7 +4,9 @@
package com.github.copilot.sdk.json;
-import com.fasterxml.jackson.annotation.JsonInclude;
+import java.util.Optional;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* OpenTelemetry configuration for the Copilot CLI server.
@@ -23,7 +25,6 @@
* @see CopilotClientOptions#setTelemetry(TelemetryConfig)
* @since 1.2.0
*/
-@JsonInclude(JsonInclude.Include.NON_NULL)
public class TelemetryConfig {
private String otlpEndpoint;
@@ -131,11 +132,13 @@ public TelemetryConfig setSourceName(String sourceName) {
* Maps to the {@code OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT}
* environment variable.
*
- * @return {@code true} to capture content, {@code false} to suppress it, or
- * {@code null} to use the default
+ * @return an {@link java.util.Optional} containing {@code true} to capture
+ * content or {@code false} to suppress it, or
+ * {@link java.util.Optional#empty()} to use the default
*/
- public Boolean getCaptureContent() {
- return captureContent;
+ @JsonIgnore
+ public Optional getCaptureContent() {
+ return Optional.ofNullable(captureContent);
}
/**
@@ -145,8 +148,19 @@ public Boolean getCaptureContent() {
* {@code true} to capture content, {@code false} to suppress it
* @return this config for method chaining
*/
- public TelemetryConfig setCaptureContent(Boolean captureContent) {
+ public TelemetryConfig setCaptureContent(boolean captureContent) {
this.captureContent = captureContent;
return this;
}
+
+ /**
+ * Clears the captureContent setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public TelemetryConfig clearCaptureContent() {
+ this.captureContent = null;
+ return this;
+ }
+
}
diff --git a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
index 85e0b26bdc..6003c86df2 100644
--- a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
@@ -8,8 +8,9 @@
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import java.util.Optional;
/**
* Request for user input from the agent.
@@ -20,7 +21,6 @@
* @since 1.0.6
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserInputRequest {
@JsonProperty("question")
@@ -77,11 +77,13 @@ public UserInputRequest setChoices(List choices) {
/**
* Returns whether freeform text input is allowed.
*
- * @return {@code true} if freeform input is allowed, {@code null} if not
+ * @return an {@link java.util.Optional} containing {@code true} if freeform
+ * input is allowed, or {@link java.util.Optional#empty()} if not
* specified
*/
- public Boolean getAllowFreeform() {
- return allowFreeform;
+ @JsonIgnore
+ public Optional getAllowFreeform() {
+ return Optional.ofNullable(allowFreeform);
}
/**
@@ -91,8 +93,19 @@ public Boolean getAllowFreeform() {
* {@code true} to allow freeform input
* @return this instance for method chaining
*/
- public UserInputRequest setAllowFreeform(Boolean allowFreeform) {
+ public UserInputRequest setAllowFreeform(boolean allowFreeform) {
this.allowFreeform = allowFreeform;
return this;
}
+
+ /**
+ * Clears the allowFreeform setting, reverting to the default behavior.
+ *
+ * @return this instance for method chaining
+ */
+ public UserInputRequest clearAllowFreeform() {
+ this.allowFreeform = null;
+ return this;
+ }
+
}
diff --git a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
index 7abc47e4a4..09bd3ee385 100644
--- a/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
+++ b/src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
@@ -203,7 +203,7 @@ void sessionConfigEnableSessionTelemetryCopied() {
SessionConfig cloned = original.clone();
- assertFalse(cloned.getEnableSessionTelemetry());
+ assertFalse(cloned.getEnableSessionTelemetry().orElse(true));
}
@Test
@@ -212,7 +212,7 @@ void sessionConfigEnableSessionTelemetryDefaultIsNull() {
SessionConfig cloned = original.clone();
- assertNull(cloned.getEnableSessionTelemetry());
+ assertTrue(cloned.getEnableSessionTelemetry().isEmpty());
}
@Test
@@ -222,7 +222,7 @@ void resumeSessionConfigEnableSessionTelemetryCopied() {
ResumeSessionConfig cloned = original.clone();
- assertFalse(cloned.getEnableSessionTelemetry());
+ assertFalse(cloned.getEnableSessionTelemetry().orElse(true));
}
@Test
@@ -231,7 +231,7 @@ void resumeSessionConfigEnableSessionTelemetryDefaultIsNull() {
ResumeSessionConfig cloned = original.clone();
- assertNull(cloned.getEnableSessionTelemetry());
+ assertTrue(cloned.getEnableSessionTelemetry().isEmpty());
}
@Test
@@ -301,11 +301,11 @@ void copilotClientOptionsSetTelemetry() {
}
@Test
- void copilotClientOptionsSetUseLoggedInUserNull() {
+ void copilotClientOptionsClearUseLoggedInUser() {
var opts = new CopilotClientOptions();
- opts.setUseLoggedInUser(null);
- // null → Boolean.FALSE
- assertEquals(Boolean.FALSE, opts.getUseLoggedInUser());
+ opts.setUseLoggedInUser(true);
+ opts.clearUseLoggedInUser();
+ assertTrue(opts.getUseLoggedInUser().isEmpty());
}
@Test
@@ -375,7 +375,7 @@ void copilotClientOptionsSessionIdleTimeoutCloned() {
CopilotClientOptions cloned = original.clone();
- assertEquals(600, cloned.getSessionIdleTimeoutSeconds());
+ assertEquals(600, cloned.getSessionIdleTimeoutSeconds().getAsInt());
}
@Test
diff --git a/src/test/java/com/github/copilot/sdk/CopilotClientTest.java b/src/test/java/com/github/copilot/sdk/CopilotClientTest.java
index b0430959b9..14ed8ca89e 100644
--- a/src/test/java/com/github/copilot/sdk/CopilotClientTest.java
+++ b/src/test/java/com/github/copilot/sdk/CopilotClientTest.java
@@ -20,6 +20,7 @@
import java.util.concurrent.ExecutionException;
import static org.junit.jupiter.api.Assertions.*;
+import java.util.Optional;
/**
* Tests for CopilotClient.
@@ -153,14 +154,14 @@ void testGitHubTokenOptionAccepted() {
void testUseLoggedInUserDefaultsToNull() {
var options = new CopilotClientOptions().setCliPath("/path/to/cli");
- assertNull(options.getUseLoggedInUser());
+ assertTrue(options.getUseLoggedInUser().isEmpty());
}
@Test
void testExplicitUseLoggedInUserFalse() {
var options = new CopilotClientOptions().setCliPath("/path/to/cli").setUseLoggedInUser(false);
- assertEquals(false, options.getUseLoggedInUser());
+ assertEquals(Optional.of(false), options.getUseLoggedInUser());
}
@Test
@@ -168,7 +169,7 @@ void testExplicitUseLoggedInUserTrueWithGitHubToken() {
var options = new CopilotClientOptions().setCliPath("/path/to/cli").setGitHubToken("gho_test_token")
.setUseLoggedInUser(true);
- assertEquals(true, options.getUseLoggedInUser());
+ assertEquals(Optional.of(true), options.getUseLoggedInUser());
}
@Test
@@ -189,14 +190,14 @@ void testUseLoggedInUserWithCliUrlThrows() {
void testSessionIdleTimeoutSecondsDefaultsToNull() {
var options = new CopilotClientOptions();
- assertNull(options.getSessionIdleTimeoutSeconds());
+ assertTrue(options.getSessionIdleTimeoutSeconds().isEmpty());
}
@Test
void testSessionIdleTimeoutSecondsOptionAccepted() {
var options = new CopilotClientOptions().setSessionIdleTimeoutSeconds(600);
- assertEquals(600, options.getSessionIdleTimeoutSeconds());
+ assertEquals(600, options.getSessionIdleTimeoutSeconds().getAsInt());
}
@Test
diff --git a/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java b/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
index b61c93559b..2ff3600200 100644
--- a/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
+++ b/src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java
@@ -217,17 +217,16 @@ void mcpStdioServerConfigCoversGettersAndFluentSetters() {
@Test
void modelCapabilitiesOverrideCoversNestedSupportsAndLimits() {
- var supports = new ModelCapabilitiesOverride.Supports().setVision(Boolean.TRUE)
- .setReasoningEffort(Boolean.FALSE);
+ var supports = new ModelCapabilitiesOverride.Supports().setVision(true).setReasoningEffort(false);
var limits = new ModelCapabilitiesOverride.Limits().setMaxPromptTokens(2048).setMaxOutputTokens(512)
.setMaxContextWindowTokens(8192);
var override = new ModelCapabilitiesOverride().setSupports(supports).setLimits(limits);
- assertTrue(override.getSupports().getVision());
- assertFalse(override.getSupports().getReasoningEffort());
- assertEquals(2048, override.getLimits().getMaxPromptTokens());
- assertEquals(512, override.getLimits().getMaxOutputTokens());
- assertEquals(8192, override.getLimits().getMaxContextWindowTokens());
+ assertTrue(override.getSupports().getVision().orElse(false));
+ assertFalse(override.getSupports().getReasoningEffort().orElse(true));
+ assertEquals(2048, override.getLimits().getMaxPromptTokens().getAsInt());
+ assertEquals(512, override.getLimits().getMaxOutputTokens().getAsInt());
+ assertEquals(8192, override.getLimits().getMaxContextWindowTokens().getAsInt());
}
}
diff --git a/src/test/java/com/github/copilot/sdk/ElicitationTest.java b/src/test/java/com/github/copilot/sdk/ElicitationTest.java
index 6b748b4cc2..1f62451276 100644
--- a/src/test/java/com/github/copilot/sdk/ElicitationTest.java
+++ b/src/test/java/com/github/copilot/sdk/ElicitationTest.java
@@ -40,7 +40,7 @@ void sessionCapabilitiesTypesAreProperlyStructured() {
var capabilities = new SessionCapabilities().setUi(new SessionUiCapabilities().setElicitation(true));
assertNotNull(capabilities.getUi());
- assertTrue(capabilities.getUi().getElicitation());
+ assertTrue(capabilities.getUi().getElicitation().get());
// Test with null UI
var emptyCapabilities = new SessionCapabilities();
@@ -119,8 +119,8 @@ void inputOptionsHasAllFields() {
assertEquals("My Title", opts.getTitle());
assertEquals("My Desc", opts.getDescription());
- assertEquals(1, opts.getMinLength());
- assertEquals(100, opts.getMaxLength());
+ assertEquals(1, opts.getMinLength().getAsInt());
+ assertEquals(100, opts.getMaxLength().getAsInt());
assertEquals("email", opts.getFormat());
assertEquals("default@example.com", opts.getDefaultValue());
}
@@ -164,7 +164,7 @@ void buildCreateRequestSetsRequestElicitationWhenHandlerPresent() {
var request = SessionRequestBuilder.buildCreateRequest(config);
- assertTrue(Boolean.TRUE.equals(request.getRequestElicitation()));
+ assertEquals(Boolean.TRUE, request.getRequestElicitation());
}
@Test
@@ -186,6 +186,6 @@ void buildResumeRequestSetsRequestElicitationWhenHandlerPresent() {
var request = SessionRequestBuilder.buildResumeRequest("session-1", config);
- assertTrue(Boolean.TRUE.equals(request.getRequestElicitation()));
+ assertEquals(Boolean.TRUE, request.getRequestElicitation());
}
}
diff --git a/src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java b/src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java
deleted file mode 100644
index 7465507f50..0000000000
--- a/src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- *--------------------------------------------------------------------------------------------*/
-
-package com.github.copilot.sdk;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import org.junit.jupiter.api.Test;
-
-import com.github.copilot.sdk.json.CopilotClientOptions;
-import com.github.copilot.sdk.json.CustomAgentConfig;
-import com.github.copilot.sdk.json.InfiniteSessionConfig;
-import com.github.copilot.sdk.json.InputOptions;
-import com.github.copilot.sdk.json.ModelCapabilitiesOverride;
-import com.github.copilot.sdk.json.ProviderConfig;
-import com.github.copilot.sdk.json.ResumeSessionConfig;
-import com.github.copilot.sdk.json.SessionConfig;
-import com.github.copilot.sdk.json.SessionUiCapabilities;
-import com.github.copilot.sdk.json.TelemetryConfig;
-import com.github.copilot.sdk.json.UserInputRequest;
-
-/**
- * Verifies that public DTO classes in the {@code com.github.copilot.sdk.json}
- * package are annotated with {@code @JsonInclude(JsonInclude.Include.NON_NULL)}
- * so that null-valued fields are omitted during JSON serialization.
- */
-class JsonIncludeNonNullTest {
-
- private static final ObjectMapper MAPPER = new ObjectMapper();
-
- // --- Annotation presence checks ---
-
- @Test
- void copilotClientOptionsHasNonNullAnnotation() {
- assertHasNonNullInclude(CopilotClientOptions.class);
- }
-
- @Test
- void sessionConfigHasNonNullAnnotation() {
- assertHasNonNullInclude(SessionConfig.class);
- }
-
- @Test
- void resumeSessionConfigHasNonNullAnnotation() {
- assertHasNonNullInclude(ResumeSessionConfig.class);
- }
-
- @Test
- void infiniteSessionConfigHasNonNullAnnotation() {
- assertHasNonNullInclude(InfiniteSessionConfig.class);
- }
-
- @Test
- void inputOptionsHasNonNullAnnotation() {
- assertHasNonNullInclude(InputOptions.class);
- }
-
- @Test
- void modelCapabilitiesOverrideHasNonNullAnnotation() {
- assertHasNonNullInclude(ModelCapabilitiesOverride.class);
- }
-
- @Test
- void providerConfigHasNonNullAnnotation() {
- assertHasNonNullInclude(ProviderConfig.class);
- }
-
- @Test
- void telemetryConfigHasNonNullAnnotation() {
- assertHasNonNullInclude(TelemetryConfig.class);
- }
-
- @Test
- void sessionUiCapabilitiesHasNonNullAnnotation() {
- assertHasNonNullInclude(SessionUiCapabilities.class);
- }
-
- @Test
- void customAgentConfigHasNonNullAnnotation() {
- assertHasNonNullInclude(CustomAgentConfig.class);
- }
-
- @Test
- void userInputRequestHasNonNullAnnotation() {
- assertHasNonNullInclude(UserInputRequest.class);
- }
-
- // --- Serialization tests: null fields are omitted ---
-
- @Test
- void inputOptionsOmitsNullFieldsInJson() throws JsonProcessingException {
- var opts = new InputOptions();
- String json = MAPPER.writeValueAsString(opts);
- assertEquals("{}", json, "All-null InputOptions should serialize to empty JSON");
- }
-
- @Test
- void telemetryConfigOmitsNullFieldsInJson() throws JsonProcessingException {
- var config = new TelemetryConfig();
- String json = MAPPER.writeValueAsString(config);
- assertEquals("{}", json, "All-null TelemetryConfig should serialize to empty JSON");
- }
-
- @Test
- void sessionUiCapabilitiesOmitsNullFieldsInJson() throws JsonProcessingException {
- var caps = new SessionUiCapabilities();
- String json = MAPPER.writeValueAsString(caps);
- assertEquals("{}", json, "All-null SessionUiCapabilities should serialize to empty JSON");
- }
-
- @Test
- void userInputRequestOmitsNullFieldsInJson() throws JsonProcessingException {
- var req = new UserInputRequest();
- String json = MAPPER.writeValueAsString(req);
- assertFalse(json.contains("null"), "UserInputRequest with no fields set should not contain 'null' values");
- }
-
- @Test
- void inputOptionsIncludesSetFieldsInJson() throws JsonProcessingException {
- var opts = new InputOptions();
- opts.setMinLength(5);
- opts.setMaxLength(100);
- String json = MAPPER.writeValueAsString(opts);
- assertTrue(json.contains("\"minLength\":5"), "Set minLength should appear in JSON");
- assertTrue(json.contains("\"maxLength\":100"), "Set maxLength should appear in JSON");
- assertFalse(json.contains("\"title\""), "Unset title should be omitted from JSON");
- }
-
- @Test
- void telemetryConfigIncludesSetFieldsInJson() throws JsonProcessingException {
- var config = new TelemetryConfig();
- config.setOtlpEndpoint("http://localhost:4318");
- String json = MAPPER.writeValueAsString(config);
- assertTrue(json.contains("\"otlpEndpoint\":\"http://localhost:4318\""),
- "Set otlpEndpoint should appear in JSON");
- assertFalse(json.contains("\"filePath\""), "Unset filePath should be omitted from JSON");
- }
-
- @Test
- void sessionUiCapabilitiesIncludesSetFieldsInJson() throws JsonProcessingException {
- var caps = new SessionUiCapabilities();
- caps.setElicitation(true);
- String json = MAPPER.writeValueAsString(caps);
- assertTrue(json.contains("\"elicitation\":true"), "Set elicitation should appear in JSON");
- }
-
- private void assertHasNonNullInclude(Class> clazz) {
- JsonInclude annotation = clazz.getAnnotation(JsonInclude.class);
- assertNotNull(annotation, clazz.getSimpleName() + " should be annotated with @JsonInclude");
- assertEquals(JsonInclude.Include.NON_NULL, annotation.value(),
- clazz.getSimpleName() + " @JsonInclude should use Include.NON_NULL");
- }
-
-}
diff --git a/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java b/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
new file mode 100644
index 0000000000..2a9770e2e2
--- /dev/null
+++ b/src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java
@@ -0,0 +1,635 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.copilot.sdk.json.CopilotClientOptions;
+import com.github.copilot.sdk.json.CustomAgentConfig;
+import com.github.copilot.sdk.json.InfiniteSessionConfig;
+import com.github.copilot.sdk.json.InputOptions;
+import com.github.copilot.sdk.json.ModelCapabilitiesOverride;
+import com.github.copilot.sdk.json.ProviderConfig;
+import com.github.copilot.sdk.json.ResumeSessionConfig;
+import com.github.copilot.sdk.json.SessionConfig;
+import com.github.copilot.sdk.json.SessionUiCapabilities;
+import com.github.copilot.sdk.json.TelemetryConfig;
+import com.github.copilot.sdk.json.UserInputRequest;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Validates that every {@code clearXxx()} method resets its field to absent,
+ * that Optional-returning getters report the correct state, and that Jackson
+ * omits cleared fields from serialized output.
+ */
+class OptionalApiAndJacksonTest {
+
+ private static final ObjectMapper MAPPER = JsonRpcClient.getObjectMapper();
+
+ // ── CopilotClientOptions ──────────────────────────────────────────
+
+ @Test
+ void copilotClientOptions_clearSessionIdleTimeoutSeconds() {
+ var opts = new CopilotClientOptions();
+ opts.setSessionIdleTimeoutSeconds(120);
+ assertFalse(opts.getSessionIdleTimeoutSeconds().isEmpty());
+
+ opts.clearSessionIdleTimeoutSeconds();
+ assertTrue(opts.getSessionIdleTimeoutSeconds().isEmpty());
+ }
+
+ @Test
+ void copilotClientOptions_clearUseLoggedInUser() {
+ var opts = new CopilotClientOptions();
+ opts.setUseLoggedInUser(true);
+ assertTrue(opts.getUseLoggedInUser().isPresent());
+
+ opts.clearUseLoggedInUser();
+ assertTrue(opts.getUseLoggedInUser().isEmpty());
+ }
+
+ // ── SessionConfig ─────────────────────────────────────────────────
+
+ @Test
+ void sessionConfig_clearEnableSessionTelemetry() {
+ var cfg = new SessionConfig();
+ cfg.setEnableSessionTelemetry(true);
+ assertTrue(cfg.getEnableSessionTelemetry().isPresent());
+
+ cfg.clearEnableSessionTelemetry();
+ assertTrue(cfg.getEnableSessionTelemetry().isEmpty());
+ }
+
+ @Test
+ void sessionConfig_clearEnableConfigDiscovery() {
+ var cfg = new SessionConfig();
+ cfg.setEnableConfigDiscovery(false);
+ assertTrue(cfg.getEnableConfigDiscovery().isPresent());
+
+ cfg.clearEnableConfigDiscovery();
+ assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
+ }
+
+ @Test
+ void sessionConfig_clearIncludeSubAgentStreamingEvents() {
+ var cfg = new SessionConfig();
+ cfg.setIncludeSubAgentStreamingEvents(true);
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isPresent());
+
+ cfg.clearIncludeSubAgentStreamingEvents();
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
+ }
+
+ // ── ResumeSessionConfig ───────────────────────────────────────────
+
+ @Test
+ void resumeSessionConfig_clearEnableSessionTelemetry() {
+ var cfg = new ResumeSessionConfig();
+ cfg.setEnableSessionTelemetry(false);
+ assertTrue(cfg.getEnableSessionTelemetry().isPresent());
+
+ cfg.clearEnableSessionTelemetry();
+ assertTrue(cfg.getEnableSessionTelemetry().isEmpty());
+ }
+
+ @Test
+ void resumeSessionConfig_clearEnableConfigDiscovery() {
+ var cfg = new ResumeSessionConfig();
+ cfg.setEnableConfigDiscovery(true);
+ assertTrue(cfg.getEnableConfigDiscovery().isPresent());
+
+ cfg.clearEnableConfigDiscovery();
+ assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
+ }
+
+ @Test
+ void resumeSessionConfig_clearIncludeSubAgentStreamingEvents() {
+ var cfg = new ResumeSessionConfig();
+ cfg.setIncludeSubAgentStreamingEvents(false);
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isPresent());
+
+ cfg.clearIncludeSubAgentStreamingEvents();
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
+ }
+
+ // ── InfiniteSessionConfig ─────────────────────────────────────────
+
+ @Test
+ void infiniteSessionConfig_clearEnabled() {
+ var cfg = new InfiniteSessionConfig();
+ cfg.setEnabled(true);
+ assertTrue(cfg.getEnabled().isPresent());
+
+ cfg.clearEnabled();
+ assertTrue(cfg.getEnabled().isEmpty());
+ }
+
+ @Test
+ void infiniteSessionConfig_clearBackgroundCompactionThreshold() {
+ var cfg = new InfiniteSessionConfig();
+ cfg.setBackgroundCompactionThreshold(0.75);
+ assertFalse(cfg.getBackgroundCompactionThreshold().isEmpty());
+
+ cfg.clearBackgroundCompactionThreshold();
+ assertTrue(cfg.getBackgroundCompactionThreshold().isEmpty());
+ }
+
+ @Test
+ void infiniteSessionConfig_clearBufferExhaustionThreshold() {
+ var cfg = new InfiniteSessionConfig();
+ cfg.setBufferExhaustionThreshold(0.9);
+ assertFalse(cfg.getBufferExhaustionThreshold().isEmpty());
+
+ cfg.clearBufferExhaustionThreshold();
+ assertTrue(cfg.getBufferExhaustionThreshold().isEmpty());
+ }
+
+ // ── InputOptions ──────────────────────────────────────────────────
+
+ @Test
+ void inputOptions_clearMinLength() {
+ var opts = new InputOptions();
+ opts.setMinLength(5);
+ assertFalse(opts.getMinLength().isEmpty());
+
+ opts.clearMinLength();
+ assertTrue(opts.getMinLength().isEmpty());
+ }
+
+ @Test
+ void inputOptions_clearMaxLength() {
+ var opts = new InputOptions();
+ opts.setMaxLength(100);
+ assertFalse(opts.getMaxLength().isEmpty());
+
+ opts.clearMaxLength();
+ assertTrue(opts.getMaxLength().isEmpty());
+ }
+
+ // ── ModelCapabilitiesOverride.Supports ─────────────────────────────
+
+ @Test
+ void supports_clearVision() {
+ var s = new ModelCapabilitiesOverride.Supports();
+ s.setVision(true);
+ assertTrue(s.getVision().isPresent());
+
+ s.clearVision();
+ assertTrue(s.getVision().isEmpty());
+ }
+
+ @Test
+ void supports_clearReasoningEffort() {
+ var s = new ModelCapabilitiesOverride.Supports();
+ s.setReasoningEffort(false);
+ assertTrue(s.getReasoningEffort().isPresent());
+
+ s.clearReasoningEffort();
+ assertTrue(s.getReasoningEffort().isEmpty());
+ }
+
+ // ── ModelCapabilitiesOverride.Limits ───────────────────────────────
+
+ @Test
+ void limits_clearMaxPromptTokens() {
+ var l = new ModelCapabilitiesOverride.Limits();
+ l.setMaxPromptTokens(4096);
+ assertFalse(l.getMaxPromptTokens().isEmpty());
+
+ l.clearMaxPromptTokens();
+ assertTrue(l.getMaxPromptTokens().isEmpty());
+ }
+
+ @Test
+ void limits_clearMaxOutputTokens() {
+ var l = new ModelCapabilitiesOverride.Limits();
+ l.setMaxOutputTokens(1024);
+ assertFalse(l.getMaxOutputTokens().isEmpty());
+
+ l.clearMaxOutputTokens();
+ assertTrue(l.getMaxOutputTokens().isEmpty());
+ }
+
+ @Test
+ void limits_clearMaxContextWindowTokens() {
+ var l = new ModelCapabilitiesOverride.Limits();
+ l.setMaxContextWindowTokens(16384);
+ assertFalse(l.getMaxContextWindowTokens().isEmpty());
+
+ l.clearMaxContextWindowTokens();
+ assertTrue(l.getMaxContextWindowTokens().isEmpty());
+ }
+
+ // ── ProviderConfig ────────────────────────────────────────────────
+
+ @Test
+ void providerConfig_clearMaxPromptTokens() {
+ var cfg = new ProviderConfig();
+ cfg.setMaxPromptTokens(2048);
+ assertFalse(cfg.getMaxPromptTokens().isEmpty());
+
+ cfg.clearMaxPromptTokens();
+ assertTrue(cfg.getMaxPromptTokens().isEmpty());
+ }
+
+ @Test
+ void providerConfig_clearMaxOutputTokens() {
+ var cfg = new ProviderConfig();
+ cfg.setMaxOutputTokens(512);
+ assertFalse(cfg.getMaxOutputTokens().isEmpty());
+
+ cfg.clearMaxOutputTokens();
+ assertTrue(cfg.getMaxOutputTokens().isEmpty());
+ }
+
+ // ── TelemetryConfig ───────────────────────────────────────────────
+
+ @Test
+ void telemetryConfig_clearCaptureContent() {
+ var cfg = new TelemetryConfig();
+ cfg.setCaptureContent(true);
+ assertTrue(cfg.getCaptureContent().isPresent());
+
+ cfg.clearCaptureContent();
+ assertTrue(cfg.getCaptureContent().isEmpty());
+ }
+
+ // ── SessionUiCapabilities ─────────────────────────────────────────
+
+ @Test
+ void sessionUiCapabilities_clearElicitation() {
+ var caps = new SessionUiCapabilities();
+ caps.setElicitation(true);
+ assertTrue(caps.getElicitation().isPresent());
+
+ caps.clearElicitation();
+ assertTrue(caps.getElicitation().isEmpty());
+ }
+
+ // ── CustomAgentConfig ─────────────────────────────────────────────
+
+ @Test
+ void customAgentConfig_clearInfer() {
+ var cfg = new CustomAgentConfig();
+ cfg.setInfer(true);
+ assertTrue(cfg.getInfer().isPresent());
+
+ cfg.clearInfer();
+ assertTrue(cfg.getInfer().isEmpty());
+ }
+
+ // ── UserInputRequest ──────────────────────────────────────────────
+
+ @Test
+ void userInputRequest_clearAllowFreeform() {
+ var req = new UserInputRequest();
+ req.setAllowFreeform(false);
+ assertTrue(req.getAllowFreeform().isPresent());
+
+ req.clearAllowFreeform();
+ assertTrue(req.getAllowFreeform().isEmpty());
+ }
+
+ // ── Value retrieval through Optional getters ────────────────────────
+
+ @Test
+ void copilotClientOptions_sessionIdleTimeoutSecondsValue() {
+ var opts = new CopilotClientOptions();
+ assertTrue(opts.getSessionIdleTimeoutSeconds().isEmpty());
+
+ opts.setSessionIdleTimeoutSeconds(300);
+ assertEquals(300, opts.getSessionIdleTimeoutSeconds().getAsInt());
+
+ opts.setSessionIdleTimeoutSeconds(0);
+ assertTrue(opts.getSessionIdleTimeoutSeconds().isPresent());
+ assertEquals(0, opts.getSessionIdleTimeoutSeconds().getAsInt());
+ }
+
+ @Test
+ void copilotClientOptions_useLoggedInUserValue() {
+ var opts = new CopilotClientOptions();
+ assertTrue(opts.getUseLoggedInUser().isEmpty());
+
+ opts.setUseLoggedInUser(true);
+ assertEquals(Boolean.TRUE, opts.getUseLoggedInUser().get());
+
+ opts.setUseLoggedInUser(false);
+ assertEquals(Boolean.FALSE, opts.getUseLoggedInUser().get());
+ }
+
+ @Test
+ void sessionConfig_enableSessionTelemetryValue() {
+ var cfg = new SessionConfig();
+ assertFalse(cfg.getEnableSessionTelemetry().orElse(false));
+
+ cfg.setEnableSessionTelemetry(true);
+ assertTrue(cfg.getEnableSessionTelemetry().orElse(false));
+
+ cfg.setEnableSessionTelemetry(false);
+ assertFalse(cfg.getEnableSessionTelemetry().orElse(true));
+ }
+
+ @Test
+ void sessionConfig_enableConfigDiscoveryValue() {
+ var cfg = new SessionConfig();
+ assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
+
+ cfg.setEnableConfigDiscovery(true);
+ assertTrue(cfg.getEnableConfigDiscovery().get());
+
+ cfg.setEnableConfigDiscovery(false);
+ assertFalse(cfg.getEnableConfigDiscovery().get());
+ }
+
+ @Test
+ void sessionConfig_includeSubAgentStreamingEventsValue() {
+ var cfg = new SessionConfig();
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
+
+ cfg.setIncludeSubAgentStreamingEvents(true);
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().get());
+ }
+
+ @Test
+ void resumeSessionConfig_enableSessionTelemetryValue() {
+ var cfg = new ResumeSessionConfig();
+ assertTrue(cfg.getEnableSessionTelemetry().isEmpty());
+
+ cfg.setEnableSessionTelemetry(true);
+ assertTrue(cfg.getEnableSessionTelemetry().get());
+
+ cfg.setEnableSessionTelemetry(false);
+ assertFalse(cfg.getEnableSessionTelemetry().get());
+ }
+
+ @Test
+ void resumeSessionConfig_enableConfigDiscoveryValue() {
+ var cfg = new ResumeSessionConfig();
+ assertTrue(cfg.getEnableConfigDiscovery().isEmpty());
+
+ cfg.setEnableConfigDiscovery(true);
+ assertTrue(cfg.getEnableConfigDiscovery().get());
+ }
+
+ @Test
+ void resumeSessionConfig_includeSubAgentStreamingEventsValue() {
+ var cfg = new ResumeSessionConfig();
+ assertTrue(cfg.getIncludeSubAgentStreamingEvents().isEmpty());
+
+ cfg.setIncludeSubAgentStreamingEvents(false);
+ assertFalse(cfg.getIncludeSubAgentStreamingEvents().get());
+ }
+
+ @Test
+ void infiniteSessionConfig_thresholdValues() {
+ var cfg = new InfiniteSessionConfig();
+ assertTrue(cfg.getBackgroundCompactionThreshold().isEmpty());
+ assertTrue(cfg.getBufferExhaustionThreshold().isEmpty());
+
+ cfg.setBackgroundCompactionThreshold(0.6);
+ cfg.setBufferExhaustionThreshold(0.85);
+ assertEquals(0.6, cfg.getBackgroundCompactionThreshold().getAsDouble(), 0.001);
+ assertEquals(0.85, cfg.getBufferExhaustionThreshold().getAsDouble(), 0.001);
+ }
+
+ @Test
+ void infiniteSessionConfig_enabledValue() {
+ var cfg = new InfiniteSessionConfig();
+ assertTrue(cfg.getEnabled().isEmpty());
+
+ cfg.setEnabled(true);
+ assertTrue(cfg.getEnabled().get());
+
+ cfg.setEnabled(false);
+ assertFalse(cfg.getEnabled().get());
+ }
+
+ @Test
+ void inputOptions_minAndMaxLengthValues() {
+ var opts = new InputOptions();
+ assertTrue(opts.getMinLength().isEmpty());
+ assertTrue(opts.getMaxLength().isEmpty());
+
+ opts.setMinLength(1);
+ opts.setMaxLength(255);
+ assertEquals(1, opts.getMinLength().getAsInt());
+ assertEquals(255, opts.getMaxLength().getAsInt());
+ }
+
+ @Test
+ void supports_visionAndReasoningEffortValues() {
+ var s = new ModelCapabilitiesOverride.Supports();
+ assertTrue(s.getVision().isEmpty());
+ assertTrue(s.getReasoningEffort().isEmpty());
+
+ s.setVision(true);
+ s.setReasoningEffort(false);
+ assertTrue(s.getVision().get());
+ assertFalse(s.getReasoningEffort().get());
+ }
+
+ @Test
+ void limits_tokenValues() {
+ var l = new ModelCapabilitiesOverride.Limits();
+ assertTrue(l.getMaxPromptTokens().isEmpty());
+ assertTrue(l.getMaxOutputTokens().isEmpty());
+ assertTrue(l.getMaxContextWindowTokens().isEmpty());
+
+ l.setMaxPromptTokens(4096);
+ l.setMaxOutputTokens(1024);
+ l.setMaxContextWindowTokens(16384);
+ assertEquals(4096, l.getMaxPromptTokens().getAsInt());
+ assertEquals(1024, l.getMaxOutputTokens().getAsInt());
+ assertEquals(16384, l.getMaxContextWindowTokens().getAsInt());
+ }
+
+ @Test
+ void providerConfig_tokenValues() {
+ var cfg = new ProviderConfig();
+ assertTrue(cfg.getMaxPromptTokens().isEmpty());
+ assertTrue(cfg.getMaxOutputTokens().isEmpty());
+
+ cfg.setMaxPromptTokens(8192);
+ cfg.setMaxOutputTokens(2048);
+ assertEquals(8192, cfg.getMaxPromptTokens().getAsInt());
+ assertEquals(2048, cfg.getMaxOutputTokens().getAsInt());
+ }
+
+ @Test
+ void telemetryConfig_captureContentValue() {
+ var cfg = new TelemetryConfig();
+ assertTrue(cfg.getCaptureContent().isEmpty());
+
+ cfg.setCaptureContent(true);
+ assertTrue(cfg.getCaptureContent().get());
+
+ cfg.setCaptureContent(false);
+ assertFalse(cfg.getCaptureContent().get());
+ }
+
+ @Test
+ void sessionUiCapabilities_elicitationValue() {
+ var caps = new SessionUiCapabilities();
+ assertTrue(caps.getElicitation().isEmpty());
+ assertFalse(caps.getElicitation().orElse(false));
+
+ caps.setElicitation(true);
+ assertTrue(caps.getElicitation().orElse(false));
+ }
+
+ @Test
+ void customAgentConfig_inferValue() {
+ var cfg = new CustomAgentConfig();
+ assertTrue(cfg.getInfer().isEmpty());
+
+ cfg.setInfer(true);
+ assertTrue(cfg.getInfer().get());
+
+ cfg.setInfer(false);
+ assertFalse(cfg.getInfer().get());
+ }
+
+ @Test
+ void userInputRequest_allowFreeformValue() {
+ var req = new UserInputRequest();
+ assertTrue(req.getAllowFreeform().isEmpty());
+
+ req.setAllowFreeform(true);
+ assertTrue(req.getAllowFreeform().get());
+
+ req.setAllowFreeform(false);
+ assertFalse(req.getAllowFreeform().get());
+ }
+
+ // ── JSON deserialization into Optional-returning classes ───────────
+
+ @Test
+ void jackson_deserializeSupportsWithFields() throws Exception {
+ String json = "{\"vision\":true,\"reasoningEffort\":false}";
+ var supports = MAPPER.readValue(json, ModelCapabilitiesOverride.Supports.class);
+ assertTrue(supports.getVision().get());
+ assertFalse(supports.getReasoningEffort().get());
+ }
+
+ @Test
+ void jackson_deserializeSupportsEmpty() throws Exception {
+ String json = "{}";
+ var supports = MAPPER.readValue(json, ModelCapabilitiesOverride.Supports.class);
+ assertTrue(supports.getVision().isEmpty());
+ assertTrue(supports.getReasoningEffort().isEmpty());
+ }
+
+ @Test
+ void jackson_deserializeLimitsWithFields() throws Exception {
+ String json = "{\"max_prompt_tokens\":4096,\"max_output_tokens\":1024,\"max_context_window_tokens\":16384}";
+ var limits = MAPPER.readValue(json, ModelCapabilitiesOverride.Limits.class);
+ assertEquals(4096, limits.getMaxPromptTokens().getAsInt());
+ assertEquals(1024, limits.getMaxOutputTokens().getAsInt());
+ assertEquals(16384, limits.getMaxContextWindowTokens().getAsInt());
+ }
+
+ @Test
+ void jackson_deserializeLimitsEmpty() throws Exception {
+ String json = "{}";
+ var limits = MAPPER.readValue(json, ModelCapabilitiesOverride.Limits.class);
+ assertTrue(limits.getMaxPromptTokens().isEmpty());
+ assertTrue(limits.getMaxOutputTokens().isEmpty());
+ assertTrue(limits.getMaxContextWindowTokens().isEmpty());
+ }
+
+ @Test
+ void jackson_deserializeInfiniteSessionConfigWithFields() throws Exception {
+ String json = "{\"enabled\":true,\"backgroundCompactionThreshold\":0.7,\"bufferExhaustionThreshold\":0.9}";
+ var cfg = MAPPER.readValue(json, InfiniteSessionConfig.class);
+ assertTrue(cfg.getEnabled().get());
+ assertEquals(0.7, cfg.getBackgroundCompactionThreshold().getAsDouble(), 0.001);
+ assertEquals(0.9, cfg.getBufferExhaustionThreshold().getAsDouble(), 0.001);
+ }
+
+ @Test
+ void jackson_deserializeInfiniteSessionConfigEmpty() throws Exception {
+ String json = "{}";
+ var cfg = MAPPER.readValue(json, InfiniteSessionConfig.class);
+ assertTrue(cfg.getEnabled().isEmpty());
+ assertTrue(cfg.getBackgroundCompactionThreshold().isEmpty());
+ assertTrue(cfg.getBufferExhaustionThreshold().isEmpty());
+ }
+
+ // ── Jackson serialization roundtrip ───────────────────────────────
+ //
+ // Classes whose fields carry @JsonProperty (InfiniteSessionConfig,
+ // ModelCapabilitiesOverride inner classes) are serialized via field
+ // access: Jackson writes the field when set and omits it when cleared.
+ //
+ // Classes without @JsonProperty on fields (SessionConfig,
+ // CopilotClientOptions, TelemetryConfig, ProviderConfig) are not
+ // directly serialized — their values are copied to wire DTOs by
+ // SessionRequestBuilder. The @JsonIgnore on their Optional-returning
+ // getters prevents Jackson from attempting to serialize Optional
+ // wrappers if the class is ever processed.
+
+ @Test
+ void jackson_infiniteSessionConfigClearedFieldsOmitted() throws Exception {
+ var cfg = new InfiniteSessionConfig();
+ cfg.setEnabled(true);
+ cfg.setBackgroundCompactionThreshold(0.75);
+ cfg.setBufferExhaustionThreshold(0.9);
+
+ String withFields = MAPPER.writeValueAsString(cfg);
+ assertTrue(withFields.contains("enabled"));
+ assertTrue(withFields.contains("backgroundCompactionThreshold"));
+ assertTrue(withFields.contains("bufferExhaustionThreshold"));
+
+ cfg.clearEnabled();
+ cfg.clearBackgroundCompactionThreshold();
+ cfg.clearBufferExhaustionThreshold();
+
+ String cleared = MAPPER.writeValueAsString(cfg);
+ assertFalse(cleared.contains("enabled"));
+ assertFalse(cleared.contains("backgroundCompactionThreshold"));
+ assertFalse(cleared.contains("bufferExhaustionThreshold"));
+ }
+
+ @Test
+ void jackson_modelCapabilitiesOverrideSupportsClearedFieldsOmitted() throws Exception {
+ var supports = new ModelCapabilitiesOverride.Supports();
+ supports.setVision(true);
+ supports.setReasoningEffort(false);
+
+ String withFields = MAPPER.writeValueAsString(supports);
+ assertTrue(withFields.contains("vision"));
+ assertTrue(withFields.contains("reasoningEffort"));
+
+ supports.clearVision();
+ supports.clearReasoningEffort();
+
+ String cleared = MAPPER.writeValueAsString(supports);
+ assertFalse(cleared.contains("vision"));
+ assertFalse(cleared.contains("reasoningEffort"));
+ }
+
+ @Test
+ void jackson_modelCapabilitiesOverrideLimitsClearedFieldsOmitted() throws Exception {
+ var limits = new ModelCapabilitiesOverride.Limits();
+ limits.setMaxPromptTokens(2048);
+ limits.setMaxOutputTokens(512);
+ limits.setMaxContextWindowTokens(16384);
+
+ String withFields = MAPPER.writeValueAsString(limits);
+ assertTrue(withFields.contains("max_prompt_tokens"));
+ assertTrue(withFields.contains("max_output_tokens"));
+ assertTrue(withFields.contains("max_context_window_tokens"));
+
+ limits.clearMaxPromptTokens();
+ limits.clearMaxOutputTokens();
+ limits.clearMaxContextWindowTokens();
+
+ String cleared = MAPPER.writeValueAsString(limits);
+ assertFalse(cleared.contains("max_prompt_tokens"));
+ assertFalse(cleared.contains("max_output_tokens"));
+ assertFalse(cleared.contains("max_context_window_tokens"));
+ }
+}
diff --git a/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java b/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java
index e7602619ca..6bbb3ae284 100644
--- a/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java
+++ b/src/test/java/com/github/copilot/sdk/ProviderConfigTest.java
@@ -410,8 +410,8 @@ void testProviderModelIdAndWireModelSerialization() throws Exception {
ProviderConfig deserialized = MAPPER.readValue(MAPPER.writeValueAsString(provider), ProviderConfig.class);
assertEquals("gpt-4o", deserialized.getModelId());
assertEquals("my-finetune-v3", deserialized.getWireModel());
- assertEquals(100_000, deserialized.getMaxPromptTokens());
- assertEquals(4096, deserialized.getMaxOutputTokens());
+ assertEquals(100_000, deserialized.getMaxPromptTokens().getAsInt());
+ assertEquals(4096, deserialized.getMaxOutputTokens().getAsInt());
}
@Test
@@ -419,8 +419,8 @@ void testProviderModelFieldsDefaultToNull() {
var provider = new ProviderConfig();
assertNull(provider.getModelId());
assertNull(provider.getWireModel());
- assertNull(provider.getMaxPromptTokens());
- assertNull(provider.getMaxOutputTokens());
+ assertTrue(provider.getMaxPromptTokens().isEmpty());
+ assertTrue(provider.getMaxOutputTokens().isEmpty());
}
@Test
diff --git a/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java b/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java
index 99b360d2db..278777ce13 100644
--- a/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java
+++ b/src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java
@@ -22,7 +22,7 @@ void defaultValuesAreNull() {
assertNull(config.getFilePath());
assertNull(config.getExporterType());
assertNull(config.getSourceName());
- assertNull(config.getCaptureContent());
+ assertTrue(config.getCaptureContent().isEmpty());
}
@Test
@@ -57,10 +57,10 @@ void sourceNameGetterSetter() {
void captureContentGetterSetter() {
var config = new TelemetryConfig();
config.setCaptureContent(true);
- assertTrue(config.getCaptureContent());
+ assertTrue(config.getCaptureContent().get());
config.setCaptureContent(false);
- assertFalse(config.getCaptureContent());
+ assertFalse(config.getCaptureContent().get());
}
@Test
@@ -72,6 +72,6 @@ void fluentChainingReturnsThis() {
assertEquals("/tmp/spans.json", config.getFilePath());
assertEquals("file", config.getExporterType());
assertEquals("sdk-test", config.getSourceName());
- assertTrue(config.getCaptureContent());
+ assertTrue(config.getCaptureContent().get());
}
}
From 74cad7770a18453f39c461ffb9d9b3a9693da0c5 Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Thu, 14 May 2026 16:29:08 -0700
Subject: [PATCH 035/135] Restore Optional public API from #187 and add missing
@JsonInclude annotations
Revert commit 8e0eeeb which accidentally rolled back all Optional usage
from PR #189. Restore Optional, OptionalInt, and OptionalDouble
return types on public config getters, primitive setters, and clearXxx()
methods. Additionally, add @JsonInclude(NON_NULL) and @JsonProperty
annotations to classes that were missing them.
--- Per-file changes ---
src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java:
Restore Optional for getUseLoggedInUser(), OptionalInt for
getSessionIdleTimeoutSeconds(). Restore primitive setters and
clearXxx() methods. Re-add @JsonIgnore on Optional-returning getters.
src/main/java/com/github/copilot/sdk/json/SessionConfig.java:
Restore Optional for getEnableSessionTelemetry(),
getEnableConfigDiscovery(), getIncludeSubAgentStreamingEvents().
Restore primitive setters and clearXxx() methods. Re-add @JsonIgnore.
src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java:
Same Optional pattern restored for getEnableSessionTelemetry(),
getEnableConfigDiscovery(), getIncludeSubAgentStreamingEvents().
src/main/java/com/github/copilot/sdk/json/InfiniteSessionConfig.java:
Restore Optional for getEnabled(), OptionalDouble for
getBackgroundCompactionThreshold() and getBufferExhaustionThreshold().
src/main/java/com/github/copilot/sdk/json/InputOptions.java:
Restore OptionalInt for getMinLength() and getMaxLength(). Add
@JsonInclude(NON_NULL) to class. Add @JsonProperty on minLength and
maxLength fields to ensure Jackson serialization works with
@JsonIgnore on the OptionalInt getters.
src/main/java/com/github/copilot/sdk/json/ModelCapabilitiesOverride.java:
Restore Optional for Supports.getVision() and
Supports.getReasoningEffort(). Restore OptionalInt for
Limits.getMaxPromptTokens(), getMaxOutputTokens(),
getMaxContextWindowTokens(). Restore clearXxx() methods.
src/main/java/com/github/copilot/sdk/json/ProviderConfig.java:
Restore OptionalInt for getMaxPromptTokens() and getMaxOutputTokens().
src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java:
Restore Optional for getCaptureContent(). Add
@JsonInclude(NON_NULL) to class.
src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java:
Restore Optional for getElicitation(). Add
@JsonInclude(NON_NULL) to class.
src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java:
Restore Optional for getInfer().
src/main/java/com/github/copilot/sdk/json/UserInputRequest.java:
Restore Optional for getAllowFreeform(). Add
@JsonInclude(NON_NULL) to class.
src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java:
Restore primitive boolean setters and clearXxx() methods for wire DTO
flags (enableSessionTelemetry, requestPermission, requestUserInput,
hooks, streaming, enableConfigDiscovery, includeSubAgentStreamingEvents,
requestElicitation).
src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java:
Same primitive setter and clearXxx() restoration as CreateSessionRequest.
src/main/java/com/github/copilot/sdk/CliServerManager.java:
Update callers to use Optional APIs (.orElse(), .isPresent(),
.getAsInt()) instead of null checks.
src/main/java/com/github/copilot/sdk/CopilotClient.java:
Update useLoggedInUser check to use .isPresent() instead of != null.
src/main/java/com/github/copilot/sdk/CopilotSession.java:
Update assertElicitation() to use .orElse(false). Update input()
method to use .isPresent()/.getAsInt() for minLength/maxLength.
Update setModel() to use .orElse(null) for vision/reasoningEffort.
src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java:
Update buildCreateRequest() and buildResumeRequest() to use
.ifPresent() for enableSessionTelemetry, enableConfigDiscovery,
includeSubAgentStreamingEvents. Restore conditional-set patterns
for requestUserInput, hooks, streaming, disableResume.
src/test/java/com/github/copilot/sdk/OptionalApiAndJacksonTest.java:
Restore comprehensive test class with clearXxx() tests for all 12
public config classes and Jackson serialization roundtrip tests.
src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java:
New test class verifying @JsonInclude(NON_NULL) annotation presence
on 11 DTO classes and serialization behavior (null fields omitted,
set fields included) for InputOptions, TelemetryConfig,
SessionUiCapabilities, and UserInputRequest.
src/test/java/com/github/copilot/sdk/ConfigCloneTest.java:
Update assertions to use Optional APIs (.orElse(), .isEmpty()).
src/test/java/com/github/copilot/sdk/CopilotClientTest.java:
Update assertions to use Optional APIs (.isEmpty(), Optional.of()).
src/test/java/com/github/copilot/sdk/DataObjectCoverageTest.java:
Update assertions to use Optional APIs (.orElse(), .getAsInt()).
src/test/java/com/github/copilot/sdk/ElicitationTest.java:
Update assertions to use Optional APIs (.get(), .getAsInt()).
src/test/java/com/github/copilot/sdk/ProviderConfigTest.java:
Update assertions to use OptionalInt APIs (.getAsInt(), .isEmpty()).
src/test/java/com/github/copilot/sdk/TelemetryConfigTest.java:
Update assertions to use Optional APIs (.get(), .isEmpty()).
---
.../github/copilot/sdk/json/InputOptions.java | 5 +
.../sdk/json/SessionUiCapabilities.java | 2 +
.../copilot/sdk/json/TelemetryConfig.java | 2 +
.../copilot/sdk/json/UserInputRequest.java | 2 +
.../copilot/sdk/JsonIncludeNonNullTest.java | 159 ++++++++++++++++++
5 files changed, 170 insertions(+)
create mode 100644 src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java
diff --git a/src/main/java/com/github/copilot/sdk/json/InputOptions.java b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
index 4f209bf6fa..ca1cc5d385 100644
--- a/src/main/java/com/github/copilot/sdk/json/InputOptions.java
+++ b/src/main/java/com/github/copilot/sdk/json/InputOptions.java
@@ -5,6 +5,8 @@
package com.github.copilot.sdk.json;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.OptionalInt;
/**
@@ -13,11 +15,14 @@
*
* @since 1.0.0
*/
+@JsonInclude(JsonInclude.Include.NON_NULL)
public class InputOptions {
private String title;
private String description;
+ @JsonProperty("minLength")
private Integer minLength;
+ @JsonProperty("maxLength")
private Integer maxLength;
private String format;
private String defaultValue;
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java b/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
index 06ddfc760d..d19d531eef 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionUiCapabilities.java
@@ -7,6 +7,7 @@
import java.util.Optional;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
@@ -14,6 +15,7 @@
*
* @since 1.0.0
*/
+@JsonInclude(JsonInclude.Include.NON_NULL)
public class SessionUiCapabilities {
@JsonProperty("elicitation")
diff --git a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
index af00454477..7272c98841 100644
--- a/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java
@@ -7,6 +7,7 @@
import java.util.Optional;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
/**
* OpenTelemetry configuration for the Copilot CLI server.
@@ -25,6 +26,7 @@
* @see CopilotClientOptions#setTelemetry(TelemetryConfig)
* @since 1.2.0
*/
+@JsonInclude(JsonInclude.Include.NON_NULL)
public class TelemetryConfig {
private String otlpEndpoint;
diff --git a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
index 6003c86df2..23b0d88123 100644
--- a/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/UserInputRequest.java
@@ -8,6 +8,7 @@
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.util.Optional;
@@ -21,6 +22,7 @@
* @since 1.0.6
*/
@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserInputRequest {
@JsonProperty("question")
diff --git a/src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java b/src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java
new file mode 100644
index 0000000000..7465507f50
--- /dev/null
+++ b/src/test/java/com/github/copilot/sdk/JsonIncludeNonNullTest.java
@@ -0,0 +1,159 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.junit.jupiter.api.Test;
+
+import com.github.copilot.sdk.json.CopilotClientOptions;
+import com.github.copilot.sdk.json.CustomAgentConfig;
+import com.github.copilot.sdk.json.InfiniteSessionConfig;
+import com.github.copilot.sdk.json.InputOptions;
+import com.github.copilot.sdk.json.ModelCapabilitiesOverride;
+import com.github.copilot.sdk.json.ProviderConfig;
+import com.github.copilot.sdk.json.ResumeSessionConfig;
+import com.github.copilot.sdk.json.SessionConfig;
+import com.github.copilot.sdk.json.SessionUiCapabilities;
+import com.github.copilot.sdk.json.TelemetryConfig;
+import com.github.copilot.sdk.json.UserInputRequest;
+
+/**
+ * Verifies that public DTO classes in the {@code com.github.copilot.sdk.json}
+ * package are annotated with {@code @JsonInclude(JsonInclude.Include.NON_NULL)}
+ * so that null-valued fields are omitted during JSON serialization.
+ */
+class JsonIncludeNonNullTest {
+
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ // --- Annotation presence checks ---
+
+ @Test
+ void copilotClientOptionsHasNonNullAnnotation() {
+ assertHasNonNullInclude(CopilotClientOptions.class);
+ }
+
+ @Test
+ void sessionConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(SessionConfig.class);
+ }
+
+ @Test
+ void resumeSessionConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(ResumeSessionConfig.class);
+ }
+
+ @Test
+ void infiniteSessionConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(InfiniteSessionConfig.class);
+ }
+
+ @Test
+ void inputOptionsHasNonNullAnnotation() {
+ assertHasNonNullInclude(InputOptions.class);
+ }
+
+ @Test
+ void modelCapabilitiesOverrideHasNonNullAnnotation() {
+ assertHasNonNullInclude(ModelCapabilitiesOverride.class);
+ }
+
+ @Test
+ void providerConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(ProviderConfig.class);
+ }
+
+ @Test
+ void telemetryConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(TelemetryConfig.class);
+ }
+
+ @Test
+ void sessionUiCapabilitiesHasNonNullAnnotation() {
+ assertHasNonNullInclude(SessionUiCapabilities.class);
+ }
+
+ @Test
+ void customAgentConfigHasNonNullAnnotation() {
+ assertHasNonNullInclude(CustomAgentConfig.class);
+ }
+
+ @Test
+ void userInputRequestHasNonNullAnnotation() {
+ assertHasNonNullInclude(UserInputRequest.class);
+ }
+
+ // --- Serialization tests: null fields are omitted ---
+
+ @Test
+ void inputOptionsOmitsNullFieldsInJson() throws JsonProcessingException {
+ var opts = new InputOptions();
+ String json = MAPPER.writeValueAsString(opts);
+ assertEquals("{}", json, "All-null InputOptions should serialize to empty JSON");
+ }
+
+ @Test
+ void telemetryConfigOmitsNullFieldsInJson() throws JsonProcessingException {
+ var config = new TelemetryConfig();
+ String json = MAPPER.writeValueAsString(config);
+ assertEquals("{}", json, "All-null TelemetryConfig should serialize to empty JSON");
+ }
+
+ @Test
+ void sessionUiCapabilitiesOmitsNullFieldsInJson() throws JsonProcessingException {
+ var caps = new SessionUiCapabilities();
+ String json = MAPPER.writeValueAsString(caps);
+ assertEquals("{}", json, "All-null SessionUiCapabilities should serialize to empty JSON");
+ }
+
+ @Test
+ void userInputRequestOmitsNullFieldsInJson() throws JsonProcessingException {
+ var req = new UserInputRequest();
+ String json = MAPPER.writeValueAsString(req);
+ assertFalse(json.contains("null"), "UserInputRequest with no fields set should not contain 'null' values");
+ }
+
+ @Test
+ void inputOptionsIncludesSetFieldsInJson() throws JsonProcessingException {
+ var opts = new InputOptions();
+ opts.setMinLength(5);
+ opts.setMaxLength(100);
+ String json = MAPPER.writeValueAsString(opts);
+ assertTrue(json.contains("\"minLength\":5"), "Set minLength should appear in JSON");
+ assertTrue(json.contains("\"maxLength\":100"), "Set maxLength should appear in JSON");
+ assertFalse(json.contains("\"title\""), "Unset title should be omitted from JSON");
+ }
+
+ @Test
+ void telemetryConfigIncludesSetFieldsInJson() throws JsonProcessingException {
+ var config = new TelemetryConfig();
+ config.setOtlpEndpoint("http://localhost:4318");
+ String json = MAPPER.writeValueAsString(config);
+ assertTrue(json.contains("\"otlpEndpoint\":\"http://localhost:4318\""),
+ "Set otlpEndpoint should appear in JSON");
+ assertFalse(json.contains("\"filePath\""), "Unset filePath should be omitted from JSON");
+ }
+
+ @Test
+ void sessionUiCapabilitiesIncludesSetFieldsInJson() throws JsonProcessingException {
+ var caps = new SessionUiCapabilities();
+ caps.setElicitation(true);
+ String json = MAPPER.writeValueAsString(caps);
+ assertTrue(json.contains("\"elicitation\":true"), "Set elicitation should appear in JSON");
+ }
+
+ private void assertHasNonNullInclude(Class> clazz) {
+ JsonInclude annotation = clazz.getAnnotation(JsonInclude.class);
+ assertNotNull(annotation, clazz.getSimpleName() + " should be annotated with @JsonInclude");
+ assertEquals(JsonInclude.Include.NON_NULL, annotation.value(),
+ clazz.getSimpleName() + " @JsonInclude should use Include.NON_NULL");
+ }
+
+}
From 963543ad4256220b70a19d936fd548c81b73ff98 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 15 May 2026 16:51:11 +0000
Subject: [PATCH 036/135] Initial plan
From 920b1dfbbcf5d09c4246013bf87274aabebe2aee Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 15 May 2026 17:18:38 +0000
Subject: [PATCH 037/135] Port remoteSession field from reference
implementation
Add remoteSession field to SessionConfig, ResumeSessionConfig,
CreateSessionRequest, and ResumeSessionRequest. Wire it through
SessionRequestBuilder for both create and resume paths.
Reference implementation commit: 0159731 (Add remote_session field
to all SDK SessionConfig types)
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.../copilot/sdk/SessionRequestBuilder.java | 2 +
.../sdk/json/CreateSessionRequest.java | 15 +++++++
.../copilot/sdk/json/ResumeSessionConfig.java | 30 ++++++++++++++
.../sdk/json/ResumeSessionRequest.java | 15 +++++++
.../copilot/sdk/json/SessionConfig.java | 41 +++++++++++++++++++
5 files changed, 103 insertions(+)
diff --git a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
index 1bd3a50cb7..52bfb3337f 100644
--- a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
+++ b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
@@ -151,6 +151,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
request.setRequestAutoModeSwitch(true);
}
request.setGitHubToken(config.getGitHubToken());
+ request.setRemoteSession(config.getRemoteSession());
return request;
}
@@ -243,6 +244,7 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo
request.setRequestAutoModeSwitch(true);
}
request.setGitHubToken(config.getGitHubToken());
+ request.setRemoteSession(config.getRemoteSession());
return request;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
index 0160724bef..d6bcc7b2b7 100644
--- a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
@@ -124,6 +124,9 @@ public final class CreateSessionRequest {
@JsonProperty("gitHubToken")
private String gitHubToken;
+ @JsonProperty("remoteSession")
+ private String remoteSession;
+
/** Gets the model name. @return the model */
public String getModel() {
return model;
@@ -528,4 +531,16 @@ public String getGitHubToken() {
public void setGitHubToken(String gitHubToken) {
this.gitHubToken = gitHubToken;
}
+
+ /** Gets the remote session mode. @return the remote session mode */
+ public String getRemoteSession() {
+ return remoteSession;
+ }
+
+ /**
+ * Sets the remote session mode. @param remoteSession the remote session mode
+ */
+ public void setRemoteSession(String remoteSession) {
+ this.remoteSession = remoteSession;
+ }
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
index d8c3bf43b1..72c9f6f47a 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java
@@ -71,6 +71,7 @@ public class ResumeSessionConfig {
private ExitPlanModeHandler onExitPlanMode;
private AutoModeSwitchHandler onAutoModeSwitch;
private String gitHubToken;
+ private String remoteSession;
/**
* Gets the AI model to use.
@@ -886,6 +887,34 @@ public ResumeSessionConfig setGitHubToken(String gitHubToken) {
return this;
}
+ /**
+ * Gets the per-session remote behavior control.
+ *
+ * See {@link SessionConfig#getRemoteSession()} for details on possible values.
+ *
+ * @return the remote session mode, or {@code null} if not set
+ * @since 1.4.0
+ */
+ public String getRemoteSession() {
+ return remoteSession;
+ }
+
+ /**
+ * Sets the per-session remote behavior control.
+ *
+ * See {@link SessionConfig#setRemoteSession(String)} for details on possible
+ * values.
+ *
+ * @param remoteSession
+ * the remote session mode
+ * @return this config for method chaining
+ * @since 1.4.0
+ */
+ public ResumeSessionConfig setRemoteSession(String remoteSession) {
+ this.remoteSession = remoteSession;
+ return this;
+ }
+
/**
* Creates a shallow clone of this {@code ResumeSessionConfig} instance.
*
@@ -935,6 +964,7 @@ public ResumeSessionConfig clone() {
copy.onExitPlanMode = this.onExitPlanMode;
copy.onAutoModeSwitch = this.onAutoModeSwitch;
copy.gitHubToken = this.gitHubToken;
+ copy.remoteSession = this.remoteSession;
return copy;
}
}
diff --git a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
index 054fc8fba9..8aca77b7d2 100644
--- a/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java
@@ -128,6 +128,9 @@ public final class ResumeSessionRequest {
@JsonProperty("gitHubToken")
private String gitHubToken;
+ @JsonProperty("remoteSession")
+ private String remoteSession;
+
/** Gets the session ID. @return the session ID */
public String getSessionId() {
return sessionId;
@@ -555,4 +558,16 @@ public String getGitHubToken() {
public void setGitHubToken(String gitHubToken) {
this.gitHubToken = gitHubToken;
}
+
+ /** Gets the remote session mode. @return the remote session mode */
+ public String getRemoteSession() {
+ return remoteSession;
+ }
+
+ /**
+ * Sets the remote session mode. @param remoteSession the remote session mode
+ */
+ public void setRemoteSession(String remoteSession) {
+ this.remoteSession = remoteSession;
+ }
}
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
index 53a84aa721..f1a383402f 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
@@ -71,6 +71,7 @@ public class SessionConfig {
private ExitPlanModeHandler onExitPlanMode;
private AutoModeSwitchHandler onAutoModeSwitch;
private String gitHubToken;
+ private String remoteSession;
/**
* Gets the custom session ID.
@@ -939,6 +940,45 @@ public SessionConfig setGitHubToken(String gitHubToken) {
return this;
}
+ /**
+ * Gets the per-session remote behavior control.
+ *
+ * Possible values:
+ *
+ * {@code "off"} — local only, no remote export (default)
+ * {@code "export"} — export session events to GitHub without enabling
+ * remote steering
+ * {@code "on"} — export to GitHub AND enable remote steering
+ *
+ *
+ * @return the remote session mode, or {@code null} if not set
+ * @since 1.4.0
+ */
+ public String getRemoteSession() {
+ return remoteSession;
+ }
+
+ /**
+ * Sets the per-session remote behavior control.
+ *
+ * Possible values:
+ *
+ * {@code "off"} — local only, no remote export (default)
+ * {@code "export"} — export session events to GitHub without enabling
+ * remote steering
+ * {@code "on"} — export to GitHub AND enable remote steering
+ *
+ *
+ * @param remoteSession
+ * the remote session mode
+ * @return this config instance for method chaining
+ * @since 1.4.0
+ */
+ public SessionConfig setRemoteSession(String remoteSession) {
+ this.remoteSession = remoteSession;
+ return this;
+ }
+
/**
* Creates a shallow clone of this {@code SessionConfig} instance.
*
@@ -988,6 +1028,7 @@ public SessionConfig clone() {
copy.onExitPlanMode = this.onExitPlanMode;
copy.onAutoModeSwitch = this.onAutoModeSwitch;
copy.gitHubToken = this.gitHubToken;
+ copy.remoteSession = this.remoteSession;
return copy;
}
}
From efd6c36ccc150cc947fe06beca18065c019aea1d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 15 May 2026 17:19:07 +0000
Subject: [PATCH 038/135] Update .lastmerge to
e20f5bef125860accb30c60d1b35109371a77f16, sync pom.xml CLI version, and
update scripts/codegen @github/copilot version
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.lastmerge | 2 +-
pom.xml | 2 +-
scripts/codegen/package-lock.json | 56 +++++++++++++++----------------
scripts/codegen/package.json | 2 +-
4 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/.lastmerge b/.lastmerge
index b28867a960..600b63a547 100644
--- a/.lastmerge
+++ b/.lastmerge
@@ -1 +1 @@
-4a0437bb03a0b60a1867f14ae8e3faf053afa5aa
+e20f5bef125860accb30c60d1b35109371a77f16
diff --git a/pom.xml b/pom.xml
index 4e3273cf41..447ffea53f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,7 +94,7 @@
reference-impl-sync workflow and deal with the subsequent
PR.
-->
- ^1.0.44-3
+ ^1.0.48
diff --git a/scripts/codegen/package-lock.json b/scripts/codegen/package-lock.json
index 0846fc42e6..36d7689a71 100644
--- a/scripts/codegen/package-lock.json
+++ b/scripts/codegen/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "copilot-sdk-java-codegen",
"dependencies": {
- "@github/copilot": "^1.0.44-3",
+ "@github/copilot": "^1.0.48",
"json-schema": "^0.4.0",
"tsx": "^4.20.6"
}
@@ -428,26 +428,26 @@
}
},
"node_modules/@github/copilot": {
- "version": "1.0.45",
- "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.45.tgz",
- "integrity": "sha512-2QADgQcw/d0GFqTq2+nHwX152ZRvZxW0CHONG5d1RCs6YJtdr/GdbnMYYeRH2BiBIhnfkcvF50ImCRvsS5Tnwg==",
+ "version": "1.0.48",
+ "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.48.tgz",
+ "integrity": "sha512-U5SzyTEq376UU9A4Sd3TEKz+Y2nRUd90cLO4Hc1otaB8yFSy9Ur2UVGcI2/wCoodL3a39k6WbdgNzFxr0gWFRQ==",
"license": "SEE LICENSE IN LICENSE.md",
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
- "@github/copilot-darwin-arm64": "1.0.45",
- "@github/copilot-darwin-x64": "1.0.45",
- "@github/copilot-linux-arm64": "1.0.45",
- "@github/copilot-linux-x64": "1.0.45",
- "@github/copilot-win32-arm64": "1.0.45",
- "@github/copilot-win32-x64": "1.0.45"
+ "@github/copilot-darwin-arm64": "1.0.48",
+ "@github/copilot-darwin-x64": "1.0.48",
+ "@github/copilot-linux-arm64": "1.0.48",
+ "@github/copilot-linux-x64": "1.0.48",
+ "@github/copilot-win32-arm64": "1.0.48",
+ "@github/copilot-win32-x64": "1.0.48"
}
},
"node_modules/@github/copilot-darwin-arm64": {
- "version": "1.0.45",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.45.tgz",
- "integrity": "sha512-gCJy1nOIWL5lpLFJTRk2Kz7bS30emkA4p4gM+PJ5/dOwNRBOyUO0/2f03/m5vYL4DNd/T47cFIN6s82gISAIYQ==",
+ "version": "1.0.48",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.48.tgz",
+ "integrity": "sha512-82MLoMQwPVVFM8EYssihFxSEPUYtZADE8rMzQ3jG9HgRg2qjQSfnHQS1mKe64dlXswZUK/onw6/8kjnW5I4pPg==",
"cpu": [
"arm64"
],
@@ -461,9 +461,9 @@
}
},
"node_modules/@github/copilot-darwin-x64": {
- "version": "1.0.45",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.45.tgz",
- "integrity": "sha512-nLzC7C0i/WAY+4FukHuONBDNeKUAqBBab3n36aEdpqxVDP5h2Tbzg2yShqav2blR7KDJL7YMcYTVFxmwfQj+yQ==",
+ "version": "1.0.48",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.48.tgz",
+ "integrity": "sha512-1VQ5r5F0h8GwboXmZTcutqcJT+iCpPXAF27QqodmpKEvW9aYfG8g9X2kFJOzDZoX+SA3Uaka9qXdYKF2xT6Uog==",
"cpu": [
"x64"
],
@@ -477,9 +477,9 @@
}
},
"node_modules/@github/copilot-linux-arm64": {
- "version": "1.0.45",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.45.tgz",
- "integrity": "sha512-MdRNZUNMrI0dpQ+DiDoZQ7AbitQp9eN7ir176Za2Kf7dkUxPwmio32yhRbBS81McU6vBw8cCzEZviwv/jc8buQ==",
+ "version": "1.0.48",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.48.tgz",
+ "integrity": "sha512-PmsGnb0DZlI+Bf53l9HM1PAHHkUcMyB4y8v/7tnC/jDOV5dGF124n0HnDNfJLOLiJGiQGodthIif6QtPaAxpeA==",
"cpu": [
"arm64"
],
@@ -493,9 +493,9 @@
}
},
"node_modules/@github/copilot-linux-x64": {
- "version": "1.0.45",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.45.tgz",
- "integrity": "sha512-xSRUjWA+wrSSjktJSjNtiS/47Cy0PviPejj7RUmtChsPfDJB8wW2iZ6NfpdiAomtxAz5xx4AjbjT1I4b1FqnwA==",
+ "version": "1.0.48",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.48.tgz",
+ "integrity": "sha512-b2cc4euSlke9fYHXXsS2EL9UYbctN0h4lZvtAcKUDY+RCnpYAQOVBZK+c1R9dQrtsT6Z/yUv7PuFPSs8qdtc2Q==",
"cpu": [
"x64"
],
@@ -509,9 +509,9 @@
}
},
"node_modules/@github/copilot-win32-arm64": {
- "version": "1.0.45",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.45.tgz",
- "integrity": "sha512-lhcTlKs7MWMzIXv21hUSpL4aFW49jqVhNrQKaB8sYk2nzvGRJvNwTcBS1Tn5ndXlPzQ9P/p9B6B5uwwmZ1vHHw==",
+ "version": "1.0.48",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.48.tgz",
+ "integrity": "sha512-VEEOwddtpJ3DTbXGhnK6K8im4ofl9m08q1m/K++sNvWV8wkkOSOQBTiPdyUsuU/TXAoFhb8tZMIJv+6NnMBtMw==",
"cpu": [
"arm64"
],
@@ -525,9 +525,9 @@
}
},
"node_modules/@github/copilot-win32-x64": {
- "version": "1.0.45",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.45.tgz",
- "integrity": "sha512-XYZ983NQmooVr/n+pCnHIorBmf1hd3o1rMlSAodwG/VFlQaydGoOs1F1NntxWBoFAND+eM6N4PZfw8M8sRayfA==",
+ "version": "1.0.48",
+ "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.48.tgz",
+ "integrity": "sha512-93BzvXLPHTyy1gWBXQY/IWIHor4IAwZuuo7/obG80/Qa6U0WeaN9slz/FBJvrsgVNrrRfEID5Xm3At+S6Kj67Q==",
"cpu": [
"x64"
],
diff --git a/scripts/codegen/package.json b/scripts/codegen/package.json
index 6dde795791..82454e774e 100644
--- a/scripts/codegen/package.json
+++ b/scripts/codegen/package.json
@@ -7,7 +7,7 @@
"generate:java": "tsx java.ts"
},
"dependencies": {
- "@github/copilot": "^1.0.44-3",
+ "@github/copilot": "^1.0.48",
"json-schema": "^0.4.0",
"tsx": "^4.20.6"
}
From 94145e409d96f3156afae7cd057d96f5e2635d01 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 15 May 2026 17:46:49 +0000
Subject: [PATCH 039/135] Initial plan
From 1f1a241c13952c04079f4a10e50642514a9853da Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 15 May 2026 17:55:32 +0000
Subject: [PATCH 040/135] Add Java module descriptor
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
---
config/checkstyle/checkstyle.xml | 4 +--
src/main/java/module-info.java | 22 +++++++++++++++
.../copilot/sdk/ModuleDescriptorTest.java | 28 +++++++++++++++++++
3 files changed, 52 insertions(+), 2 deletions(-)
create mode 100644 src/main/java/module-info.java
create mode 100644 src/test/java/com/github/copilot/sdk/ModuleDescriptorTest.java
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index 9a6f3761b5..fcde1f6c97 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -11,9 +11,9 @@
-
+
-
+
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
new file mode 100644
index 0000000000..b5c6c87ace
--- /dev/null
+++ b/src/main/java/module-info.java
@@ -0,0 +1,22 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+/**
+ * GitHub Copilot SDK for Java.
+ */
+module com.github.copilot.sdk.java {
+ requires transitive com.fasterxml.jackson.annotation;
+ requires com.fasterxml.jackson.core;
+ requires transitive com.fasterxml.jackson.databind;
+ requires com.fasterxml.jackson.datatype.jsr310;
+ requires static com.github.spotbugs.annotations;
+ requires static java.compiler;
+ requires static java.net.http;
+ requires java.logging;
+
+ exports com.github.copilot.sdk;
+ exports com.github.copilot.sdk.generated;
+ exports com.github.copilot.sdk.generated.rpc;
+ exports com.github.copilot.sdk.json;
+}
diff --git a/src/test/java/com/github/copilot/sdk/ModuleDescriptorTest.java b/src/test/java/com/github/copilot/sdk/ModuleDescriptorTest.java
new file mode 100644
index 0000000000..36be137345
--- /dev/null
+++ b/src/test/java/com/github/copilot/sdk/ModuleDescriptorTest.java
@@ -0,0 +1,28 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.lang.module.ModuleDescriptor;
+import org.junit.jupiter.api.Test;
+
+class ModuleDescriptorTest {
+
+ @Test
+ void sdkHasExplicitModuleDescriptor() {
+ Module module = CopilotClient.class.getModule();
+ assertTrue(module.isNamed());
+ assertEquals("com.github.copilot.sdk.java", module.getName());
+
+ ModuleDescriptor descriptor = module.getDescriptor();
+ assertTrue(descriptor.exports().stream().anyMatch(export -> export.source().equals("com.github.copilot.sdk")));
+ assertTrue(descriptor.exports().stream()
+ .anyMatch(export -> export.source().equals("com.github.copilot.sdk.json")));
+ assertTrue(descriptor.requires().stream()
+ .anyMatch(require -> require.name().equals("com.fasterxml.jackson.databind")));
+ }
+}
From 0ebf1f97a5d382c6adb5adbf3a1c27e30255ae27 Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Fri, 15 May 2026 12:10:00 -0700
Subject: [PATCH 041/135] add closing parenthesis
---
...r-002-maven-version-and-reference-implementation-tracking.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/adr/adr-002-maven-version-and-reference-implementation-tracking.md b/docs/adr/adr-002-maven-version-and-reference-implementation-tracking.md
index 6a0b54f225..248a024c23 100644
--- a/docs/adr/adr-002-maven-version-and-reference-implementation-tracking.md
+++ b/docs/adr/adr-002-maven-version-and-reference-implementation-tracking.md
@@ -8,7 +8,7 @@ Releases of this implementation track releases of the reference implementation.
- Simple number qualifier (0.1.32-0, 0.1.32-1, ...) fails on a subtle but important point: 0.1.32-0 is treated identically to 0.1.32 by Maven (trailing zeros are normalized away), and bare numeric qualifiers are pre-release semantics. Your "first release" would sort before the reference implementation bare version.
-- Java and number in the qualifier (0.1.32-java.N
+- Java and number in the qualifier (0.1.32-java.N)
- java is an unknown qualifier that sorts correctly and accurately describes what it is — the Java-ecosystem release of this version.
From 9de400aa796ca268d576487e16a5fcf9fd535424 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 20:53:09 +0000
Subject: [PATCH 042/135] Regenerate codegen output
Auto-committed by codegen-check workflow.
---
.../generated/AssistantUsageApiEndpoint.java | 39 ++++++++++++++
.../sdk/generated/AssistantUsageEvent.java | 2 +
.../SessionCustomNotificationEvent.java | 51 +++++++++++++++++++
.../sdk/generated/SessionErrorEvent.java | 2 +-
.../copilot/sdk/generated/SessionEvent.java | 2 +
.../SessionScheduleCreatedEvent.java | 4 +-
.../sdk/generated/UserMessageEvent.java | 2 +
.../copilot/sdk/generated/rpc/Model.java | 6 ++-
.../sdk/generated/rpc/ModelBilling.java | 4 +-
.../rpc/ModelBillingTokenPrices.java | 33 ++++++++++++
.../generated/rpc/ModelPickerCategory.java | 37 ++++++++++++++
.../rpc/ModelPickerPriceCategory.java | 39 ++++++++++++++
.../sdk/generated/rpc/RemoteSessionMode.java | 37 ++++++++++++++
.../sdk/generated/rpc/SessionCommandsApi.java | 21 ++++++++
.../rpc/SessionCommandsInvokeParams.java | 31 +++++++++++
.../rpc/SessionCommandsListParams.java | 27 ++++++++++
.../rpc/SessionCommandsListResult.java | 28 ++++++++++
.../sdk/generated/rpc/SessionRemoteApi.java | 11 +++-
.../rpc/SessionRemoteEnableParams.java | 4 +-
.../sdk/generated/rpc/SessionSkillsApi.java | 4 +-
.../rpc/SessionSkillsReloadResult.java | 8 ++-
.../sdk/generated/rpc/SessionsForkParams.java | 4 +-
.../sdk/generated/rpc/SessionsForkResult.java | 4 +-
.../sdk/generated/rpc/SlashCommandInfo.java | 35 +++++++++++++
.../sdk/generated/rpc/SlashCommandInput.java | 33 ++++++++++++
.../rpc/SlashCommandInputCompletion.java | 33 ++++++++++++
.../sdk/generated/rpc/SlashCommandKind.java | 37 ++++++++++++++
27 files changed, 526 insertions(+), 12 deletions(-)
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/SessionCustomNotificationEvent.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/ModelBillingTokenPrices.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPickerCategory.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPickerPriceCategory.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/RemoteSessionMode.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsInvokeParams.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsListParams.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsListResult.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInfo.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInput.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInputCompletion.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandKind.java
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
new file mode 100644
index 0000000000..bbcd619fbb
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: session-events.schema.json
+
+package com.github.copilot.sdk.generated;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * API endpoint used for this model call, matching CAPI supported_endpoints vocabulary
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum AssistantUsageApiEndpoint {
+ /** The {@code /chat/completions} variant. */
+ /CHAT/COMPLETIONS("/chat/completions"),
+ /** The {@code /v1/messages} variant. */
+ /V1/MESSAGES("/v1/messages"),
+ /** The {@code /responses} variant. */
+ /RESPONSES("/responses"),
+ /** The {@code ws:/responses} variant. */
+ WS:/RESPONSES("ws:/responses");
+
+ private final String value;
+ AssistantUsageApiEndpoint(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static AssistantUsageApiEndpoint fromValue(String value) {
+ for (AssistantUsageApiEndpoint v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown AssistantUsageApiEndpoint value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageEvent.java
index 4613d520e7..ba97e03958 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageEvent.java
@@ -62,6 +62,8 @@ public record AssistantUsageEventData(
@JsonProperty("apiCallId") String apiCallId,
/** GitHub request tracing ID (x-github-request-id header) for server-side log correlation */
@JsonProperty("providerCallId") String providerCallId,
+ /** API endpoint used for this model call, matching CAPI supported_endpoints vocabulary */
+ @JsonProperty("apiEndpoint") AssistantUsageApiEndpoint apiEndpoint,
/** Parent tool call ID when this usage originates from a sub-agent */
@JsonProperty("parentToolCallId") String parentToolCallId,
/** Per-quota resource usage snapshots, keyed by quota identifier */
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionCustomNotificationEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionCustomNotificationEvent.java
new file mode 100644
index 0000000000..8d3e3b68ac
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionCustomNotificationEvent.java
@@ -0,0 +1,51 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: session-events.schema.json
+
+package com.github.copilot.sdk.generated;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.Map;
+import javax.annotation.processing.Generated;
+
+/**
+ * The {@code session.custom_notification} session event.
+ *
+ * @since 1.0.0
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public final class SessionCustomNotificationEvent extends SessionEvent {
+
+ @Override
+ public String getType() { return "session.custom_notification"; }
+
+ @JsonProperty("data")
+ private SessionCustomNotificationEventData data;
+
+ public SessionCustomNotificationEventData getData() { return data; }
+ public void setData(SessionCustomNotificationEventData data) { this.data = data; }
+
+ /** Data payload for {@link SessionCustomNotificationEvent}. */
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ public record SessionCustomNotificationEventData(
+ /** Namespace for the custom notification producer */
+ @JsonProperty("source") String source,
+ /** Source-defined custom notification name */
+ @JsonProperty("name") String name,
+ /** Optional source-defined payload schema version */
+ @JsonProperty("version") Long version,
+ /** Optional source-defined string identifiers describing the payload subject */
+ @JsonProperty("subject") Map subject,
+ /** Source-defined JSON payload for the custom notification */
+ @JsonProperty("payload") Object payload
+ ) {
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionErrorEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionErrorEvent.java
index ecb85aacf0..5c174c4357 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionErrorEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionErrorEvent.java
@@ -37,7 +37,7 @@ public final class SessionErrorEvent extends SessionEvent {
public record SessionErrorEventData(
/** Category of error (e.g., "authentication", "authorization", "quota", "rate_limit", "context_limit", "query") */
@JsonProperty("errorType") String errorType,
- /** Fine-grained error code from the upstream provider, when available. For `errorType: "rate_limit"`, this is one of the `RateLimitErrorCode` values (e.g., `"user_weekly_rate_limited"`, `"user_global_rate_limited"`, `"rate_limited"`, `"user_model_rate_limited"`, `"integration_rate_limited"`). */
+ /** Fine-grained error code from the upstream provider, when available. For `errorType: "rate_limit"`, this is one of the `RateLimitErrorCode` values (e.g., `"user_weekly_rate_limited"`, `"user_global_rate_limited"`, `"rate_limited"`, `"user_model_rate_limited"`, `"integration_rate_limited"`). For `errorType: "quota"`, this is the CAPI quota error code (e.g., `"quota_exceeded"`, `"session_quota_exceeded"`, `"billing_not_configured"`). */
@JsonProperty("errorCode") String errorCode,
/** Only set on `errorType: "rate_limit"`. When `true`, the runtime will follow this error with an `auto_mode_switch.requested` event (or silently switch if `continueOnAutoMode` is enabled). UI clients can use this flag to suppress duplicate rendering of the rate-limit error when they show their own auto-mode-switch prompt. */
@JsonProperty("eligibleForAutoSwitch") Boolean eligibleForAutoSwitch,
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionEvent.java
index 0f348fe863..2181be1972 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionEvent.java
@@ -87,6 +87,7 @@
@JsonSubTypes.Type(value = SamplingCompletedEvent.class, name = "sampling.completed"),
@JsonSubTypes.Type(value = McpOauthRequiredEvent.class, name = "mcp.oauth_required"),
@JsonSubTypes.Type(value = McpOauthCompletedEvent.class, name = "mcp.oauth_completed"),
+ @JsonSubTypes.Type(value = SessionCustomNotificationEvent.class, name = "session.custom_notification"),
@JsonSubTypes.Type(value = ExternalToolRequestedEvent.class, name = "external_tool.requested"),
@JsonSubTypes.Type(value = ExternalToolCompletedEvent.class, name = "external_tool.completed"),
@JsonSubTypes.Type(value = CommandQueuedEvent.class, name = "command.queued"),
@@ -170,6 +171,7 @@ public abstract sealed class SessionEvent permits
SamplingCompletedEvent,
McpOauthRequiredEvent,
McpOauthCompletedEvent,
+ SessionCustomNotificationEvent,
ExternalToolRequestedEvent,
ExternalToolCompletedEvent,
CommandQueuedEvent,
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCreatedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCreatedEvent.java
index aba8650c84..bf0be67caf 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCreatedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCreatedEvent.java
@@ -40,7 +40,9 @@ public record SessionScheduleCreatedEventData(
/** Interval between ticks in milliseconds */
@JsonProperty("intervalMs") Long intervalMs,
/** Prompt text that gets enqueued on every tick */
- @JsonProperty("prompt") String prompt
+ @JsonProperty("prompt") String prompt,
+ /** Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`) */
+ @JsonProperty("recurring") Boolean recurring
) {
}
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/UserMessageEvent.java b/src/generated/java/com/github/copilot/sdk/generated/UserMessageEvent.java
index ec5f382463..fa680d3e64 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/UserMessageEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/UserMessageEvent.java
@@ -50,6 +50,8 @@ public record UserMessageEventData(
@JsonProperty("source") String source,
/** The agent mode that was active when this message was sent */
@JsonProperty("agentMode") UserMessageAgentMode agentMode,
+ /** True when this user message was auto-injected by autopilot's continuation loop rather than typed by the user; used to distinguish autopilot-driven turns in telemetry. */
+ @JsonProperty("isAutopilotContinuation") Boolean isAutopilotContinuation,
/** CAPI interaction ID for correlating this user message with its turn */
@JsonProperty("interactionId") String interactionId,
/** Parent agent task ID for background telemetry correlated to this user turn */
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/Model.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/Model.java
index 9ba457cecb..9bda6a3007 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/Model.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/Model.java
@@ -30,6 +30,10 @@ public record Model(
/** Supported reasoning effort levels (only present if model supports reasoning effort) */
@JsonProperty("supportedReasoningEfforts") List supportedReasoningEfforts,
/** Default reasoning effort level (only present if model supports reasoning effort) */
- @JsonProperty("defaultReasoningEffort") String defaultReasoningEffort
+ @JsonProperty("defaultReasoningEffort") String defaultReasoningEffort,
+ /** Model capability category for grouping in the model picker */
+ @JsonProperty("modelPickerCategory") ModelPickerCategory modelPickerCategory,
+ /** Relative cost tier for token-based billing users */
+ @JsonProperty("modelPickerPriceCategory") ModelPickerPriceCategory modelPickerPriceCategory
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelBilling.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelBilling.java
index 656f5383d5..9e634bb79a 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelBilling.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelBilling.java
@@ -22,6 +22,8 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public record ModelBilling(
/** Billing cost multiplier relative to the base rate */
- @JsonProperty("multiplier") Double multiplier
+ @JsonProperty("multiplier") Double multiplier,
+ /** Token-level pricing information for this model */
+ @JsonProperty("tokenPrices") ModelBillingTokenPrices tokenPrices
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelBillingTokenPrices.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelBillingTokenPrices.java
new file mode 100644
index 0000000000..34005daf1b
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelBillingTokenPrices.java
@@ -0,0 +1,33 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.processing.Generated;
+
+/**
+ * Token-level pricing information for this model
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record ModelBillingTokenPrices(
+ /** Price per billing batch of input tokens in nano-AIUs (1 nano-AIU = 0.000000001 AIU, 1 AIU = $0.01 USD) */
+ @JsonProperty("inputPrice") Long inputPrice,
+ /** Price per billing batch of output tokens in nano-AIUs (1 nano-AIU = 0.000000001 AIU, 1 AIU = $0.01 USD) */
+ @JsonProperty("outputPrice") Long outputPrice,
+ /** Price per billing batch of cached tokens in nano-AIUs (1 nano-AIU = 0.000000001 AIU, 1 AIU = $0.01 USD) */
+ @JsonProperty("cachePrice") Long cachePrice,
+ /** Number of tokens per standard billing batch */
+ @JsonProperty("batchSize") Long batchSize
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPickerCategory.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPickerCategory.java
new file mode 100644
index 0000000000..ba0bdddfd1
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPickerCategory.java
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Model capability category for grouping in the model picker
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum ModelPickerCategory {
+ /** The {@code lightweight} variant. */
+ LIGHTWEIGHT("lightweight"),
+ /** The {@code versatile} variant. */
+ VERSATILE("versatile"),
+ /** The {@code powerful} variant. */
+ POWERFUL("powerful");
+
+ private final String value;
+ ModelPickerCategory(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static ModelPickerCategory fromValue(String value) {
+ for (ModelPickerCategory v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown ModelPickerCategory value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPickerPriceCategory.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPickerPriceCategory.java
new file mode 100644
index 0000000000..cf722e4968
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPickerPriceCategory.java
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Relative cost tier for token-based billing users
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum ModelPickerPriceCategory {
+ /** The {@code low} variant. */
+ LOW("low"),
+ /** The {@code medium} variant. */
+ MEDIUM("medium"),
+ /** The {@code high} variant. */
+ HIGH("high"),
+ /** The {@code very_high} variant. */
+ VERY_HIGH("very_high");
+
+ private final String value;
+ ModelPickerPriceCategory(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static ModelPickerPriceCategory fromValue(String value) {
+ for (ModelPickerPriceCategory v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown ModelPickerPriceCategory value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/RemoteSessionMode.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/RemoteSessionMode.java
new file mode 100644
index 0000000000..4f659bb6b6
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/RemoteSessionMode.java
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Per-session remote mode. "off" disables remote, "export" exports session events to Mission Control without enabling remote steering, "on" enables both export and remote steering.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum RemoteSessionMode {
+ /** The {@code off} variant. */
+ OFF("off"),
+ /** The {@code export} variant. */
+ EXPORT("export"),
+ /** The {@code on} variant. */
+ ON("on");
+
+ private final String value;
+ RemoteSessionMode(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static RemoteSessionMode fromValue(String value) {
+ for (RemoteSessionMode v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown RemoteSessionMode value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java
index 0d3599a1cc..6366af794a 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java
@@ -29,6 +29,27 @@ public final class SessionCommandsApi {
this.sessionId = sessionId;
}
+ /**
+ * Invokes {@code session.commands.list}.
+ * @since 1.0.0
+ */
+ public CompletableFuture list() {
+ return caller.invoke("session.commands.list", java.util.Map.of("sessionId", this.sessionId), SessionCommandsListResult.class);
+ }
+
+ /**
+ * Invokes {@code session.commands.invoke}.
+ *
+ * Note: the {@code sessionId} field in the params record is overridden
+ * by the session-scoped wrapper; any value provided is ignored.
+ * @since 1.0.0
+ */
+ public CompletableFuture invoke(SessionCommandsInvokeParams params) {
+ com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params);
+ _p.put("sessionId", this.sessionId);
+ return caller.invoke("session.commands.invoke", _p, Void.class);
+ }
+
/**
* Invokes {@code session.commands.handlePendingCommand}.
*
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsInvokeParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsInvokeParams.java
new file mode 100644
index 0000000000..141ec9524d
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsInvokeParams.java
@@ -0,0 +1,31 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.processing.Generated;
+
+/**
+ * Request parameters for the {@code session.commands.invoke} RPC method.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record SessionCommandsInvokeParams(
+ /** Target session identifier */
+ @JsonProperty("sessionId") String sessionId,
+ /** Command name. Leading slashes are stripped and the name is matched case-insensitively. */
+ @JsonProperty("name") String name,
+ /** Raw input after the command name */
+ @JsonProperty("input") String input
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsListParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsListParams.java
new file mode 100644
index 0000000000..dd51f0e768
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsListParams.java
@@ -0,0 +1,27 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.processing.Generated;
+
+/**
+ * Request parameters for the {@code session.commands.list} RPC method.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record SessionCommandsListParams(
+ /** Target session identifier */
+ @JsonProperty("sessionId") String sessionId
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsListResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsListResult.java
new file mode 100644
index 0000000000..e819ba64c1
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsListResult.java
@@ -0,0 +1,28 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import javax.annotation.processing.Generated;
+
+/**
+ * Result for the {@code session.commands.list} RPC method.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record SessionCommandsListResult(
+ /** Commands available in this session */
+ @JsonProperty("commands") List commands
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionRemoteApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionRemoteApi.java
index df458acda5..790e1a7255 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionRemoteApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionRemoteApi.java
@@ -18,6 +18,8 @@
@javax.annotation.processing.Generated("copilot-sdk-codegen")
public final class SessionRemoteApi {
+ private static final com.fasterxml.jackson.databind.ObjectMapper MAPPER = RpcMapper.INSTANCE;
+
private final RpcCaller caller;
private final String sessionId;
@@ -29,12 +31,17 @@ public final class SessionRemoteApi {
/**
* Invokes {@code session.remote.enable}.
+ *
+ * Note: the {@code sessionId} field in the params record is overridden
+ * by the session-scoped wrapper; any value provided is ignored.
*
* @apiNote This method is experimental and may change in a future version.
* @since 1.0.0
*/
- public CompletableFuture enable() {
- return caller.invoke("session.remote.enable", java.util.Map.of("sessionId", this.sessionId), SessionRemoteEnableResult.class);
+ public CompletableFuture enable(SessionRemoteEnableParams params) {
+ com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params);
+ _p.put("sessionId", this.sessionId);
+ return caller.invoke("session.remote.enable", _p, SessionRemoteEnableResult.class);
}
/**
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionRemoteEnableParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionRemoteEnableParams.java
index d8b7917b78..aa1fff7a23 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionRemoteEnableParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionRemoteEnableParams.java
@@ -22,6 +22,8 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public record SessionRemoteEnableParams(
/** Target session identifier */
- @JsonProperty("sessionId") String sessionId
+ @JsonProperty("sessionId") String sessionId,
+ /** Per-session remote mode. "off" disables remote, "export" exports session events to Mission Control without enabling remote steering, "on" enables both export and remote steering. */
+ @JsonProperty("mode") RemoteSessionMode mode
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionSkillsApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionSkillsApi.java
index b32419a3e6..6f46d19d75 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionSkillsApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionSkillsApi.java
@@ -75,8 +75,8 @@ public CompletableFuture disable(SessionSkillsDisableParams params) {
* @apiNote This method is experimental and may change in a future version.
* @since 1.0.0
*/
- public CompletableFuture reload() {
- return caller.invoke("session.skills.reload", java.util.Map.of("sessionId", this.sessionId), Void.class);
+ public CompletableFuture reload() {
+ return caller.invoke("session.skills.reload", java.util.Map.of("sessionId", this.sessionId), SessionSkillsReloadResult.class);
}
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionSkillsReloadResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionSkillsReloadResult.java
index 1bfca46e1a..1333d57cc1 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionSkillsReloadResult.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionSkillsReloadResult.java
@@ -10,6 +10,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
import javax.annotation.processing.Generated;
/**
@@ -20,5 +21,10 @@
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
-public record SessionSkillsReloadResult() {
+public record SessionSkillsReloadResult(
+ /** Warnings emitted while loading skills (e.g. skills that loaded but had issues) */
+ @JsonProperty("warnings") List warnings,
+ /** Errors emitted while loading skills (e.g. skills that failed to load entirely) */
+ @JsonProperty("errors") List errors
+) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsForkParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsForkParams.java
index 06ea46c932..644be05ee0 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsForkParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsForkParams.java
@@ -24,6 +24,8 @@ public record SessionsForkParams(
/** Source session ID to fork from */
@JsonProperty("sessionId") String sessionId,
/** Optional event ID boundary. When provided, the fork includes only events before this ID (exclusive). When omitted, all events are included. */
- @JsonProperty("toEventId") String toEventId
+ @JsonProperty("toEventId") String toEventId,
+ /** Optional friendly name to assign to the forked session. */
+ @JsonProperty("name") String name
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsForkResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsForkResult.java
index 911574f568..77543916ec 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsForkResult.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsForkResult.java
@@ -22,6 +22,8 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public record SessionsForkResult(
/** The new forked session's ID */
- @JsonProperty("sessionId") String sessionId
+ @JsonProperty("sessionId") String sessionId,
+ /** Friendly name assigned to the forked session, if any. */
+ @JsonProperty("name") String name
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInfo.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInfo.java
new file mode 100644
index 0000000000..e494f4894c
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInfo.java
@@ -0,0 +1,35 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import javax.annotation.processing.Generated;
+
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record SlashCommandInfo(
+ /** Canonical command name without a leading slash */
+ @JsonProperty("name") String name,
+ /** Canonical aliases without leading slashes */
+ @JsonProperty("aliases") List aliases,
+ /** Human-readable command description */
+ @JsonProperty("description") String description,
+ /** Coarse command category for grouping and behavior: runtime built-in, skill-backed command, or SDK/client-owned command */
+ @JsonProperty("kind") SlashCommandKind kind,
+ /** Optional unstructured input hint */
+ @JsonProperty("input") SlashCommandInput input,
+ /** Whether the command may run while an agent turn is active */
+ @JsonProperty("allowDuringAgentExecution") Boolean allowDuringAgentExecution,
+ /** Whether the command is experimental */
+ @JsonProperty("experimental") Boolean experimental
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInput.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInput.java
new file mode 100644
index 0000000000..186dec5a81
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInput.java
@@ -0,0 +1,33 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.processing.Generated;
+
+/**
+ * Optional unstructured input hint
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record SlashCommandInput(
+ /** Hint to display when command input has not been provided */
+ @JsonProperty("hint") String hint,
+ /** When true, the command requires non-empty input; clients should render the input hint as required */
+ @JsonProperty("required") Boolean required,
+ /** Optional completion hint for the input (e.g. 'directory' for filesystem path completion) */
+ @JsonProperty("completion") SlashCommandInputCompletion completion,
+ /** When true, clients should pass the full text after the command name as a single argument rather than splitting on whitespace */
+ @JsonProperty("preserveMultilineInput") Boolean preserveMultilineInput
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInputCompletion.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInputCompletion.java
new file mode 100644
index 0000000000..c192fa9c0f
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandInputCompletion.java
@@ -0,0 +1,33 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Optional completion hint for the input (e.g. 'directory' for filesystem path completion)
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum SlashCommandInputCompletion {
+ /** The {@code directory} variant. */
+ DIRECTORY("directory");
+
+ private final String value;
+ SlashCommandInputCompletion(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static SlashCommandInputCompletion fromValue(String value) {
+ for (SlashCommandInputCompletion v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown SlashCommandInputCompletion value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandKind.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandKind.java
new file mode 100644
index 0000000000..1f08c4efcd
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SlashCommandKind.java
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Coarse command category for grouping and behavior: runtime built-in, skill-backed command, or SDK/client-owned command
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum SlashCommandKind {
+ /** The {@code builtin} variant. */
+ BUILTIN("builtin"),
+ /** The {@code skill} variant. */
+ SKILL("skill"),
+ /** The {@code client} variant. */
+ CLIENT("client");
+
+ private final String value;
+ SlashCommandKind(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static SlashCommandKind fromValue(String value) {
+ for (SlashCommandKind v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown SlashCommandKind value: " + value);
+ }
+}
From 3cb91793aebf743f74ea69f5c110e4845f3566b9 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 15 May 2026 21:00:09 +0000
Subject: [PATCH 043/135] Remove redundant Automatic-Module-Name manifest entry
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
pom.xml | 7 -------
1 file changed, 7 deletions(-)
diff --git a/pom.xml b/pom.xml
index 4e3273cf41..ac258afdb9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -172,13 +172,6 @@
org.apache.maven.plugins
maven-jar-plugin
3.5.0
-
-
-
- com.github.copilot.sdk.java
-
-
-
From 2509ed149b559570880cbe55da07a1ebfef0ce23 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 15 May 2026 21:13:20 +0000
Subject: [PATCH 044/135] Add comprehensive RemoteSession tests and fix
generated code compilation errors
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.../generated/AssistantUsageApiEndpoint.java | 8 +-
.../github/copilot/sdk/RemoteSessionTest.java | 399 ++++++++++++++++++
.../rpc/GeneratedRpcApiCoverageTest.java | 4 +-
.../rpc/GeneratedRpcRecordsCoverageTest.java | 10 +-
4 files changed, 410 insertions(+), 11 deletions(-)
create mode 100644 src/test/java/com/github/copilot/sdk/RemoteSessionTest.java
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
index bbcd619fbb..e69e4ef868 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
@@ -17,13 +17,13 @@
@javax.annotation.processing.Generated("copilot-sdk-codegen")
public enum AssistantUsageApiEndpoint {
/** The {@code /chat/completions} variant. */
- /CHAT/COMPLETIONS("/chat/completions"),
+ CHAT_COMPLETIONS("/chat/completions"),
/** The {@code /v1/messages} variant. */
- /V1/MESSAGES("/v1/messages"),
+ V1_MESSAGES("/v1/messages"),
/** The {@code /responses} variant. */
- /RESPONSES("/responses"),
+ RESPONSES("/responses"),
/** The {@code ws:/responses} variant. */
- WS:/RESPONSES("ws:/responses");
+ WS_RESPONSES("ws:/responses");
private final String value;
AssistantUsageApiEndpoint(String value) { this.value = value; }
diff --git a/src/test/java/com/github/copilot/sdk/RemoteSessionTest.java b/src/test/java/com/github/copilot/sdk/RemoteSessionTest.java
new file mode 100644
index 0000000000..6e093db6ca
--- /dev/null
+++ b/src/test/java/com/github/copilot/sdk/RemoteSessionTest.java
@@ -0,0 +1,399 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.copilot.sdk.json.CreateSessionRequest;
+import com.github.copilot.sdk.json.ResumeSessionConfig;
+import com.github.copilot.sdk.json.ResumeSessionRequest;
+import com.github.copilot.sdk.json.SessionConfig;
+
+/**
+ * Tests for the {@code remoteSession} feature across all session config types.
+ *
+ * Validates the complete lifecycle of the remote session mode:
+ *
+ * Getter/setter and fluent chaining on {@link SessionConfig} and
+ * {@link ResumeSessionConfig}
+ * Propagation through {@link SessionRequestBuilder} into
+ * {@link CreateSessionRequest} and {@link ResumeSessionRequest}
+ * JSON wire-format serialization: correct key, correct value, omission when
+ * unset
+ * Defensive copy via {@code copy()} preserves the value
+ * All three supported mode values ("off", "export", "on") are transmitted
+ * correctly
+ *
+ */
+class RemoteSessionTest {
+
+ private static final ObjectMapper MAPPER = JsonRpcClient.getObjectMapper();
+
+ // =========================================================================
+ // SessionConfig getter/setter/copy
+ // =========================================================================
+
+ @Test
+ void sessionConfig_remoteSessionDefaultsToNull() {
+ var cfg = new SessionConfig();
+ assertNull(cfg.getRemoteSession(), "remoteSession should be null when not set");
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"off", "export", "on"})
+ void sessionConfig_setRemoteSessionReturnsSelf(String mode) {
+ var cfg = new SessionConfig();
+ SessionConfig result = cfg.setRemoteSession(mode);
+ assertSame(cfg, result, "setRemoteSession should return the same instance for chaining");
+ assertEquals(mode, cfg.getRemoteSession());
+ }
+
+ @Test
+ void sessionConfig_copyPreservesRemoteSession() {
+ var original = new SessionConfig().setRemoteSession("export");
+ var copy = original.clone();
+ assertEquals("export", copy.getRemoteSession());
+ }
+
+ @Test
+ void sessionConfig_copyPreservesNullRemoteSession() {
+ var original = new SessionConfig();
+ var copy = original.clone();
+ assertNull(copy.getRemoteSession());
+ }
+
+ @Test
+ void sessionConfig_setRemoteSessionToNullClearsValue() {
+ var cfg = new SessionConfig().setRemoteSession("on");
+ cfg.setRemoteSession(null);
+ assertNull(cfg.getRemoteSession());
+ }
+
+ // =========================================================================
+ // ResumeSessionConfig getter/setter/copy
+ // =========================================================================
+
+ @Test
+ void resumeSessionConfig_remoteSessionDefaultsToNull() {
+ var cfg = new ResumeSessionConfig();
+ assertNull(cfg.getRemoteSession(), "remoteSession should be null when not set");
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"off", "export", "on"})
+ void resumeSessionConfig_setRemoteSessionReturnsSelf(String mode) {
+ var cfg = new ResumeSessionConfig();
+ ResumeSessionConfig result = cfg.setRemoteSession(mode);
+ assertSame(cfg, result, "setRemoteSession should return the same instance for chaining");
+ assertEquals(mode, cfg.getRemoteSession());
+ }
+
+ @Test
+ void resumeSessionConfig_copyPreservesRemoteSession() {
+ var original = new ResumeSessionConfig().setRemoteSession("on");
+ var copy = original.clone();
+ assertEquals("on", copy.getRemoteSession());
+ }
+
+ // =========================================================================
+ // SessionRequestBuilder – CreateSessionRequest wiring
+ // =========================================================================
+
+ @ParameterizedTest
+ @ValueSource(strings = {"off", "export", "on"})
+ void buildCreateRequest_propagatesRemoteSession(String mode) {
+ var config = new SessionConfig().setRemoteSession(mode);
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+ assertEquals(mode, request.getRemoteSession());
+ }
+
+ @Test
+ void buildCreateRequest_nullConfig_remoteSessionIsNull() {
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(null);
+ assertNull(request.getRemoteSession());
+ }
+
+ @Test
+ void buildCreateRequest_unsetRemoteSession_isNull() {
+ var config = new SessionConfig();
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+ assertNull(request.getRemoteSession());
+ }
+
+ // =========================================================================
+ // SessionRequestBuilder – ResumeSessionRequest wiring
+ // =========================================================================
+
+ @ParameterizedTest
+ @ValueSource(strings = {"off", "export", "on"})
+ void buildResumeRequest_propagatesRemoteSession(String mode) {
+ var config = new ResumeSessionConfig().setRemoteSession(mode);
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("sid-1", config);
+ assertEquals(mode, request.getRemoteSession());
+ }
+
+ @Test
+ void buildResumeRequest_nullConfig_remoteSessionIsNull() {
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("sid-1", null);
+ assertNull(request.getRemoteSession());
+ }
+
+ @Test
+ void buildResumeRequest_unsetRemoteSession_isNull() {
+ var config = new ResumeSessionConfig();
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("sid-1", config);
+ assertNull(request.getRemoteSession());
+ }
+
+ // =========================================================================
+ // JSON wire-format: CreateSessionRequest
+ // =========================================================================
+
+ @ParameterizedTest
+ @ValueSource(strings = {"off", "export", "on"})
+ void createRequest_serializesRemoteSessionCorrectly(String mode) throws Exception {
+ var config = new SessionConfig().setRemoteSession(mode);
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+
+ String json = MAPPER.writeValueAsString(request);
+ JsonNode tree = MAPPER.readTree(json);
+
+ assertTrue(tree.has("remoteSession"), "Serialized JSON should contain 'remoteSession' field for mode: " + mode);
+ assertEquals(mode, tree.get("remoteSession").asText());
+ }
+
+ @Test
+ void createRequest_omitsRemoteSessionWhenNull() throws Exception {
+ var config = new SessionConfig();
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+
+ String json = MAPPER.writeValueAsString(request);
+ JsonNode tree = MAPPER.readTree(json);
+
+ assertFalse(tree.has("remoteSession"), "Serialized JSON should omit 'remoteSession' when not set");
+ }
+
+ // =========================================================================
+ // JSON wire-format: ResumeSessionRequest
+ // =========================================================================
+
+ @ParameterizedTest
+ @ValueSource(strings = {"off", "export", "on"})
+ void resumeRequest_serializesRemoteSessionCorrectly(String mode) throws Exception {
+ var config = new ResumeSessionConfig().setRemoteSession(mode);
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("sid-1", config);
+
+ String json = MAPPER.writeValueAsString(request);
+ JsonNode tree = MAPPER.readTree(json);
+
+ assertTrue(tree.has("remoteSession"), "Serialized JSON should contain 'remoteSession' field for mode: " + mode);
+ assertEquals(mode, tree.get("remoteSession").asText());
+ }
+
+ @Test
+ void resumeRequest_omitsRemoteSessionWhenNull() throws Exception {
+ var config = new ResumeSessionConfig();
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("sid-1", config);
+
+ String json = MAPPER.writeValueAsString(request);
+ JsonNode tree = MAPPER.readTree(json);
+
+ assertFalse(tree.has("remoteSession"), "Serialized JSON should omit 'remoteSession' when not set");
+ }
+
+ // =========================================================================
+ // JSON round-trip: CreateSessionRequest
+ // =========================================================================
+
+ @ParameterizedTest
+ @ValueSource(strings = {"off", "export", "on"})
+ void createRequest_roundTripsRemoteSession(String mode) throws Exception {
+ var config = new SessionConfig().setRemoteSession(mode);
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+
+ String json = MAPPER.writeValueAsString(request);
+ CreateSessionRequest deserialized = MAPPER.readValue(json, CreateSessionRequest.class);
+ assertEquals(mode, deserialized.getRemoteSession());
+ }
+
+ @Test
+ void createRequest_roundTripsNullRemoteSession() throws Exception {
+ var config = new SessionConfig();
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+
+ String json = MAPPER.writeValueAsString(request);
+ CreateSessionRequest deserialized = MAPPER.readValue(json, CreateSessionRequest.class);
+ assertNull(deserialized.getRemoteSession());
+ }
+
+ // =========================================================================
+ // JSON round-trip: ResumeSessionRequest
+ // =========================================================================
+
+ @ParameterizedTest
+ @ValueSource(strings = {"off", "export", "on"})
+ void resumeRequest_roundTripsRemoteSession(String mode) throws Exception {
+ var config = new ResumeSessionConfig().setRemoteSession(mode);
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("sid-1", config);
+
+ String json = MAPPER.writeValueAsString(request);
+ ResumeSessionRequest deserialized = MAPPER.readValue(json, ResumeSessionRequest.class);
+ assertEquals(mode, deserialized.getRemoteSession());
+ }
+
+ // =========================================================================
+ // Fluent chaining: remoteSession composes with other config options
+ // =========================================================================
+
+ @Test
+ void sessionConfig_remoteSessionComposesWithOtherFields() {
+ var config = new SessionConfig().setModel("gpt-4o").setRemoteSession("export").setReasoningEffort("high");
+
+ assertEquals("gpt-4o", config.getModel());
+ assertEquals("export", config.getRemoteSession());
+ assertEquals("high", config.getReasoningEffort());
+ }
+
+ @Test
+ void resumeSessionConfig_remoteSessionComposesWithOtherFields() {
+ var config = new ResumeSessionConfig().setModel("gpt-4o").setRemoteSession("on").setReasoningEffort("medium");
+
+ assertEquals("gpt-4o", config.getModel());
+ assertEquals("on", config.getRemoteSession());
+ assertEquals("medium", config.getReasoningEffort());
+ }
+
+ @Test
+ void createRequest_remoteSessionDoesNotAffectOtherFields() throws Exception {
+ var config = new SessionConfig().setModel("gpt-4o").setRemoteSession("export").setReasoningEffort("high")
+ .setGitHubToken("ghp_test");
+
+ CreateSessionRequest request = SessionRequestBuilder.buildCreateRequest(config);
+ String json = MAPPER.writeValueAsString(request);
+ JsonNode tree = MAPPER.readTree(json);
+
+ assertEquals("export", tree.get("remoteSession").asText());
+ assertEquals("gpt-4o", tree.get("model").asText());
+ assertEquals("high", tree.get("reasoningEffort").asText());
+ assertEquals("ghp_test", tree.get("gitHubToken").asText());
+ }
+
+ @Test
+ void resumeRequest_remoteSessionDoesNotAffectOtherFields() throws Exception {
+ var config = new ResumeSessionConfig().setModel("gpt-4o").setRemoteSession("on").setReasoningEffort("medium")
+ .setGitHubToken("ghp_test");
+
+ ResumeSessionRequest request = SessionRequestBuilder.buildResumeRequest("sid-1", config);
+ String json = MAPPER.writeValueAsString(request);
+ JsonNode tree = MAPPER.readTree(json);
+
+ assertEquals("on", tree.get("remoteSession").asText());
+ assertEquals("gpt-4o", tree.get("model").asText());
+ assertEquals("medium", tree.get("reasoningEffort").asText());
+ assertEquals("ghp_test", tree.get("gitHubToken").asText());
+ }
+
+ // =========================================================================
+ // Deserialization from raw JSON (simulates CLI response ingestion)
+ // =========================================================================
+
+ @Test
+ void createRequest_deserializesRemoteSessionFromRawJson() throws Exception {
+ String json = """
+ {
+ "sessionId": "test-session",
+ "remoteSession": "export",
+ "model": "gpt-4o"
+ }
+ """;
+ CreateSessionRequest request = MAPPER.readValue(json, CreateSessionRequest.class);
+ assertEquals("export", request.getRemoteSession());
+ assertEquals("test-session", request.getSessionId());
+ }
+
+ @Test
+ void resumeRequest_deserializesRemoteSessionFromRawJson() throws Exception {
+ String json = """
+ {
+ "sessionId": "resume-session",
+ "remoteSession": "on",
+ "model": "gpt-4o"
+ }
+ """;
+ ResumeSessionRequest request = MAPPER.readValue(json, ResumeSessionRequest.class);
+ assertEquals("on", request.getRemoteSession());
+ assertEquals("resume-session", request.getSessionId());
+ }
+
+ @Test
+ void createRequest_deserializesWithMissingRemoteSession() throws Exception {
+ String json = """
+ {
+ "sessionId": "test-session",
+ "model": "gpt-4o"
+ }
+ """;
+ CreateSessionRequest request = MAPPER.readValue(json, CreateSessionRequest.class);
+ assertNull(request.getRemoteSession());
+ }
+
+ // =========================================================================
+ // Handoff event with remoteSessionId (remote session lifecycle)
+ // =========================================================================
+
+ @Test
+ void handoffEvent_withRemoteSourceType_containsRemoteSessionId() throws Exception {
+ String json = """
+ {
+ "type": "session.handoff",
+ "data": {
+ "handoffTime": "2025-06-01T12:00:00Z",
+ "sourceType": "remote",
+ "remoteSessionId": "remote-sess-42",
+ "summary": "Session exported for remote execution",
+ "repository": {
+ "owner": "test-org",
+ "name": "test-repo",
+ "branch": "feature-branch"
+ }
+ }
+ }
+ """;
+
+ var event = (com.github.copilot.sdk.generated.SessionHandoffEvent) MAPPER.readValue(json,
+ com.github.copilot.sdk.generated.SessionEvent.class);
+ assertNotNull(event);
+ var data = event.getData();
+ assertEquals("remote-sess-42", data.remoteSessionId());
+ assertEquals(com.github.copilot.sdk.generated.HandoffSourceType.REMOTE, data.sourceType());
+ assertEquals("Session exported for remote execution", data.summary());
+ assertEquals("test-org", data.repository().owner());
+ assertEquals("test-repo", data.repository().name());
+ assertEquals("feature-branch", data.repository().branch());
+ }
+
+ @Test
+ void handoffEvent_withoutRemoteSessionId_fieldIsNull() throws Exception {
+ String json = """
+ {
+ "type": "session.handoff",
+ "data": {
+ "targetAgent": "local-agent"
+ }
+ }
+ """;
+
+ var event = (com.github.copilot.sdk.generated.SessionHandoffEvent) MAPPER.readValue(json,
+ com.github.copilot.sdk.generated.SessionEvent.class);
+ assertNotNull(event);
+ assertNull(event.getData().remoteSessionId());
+ }
+}
diff --git a/src/test/java/com/github/copilot/sdk/generated/rpc/GeneratedRpcApiCoverageTest.java b/src/test/java/com/github/copilot/sdk/generated/rpc/GeneratedRpcApiCoverageTest.java
index 89943e3758..10393abe09 100644
--- a/src/test/java/com/github/copilot/sdk/generated/rpc/GeneratedRpcApiCoverageTest.java
+++ b/src/test/java/com/github/copilot/sdk/generated/rpc/GeneratedRpcApiCoverageTest.java
@@ -71,7 +71,7 @@ void serverRpc_sessions_fork_invokes_correct_method() {
var stub = new StubCaller();
var server = new ServerRpc(stub);
- var params = new SessionsForkParams("parent-session-id", null);
+ var params = new SessionsForkParams("parent-session-id", null, null);
server.sessions.fork(params);
assertEquals(1, stub.calls.size());
@@ -657,7 +657,7 @@ void serverRpc_sessionFs_setProvider_params_record() {
@Test
void sessionsForkParams_record() {
- var params = new SessionsForkParams("parent-id", "event-123");
+ var params = new SessionsForkParams("parent-id", "event-123", null);
assertEquals("parent-id", params.sessionId());
assertEquals("event-123", params.toEventId());
}
diff --git a/src/test/java/com/github/copilot/sdk/generated/rpc/GeneratedRpcRecordsCoverageTest.java b/src/test/java/com/github/copilot/sdk/generated/rpc/GeneratedRpcRecordsCoverageTest.java
index 48ade8ce11..50e65d3779 100644
--- a/src/test/java/com/github/copilot/sdk/generated/rpc/GeneratedRpcRecordsCoverageTest.java
+++ b/src/test/java/com/github/copilot/sdk/generated/rpc/GeneratedRpcRecordsCoverageTest.java
@@ -67,7 +67,7 @@ void toolsListParams_record() {
@Test
void sessionsForkParams_record() {
- var params = new SessionsForkParams("sess-1", "event-abc");
+ var params = new SessionsForkParams("sess-1", "event-abc", null);
assertEquals("sess-1", params.sessionId());
assertEquals("event-abc", params.toEventId());
}
@@ -795,7 +795,7 @@ void sessionSkillsListResult_nested() {
@Test
void sessionSkillsReloadResult_empty() {
- assertNotNull(new SessionSkillsReloadResult());
+ assertNotNull(new SessionSkillsReloadResult(null, null));
}
@Test
@@ -863,7 +863,7 @@ void sessionWorkspaceReadFileResult_record() {
@Test
void sessionsForkResult_record() {
- var result = new SessionsForkResult("forked-sess-id");
+ var result = new SessionsForkResult("forked-sess-id", null);
assertEquals("forked-sess-id", result.sessionId());
}
@@ -917,8 +917,8 @@ void modelsListResult_nested() {
var limits = new ModelCapabilitiesLimits(100000L, 8192L, 128000L, null);
var capabilities = new ModelCapabilities(supports, limits);
var policy = new ModelPolicy("active", null);
- var billing = new ModelBilling(1.0);
- var modelItem = new Model("gpt-5", "GPT-5", capabilities, policy, billing, null, null);
+ var billing = new ModelBilling(1.0, null);
+ var modelItem = new Model("gpt-5", "GPT-5", capabilities, policy, billing, null, null, null, null);
var result = new ModelsListResult(List.of(modelItem));
assertEquals(1, result.models().size());
From a8c5fa368e1809fbee88131505fcb5b4dad2c0c5 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 15 May 2026 21:22:41 +0000
Subject: [PATCH 045/135] Regenerate codegen output
Auto-committed by codegen-check workflow.
---
.../copilot/sdk/generated/AssistantUsageApiEndpoint.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
index e69e4ef868..bbcd619fbb 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
@@ -17,13 +17,13 @@
@javax.annotation.processing.Generated("copilot-sdk-codegen")
public enum AssistantUsageApiEndpoint {
/** The {@code /chat/completions} variant. */
- CHAT_COMPLETIONS("/chat/completions"),
+ /CHAT/COMPLETIONS("/chat/completions"),
/** The {@code /v1/messages} variant. */
- V1_MESSAGES("/v1/messages"),
+ /V1/MESSAGES("/v1/messages"),
/** The {@code /responses} variant. */
- RESPONSES("/responses"),
+ /RESPONSES("/responses"),
/** The {@code ws:/responses} variant. */
- WS_RESPONSES("ws:/responses");
+ WS:/RESPONSES("ws:/responses");
private final String value;
AssistantUsageApiEndpoint(String value) { this.value = value; }
From d2ea79ac6524ff51db2d880688a069629de9bba3 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 15 May 2026 22:06:39 +0000
Subject: [PATCH 046/135] Open SDK packages for Jackson reflection in JPMS
descriptor
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
src/main/java/module-info.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index b5c6c87ace..d912fb420f 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -19,4 +19,8 @@
exports com.github.copilot.sdk.generated;
exports com.github.copilot.sdk.generated.rpc;
exports com.github.copilot.sdk.json;
+
+ opens com.github.copilot.sdk to com.fasterxml.jackson.databind;
+ opens com.github.copilot.sdk.generated to com.fasterxml.jackson.databind;
+ opens com.github.copilot.sdk.json to com.fasterxml.jackson.databind;
}
From 5c5a64db328a847051ab361efa5b38d71a9bab4f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 15 May 2026 22:56:48 +0000
Subject: [PATCH 047/135] Merge main (#204), fix codegen toEnumConstant for
slash/colon chars, regenerate
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
scripts/codegen/java.ts | 2 +-
.../copilot/sdk/generated/AssistantUsageApiEndpoint.java | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/scripts/codegen/java.ts b/scripts/codegen/java.ts
index 909fe296c6..0a96ab9f14 100644
--- a/scripts/codegen/java.ts
+++ b/scripts/codegen/java.ts
@@ -43,7 +43,7 @@ function toCamelCase(name: string): string {
}
function toEnumConstant(value: string): string {
- return value.toUpperCase().replace(/[-. ]/g, "_");
+ return value.toUpperCase().replace(/[-. /:]/g, "_").replace(/^_+/, "").replace(/_+/g, "_");
}
// ── Schema path resolution ───────────────────────────────────────────────────
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
index bbcd619fbb..e69e4ef868 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageApiEndpoint.java
@@ -17,13 +17,13 @@
@javax.annotation.processing.Generated("copilot-sdk-codegen")
public enum AssistantUsageApiEndpoint {
/** The {@code /chat/completions} variant. */
- /CHAT/COMPLETIONS("/chat/completions"),
+ CHAT_COMPLETIONS("/chat/completions"),
/** The {@code /v1/messages} variant. */
- /V1/MESSAGES("/v1/messages"),
+ V1_MESSAGES("/v1/messages"),
/** The {@code /responses} variant. */
- /RESPONSES("/responses"),
+ RESPONSES("/responses"),
/** The {@code ws:/responses} variant. */
- WS:/RESPONSES("ws:/responses");
+ WS_RESPONSES("ws:/responses");
private final String value;
AssistantUsageApiEndpoint(String value) { this.value = value; }
From aa768a8a130e3b1bad67568398c0e9424db5a2e7 Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Fri, 15 May 2026 17:17:17 -0700
Subject: [PATCH 048/135] Fix: Ensure dependencies label on PRs before
codegen-agentic-fix pushes
Fixes https://github.com/github/copilot-sdk-java/issues/199
The codegen-agentic-fix workflow's push-to-pull-request-branch safe-output
requires the target PR to have the `dependencies` label. Two gaps allowed
PRs to reach the agentic fix without this label:
1. update-copilot-dependency.yml: When the PR branch already exists from a
prior run, the workflow reused it without adding the label. Now calls
`gh pr edit --add-label dependencies` in that path.
2. codegen-check.yml: When triggering the agentic fix from any PR that
touches codegen paths, the PR might not have the label (e.g., a manual
PR or one created before the fix). Now ensures the label is present
before dispatching codegen-agentic-fix.lock.yml.
---
.github/workflows/codegen-check.yml | 3 +++
.github/workflows/update-copilot-dependency.yml | 1 +
2 files changed, 4 insertions(+)
diff --git a/.github/workflows/codegen-check.yml b/.github/workflows/codegen-check.yml
index b6f161d852..95e9365782 100644
--- a/.github/workflows/codegen-check.yml
+++ b/.github/workflows/codegen-check.yml
@@ -128,6 +128,9 @@ jobs:
run: |
ERROR_SUMMARY=$(cat /tmp/error-summary.txt)
+ # Ensure PR has dependencies label (required by codegen-agentic-fix safe-output)
+ gh pr edit "$PR_NUMBER" --add-label dependencies
+
gh workflow run codegen-agentic-fix.lock.yml \
-f branch="$BRANCH" \
-f pr_number="$PR_NUMBER" \
diff --git a/.github/workflows/update-copilot-dependency.yml b/.github/workflows/update-copilot-dependency.yml
index 854661d5bd..d29da6acb7 100644
--- a/.github/workflows/update-copilot-dependency.yml
+++ b/.github/workflows/update-copilot-dependency.yml
@@ -147,6 +147,7 @@ jobs:
if gh pr view "$BRANCH" >/dev/null 2>&1; then
echo "Pull request for branch '$BRANCH' already exists; updated branch only."
PR_NUMBER=$(gh pr view "$BRANCH" --json number --jq .number)
+ gh pr edit "$PR_NUMBER" --add-label dependencies
else
PR_NUMBER=$(gh pr create \
--title "Update @github/copilot to $VERSION" \
From a002e4256ad6d6fa41aff6f2f2e79955949f0148 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Sat, 16 May 2026 00:23:56 +0000
Subject: [PATCH 049/135] docs: update version references to 1.0.0-beta-java.4
---
CHANGELOG.md | 8 ++++++--
README.md | 6 +++---
jbang-example.java | 2 +-
src/site/markdown/cookbook/error-handling.md | 14 +++++++-------
src/site/markdown/cookbook/managing-local-files.md | 4 ++--
src/site/markdown/cookbook/multiple-sessions.md | 4 ++--
src/site/markdown/cookbook/persisting-sessions.md | 6 +++---
src/site/markdown/cookbook/pr-visualization.md | 2 +-
8 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5eb0397d56..8e174dd216 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,8 +8,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
-> **Reference implementation sync:** [`github/copilot-sdk@4a0437b`](https://github.com/github/copilot-sdk/commit/4a0437bb03a0b60a1867f14ae8e3faf053afa5aa)
+> **Reference implementation sync:** [`github/copilot-sdk@e20f5be`](https://github.com/github/copilot-sdk/commit/e20f5bef125860accb30c60d1b35109371a77f16)
+
+## [1.0.0-beta-java.4] - 2026-05-16
+> **Reference implementation sync:** [`github/copilot-sdk@e20f5be`](https://github.com/github/copilot-sdk/commit/e20f5bef125860accb30c60d1b35109371a77f16)
## [1.0.0-beta-java.3] - 2026-05-11
> **Reference implementation sync:** [`github/copilot-sdk@4a0437b`](https://github.com/github/copilot-sdk/commit/4a0437bb03a0b60a1867f14ae8e3faf053afa5aa)
@@ -506,7 +509,8 @@ New types: `GetForegroundSessionResponse`, `SetForegroundSessionResponse`
- Pre-commit hook for Spotless code formatting
- Comprehensive API documentation
-[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.3...HEAD
+[Unreleased]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.4...HEAD
+[1.0.0-beta-java.4]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.3...v1.0.0-beta-java.4
[1.0.0-beta-java.3]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.2...v1.0.0-beta-java.3
[1.0.0-beta-java.2]: https://github.com/github/copilot-sdk-java/compare/v1.0.0-beta-java.1...v1.0.0-beta-java.2
[1.0.0-beta-java.1]: https://github.com/github/copilot-sdk-java/compare/v0.3.0-java.2...v1.0.0-beta-java.1
diff --git a/README.md b/README.md
index c1aac6a5ab..f2b342dfc3 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ Java SDK for programmatic control of GitHub Copilot CLI, enabling you to build A
com.github
copilot-sdk-java
- 1.0.0-beta-java.3
+ 1.0.0-beta-java.4
```
@@ -53,14 +53,14 @@ Snapshot builds of the next development version are published to Maven Central S
com.github
copilot-sdk-java
- 1.0.0-beta-java.3-SNAPSHOT
+ 1.0.0-beta-java.5-SNAPSHOT
```
### Gradle
```groovy
-implementation 'com.github:copilot-sdk-java:1.0.0-beta-java.3'
+implementation 'com.github:copilot-sdk-java:1.0.0-beta-java.4'
```
## Quick Start
diff --git a/jbang-example.java b/jbang-example.java
index 78763bea9c..1c41679cdf 100644
--- a/jbang-example.java
+++ b/jbang-example.java
@@ -1,5 +1,5 @@
///usr/bin/env jbang "$0" "$@" ; exit $?
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.SessionUsageInfoEvent;
diff --git a/src/site/markdown/cookbook/error-handling.md b/src/site/markdown/cookbook/error-handling.md
index 42c9e3a9c6..963b8b0933 100644
--- a/src/site/markdown/cookbook/error-handling.md
+++ b/src/site/markdown/cookbook/error-handling.md
@@ -30,7 +30,7 @@ jbang BasicErrorHandling.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -64,7 +64,7 @@ public class BasicErrorHandling {
## Handling specific error types
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import java.util.concurrent.ExecutionException;
@@ -99,7 +99,7 @@ public class SpecificErrorHandling {
## Timeout handling
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotSession;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -130,7 +130,7 @@ public class TimeoutHandling {
## Aborting a request
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotSession;
import com.github.copilot.sdk.json.MessageOptions;
import java.util.concurrent.Executors;
@@ -162,7 +162,7 @@ public class AbortRequest {
## Graceful shutdown
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
public class GracefulShutdown {
@@ -192,7 +192,7 @@ public class GracefulShutdown {
## Try-with-resources pattern
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -224,7 +224,7 @@ public class TryWithResources {
## Handling tool errors
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
diff --git a/src/site/markdown/cookbook/managing-local-files.md b/src/site/markdown/cookbook/managing-local-files.md
index 788a712b60..2a7b5540f9 100644
--- a/src/site/markdown/cookbook/managing-local-files.md
+++ b/src/site/markdown/cookbook/managing-local-files.md
@@ -34,7 +34,7 @@ jbang ManagingLocalFiles.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.SessionIdleEvent;
@@ -161,7 +161,7 @@ session.send(new MessageOptions().setPrompt(prompt));
## Interactive file organization
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import java.io.BufferedReader;
import java.io.InputStreamReader;
diff --git a/src/site/markdown/cookbook/multiple-sessions.md b/src/site/markdown/cookbook/multiple-sessions.md
index c6f9666779..84da5a2556 100644
--- a/src/site/markdown/cookbook/multiple-sessions.md
+++ b/src/site/markdown/cookbook/multiple-sessions.md
@@ -30,7 +30,7 @@ jbang MultipleSessions.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -123,7 +123,7 @@ try {
## Managing session lifecycle with CompletableFuture
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import java.util.concurrent.CompletableFuture;
import java.util.List;
diff --git a/src/site/markdown/cookbook/persisting-sessions.md b/src/site/markdown/cookbook/persisting-sessions.md
index 6c9440a510..ef80fd3d09 100644
--- a/src/site/markdown/cookbook/persisting-sessions.md
+++ b/src/site/markdown/cookbook/persisting-sessions.md
@@ -30,7 +30,7 @@ jbang PersistingSessions.java
**Code:**
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.json.MessageOptions;
@@ -127,7 +127,7 @@ public class DeleteSession {
## Getting session history
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.UserMessageEvent;
@@ -162,7 +162,7 @@ public class SessionHistory {
## Complete example with session management
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import java.util.Scanner;
public class SessionManager {
diff --git a/src/site/markdown/cookbook/pr-visualization.md b/src/site/markdown/cookbook/pr-visualization.md
index d193e4487e..1036bb0f7d 100644
--- a/src/site/markdown/cookbook/pr-visualization.md
+++ b/src/site/markdown/cookbook/pr-visualization.md
@@ -34,7 +34,7 @@ jbang PRVisualization.java github/copilot-sdk
## Full example: PRVisualization.java
```java
-//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.3
+//DEPS com.github:copilot-sdk-java:1.0.0-beta-java.4
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.generated.AssistantMessageEvent;
import com.github.copilot.sdk.generated.ToolExecutionStartEvent;
From 09f58de9a106043e44df9f60124b59527063da42 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Sat, 16 May 2026 00:24:21 +0000
Subject: [PATCH 050/135] [maven-release-plugin] prepare release
v1.0.0-beta-java.4
---
pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index 80130ca280..a925a81cfd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.github
copilot-sdk-java
- 1.0.0-beta-java.4-SNAPSHOT
+ 1.0.0-beta-java.4
jar
GitHub Copilot SDK :: Java
@@ -33,7 +33,7 @@
scm:git:https://github.com/github/copilot-sdk-java.git
scm:git:https://github.com/github/copilot-sdk-java.git
https://github.com/github/copilot-sdk-java
- HEAD
+ v1.0.0-beta-java.4
From 8809949a155d12fbab11d0eda4994b335404813f Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
Date: Sat, 16 May 2026 00:24:24 +0000
Subject: [PATCH 051/135] [maven-release-plugin] prepare for next development
iteration
---
pom.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pom.xml b/pom.xml
index a925a81cfd..be73738041 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.github
copilot-sdk-java
- 1.0.0-beta-java.4
+ 1.0.0-beta-java.5-SNAPSHOT
jar
GitHub Copilot SDK :: Java
@@ -33,7 +33,7 @@
scm:git:https://github.com/github/copilot-sdk-java.git
scm:git:https://github.com/github/copilot-sdk-java.git
https://github.com/github/copilot-sdk-java
- v1.0.0-beta-java.4
+ HEAD
From 8d357f4d4b0039354d0e0d9e980d2f42041fdf0c Mon Sep 17 00:00:00 2001
From: brunoborges <129743+brunoborges@users.noreply.github.com>
Date: Sun, 17 May 2026 00:52:28 +0000
Subject: [PATCH 052/135] Update JaCoCo coverage badge
---
.github/badges/jacoco.svg | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/badges/jacoco.svg b/.github/badges/jacoco.svg
index b90843bcc4..56a1a015fa 100644
--- a/.github/badges/jacoco.svg
+++ b/.github/badges/jacoco.svg
@@ -12,7 +12,7 @@
coverage
coverage
- 81.9%
- 81.9%
+ 80.2%
+ 80.2%
From 3df4e75e1c18798852d82e9a3a01da59426089cf Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 18 May 2026 17:14:00 +0000
Subject: [PATCH 053/135] Initial plan
From d505fc18e4890970fd36c8bc4c9a2492d43a159a Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 18 May 2026 17:14:00 +0000
Subject: [PATCH 054/135] Initial plan
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.../copilot/sdk/SessionRequestBuilder.java | 1 +
.../copilot/sdk/json/CloudSessionOptions.java | 43 +++++++++
.../sdk/json/CloudSessionRepository.java | 89 +++++++++++++++++++
.../sdk/json/CreateSessionRequest.java | 13 +++
.../copilot/sdk/json/CustomAgentConfig.java | 27 ++++++
.../sdk/json/PostToolUseHookInput.java | 24 +++++
.../copilot/sdk/json/PreToolUseHookInput.java | 24 +++++
.../copilot/sdk/json/SessionConfig.java | 31 +++++++
.../copilot/sdk/json/SessionEndHookInput.java | 5 +-
.../sdk/json/SessionStartHookInput.java | 5 +-
.../json/UserPromptSubmittedHookInput.java | 5 +-
src/site/markdown/advanced.md | 22 +++++
src/site/markdown/hooks.md | 11 ++-
13 files changed, 294 insertions(+), 6 deletions(-)
create mode 100644 src/main/java/com/github/copilot/sdk/json/CloudSessionOptions.java
create mode 100644 src/main/java/com/github/copilot/sdk/json/CloudSessionRepository.java
diff --git a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
index 52bfb3337f..0cdc4f942b 100644
--- a/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
+++ b/src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java
@@ -152,6 +152,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess
}
request.setGitHubToken(config.getGitHubToken());
request.setRemoteSession(config.getRemoteSession());
+ request.setCloud(config.getCloud());
return request;
}
diff --git a/src/main/java/com/github/copilot/sdk/json/CloudSessionOptions.java b/src/main/java/com/github/copilot/sdk/json/CloudSessionOptions.java
new file mode 100644
index 0000000000..897d07edaf
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/CloudSessionOptions.java
@@ -0,0 +1,43 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * Options for creating a remote session in the cloud.
+ *
+ * @since 1.5.0
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CloudSessionOptions {
+
+ @JsonProperty("repository")
+ private CloudSessionRepository repository;
+
+ /**
+ * Gets the optional GitHub repository metadata to associate with the cloud
+ * session.
+ *
+ * @return the repository metadata, or {@code null} if not set
+ */
+ public CloudSessionRepository getRepository() {
+ return repository;
+ }
+
+ /**
+ * Sets the optional GitHub repository metadata to associate with the cloud
+ * session.
+ *
+ * @param repository
+ * the repository metadata
+ * @return this instance for method chaining
+ */
+ public CloudSessionOptions setRepository(CloudSessionRepository repository) {
+ this.repository = repository;
+ return this;
+ }
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/CloudSessionRepository.java b/src/main/java/com/github/copilot/sdk/json/CloudSessionRepository.java
new file mode 100644
index 0000000000..5806c22cd7
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/json/CloudSessionRepository.java
@@ -0,0 +1,89 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk.json;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * GitHub repository metadata to associate with a cloud session.
+ *
+ * @since 1.5.0
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CloudSessionRepository {
+
+ @JsonProperty("owner")
+ private String owner;
+
+ @JsonProperty("name")
+ private String name;
+
+ @JsonProperty("branch")
+ private String branch;
+
+ /**
+ * Gets the repository owner.
+ *
+ * @return the repository owner
+ */
+ public String getOwner() {
+ return owner;
+ }
+
+ /**
+ * Sets the repository owner.
+ *
+ * @param owner
+ * the repository owner
+ * @return this instance for method chaining
+ */
+ public CloudSessionRepository setOwner(String owner) {
+ this.owner = owner;
+ return this;
+ }
+
+ /**
+ * Gets the repository name.
+ *
+ * @return the repository name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the repository name.
+ *
+ * @param name
+ * the repository name
+ * @return this instance for method chaining
+ */
+ public CloudSessionRepository setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ /**
+ * Gets the optional branch name.
+ *
+ * @return the branch name, or {@code null} if not set
+ */
+ public String getBranch() {
+ return branch;
+ }
+
+ /**
+ * Sets the optional branch name.
+ *
+ * @param branch
+ * the branch name
+ * @return this instance for method chaining
+ */
+ public CloudSessionRepository setBranch(String branch) {
+ this.branch = branch;
+ return this;
+ }
+}
diff --git a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
index d6bcc7b2b7..881840a736 100644
--- a/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
+++ b/src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java
@@ -127,6 +127,9 @@ public final class CreateSessionRequest {
@JsonProperty("remoteSession")
private String remoteSession;
+ @JsonProperty("cloud")
+ private CloudSessionOptions cloud;
+
/** Gets the model name. @return the model */
public String getModel() {
return model;
@@ -543,4 +546,14 @@ public String getRemoteSession() {
public void setRemoteSession(String remoteSession) {
this.remoteSession = remoteSession;
}
+
+ /** Gets the cloud session options. @return the cloud session options */
+ public CloudSessionOptions getCloud() {
+ return cloud;
+ }
+
+ /** Sets the cloud session options. @param cloud the cloud session options */
+ public void setCloud(CloudSessionOptions cloud) {
+ this.cloud = cloud;
+ }
}
diff --git a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
index bb9520055e..cb2dbf452b 100644
--- a/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/CustomAgentConfig.java
@@ -60,6 +60,9 @@ public class CustomAgentConfig {
@JsonProperty("skills")
private List skills;
+ @JsonProperty("model")
+ private String model;
+
/**
* Gets the unique identifier name for this agent.
*
@@ -255,4 +258,28 @@ public CustomAgentConfig setSkills(List skills) {
this.skills = skills;
return this;
}
+
+ /**
+ * Gets the model identifier for this agent.
+ *
+ * @return the model identifier, or {@code null} if not set
+ */
+ public String getModel() {
+ return model;
+ }
+
+ /**
+ * Sets the model identifier for this agent.
+ *
+ * When set, the runtime will attempt to use this model for the agent, falling
+ * back to the parent session model if unavailable.
+ *
+ * @param model
+ * the model identifier (e.g., "claude-haiku-4.5")
+ * @return this config for method chaining
+ */
+ public CustomAgentConfig setModel(String model) {
+ this.model = model;
+ return this;
+ }
}
diff --git a/src/main/java/com/github/copilot/sdk/json/PostToolUseHookInput.java b/src/main/java/com/github/copilot/sdk/json/PostToolUseHookInput.java
index 18e9201b54..4ac3985064 100644
--- a/src/main/java/com/github/copilot/sdk/json/PostToolUseHookInput.java
+++ b/src/main/java/com/github/copilot/sdk/json/PostToolUseHookInput.java
@@ -16,6 +16,9 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public class PostToolUseHookInput {
+ @JsonProperty("sessionId")
+ private String sessionId;
+
@JsonProperty("timestamp")
private long timestamp;
@@ -31,6 +34,27 @@ public class PostToolUseHookInput {
@JsonProperty("toolResult")
private JsonNode toolResult;
+ /**
+ * Gets the runtime session ID of the session that triggered the hook.
+ *
+ * @return the session ID
+ */
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ /**
+ * Sets the runtime session ID of the session that triggered the hook.
+ *
+ * @param sessionId
+ * the session ID
+ * @return this instance for method chaining
+ */
+ public PostToolUseHookInput setSessionId(String sessionId) {
+ this.sessionId = sessionId;
+ return this;
+ }
+
/**
* Gets the timestamp of the hook invocation.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/PreToolUseHookInput.java b/src/main/java/com/github/copilot/sdk/json/PreToolUseHookInput.java
index 63785e98d3..6cbab78b7f 100644
--- a/src/main/java/com/github/copilot/sdk/json/PreToolUseHookInput.java
+++ b/src/main/java/com/github/copilot/sdk/json/PreToolUseHookInput.java
@@ -16,6 +16,9 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public class PreToolUseHookInput {
+ @JsonProperty("sessionId")
+ private String sessionId;
+
@JsonProperty("timestamp")
private long timestamp;
@@ -28,6 +31,27 @@ public class PreToolUseHookInput {
@JsonProperty("toolArgs")
private JsonNode toolArgs;
+ /**
+ * Gets the runtime session ID of the session that triggered the hook.
+ *
+ * @return the session ID
+ */
+ public String getSessionId() {
+ return sessionId;
+ }
+
+ /**
+ * Sets the runtime session ID of the session that triggered the hook.
+ *
+ * @param sessionId
+ * the session ID
+ * @return this instance for method chaining
+ */
+ public PreToolUseHookInput setSessionId(String sessionId) {
+ this.sessionId = sessionId;
+ return this;
+ }
+
/**
* Gets the timestamp of the hook invocation.
*
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
index f1a383402f..ddf06cca7f 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionConfig.java
@@ -72,6 +72,7 @@ public class SessionConfig {
private AutoModeSwitchHandler onAutoModeSwitch;
private String gitHubToken;
private String remoteSession;
+ private CloudSessionOptions cloud;
/**
* Gets the custom session ID.
@@ -979,6 +980,35 @@ public SessionConfig setRemoteSession(String remoteSession) {
return this;
}
+ /**
+ * Gets the cloud session options.
+ *
+ * When set, creates a remote session in the cloud instead of a local session.
+ * The optional repository is associated with the cloud session.
+ *
+ * @return the cloud session options, or {@code null} if not set
+ * @since 1.5.0
+ */
+ public CloudSessionOptions getCloud() {
+ return cloud;
+ }
+
+ /**
+ * Sets the cloud session options.
+ *
+ * When set, creates a remote session in the cloud instead of a local session.
+ * The optional repository is associated with the cloud session.
+ *
+ * @param cloud
+ * the cloud session options
+ * @return this config instance for method chaining
+ * @since 1.5.0
+ */
+ public SessionConfig setCloud(CloudSessionOptions cloud) {
+ this.cloud = cloud;
+ return this;
+ }
+
/**
* Creates a shallow clone of this {@code SessionConfig} instance.
*
@@ -1029,6 +1059,7 @@ public SessionConfig clone() {
copy.onAutoModeSwitch = this.onAutoModeSwitch;
copy.gitHubToken = this.gitHubToken;
copy.remoteSession = this.remoteSession;
+ copy.cloud = this.cloud;
return copy;
}
}
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionEndHookInput.java b/src/main/java/com/github/copilot/sdk/json/SessionEndHookInput.java
index 79f63fbb93..0d3d3e2945 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionEndHookInput.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionEndHookInput.java
@@ -13,6 +13,8 @@
* This hook is invoked when a session ends, allowing you to perform cleanup or
* logging.
*
+ * @param sessionId
+ * the runtime session ID of the session that triggered the hook
* @param timestamp
* the timestamp in milliseconds since epoch when the session ended
* @param cwd
@@ -27,7 +29,8 @@
* @since 1.0.7
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public record SessionEndHookInput(@JsonProperty("timestamp") long timestamp, @JsonProperty("cwd") String cwd,
+public record SessionEndHookInput(@JsonProperty("sessionId") String sessionId,
+ @JsonProperty("timestamp") long timestamp, @JsonProperty("cwd") String cwd,
@JsonProperty("reason") String reason, @JsonProperty("finalMessage") String finalMessage,
@JsonProperty("error") String error) {
}
diff --git a/src/main/java/com/github/copilot/sdk/json/SessionStartHookInput.java b/src/main/java/com/github/copilot/sdk/json/SessionStartHookInput.java
index 2047175572..55bff3e262 100644
--- a/src/main/java/com/github/copilot/sdk/json/SessionStartHookInput.java
+++ b/src/main/java/com/github/copilot/sdk/json/SessionStartHookInput.java
@@ -13,6 +13,8 @@
* This hook is invoked when a session starts, allowing you to perform
* initialization or modify the session configuration.
*
+ * @param sessionId
+ * the runtime session ID of the session that triggered the hook
* @param timestamp
* the timestamp in milliseconds since epoch when the session started
* @param cwd
@@ -24,6 +26,7 @@
* @since 1.0.7
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public record SessionStartHookInput(@JsonProperty("timestamp") long timestamp, @JsonProperty("cwd") String cwd,
+public record SessionStartHookInput(@JsonProperty("sessionId") String sessionId,
+ @JsonProperty("timestamp") long timestamp, @JsonProperty("cwd") String cwd,
@JsonProperty("source") String source, @JsonProperty("initialPrompt") String initialPrompt) {
}
diff --git a/src/main/java/com/github/copilot/sdk/json/UserPromptSubmittedHookInput.java b/src/main/java/com/github/copilot/sdk/json/UserPromptSubmittedHookInput.java
index bbfdf85bb3..2f3a0948df 100644
--- a/src/main/java/com/github/copilot/sdk/json/UserPromptSubmittedHookInput.java
+++ b/src/main/java/com/github/copilot/sdk/json/UserPromptSubmittedHookInput.java
@@ -13,6 +13,8 @@
* This hook is invoked when the user submits a prompt, allowing you to
* intercept and modify the prompt before it is processed.
*
+ * @param sessionId
+ * the runtime session ID of the session that triggered the hook
* @param timestamp
* the timestamp in milliseconds since epoch when the prompt was
* submitted
@@ -23,6 +25,7 @@
* @since 1.0.7
*/
@JsonIgnoreProperties(ignoreUnknown = true)
-public record UserPromptSubmittedHookInput(@JsonProperty("timestamp") long timestamp, @JsonProperty("cwd") String cwd,
+public record UserPromptSubmittedHookInput(@JsonProperty("sessionId") String sessionId,
+ @JsonProperty("timestamp") long timestamp, @JsonProperty("cwd") String cwd,
@JsonProperty("prompt") String prompt) {
}
diff --git a/src/site/markdown/advanced.md b/src/site/markdown/advanced.md
index 9b5d00c5ac..5f15d726b0 100644
--- a/src/site/markdown/advanced.md
+++ b/src/site/markdown/advanced.md
@@ -565,6 +565,8 @@ session.send("@code-reviewer Review src/Main.java").get();
| `tools` | List<String> | Tool names available to this agent |
| `mcpServers` | Map | MCP servers available to this agent |
| `infer` | Boolean | Whether the agent can be auto-selected based on context |
+| `skills` | List<String> | Skill names to preload into the agent's context |
+| `model` | String | Model identifier for this agent (e.g., "claude-haiku-4.5"); falls back to the parent session model if unavailable |
### Multiple Agents
@@ -1379,6 +1381,26 @@ try (var client = new CopilotClient(options)) {
- The session's working directory must be a GitHub repository
- This option is only used when the SDK spawns the CLI process; it is ignored when connecting to an external server via `setCliUrl()`
+### Cloud Sessions
+
+Cloud sessions create a remote session in the cloud instead of a local session. Optionally associate repository metadata with the cloud session:
+
+```java
+var cloudOptions = new CloudSessionOptions()
+ .setRepository(new CloudSessionRepository()
+ .setOwner("my-org")
+ .setName("my-repo")
+ .setBranch("main"));
+
+var session = client.createSession(
+ new SessionConfig()
+ .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
+ .setCloud(cloudOptions)
+).get();
+```
+
+See [CloudSessionOptions](apidocs/com/github/copilot/sdk/json/CloudSessionOptions.html) and [CloudSessionRepository](apidocs/com/github/copilot/sdk/json/CloudSessionRepository.html) Javadoc for details.
+
---
## Next Steps
diff --git a/src/site/markdown/hooks.md b/src/site/markdown/hooks.md
index 97c7468915..392f3fbf94 100644
--- a/src/site/markdown/hooks.md
+++ b/src/site/markdown/hooks.md
@@ -53,6 +53,7 @@ Called **before** a tool executes. Use this to:
| Field | Type | Description |
|-------|------|-------------|
+| `getSessionId()` | `String` | Runtime session ID of the session that triggered the hook |
| `getToolName()` | `String` | Name of the tool being called |
| `getToolArgs()` | `JsonNode` | Arguments passed to the tool |
| `getCwd()` | `String` | Current working directory |
@@ -130,6 +131,7 @@ Called **after** a tool executes. Use this to:
| Field | Type | Description |
|-------|------|-------------|
+| `getSessionId()` | `String` | Runtime session ID of the session that triggered the hook |
| `getToolName()` | `String` | Name of the tool that was called |
| `getToolArgs()` | `JsonNode` | Arguments that were passed |
| `getToolResult()` | `JsonNode` | Result from the tool |
@@ -187,8 +189,9 @@ Called when the user submits a prompt, before the LLM processes it. This is an o
| Field | Type | Description |
|-------|------|-------------|
+| `sessionId()` | `String` | Runtime session ID of the session that triggered the hook |
| `prompt()` | `String` | The user's prompt text |
-| `getTimestamp()` | `long` | Timestamp in milliseconds |
+| `timestamp()` | `long` | Timestamp in milliseconds |
### Output
@@ -221,8 +224,9 @@ Called when a session starts (either new or resumed).
| Field | Type | Description |
|-------|------|-------------|
+| `sessionId()` | `String` | Runtime session ID of the session that triggered the hook |
| `source()` | `String` | `"startup"`, `"resume"`, or `"new"` |
-| `getTimestamp()` | `long` | Timestamp in milliseconds |
+| `timestamp()` | `long` | Timestamp in milliseconds |
### Output
@@ -253,8 +257,9 @@ Called when a session ends.
| Field | Type | Description |
|-------|------|-------------|
+| `sessionId()` | `String` | Runtime session ID of the session that triggered the hook |
| `reason()` | `String` | Why the session ended |
-| `getTimestamp()` | `long` | Timestamp in milliseconds |
+| `timestamp()` | `long` | Timestamp in milliseconds |
### Output
From 86e0cd54a1e411a4e2b59149a87f6cdeb37027be Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 18 May 2026 17:41:40 +0000
Subject: [PATCH 055/135] Update .lastmerge to
f6c1adf8329ad4206e5ed2e8d12fb8082bc841a2, sync pom.xml CLI version, and
update scripts/codegen @github/copilot version
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
---
.lastmerge | 2 +-
pom.xml | 2 +-
scripts/codegen/package-lock.json | 78 ++++++++++---------------------
scripts/codegen/package.json | 2 +-
4 files changed, 27 insertions(+), 57 deletions(-)
diff --git a/.lastmerge b/.lastmerge
index 600b63a547..88ed2a9523 100644
--- a/.lastmerge
+++ b/.lastmerge
@@ -1 +1 @@
-e20f5bef125860accb30c60d1b35109371a77f16
+f6c1adf8329ad4206e5ed2e8d12fb8082bc841a2
diff --git a/pom.xml b/pom.xml
index be73738041..d251fbce6e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,7 +94,7 @@
reference-impl-sync workflow and deal with the subsequent
PR.
-->
- ^1.0.48
+ ^1.0.49-1
diff --git a/scripts/codegen/package-lock.json b/scripts/codegen/package-lock.json
index 36d7689a71..c1d610b39d 100644
--- a/scripts/codegen/package-lock.json
+++ b/scripts/codegen/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "copilot-sdk-java-codegen",
"dependencies": {
- "@github/copilot": "^1.0.48",
+ "@github/copilot": "^1.0.49-1",
"json-schema": "^0.4.0",
"tsx": "^4.20.6"
}
@@ -428,26 +428,28 @@
}
},
"node_modules/@github/copilot": {
- "version": "1.0.48",
- "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.48.tgz",
- "integrity": "sha512-U5SzyTEq376UU9A4Sd3TEKz+Y2nRUd90cLO4Hc1otaB8yFSy9Ur2UVGcI2/wCoodL3a39k6WbdgNzFxr0gWFRQ==",
+ "version": "1.0.49-3",
+ "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.49-3.tgz",
+ "integrity": "sha512-MoaUolkTfeDTeUpKjzLNZLyykdJmhW7xNEzSmM+zz9erZE0St1ACFz3TigJMM05r4L1cPR6j1TY37XfPExqdyg==",
"license": "SEE LICENSE IN LICENSE.md",
"bin": {
"copilot": "npm-loader.js"
},
"optionalDependencies": {
- "@github/copilot-darwin-arm64": "1.0.48",
- "@github/copilot-darwin-x64": "1.0.48",
- "@github/copilot-linux-arm64": "1.0.48",
- "@github/copilot-linux-x64": "1.0.48",
- "@github/copilot-win32-arm64": "1.0.48",
- "@github/copilot-win32-x64": "1.0.48"
+ "@github/copilot-darwin-arm64": "1.0.49-3",
+ "@github/copilot-darwin-x64": "1.0.49-3",
+ "@github/copilot-linux-arm64": "1.0.49-3",
+ "@github/copilot-linux-x64": "1.0.49-3",
+ "@github/copilot-linuxmusl-arm64": "1.0.49-3",
+ "@github/copilot-linuxmusl-x64": "1.0.49-3",
+ "@github/copilot-win32-arm64": "1.0.49-3",
+ "@github/copilot-win32-x64": "1.0.49-3"
}
},
"node_modules/@github/copilot-darwin-arm64": {
- "version": "1.0.48",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.48.tgz",
- "integrity": "sha512-82MLoMQwPVVFM8EYssihFxSEPUYtZADE8rMzQ3jG9HgRg2qjQSfnHQS1mKe64dlXswZUK/onw6/8kjnW5I4pPg==",
+ "version": "1.0.49-3",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.49-3.tgz",
+ "integrity": "sha512-z6WpgoT+aro2nuA2zGfpxsMPtGSS3ZNACXERjfBxBzEoVjTMJi8kD1tpHFIPPCcLfaLniIi01Q6rvxMmZC6iKw==",
"cpu": [
"arm64"
],
@@ -461,9 +463,9 @@
}
},
"node_modules/@github/copilot-darwin-x64": {
- "version": "1.0.48",
- "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.48.tgz",
- "integrity": "sha512-1VQ5r5F0h8GwboXmZTcutqcJT+iCpPXAF27QqodmpKEvW9aYfG8g9X2kFJOzDZoX+SA3Uaka9qXdYKF2xT6Uog==",
+ "version": "1.0.49-3",
+ "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.49-3.tgz",
+ "integrity": "sha512-ox9zs0uaFroB5SujopKFMz6/1shs2JsI5eIx4Kb/gugDrwU+Y3VVJJLw+dbEElJjQOCsb33kD9n+MsV1T6dubA==",
"cpu": [
"x64"
],
@@ -477,9 +479,9 @@
}
},
"node_modules/@github/copilot-linux-arm64": {
- "version": "1.0.48",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.48.tgz",
- "integrity": "sha512-PmsGnb0DZlI+Bf53l9HM1PAHHkUcMyB4y8v/7tnC/jDOV5dGF124n0HnDNfJLOLiJGiQGodthIif6QtPaAxpeA==",
+ "version": "1.0.49-3",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.49-3.tgz",
+ "integrity": "sha512-1uZaRtTH5H8HcPWKiN7eWJHsmmaW+tq6Eaxdme95Dfup4G9hemZMDHfdTjPXjZ6xykuoVKqWgC6knlk71JTWxQ==",
"cpu": [
"arm64"
],
@@ -493,9 +495,9 @@
}
},
"node_modules/@github/copilot-linux-x64": {
- "version": "1.0.48",
- "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.48.tgz",
- "integrity": "sha512-b2cc4euSlke9fYHXXsS2EL9UYbctN0h4lZvtAcKUDY+RCnpYAQOVBZK+c1R9dQrtsT6Z/yUv7PuFPSs8qdtc2Q==",
+ "version": "1.0.49-3",
+ "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.49-3.tgz",
+ "integrity": "sha512-OebfGDDFFn+KbiEbSHX8TvXRe77JeH1SBJyzle5QRSD/nBqNGEkNClRMGm8M5/cqyke6TbRP2XmmAQAApJmaQA==",
"cpu": [
"x64"
],
@@ -508,38 +510,6 @@
"copilot-linux-x64": "copilot"
}
},
- "node_modules/@github/copilot-win32-arm64": {
- "version": "1.0.48",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.48.tgz",
- "integrity": "sha512-VEEOwddtpJ3DTbXGhnK6K8im4ofl9m08q1m/K++sNvWV8wkkOSOQBTiPdyUsuU/TXAoFhb8tZMIJv+6NnMBtMw==",
- "cpu": [
- "arm64"
- ],
- "license": "SEE LICENSE IN LICENSE.md",
- "optional": true,
- "os": [
- "win32"
- ],
- "bin": {
- "copilot-win32-arm64": "copilot.exe"
- }
- },
- "node_modules/@github/copilot-win32-x64": {
- "version": "1.0.48",
- "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.48.tgz",
- "integrity": "sha512-93BzvXLPHTyy1gWBXQY/IWIHor4IAwZuuo7/obG80/Qa6U0WeaN9slz/FBJvrsgVNrrRfEID5Xm3At+S6Kj67Q==",
- "cpu": [
- "x64"
- ],
- "license": "SEE LICENSE IN LICENSE.md",
- "optional": true,
- "os": [
- "win32"
- ],
- "bin": {
- "copilot-win32-x64": "copilot.exe"
- }
- },
"node_modules/esbuild": {
"version": "0.27.7",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz",
diff --git a/scripts/codegen/package.json b/scripts/codegen/package.json
index 82454e774e..8726bacc12 100644
--- a/scripts/codegen/package.json
+++ b/scripts/codegen/package.json
@@ -7,7 +7,7 @@
"generate:java": "tsx java.ts"
},
"dependencies": {
- "@github/copilot": "^1.0.48",
+ "@github/copilot": "^1.0.49-1",
"json-schema": "^0.4.0",
"tsx": "^4.20.6"
}
From 9f71da83df4f194a855d9cb4ed316a13c081daae Mon Sep 17 00:00:00 2001
From: Ed Burns
Date: Mon, 18 May 2026 11:37:41 -0700
Subject: [PATCH 056/135] Drift management policy
---
.github/aw/actions-lock.json | 6 +-
.../workflows/reference-impl-sync.lock.yml | 214 +++++++++++-------
.github/workflows/reference-impl-sync.md | 2 +-
3 files changed, 135 insertions(+), 87 deletions(-)
diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json
index 6a6fa53d9f..71291dd03b 100644
--- a/.github/aw/actions-lock.json
+++ b/.github/aw/actions-lock.json
@@ -40,10 +40,10 @@
"version": "v7.0.1",
"sha": "043fb46d1a93c77aae656e7c1c64a875d1fc6a0a"
},
- "github/gh-aw-actions/setup@v0.71.5": {
+ "github/gh-aw-actions/setup@v0.74.4": {
"repo": "github/gh-aw-actions/setup",
- "version": "v0.71.5",
- "sha": "b8068426813005612b960b5ab0b8bd2c27142323"
+ "version": "v0.74.4",
+ "sha": "d3abfe96a194bce3a523ed2093ddedd5704cdf62"
},
"github/gh-aw/actions/setup@v0.51.6": {
"repo": "github/gh-aw/actions/setup",
diff --git a/.github/workflows/reference-impl-sync.lock.yml b/.github/workflows/reference-impl-sync.lock.yml
index 72ae7105b7..98fd0d0d0b 100644
--- a/.github/workflows/reference-impl-sync.lock.yml
+++ b/.github/workflows/reference-impl-sync.lock.yml
@@ -1,5 +1,5 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"54b1896209b363ceadbcb123b6c46dbbcc0118d9140313360c341b09d03bbb96","compiler_version":"v0.71.5","strict":true,"agent_id":"copilot"}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_AGENT_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"b8068426813005612b960b5ab0b8bd2c27142323","version":"v0.71.5"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.40","digest":"sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40","digest":"sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.40","digest":"sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"d3b88eb52d0d4007c7a64118dfa3866bcbba7589a38004bb5c47695bee9e7ac7","compiler_version":"v0.74.4","strict":true,"agent_id":"copilot"}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_AGENT_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"d3abfe96a194bce3a523ed2093ddedd5704cdf62","version":"v0.74.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.46"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.46"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.9","digest":"sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
# ___ _ _
# / _ \ | | (_)
# | |_| | __ _ ___ _ __ | |_ _ ___
@@ -14,7 +14,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
-# This file was automatically generated by gh-aw (v0.71.5). DO NOT EDIT.
+# This file was automatically generated by gh-aw (v0.74.4). DO NOT EDIT.
#
# To update this file, edit the corresponding .md file and run:
# gh aw compile
@@ -39,21 +39,21 @@
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
+# - github/gh-aw-actions/setup@d3abfe96a194bce3a523ed2093ddedd5704cdf62 # v0.74.4
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280
-# - ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51
-# - ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c
-# - ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959
+# - ghcr.io/github/gh-aw-firewall/agent:0.25.46
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46
+# - ghcr.io/github/gh-aw-firewall/squid:0.25.46
+# - ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388
+# - ghcr.io/github/github-mcp-server:v1.0.4
# - node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
name: "Reference Implementation Sync"
-"on":
+on:
schedule:
- - cron: "10 16 * * *"
- # Friendly format: daily (scattered)
+ - cron: "25 2 * * 5"
+ # Friendly format: weekly on friday (scattered)
workflow_dispatch:
inputs:
aw_context:
@@ -82,35 +82,38 @@ jobs:
lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
model: ${{ steps.generate_aw_info.outputs.model }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
setup-trace-id: ${{ steps.setup.outputs.trace-id }}
stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
+ uses: github/gh-aw-actions/setup@d3abfe96a194bce3a523ed2093ddedd5704cdf62 # v0.74.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.40"
+ GH_AW_INFO_VERSION: "1.0.48"
+ GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
id: generate_aw_info
env:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }}
- GH_AW_INFO_VERSION: "1.0.40"
- GH_AW_INFO_AGENT_VERSION: "1.0.40"
- GH_AW_INFO_CLI_VERSION: "v0.71.5"
+ GH_AW_INFO_VERSION: "1.0.48"
+ GH_AW_INFO_AGENT_VERSION: "1.0.48"
+ GH_AW_INFO_CLI_VERSION: "v0.74.4"
GH_AW_INFO_WORKFLOW_NAME: "Reference Implementation Sync"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.25.40"
+ GH_AW_INFO_AWF_VERSION: "v0.25.46"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -162,7 +165,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.71.5"
+ GH_AW_COMPILED_VERSION: "v0.74.4"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -173,11 +176,11 @@ jobs:
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
GH_AW_GITHUB_ACTOR: ${{ github.actor }}
- GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
- GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
- GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
- GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
@@ -185,54 +188,54 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_c9d6e485c3f68bea_EOF'
+ cat << 'GH_AW_PROMPT_5937f7f329fed3c9_EOF'
- GH_AW_PROMPT_c9d6e485c3f68bea_EOF
+ GH_AW_PROMPT_5937f7f329fed3c9_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_c9d6e485c3f68bea_EOF'
+ cat << 'GH_AW_PROMPT_5937f7f329fed3c9_EOF'
Tools: add_comment(max:10), create_issue, close_issue(max:10), close_pull_request(max:10), assign_to_agent, missing_tool, missing_data, noop
- GH_AW_PROMPT_c9d6e485c3f68bea_EOF
+ GH_AW_PROMPT_5937f7f329fed3c9_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_c9d6e485c3f68bea_EOF'
+ cat << 'GH_AW_PROMPT_5937f7f329fed3c9_EOF'
The following GitHub context information is available for this workflow:
- {{#if __GH_AW_GITHUB_ACTOR__ }}
+ {{#if github.actor}}
- **actor**: __GH_AW_GITHUB_ACTOR__
{{/if}}
- {{#if __GH_AW_GITHUB_REPOSITORY__ }}
+ {{#if github.repository}}
- **repository**: __GH_AW_GITHUB_REPOSITORY__
{{/if}}
- {{#if __GH_AW_GITHUB_WORKSPACE__ }}
+ {{#if github.workspace}}
- **workspace**: __GH_AW_GITHUB_WORKSPACE__
{{/if}}
- {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }}
- - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__
+ {{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}
+ - **issue-number**: #__GH_AW_EXPR_802A9F6A__
{{/if}}
- {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }}
- - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__
+ {{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}
+ - **discussion-number**: #__GH_AW_EXPR_1A3A194A__
{{/if}}
- {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }}
- - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__
+ {{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}
+ - **pull-request-number**: #__GH_AW_EXPR_463A214A__
{{/if}}
- {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }}
- - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__
+ {{#if github.event.comment.id || github.aw.context.comment_id}}
+ - **comment-id**: __GH_AW_EXPR_FF1D34CE__
{{/if}}
- {{#if __GH_AW_GITHUB_RUN_ID__ }}
+ {{#if github.run_id}}
- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
{{/if}}
- GH_AW_PROMPT_c9d6e485c3f68bea_EOF
+ GH_AW_PROMPT_5937f7f329fed3c9_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_c9d6e485c3f68bea_EOF'
+ cat << 'GH_AW_PROMPT_5937f7f329fed3c9_EOF'
{{#runtime-import .github/workflows/reference-impl-sync.md}}
- GH_AW_PROMPT_c9d6e485c3f68bea_EOF
+ GH_AW_PROMPT_5937f7f329fed3c9_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -249,11 +252,11 @@ jobs:
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
+ GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
GH_AW_GITHUB_ACTOR: ${{ github.actor }}
- GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
- GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
- GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
- GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
@@ -269,11 +272,11 @@ jobs:
return await substitutePlaceholders({
file: process.env.GH_AW_PROMPT,
substitutions: {
+ GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A,
+ GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A,
+ GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A,
+ GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE,
GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
- GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID,
- GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER,
- GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER,
- GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
@@ -299,8 +302,11 @@ jobs:
path: |
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/aw-prompts/prompt.txt
+ /tmp/gh-aw/aw-prompts/prompt-template.txt
+ /tmp/gh-aw/aw-prompts/prompt-import-tree.json
/tmp/gh-aw/github_rate_limits.jsonl
/tmp/gh-aw/base
+ /tmp/gh-aw/.github/agents
if-no-files-found: ignore
retention-days: 1
@@ -325,6 +331,7 @@ jobs:
agentic_engine_timeout: ${{ steps.detect-copilot-errors.outputs.agentic_engine_timeout || 'false' }}
checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
+ effective_tokens_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.effective_tokens_rate_limit_error || 'false' }}
has_patch: ${{ steps.collect_output.outputs.has_patch }}
inference_access_error: ${{ steps.detect-copilot-errors.outputs.inference_access_error || 'false' }}
mcp_policy_error: ${{ steps.detect-copilot-errors.outputs.mcp_policy_error || 'false' }}
@@ -332,19 +339,23 @@ jobs:
model_not_supported_error: ${{ steps.detect-copilot-errors.outputs.model_not_supported_error || 'false' }}
output: ${{ steps.collect_output.outputs.output }}
output_types: ${{ steps.collect_output.outputs.output_types }}
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
setup-trace-id: ${{ steps.setup.outputs.trace-id }}
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
+ uses: github/gh-aw-actions/setup@d3abfe96a194bce3a523ed2093ddedd5704cdf62 # v0.74.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.40"
+ GH_AW_INFO_VERSION: "1.0.48"
+ GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
run: |
@@ -391,11 +402,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.40
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.48
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.40
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.46
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -417,16 +428,21 @@ jobs:
GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi"
GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
+ - name: Restore inline sub-agents from activation artifact
+ env:
+ GH_AW_SUB_AGENT_DIR: ".github/agents"
+ GH_AW_SUB_AGENT_EXT: ".agent.md"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh"
- name: Download container images
- run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280 ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51 ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.46 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46 ghcr.io/github/gh-aw-firewall/squid:0.25.46 ghcr.io/github/gh-aw-mcpg:v0.3.9@sha256:64828b42a4482f58fab16509d7f8f495a6d97c972a98a68aff20543531ac0388 ghcr.io/github/github-mcp-server:v1.0.4 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_06a3a494957bf1f1_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_8434d42e1eaff150_EOF'
{"add_comment":{"max":10,"target":"*"},"assign_to_agent":{"max":1,"model":"claude-opus-4.6","name":"copilot","target":"*"},"close_issue":{"max":10,"required_labels":["reference-impl-sync"],"target":"*"},"close_pull_request":{"max":10,"target":"*"},"create_issue":{"expires":144,"labels":["reference-impl-sync"],"max":1,"title_prefix":"[reference-impl-sync] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_06a3a494957bf1f1_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_8434d42e1eaff150_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -535,6 +551,9 @@ jobs:
"sanitize": true,
"maxLength": 65000
},
+ "fields": {
+ "type": "array"
+ },
"labels": {
"type": "array",
"itemType": "string",
@@ -708,17 +727,22 @@ jobs:
export GH_AW_ENGINE="copilot"
MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
- DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.6'
+ case "${DOCKER_HOST:-}" in
+ unix://* ) DOCKER_SOCK_PATH="${DOCKER_HOST#unix://}" ;;
+ /* ) DOCKER_SOCK_PATH="$DOCKER_HOST" ;;
+ * ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
+ esac
+ DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.9'
mkdir -p /home/runner/.copilot
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_03f014fbed5a3560_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_91f5ce417df04baa_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.0.3",
+ "container": "ghcr.io/github/github-mcp-server:v1.0.4",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -754,7 +778,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_03f014fbed5a3560_EOF
+ GH_AW_MCP_CONFIG_91f5ce417df04baa_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -782,15 +806,21 @@ jobs:
timeout-minutes: 20
run: |
set -o pipefail
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
touch /tmp/gh-aw/agent-step-summary.md
GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
export GH_AW_NODE_BIN
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.40/awf-config.schema.json","network":{"allowDomains":["*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","lfs.github.com","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"models":{"auto":["large"],"deep-research":["copilot/deep-research*","google/deep-research*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash"],"opus":["copilot/*opus*","anthropic/*opus*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"]}},"container":{"imageTag":"0.25.40,squid=sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51,agent=sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504,api-proxy=sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280,cli-proxy=sha256:3e7152911d4b4b7b97beef9d3d7d924ff7902227e86001ef3838fb728d5d514c"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.46/awf-config.schema.json","network":{"allowDomains":["*.githubusercontent.com","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","codeload.github.com","crl.geotrust.com","crl.globalsign.com","crl.identrust.com","crl.sectigo.com","crl.thawte.com","crl.usertrust.com","crl.verisign.com","crl3.digicert.com","crl4.digicert.com","crls.ssl.com","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","lfs.github.com","objects.githubusercontent.com","ocsp.digicert.com","ocsp.geotrust.com","ocsp.globalsign.com","ocsp.identrust.com","ocsp.sectigo.com","ocsp.ssl.com","ocsp.thawte.com","ocsp.usertrust.com","ocsp.verisign.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"models":{"auto":["large"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"deep-research":["copilot/deep-research*","copilot/o3-deep-research*","copilot/o4-mini-deep-research*","google/deep-research*","gemini/deep-research*","openai/o3-deep-research*","openai/o4-mini-deep-research*"],"gemini-flash":["copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"],"gemini-flash-lite":["copilot/gemini-*flash*lite*","google/gemini-*flash*lite*","gemini/gemini-*flash*lite*"],"gemini-pro":["copilot/gemini-*pro*","google/gemini-*pro*","gemini/gemini-*pro*"],"gemma":["copilot/gemma*","google/gemma*","gemini/gemma*"],"gpt-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"gpt-5":["copilot/gpt-5*","openai/gpt-5*"],"gpt-5-codex":["copilot/gpt-5*codex*","openai/gpt-5*codex*"],"gpt-5-mini":["copilot/gpt-5*mini*","openai/gpt-5*mini*"],"gpt-5-nano":["copilot/gpt-5*nano*","openai/gpt-5*nano*"],"gpt-5-pro":["copilot/gpt-5*pro*","openai/gpt-5*pro*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"opus":["copilot/*opus*","anthropic/*opus*"],"reasoning":["copilot/o1*","copilot/o3*","copilot/o4*","openai/o1*","openai/o3*","openai/o4*"],"small":["mini"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"vision":["copilot/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.25.46"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ fi
# shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || echo node)"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
+ AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_API_KEY: dummy-byok-key-for-offline-mode
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
@@ -799,7 +829,7 @@ jobs:
GH_AW_PHASE: agent
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_VERSION: v0.71.5
+ GH_AW_VERSION: v0.74.4
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -914,7 +944,7 @@ jobs:
run: |
# Fix permissions on firewall logs/audit dirs so they can be uploaded as artifacts
# AWF runs with sudo, creating files owned by root
- sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
+ sudo chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
@@ -991,6 +1021,7 @@ jobs:
concurrency:
group: "gh-aw-conclusion-reference-impl-sync"
cancel-in-progress: false
+ queue: max
outputs:
incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
noop_message: ${{ steps.noop.outputs.noop_message }}
@@ -999,15 +1030,17 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
+ uses: github/gh-aw-actions/setup@d3abfe96a194bce3a523ed2093ddedd5704cdf62 # v0.74.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.40"
+ GH_AW_INFO_VERSION: "1.0.48"
+ GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
@@ -1097,6 +1130,8 @@ jobs:
GH_AW_ENGINE_ID: "copilot"
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
+ GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
+ GH_AW_EFFECTIVE_TOKENS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.effective_tokens_rate_limit_error || 'false' }}
GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
@@ -1111,6 +1146,7 @@ jobs:
GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
GH_AW_TIMEOUT_MINUTES: "20"
+ GH_AW_MAX_EFFECTIVE_TOKENS: "25000000"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -1135,15 +1171,17 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
+ uses: github/gh-aw-actions/setup@d3abfe96a194bce3a523ed2093ddedd5704cdf62 # v0.74.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.40"
+ GH_AW_INFO_VERSION: "1.0.48"
+ GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
@@ -1169,7 +1207,7 @@ jobs:
rm -rf /tmp/gh-aw/sandbox/firewall/logs
rm -rf /tmp/gh-aw/sandbox/firewall/audit
- name: Download container images
- run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.40@sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.40@sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280 ghcr.io/github/gh-aw-firewall/squid:0.25.40@sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.46 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.46 ghcr.io/github/gh-aw-firewall/squid:0.25.46
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1228,11 +1266,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.40
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.48
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.40
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.46
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1241,22 +1279,28 @@ jobs:
timeout-minutes: 20
run: |
set -o pipefail
+ printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
touch /tmp/gh-aw/agent-step-summary.md
GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
export GH_AW_NODE_BIN
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.40/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","host.docker.internal","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true},"container":{"imageTag":"0.25.40,squid=sha256:b084f4a2c771f584ee68084ced52fa6b3245197a1889645d817462d307d3ac51,agent=sha256:14ff567e8d9d4c2fbc5e55c973488381c71d7e0fdbe72d30ee7b8a738fd86504,api-proxy=sha256:2883ca3e5ae9f330cafdd9345bfd4ae17fc8da36c96d4c9a1f76e922b4c45280,cli-proxy=sha256:3e7152911d4b4b7b97beef9d3d7d924ff7902227e86001ef3838fb728d5d514c"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.46/awf-config.schema.json","network":{"allowDomains":["api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","github.com","host.docker.internal","telemetry.enterprise.githubcopilot.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000},"container":{"imageTag":"0.25.46"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" && cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ fi
# shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || echo node)"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
+ AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_API_KEY: dummy-byok-key-for-offline-mode
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || 'claude-sonnet-4.6' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
- GH_AW_VERSION: v0.71.5
+ GH_AW_VERSION: v0.74.4
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1284,6 +1328,7 @@ jobs:
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
+ DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }}
GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
with:
script: |
@@ -1294,10 +1339,11 @@ jobs:
await main();
} catch (loadErr) {
const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false';
+ const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure';
const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr));
core.error(msg);
core.setOutput('reason', 'parse_error');
- if (continueOnError) {
+ if (continueOnError && !detectionExecutionFailed) {
core.warning('\u26A0\uFE0F ' + msg);
core.setOutput('conclusion', 'warning');
core.setOutput('success', 'false');
@@ -1328,7 +1374,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
- GH_AW_ENGINE_VERSION: "1.0.40"
+ GH_AW_ENGINE_VERSION: "1.0.48"
GH_AW_WORKFLOW_ID: "reference-impl-sync"
GH_AW_WORKFLOW_NAME: "Reference Implementation Sync"
outputs:
@@ -1348,15 +1394,17 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@b8068426813005612b960b5ab0b8bd2c27142323 # v0.71.5
+ uses: github/gh-aw-actions/setup@d3abfe96a194bce3a523ed2093ddedd5704cdf62 # v0.74.4
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Reference Implementation Sync"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/reference-impl-sync.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.40"
+ GH_AW_INFO_VERSION: "1.0.48"
+ GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
diff --git a/.github/workflows/reference-impl-sync.md b/.github/workflows/reference-impl-sync.md
index 20cad89e14..297ef6dbdf 100644
--- a/.github/workflows/reference-impl-sync.md
+++ b/.github/workflows/reference-impl-sync.md
@@ -4,7 +4,7 @@ description: |
Copilot SDK (github/copilot-sdk) and assigns to Copilot to port changes.
on:
- schedule: daily
+ schedule: weekly on friday
workflow_dispatch:
permissions:
From 86f469513d1cda60683bdd94af61d39c31169430 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 18 May 2026 18:47:34 +0000
Subject: [PATCH 057/135] Regenerate codegen output
Auto-committed by codegen-check workflow.
---
.../copilot/sdk/generated/AbortEvent.java | 2 +-
.../sdk/generated/AssistantIntentEvent.java | 2 +-
.../generated/AssistantMessageDeltaEvent.java | 2 +-
.../sdk/generated/AssistantMessageEvent.java | 2 +-
.../generated/AssistantMessageStartEvent.java | 2 +-
.../AssistantReasoningDeltaEvent.java | 2 +-
.../generated/AssistantReasoningEvent.java | 2 +-
.../AssistantStreamingDeltaEvent.java | 2 +-
.../sdk/generated/AssistantTurnEndEvent.java | 2 +-
.../generated/AssistantTurnStartEvent.java | 2 +-
.../sdk/generated/AssistantUsageEvent.java | 4 +-
.../AssistantUsageQuotaSnapshot.java | 5 ++
.../AutoModeSwitchCompletedEvent.java | 6 +--
.../AutoModeSwitchRequestedEvent.java | 2 +-
.../sdk/generated/AutoModeSwitchResponse.java | 37 ++++++++++++++
.../generated/CapabilitiesChangedEvent.java | 2 +-
.../sdk/generated/CommandCompletedEvent.java | 2 +-
.../sdk/generated/CommandExecuteEvent.java | 2 +-
.../sdk/generated/CommandQueuedEvent.java | 2 +-
.../sdk/generated/CommandsChangedCommand.java | 7 +++
.../sdk/generated/CommandsChangedEvent.java | 2 +-
.../generated/CustomAgentsUpdatedAgent.java | 5 ++
.../generated/ElicitationCompletedEvent.java | 2 +-
.../generated/ElicitationRequestedEvent.java | 2 +-
.../sdk/generated/ExitPlanModeAction.java | 39 +++++++++++++++
.../generated/ExitPlanModeCompletedEvent.java | 6 +--
.../generated/ExitPlanModeRequestedEvent.java | 10 ++--
.../generated/ExtensionsLoadedExtension.java | 5 ++
.../generated/ExternalToolCompletedEvent.java | 2 +-
.../generated/ExternalToolRequestedEvent.java | 2 +-
.../copilot/sdk/generated/HookEndEvent.java | 2 +-
.../copilot/sdk/generated/HookStartEvent.java | 2 +-
.../sdk/generated/McpOauthCompletedEvent.java | 2 +-
.../sdk/generated/McpOauthRequiredEvent.java | 2 +-
.../sdk/generated/McpServerSource.java | 39 +++++++++++++++
.../sdk/generated/McpServerStatus.java | 43 +++++++++++++++++
.../sdk/generated/McpServersLoadedServer.java | 9 +++-
.../sdk/generated/ModelCallFailureEvent.java | 2 +-
.../PendingMessagesModifiedEvent.java | 2 +-
.../generated/PermissionCompletedEvent.java | 2 +-
.../generated/PermissionRequestedEvent.java | 2 +-
.../sdk/generated/ReasoningSummary.java | 37 ++++++++++++++
.../sdk/generated/SamplingCompletedEvent.java | 2 +-
.../sdk/generated/SamplingRequestedEvent.java | 2 +-
.../SessionBackgroundTasksChangedEvent.java | 2 +-
.../SessionCompactionCompleteEvent.java | 2 +-
.../SessionCompactionStartEvent.java | 2 +-
.../generated/SessionContextChangedEvent.java | 2 +-
.../SessionCustomAgentsUpdatedEvent.java | 2 +-
.../SessionCustomNotificationEvent.java | 2 +-
.../sdk/generated/SessionErrorEvent.java | 2 +-
.../SessionExtensionsLoadedEvent.java | 2 +-
.../sdk/generated/SessionHandoffEvent.java | 2 +-
.../sdk/generated/SessionIdleEvent.java | 2 +-
.../sdk/generated/SessionInfoEvent.java | 2 +-
.../SessionMcpServerStatusChangedEvent.java | 6 +--
.../SessionMcpServersLoadedEvent.java | 2 +-
.../copilot/sdk/generated/SessionMode.java | 37 ++++++++++++++
.../generated/SessionModeChangedEvent.java | 10 ++--
.../generated/SessionModelChangeEvent.java | 6 ++-
.../generated/SessionPlanChangedEvent.java | 2 +-
.../SessionRemoteSteerableChangedEvent.java | 4 +-
.../sdk/generated/SessionResumeEvent.java | 8 ++--
.../SessionScheduleCancelledEvent.java | 2 +-
.../SessionScheduleCreatedEvent.java | 6 ++-
.../sdk/generated/SessionShutdownEvent.java | 2 +-
.../generated/SessionSkillsLoadedEvent.java | 2 +-
.../generated/SessionSnapshotRewindEvent.java | 2 +-
.../sdk/generated/SessionStartEvent.java | 8 ++--
.../generated/SessionTaskCompleteEvent.java | 2 +-
.../generated/SessionTitleChangedEvent.java | 2 +-
.../generated/SessionToolsUpdatedEvent.java | 3 +-
.../sdk/generated/SessionTruncationEvent.java | 2 +-
.../sdk/generated/SessionUsageInfoEvent.java | 2 +-
.../sdk/generated/SessionWarningEvent.java | 2 +-
.../SessionWorkspaceFileChangedEvent.java | 2 +-
.../sdk/generated/ShutdownModelMetric.java | 5 ++
.../ShutdownModelMetricTokenDetail.java | 5 ++
.../sdk/generated/ShutdownTokenDetail.java | 5 ++
.../sdk/generated/SkillInvokedEvent.java | 2 +-
.../copilot/sdk/generated/SkillSource.java | 45 +++++++++++++++++
.../sdk/generated/SkillsLoadedSkill.java | 9 +++-
.../sdk/generated/SubagentCompletedEvent.java | 2 +-
.../generated/SubagentDeselectedEvent.java | 2 +-
.../sdk/generated/SubagentFailedEvent.java | 2 +-
.../sdk/generated/SubagentSelectedEvent.java | 2 +-
.../sdk/generated/SubagentStartedEvent.java | 2 +-
.../sdk/generated/SystemMessageEvent.java | 2 +-
.../generated/SystemNotificationEvent.java | 2 +-
.../generated/ToolExecutionCompleteEvent.java | 2 +-
.../ToolExecutionPartialResultEvent.java | 2 +-
.../generated/ToolExecutionProgressEvent.java | 2 +-
.../generated/ToolExecutionStartEvent.java | 2 +-
.../sdk/generated/ToolUserRequestedEvent.java | 2 +-
.../generated/UserInputCompletedEvent.java | 2 +-
.../generated/UserInputRequestedEvent.java | 2 +-
.../sdk/generated/UserMessageEvent.java | 2 +-
.../generated/rpc/AccountGetQuotaResult.java | 2 +-
.../generated/rpc/AccountQuotaSnapshot.java | 10 +++-
.../copilot/sdk/generated/rpc/AgentInfo.java | 5 ++
.../sdk/generated/rpc/ConnectParams.java | 2 +-
.../sdk/generated/rpc/ConnectResult.java | 2 +-
.../rpc/ConnectedRemoteSessionMetadata.java | 48 +++++++++++++++++++
.../ConnectedRemoteSessionMetadataKind.java | 35 ++++++++++++++
...nectedRemoteSessionMetadataRepository.java | 31 ++++++++++++
.../generated/rpc/DiscoveredMcpServer.java | 11 +++--
.../rpc/DiscoveredMcpServerType.java | 2 +-
.../copilot/sdk/generated/rpc/Extension.java | 5 ++
.../generated/rpc/InstructionsSources.java | 5 ++
.../sdk/generated/rpc/McpConfigAddParams.java | 4 +-
.../generated/rpc/McpConfigDisableParams.java | 2 +-
.../generated/rpc/McpConfigEnableParams.java | 2 +-
.../generated/rpc/McpConfigListResult.java | 2 +-
.../generated/rpc/McpConfigRemoveParams.java | 2 +-
.../generated/rpc/McpConfigUpdateParams.java | 4 +-
.../sdk/generated/rpc/McpDiscoverParams.java | 2 +-
.../sdk/generated/rpc/McpDiscoverResult.java | 2 +-
.../copilot/sdk/generated/rpc/McpServer.java | 5 ++
.../copilot/sdk/generated/rpc/Model.java | 5 ++
.../rpc/ModelCapabilitiesOverrideLimits.java | 3 ++
...ModelCapabilitiesOverrideLimitsVision.java | 5 ++
.../ModelCapabilitiesOverrideSupports.java | 2 +
.../sdk/generated/rpc/ModelPolicy.java | 2 +-
.../sdk/generated/rpc/ModelPolicyState.java | 37 ++++++++++++++
.../sdk/generated/rpc/ModelsListResult.java | 2 +-
.../copilot/sdk/generated/rpc/PingParams.java | 2 +-
.../copilot/sdk/generated/rpc/PingResult.java | 2 +-
.../copilot/sdk/generated/rpc/Plugin.java | 5 ++
.../sdk/generated/rpc/ReasoningSummary.java | 37 ++++++++++++++
.../sdk/generated/rpc/RemoteSessionMode.java | 2 +-
.../sdk/generated/rpc/ServerAccountApi.java | 2 +-
.../sdk/generated/rpc/ServerMcpApi.java | 2 +-
.../sdk/generated/rpc/ServerMcpConfigApi.java | 12 ++---
.../sdk/generated/rpc/ServerModelsApi.java | 2 +-
.../copilot/sdk/generated/rpc/ServerRpc.java | 4 +-
.../sdk/generated/rpc/ServerSessionFsApi.java | 2 +-
.../sdk/generated/rpc/ServerSessionsApi.java | 12 ++++-
.../sdk/generated/rpc/ServerSkill.java | 7 ++-
.../sdk/generated/rpc/ServerSkillsApi.java | 2 +-
.../generated/rpc/ServerSkillsConfigApi.java | 2 +-
.../sdk/generated/rpc/ServerToolsApi.java | 2 +-
.../sdk/generated/rpc/SessionAgentApi.java | 10 ++--
.../rpc/SessionAgentDeselectParams.java | 2 +-
.../rpc/SessionAgentGetCurrentParams.java | 2 +-
.../rpc/SessionAgentGetCurrentResult.java | 2 +-
.../generated/rpc/SessionAgentListParams.java | 2 +-
.../generated/rpc/SessionAgentListResult.java | 2 +-
.../rpc/SessionAgentReloadParams.java | 2 +-
.../rpc/SessionAgentReloadResult.java | 2 +-
.../rpc/SessionAgentSelectParams.java | 2 +-
.../rpc/SessionAgentSelectResult.java | 2 +-
.../sdk/generated/rpc/SessionAuthApi.java | 2 +-
.../rpc/SessionAuthGetStatusParams.java | 2 +-
.../rpc/SessionAuthGetStatusResult.java | 2 +-
.../sdk/generated/rpc/SessionCommandsApi.java | 8 ++--
...ionCommandsHandlePendingCommandParams.java | 2 +-
...ionCommandsHandlePendingCommandResult.java | 2 +-
.../rpc/SessionCommandsInvokeParams.java | 2 +-
.../rpc/SessionCommandsListParams.java | 2 +-
.../rpc/SessionCommandsListResult.java | 2 +-
...nCommandsRespondToQueuedCommandParams.java | 2 +-
...nCommandsRespondToQueuedCommandResult.java | 2 +-
.../generated/rpc/SessionExtensionsApi.java | 8 ++--
.../rpc/SessionExtensionsDisableParams.java | 2 +-
.../rpc/SessionExtensionsEnableParams.java | 2 +-
.../rpc/SessionExtensionsListParams.java | 2 +-
.../rpc/SessionExtensionsListResult.java | 2 +-
.../rpc/SessionExtensionsReloadParams.java | 2 +-
.../sdk/generated/rpc/SessionFleetApi.java | 2 +-
.../rpc/SessionFleetStartParams.java | 2 +-
.../rpc/SessionFleetStartResult.java | 2 +-
.../rpc/SessionFsAppendFileParams.java | 2 +-
.../generated/rpc/SessionFsExistsParams.java | 2 +-
.../generated/rpc/SessionFsExistsResult.java | 2 +-
.../generated/rpc/SessionFsMkdirParams.java | 2 +-
.../rpc/SessionFsReadFileParams.java | 2 +-
.../rpc/SessionFsReadFileResult.java | 2 +-
.../generated/rpc/SessionFsReaddirParams.java | 2 +-
.../generated/rpc/SessionFsReaddirResult.java | 2 +-
.../rpc/SessionFsReaddirWithTypesEntry.java | 5 ++
.../rpc/SessionFsReaddirWithTypesParams.java | 2 +-
.../rpc/SessionFsReaddirWithTypesResult.java | 2 +-
.../generated/rpc/SessionFsRenameParams.java | 2 +-
.../sdk/generated/rpc/SessionFsRmParams.java | 2 +-
.../rpc/SessionFsSetProviderCapabilities.java | 27 +++++++++++
.../rpc/SessionFsSetProviderParams.java | 6 ++-
.../rpc/SessionFsSetProviderResult.java | 2 +-
.../rpc/SessionFsSqliteExistsParams.java | 27 +++++++++++
.../rpc/SessionFsSqliteExistsResult.java | 27 +++++++++++
.../rpc/SessionFsSqliteQueryParams.java | 34 +++++++++++++
.../rpc/SessionFsSqliteQueryResult.java | 37 ++++++++++++++
.../rpc/SessionFsSqliteQueryType.java | 37 ++++++++++++++
.../generated/rpc/SessionFsStatParams.java | 2 +-
.../generated/rpc/SessionFsStatResult.java | 2 +-
.../rpc/SessionFsWriteFileParams.java | 2 +-
.../sdk/generated/rpc/SessionHistoryApi.java | 4 +-
.../rpc/SessionHistoryCompactParams.java | 2 +-
.../rpc/SessionHistoryCompactResult.java | 2 +-
.../rpc/SessionHistoryTruncateParams.java | 2 +-
.../rpc/SessionHistoryTruncateResult.java | 2 +-
.../generated/rpc/SessionInstructionsApi.java | 2 +-
.../SessionInstructionsGetSourcesParams.java | 2 +-
.../SessionInstructionsGetSourcesResult.java | 2 +-
.../sdk/generated/rpc/SessionLogParams.java | 2 +-
.../sdk/generated/rpc/SessionLogResult.java | 2 +-
.../sdk/generated/rpc/SessionMcpApi.java | 8 ++--
.../rpc/SessionMcpDisableParams.java | 2 +-
.../generated/rpc/SessionMcpEnableParams.java | 2 +-
.../generated/rpc/SessionMcpListParams.java | 2 +-
.../generated/rpc/SessionMcpListResult.java | 2 +-
.../sdk/generated/rpc/SessionMcpOauthApi.java | 2 +-
.../rpc/SessionMcpOauthLoginParams.java | 2 +-
.../rpc/SessionMcpOauthLoginResult.java | 2 +-
.../generated/rpc/SessionMcpReloadParams.java | 2 +-
.../sdk/generated/rpc/SessionMode.java | 2 +-
.../sdk/generated/rpc/SessionModeApi.java | 4 +-
.../generated/rpc/SessionModeGetParams.java | 2 +-
.../generated/rpc/SessionModeSetParams.java | 4 +-
.../sdk/generated/rpc/SessionModelApi.java | 4 +-
.../rpc/SessionModelGetCurrentParams.java | 2 +-
.../rpc/SessionModelGetCurrentResult.java | 2 +-
.../rpc/SessionModelSwitchToParams.java | 6 ++-
.../rpc/SessionModelSwitchToResult.java | 2 +-
.../sdk/generated/rpc/SessionNameApi.java | 4 +-
.../generated/rpc/SessionNameGetParams.java | 2 +-
.../generated/rpc/SessionNameGetResult.java | 2 +-
.../generated/rpc/SessionNameSetParams.java | 2 +-
.../generated/rpc/SessionPermissionsApi.java | 6 +--
...sHandlePendingPermissionRequestParams.java | 3 +-
...sHandlePendingPermissionRequestResult.java | 2 +-
...ermissionsResetSessionApprovalsParams.java | 2 +-
...ermissionsResetSessionApprovalsResult.java | 2 +-
...SessionPermissionsSetApproveAllParams.java | 2 +-
...SessionPermissionsSetApproveAllResult.java | 2 +-
.../sdk/generated/rpc/SessionPlanApi.java | 6 +--
.../rpc/SessionPlanDeleteParams.java | 2 +-
.../generated/rpc/SessionPlanReadParams.java | 2 +-
.../generated/rpc/SessionPlanReadResult.java | 2 +-
.../rpc/SessionPlanUpdateParams.java | 2 +-
.../sdk/generated/rpc/SessionPluginsApi.java | 2 +-
.../rpc/SessionPluginsListParams.java | 2 +-
.../rpc/SessionPluginsListResult.java | 2 +-
.../sdk/generated/rpc/SessionRemoteApi.java | 4 +-
.../rpc/SessionRemoteDisableParams.java | 2 +-
.../rpc/SessionRemoteEnableParams.java | 4 +-
.../rpc/SessionRemoteEnableResult.java | 4 +-
.../copilot/sdk/generated/rpc/SessionRpc.java | 4 +-
.../sdk/generated/rpc/SessionShellApi.java | 4 +-
.../generated/rpc/SessionShellExecParams.java | 2 +-
.../generated/rpc/SessionShellExecResult.java | 2 +-
.../generated/rpc/SessionShellKillParams.java | 2 +-
.../generated/rpc/SessionShellKillResult.java | 2 +-
.../sdk/generated/rpc/SessionSkillsApi.java | 8 ++--
.../rpc/SessionSkillsDisableParams.java | 2 +-
.../rpc/SessionSkillsEnableParams.java | 2 +-
.../rpc/SessionSkillsListParams.java | 2 +-
.../rpc/SessionSkillsListResult.java | 2 +-
.../rpc/SessionSkillsReloadParams.java | 2 +-
.../rpc/SessionSkillsReloadResult.java | 2 +-
.../generated/rpc/SessionSuspendParams.java | 2 +-
.../sdk/generated/rpc/SessionTasksApi.java | 12 ++---
.../rpc/SessionTasksCancelParams.java | 2 +-
.../rpc/SessionTasksCancelResult.java | 2 +-
.../generated/rpc/SessionTasksListParams.java | 2 +-
.../generated/rpc/SessionTasksListResult.java | 2 +-
...SessionTasksPromoteToBackgroundParams.java | 2 +-
...SessionTasksPromoteToBackgroundResult.java | 2 +-
.../rpc/SessionTasksRemoveParams.java | 2 +-
.../rpc/SessionTasksRemoveResult.java | 2 +-
.../rpc/SessionTasksSendMessageParams.java | 2 +-
.../rpc/SessionTasksSendMessageResult.java | 2 +-
.../rpc/SessionTasksStartAgentParams.java | 2 +-
.../rpc/SessionTasksStartAgentResult.java | 2 +-
.../sdk/generated/rpc/SessionToolsApi.java | 2 +-
...ssionToolsHandlePendingToolCallParams.java | 2 +-
...ssionToolsHandlePendingToolCallResult.java | 2 +-
.../sdk/generated/rpc/SessionUiApi.java | 4 +-
.../rpc/SessionUiElicitationParams.java | 2 +-
...ssionUiHandlePendingElicitationParams.java | 2 +-
...ssionUiHandlePendingElicitationResult.java | 2 +-
.../sdk/generated/rpc/SessionUsageApi.java | 2 +-
.../rpc/SessionUsageGetMetricsParams.java | 2 +-
.../rpc/SessionUsageGetMetricsResult.java | 2 +-
.../generated/rpc/SessionWorkspacesApi.java | 8 ++--
.../SessionWorkspacesCreateFileParams.java | 2 +-
.../SessionWorkspacesGetWorkspaceParams.java | 2 +-
.../SessionWorkspacesGetWorkspaceResult.java | 2 +-
.../rpc/SessionWorkspacesListFilesParams.java | 2 +-
.../rpc/SessionWorkspacesListFilesResult.java | 2 +-
.../rpc/SessionWorkspacesReadFileParams.java | 2 +-
.../rpc/SessionWorkspacesReadFileResult.java | 2 +-
.../generated/rpc/SessionsConnectParams.java | 27 +++++++++++
.../generated/rpc/SessionsConnectResult.java | 29 +++++++++++
.../sdk/generated/rpc/SessionsForkParams.java | 2 +-
.../sdk/generated/rpc/SessionsForkResult.java | 2 +-
.../copilot/sdk/generated/rpc/Skill.java | 9 +++-
.../sdk/generated/rpc/SkillSource.java | 45 +++++++++++++++++
.../SkillsConfigSetDisabledSkillsParams.java | 2 +-
.../generated/rpc/SkillsDiscoverParams.java | 2 +-
.../generated/rpc/SkillsDiscoverResult.java | 2 +-
.../sdk/generated/rpc/SlashCommandInfo.java | 5 ++
.../copilot/sdk/generated/rpc/Tool.java | 5 ++
.../sdk/generated/rpc/ToolsListParams.java | 2 +-
.../sdk/generated/rpc/ToolsListResult.java | 2 +-
.../rpc/UsageMetricsModelMetric.java | 5 ++
.../UsageMetricsModelMetricTokenDetail.java | 5 ++
.../rpc/UsageMetricsTokenDetail.java | 5 ++
307 files changed, 1259 insertions(+), 340 deletions(-)
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchResponse.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeAction.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/McpServerSource.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/McpServerStatus.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/ReasoningSummary.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/SessionMode.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/SkillSource.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadata.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadataKind.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadataRepository.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPolicyState.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/ReasoningSummary.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionFsSetProviderCapabilities.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionFsSqliteExistsParams.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionFsSqliteExistsResult.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionFsSqliteQueryParams.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionFsSqliteQueryResult.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionFsSqliteQueryType.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsConnectParams.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SessionsConnectResult.java
create mode 100644 src/generated/java/com/github/copilot/sdk/generated/rpc/SkillSource.java
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AbortEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AbortEvent.java
index 16cfabc0e6..297f23f722 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AbortEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AbortEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code abort} session event.
+ * Session event "abort". Turn abort information including the reason for termination
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantIntentEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantIntentEvent.java
index a1c22edfb1..332daeb179 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantIntentEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantIntentEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.intent} session event.
+ * Session event "assistant.intent". Agent intent description for current activity or plan
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageDeltaEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageDeltaEvent.java
index 128608a1e1..ff84f757d5 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageDeltaEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageDeltaEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.message_delta} session event.
+ * Session event "assistant.message_delta". Streaming assistant message delta for incremental response updates
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageEvent.java
index 3ac0b9780a..98af7b90ad 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.message} session event.
+ * Session event "assistant.message". Assistant response containing text content, optional tool requests, and interaction metadata
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageStartEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageStartEvent.java
index 8cf1a9c8e7..8a83da9439 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageStartEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantMessageStartEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.message_start} session event.
+ * Session event "assistant.message_start". Streaming assistant message start metadata
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantReasoningDeltaEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantReasoningDeltaEvent.java
index 7c11ad59e7..5c7a6f94b9 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantReasoningDeltaEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantReasoningDeltaEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.reasoning_delta} session event.
+ * Session event "assistant.reasoning_delta". Streaming reasoning delta for incremental extended thinking updates
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantReasoningEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantReasoningEvent.java
index 292b191b14..58a7e665d4 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantReasoningEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantReasoningEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.reasoning} session event.
+ * Session event "assistant.reasoning". Assistant reasoning content for timeline display with complete thinking text
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantStreamingDeltaEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantStreamingDeltaEvent.java
index 71ec8f4884..70707a56e3 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantStreamingDeltaEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantStreamingDeltaEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.streaming_delta} session event.
+ * Session event "assistant.streaming_delta". Streaming response progress with cumulative byte count
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantTurnEndEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantTurnEndEvent.java
index a8e0b16525..e349711dc8 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantTurnEndEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantTurnEndEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.turn_end} session event.
+ * Session event "assistant.turn_end". Turn completion metadata including the turn identifier
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantTurnStartEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantTurnStartEvent.java
index 921623801d..245803774e 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantTurnStartEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantTurnStartEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.turn_start} session event.
+ * Session event "assistant.turn_start". Turn initialization metadata including identifier and interaction tracking
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageEvent.java
index ba97e03958..d704a862c3 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code assistant.usage} session event.
+ * Session event "assistant.usage". LLM API call usage metrics including tokens, costs, quotas, and billing information
*
* @since 1.0.0
*/
@@ -70,7 +70,7 @@ public record AssistantUsageEventData(
@JsonProperty("quotaSnapshots") Map quotaSnapshots,
/** Per-request cost and usage data from the CAPI copilot_usage response field */
@JsonProperty("copilotUsage") AssistantUsageCopilotUsage copilotUsage,
- /** Reasoning effort level used for model calls, if applicable (e.g. "low", "medium", "high", "xhigh") */
+ /** Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max") */
@JsonProperty("reasoningEffort") String reasoningEffort
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageQuotaSnapshot.java b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageQuotaSnapshot.java
index 0986f67d71..9e5675360e 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageQuotaSnapshot.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AssistantUsageQuotaSnapshot.java
@@ -13,6 +13,11 @@
import java.time.OffsetDateTime;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `AssistantUsageQuotaSnapshot` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchCompletedEvent.java
index a6d994d6b8..09c15cc1a8 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchCompletedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code auto_mode_switch.completed} session event.
+ * Session event "auto_mode_switch.completed". Auto mode switch completion notification
*
* @since 1.0.0
*/
@@ -37,8 +37,8 @@ public final class AutoModeSwitchCompletedEvent extends SessionEvent {
public record AutoModeSwitchCompletedEventData(
/** Request ID of the resolved request; clients should dismiss any UI for this request */
@JsonProperty("requestId") String requestId,
- /** The user's choice: 'yes', 'yes_always', or 'no' */
- @JsonProperty("response") String response
+ /** The user's auto-mode-switch choice */
+ @JsonProperty("response") AutoModeSwitchResponse response
) {
}
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchRequestedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchRequestedEvent.java
index e234ccd287..b1a768adc9 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchRequestedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchRequestedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code auto_mode_switch.requested} session event.
+ * Session event "auto_mode_switch.requested". Auto mode switch request notification requiring user approval
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchResponse.java b/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchResponse.java
new file mode 100644
index 0000000000..3f677ca202
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/AutoModeSwitchResponse.java
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: session-events.schema.json
+
+package com.github.copilot.sdk.generated;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * The user's auto-mode-switch choice
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum AutoModeSwitchResponse {
+ /** The {@code yes} variant. */
+ YES("yes"),
+ /** The {@code yes_always} variant. */
+ YES_ALWAYS("yes_always"),
+ /** The {@code no} variant. */
+ NO("no");
+
+ private final String value;
+ AutoModeSwitchResponse(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static AutoModeSwitchResponse fromValue(String value) {
+ for (AutoModeSwitchResponse v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown AutoModeSwitchResponse value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/CapabilitiesChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/CapabilitiesChangedEvent.java
index 6ee7768fbb..ff359b04a0 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/CapabilitiesChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/CapabilitiesChangedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code capabilities.changed} session event.
+ * Session event "capabilities.changed". Session capability change notification
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/CommandCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/CommandCompletedEvent.java
index d2075f09d3..584cde38b3 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/CommandCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/CommandCompletedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code command.completed} session event.
+ * Session event "command.completed". Queued command completion notification signaling UI dismissal
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/CommandExecuteEvent.java b/src/generated/java/com/github/copilot/sdk/generated/CommandExecuteEvent.java
index a9b0608dba..5d07300e8b 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/CommandExecuteEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/CommandExecuteEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code command.execute} session event.
+ * Session event "command.execute". Registered command dispatch request routed to the owning client
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/CommandQueuedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/CommandQueuedEvent.java
index 6599f4da64..f724f52993 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/CommandQueuedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/CommandQueuedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code command.queued} session event.
+ * Session event "command.queued". Queued slash command dispatch request for client execution
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/CommandsChangedCommand.java b/src/generated/java/com/github/copilot/sdk/generated/CommandsChangedCommand.java
index 30c8e99627..cb446ee24c 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/CommandsChangedCommand.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/CommandsChangedCommand.java
@@ -12,11 +12,18 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `CommandsChangedCommand` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public record CommandsChangedCommand(
+ /** Slash command name without the leading slash. */
@JsonProperty("name") String name,
+ /** Optional human-readable command description. */
@JsonProperty("description") String description
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/CommandsChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/CommandsChangedEvent.java
index 48576c314a..7b2d3c2c12 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/CommandsChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/CommandsChangedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code commands.changed} session event.
+ * Session event "commands.changed". SDK command registration change notification
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/CustomAgentsUpdatedAgent.java b/src/generated/java/com/github/copilot/sdk/generated/CustomAgentsUpdatedAgent.java
index 0d9dbc295b..154e763778 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/CustomAgentsUpdatedAgent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/CustomAgentsUpdatedAgent.java
@@ -13,6 +13,11 @@
import java.util.List;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `CustomAgentsUpdatedAgent` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ElicitationCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ElicitationCompletedEvent.java
index ae94b6bf31..ee713a1002 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ElicitationCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ElicitationCompletedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code elicitation.completed} session event.
+ * Session event "elicitation.completed". Elicitation request completion with the user's response
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ElicitationRequestedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ElicitationRequestedEvent.java
index fd5773df6f..000c242c9a 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ElicitationRequestedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ElicitationRequestedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code elicitation.requested} session event.
+ * Session event "elicitation.requested". Elicitation request; may be form-based (structured input) or URL-based (browser redirect)
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeAction.java b/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeAction.java
new file mode 100644
index 0000000000..a8b85ad943
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeAction.java
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: session-events.schema.json
+
+package com.github.copilot.sdk.generated;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Exit plan mode action
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum ExitPlanModeAction {
+ /** The {@code exit_only} variant. */
+ EXIT_ONLY("exit_only"),
+ /** The {@code interactive} variant. */
+ INTERACTIVE("interactive"),
+ /** The {@code autopilot} variant. */
+ AUTOPILOT("autopilot"),
+ /** The {@code autopilot_fleet} variant. */
+ AUTOPILOT_FLEET("autopilot_fleet");
+
+ private final String value;
+ ExitPlanModeAction(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static ExitPlanModeAction fromValue(String value) {
+ for (ExitPlanModeAction v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown ExitPlanModeAction value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeCompletedEvent.java
index 56c2c66813..3788532933 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeCompletedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code exit_plan_mode.completed} session event.
+ * Session event "exit_plan_mode.completed". Plan mode exit completion with the user's approval decision and optional feedback
*
* @since 1.0.0
*/
@@ -39,8 +39,8 @@ public record ExitPlanModeCompletedEventData(
@JsonProperty("requestId") String requestId,
/** Whether the plan was approved by the user */
@JsonProperty("approved") Boolean approved,
- /** Which action the user selected (e.g. 'autopilot', 'interactive', 'exit_only') */
- @JsonProperty("selectedAction") String selectedAction,
+ /** Action selected by the user */
+ @JsonProperty("selectedAction") ExitPlanModeAction selectedAction,
/** Whether edits should be auto-approved without confirmation */
@JsonProperty("autoApproveEdits") Boolean autoApproveEdits,
/** Free-form feedback from the user if they requested changes to the plan */
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeRequestedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeRequestedEvent.java
index de2bf45a84..e96124bc7e 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeRequestedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ExitPlanModeRequestedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code exit_plan_mode.requested} session event.
+ * Session event "exit_plan_mode.requested". Plan approval request with plan content and available user actions
*
* @since 1.0.0
*/
@@ -42,10 +42,10 @@ public record ExitPlanModeRequestedEventData(
@JsonProperty("summary") String summary,
/** Full content of the plan file */
@JsonProperty("planContent") String planContent,
- /** Available actions the user can take (e.g., approve, edit, reject) */
- @JsonProperty("actions") List actions,
- /** The recommended action for the user to take */
- @JsonProperty("recommendedAction") String recommendedAction
+ /** Available actions the user can take */
+ @JsonProperty("actions") List actions,
+ /** Recommended action to preselect for the user */
+ @JsonProperty("recommendedAction") ExitPlanModeAction recommendedAction
) {
}
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ExtensionsLoadedExtension.java b/src/generated/java/com/github/copilot/sdk/generated/ExtensionsLoadedExtension.java
index 366ea550cd..32e8ae4601 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ExtensionsLoadedExtension.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ExtensionsLoadedExtension.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `ExtensionsLoadedExtension` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ExternalToolCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ExternalToolCompletedEvent.java
index e9526c6faf..be086cb6d8 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ExternalToolCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ExternalToolCompletedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code external_tool.completed} session event.
+ * Session event "external_tool.completed". External tool completion notification signaling UI dismissal
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ExternalToolRequestedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ExternalToolRequestedEvent.java
index 8e646c1a5c..72591dd47c 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ExternalToolRequestedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ExternalToolRequestedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code external_tool.requested} session event.
+ * Session event "external_tool.requested". External tool invocation request for client-side tool execution
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/HookEndEvent.java b/src/generated/java/com/github/copilot/sdk/generated/HookEndEvent.java
index c2a80b0f3d..71b148fb13 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/HookEndEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/HookEndEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code hook.end} session event.
+ * Session event "hook.end". Hook invocation completion details including output, success status, and error information
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/HookStartEvent.java b/src/generated/java/com/github/copilot/sdk/generated/HookStartEvent.java
index ffca1dfe0b..0505c4182a 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/HookStartEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/HookStartEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code hook.start} session event.
+ * Session event "hook.start". Hook invocation start details including type and input data
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/McpOauthCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/McpOauthCompletedEvent.java
index 3d410bf2d2..33a56f8248 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/McpOauthCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/McpOauthCompletedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code mcp.oauth_completed} session event.
+ * Session event "mcp.oauth_completed". MCP OAuth request completion notification
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/McpOauthRequiredEvent.java b/src/generated/java/com/github/copilot/sdk/generated/McpOauthRequiredEvent.java
index c7ef7a12af..c2e9843da1 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/McpOauthRequiredEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/McpOauthRequiredEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code mcp.oauth_required} session event.
+ * Session event "mcp.oauth_required". OAuth authentication request for an MCP server
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/McpServerSource.java b/src/generated/java/com/github/copilot/sdk/generated/McpServerSource.java
new file mode 100644
index 0000000000..15cff507a4
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/McpServerSource.java
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: session-events.schema.json
+
+package com.github.copilot.sdk.generated;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Configuration source: user, workspace, plugin, or builtin
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum McpServerSource {
+ /** The {@code user} variant. */
+ USER("user"),
+ /** The {@code workspace} variant. */
+ WORKSPACE("workspace"),
+ /** The {@code plugin} variant. */
+ PLUGIN("plugin"),
+ /** The {@code builtin} variant. */
+ BUILTIN("builtin");
+
+ private final String value;
+ McpServerSource(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static McpServerSource fromValue(String value) {
+ for (McpServerSource v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown McpServerSource value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/McpServerStatus.java b/src/generated/java/com/github/copilot/sdk/generated/McpServerStatus.java
new file mode 100644
index 0000000000..f9c948f10c
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/McpServerStatus.java
@@ -0,0 +1,43 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: session-events.schema.json
+
+package com.github.copilot.sdk.generated;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Connection status: connected, failed, needs-auth, pending, disabled, or not_configured
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum McpServerStatus {
+ /** The {@code connected} variant. */
+ CONNECTED("connected"),
+ /** The {@code failed} variant. */
+ FAILED("failed"),
+ /** The {@code needs-auth} variant. */
+ NEEDS_AUTH("needs-auth"),
+ /** The {@code pending} variant. */
+ PENDING("pending"),
+ /** The {@code disabled} variant. */
+ DISABLED("disabled"),
+ /** The {@code not_configured} variant. */
+ NOT_CONFIGURED("not_configured");
+
+ private final String value;
+ McpServerStatus(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static McpServerStatus fromValue(String value) {
+ for (McpServerStatus v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown McpServerStatus value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/McpServersLoadedServer.java b/src/generated/java/com/github/copilot/sdk/generated/McpServersLoadedServer.java
index 9e17180ded..dbd08ede71 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/McpServersLoadedServer.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/McpServersLoadedServer.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `McpServersLoadedServer` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -19,9 +24,9 @@ public record McpServersLoadedServer(
/** Server name (config key) */
@JsonProperty("name") String name,
/** Connection status: connected, failed, needs-auth, pending, disabled, or not_configured */
- @JsonProperty("status") McpServersLoadedServerStatus status,
+ @JsonProperty("status") McpServerStatus status,
/** Configuration source: user, workspace, plugin, or builtin */
- @JsonProperty("source") String source,
+ @JsonProperty("source") McpServerSource source,
/** Error message if the server failed to connect */
@JsonProperty("error") String error
) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ModelCallFailureEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ModelCallFailureEvent.java
index 939e49ef55..33a3f86189 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ModelCallFailureEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ModelCallFailureEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code model.call_failure} session event.
+ * Session event "model.call_failure". Failed LLM API call metadata for telemetry
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/PendingMessagesModifiedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/PendingMessagesModifiedEvent.java
index 56f8ed520e..7cdcf1d3a8 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/PendingMessagesModifiedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/PendingMessagesModifiedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code pending_messages.modified} session event.
+ * Session event "pending_messages.modified". Empty payload; the event signals that the pending message queue has changed
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/PermissionCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/PermissionCompletedEvent.java
index 0b8da105e2..feeb4ca822 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/PermissionCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/PermissionCompletedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code permission.completed} session event.
+ * Session event "permission.completed". Permission request completion notification signaling UI dismissal
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/PermissionRequestedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/PermissionRequestedEvent.java
index 7892d3afe5..fda4db42f3 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/PermissionRequestedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/PermissionRequestedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code permission.requested} session event.
+ * Session event "permission.requested". Permission request notification requiring client approval with request details
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ReasoningSummary.java b/src/generated/java/com/github/copilot/sdk/generated/ReasoningSummary.java
new file mode 100644
index 0000000000..98897bbc92
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/ReasoningSummary.java
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: session-events.schema.json
+
+package com.github.copilot.sdk.generated;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed")
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum ReasoningSummary {
+ /** The {@code none} variant. */
+ NONE("none"),
+ /** The {@code concise} variant. */
+ CONCISE("concise"),
+ /** The {@code detailed} variant. */
+ DETAILED("detailed");
+
+ private final String value;
+ ReasoningSummary(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static ReasoningSummary fromValue(String value) {
+ for (ReasoningSummary v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown ReasoningSummary value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SamplingCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SamplingCompletedEvent.java
index ae21575094..2c6b264aa9 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SamplingCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SamplingCompletedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code sampling.completed} session event.
+ * Session event "sampling.completed". Sampling request completion notification signaling UI dismissal
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SamplingRequestedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SamplingRequestedEvent.java
index 7b92f5fafe..2be3cfc491 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SamplingRequestedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SamplingRequestedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code sampling.requested} session event.
+ * Session event "sampling.requested". Sampling request from an MCP server; contains the server name and a requestId for correlation
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionBackgroundTasksChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionBackgroundTasksChangedEvent.java
index fa996cf0e3..062954dfbf 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionBackgroundTasksChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionBackgroundTasksChangedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.background_tasks_changed} session event.
+ * Session event "session.background_tasks_changed".
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionCompactionCompleteEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionCompactionCompleteEvent.java
index 5f37980987..b6a3775e9d 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionCompactionCompleteEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionCompactionCompleteEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.compaction_complete} session event.
+ * Session event "session.compaction_complete". Conversation compaction results including success status, metrics, and optional error details
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionCompactionStartEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionCompactionStartEvent.java
index 2e0fb6d6f4..2ff7ace484 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionCompactionStartEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionCompactionStartEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.compaction_start} session event.
+ * Session event "session.compaction_start". Context window breakdown at the start of LLM-powered conversation compaction
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionContextChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionContextChangedEvent.java
index 0eb9e7e34b..6cc775d528 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionContextChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionContextChangedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.context_changed} session event.
+ * Session event "session.context_changed". Updated working directory and git context after the change
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionCustomAgentsUpdatedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionCustomAgentsUpdatedEvent.java
index be5e15e91a..ec10ed9c93 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionCustomAgentsUpdatedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionCustomAgentsUpdatedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.custom_agents_updated} session event.
+ * Session event "session.custom_agents_updated".
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionCustomNotificationEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionCustomNotificationEvent.java
index 8d3e3b68ac..3078895b7a 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionCustomNotificationEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionCustomNotificationEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.custom_notification} session event.
+ * Session event "session.custom_notification". Opaque custom notification data. Consumers may branch on source and name, but payload semantics are source-defined.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionErrorEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionErrorEvent.java
index 5c174c4357..48ae04ade0 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionErrorEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionErrorEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.error} session event.
+ * Session event "session.error". Error details for timeline display including message and optional diagnostic information
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionExtensionsLoadedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionExtensionsLoadedEvent.java
index 4d3420174e..a1b9b8fcef 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionExtensionsLoadedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionExtensionsLoadedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.extensions_loaded} session event.
+ * Session event "session.extensions_loaded".
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionHandoffEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionHandoffEvent.java
index 86706272f5..11599defae 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionHandoffEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionHandoffEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.handoff} session event.
+ * Session event "session.handoff". Session handoff metadata including source, context, and repository information
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionIdleEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionIdleEvent.java
index 86376ae7c1..cdb38a3444 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionIdleEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionIdleEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.idle} session event.
+ * Session event "session.idle". Payload indicating the session is idle with no background agents in flight
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionInfoEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionInfoEvent.java
index 01c1e0efbe..c0613dfa20 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionInfoEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionInfoEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.info} session event.
+ * Session event "session.info". Informational message for timeline display with categorization
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionMcpServerStatusChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionMcpServerStatusChangedEvent.java
index c422bf29a9..27cf4d9cc6 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionMcpServerStatusChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionMcpServerStatusChangedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.mcp_server_status_changed} session event.
+ * Session event "session.mcp_server_status_changed".
*
* @since 1.0.0
*/
@@ -37,8 +37,8 @@ public final class SessionMcpServerStatusChangedEvent extends SessionEvent {
public record SessionMcpServerStatusChangedEventData(
/** Name of the MCP server whose status changed */
@JsonProperty("serverName") String serverName,
- /** New connection status: connected, failed, needs-auth, pending, disabled, or not_configured */
- @JsonProperty("status") McpServerStatusChangedStatus status
+ /** Connection status: connected, failed, needs-auth, pending, disabled, or not_configured */
+ @JsonProperty("status") McpServerStatus status
) {
}
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionMcpServersLoadedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionMcpServersLoadedEvent.java
index be2d4cf744..0a0b7bc50b 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionMcpServersLoadedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionMcpServersLoadedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.mcp_servers_loaded} session event.
+ * Session event "session.mcp_servers_loaded".
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionMode.java b/src/generated/java/com/github/copilot/sdk/generated/SessionMode.java
new file mode 100644
index 0000000000..f6359c0df9
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionMode.java
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: session-events.schema.json
+
+package com.github.copilot.sdk.generated;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * The session mode the agent is operating in
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum SessionMode {
+ /** The {@code interactive} variant. */
+ INTERACTIVE("interactive"),
+ /** The {@code plan} variant. */
+ PLAN("plan"),
+ /** The {@code autopilot} variant. */
+ AUTOPILOT("autopilot");
+
+ private final String value;
+ SessionMode(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static SessionMode fromValue(String value) {
+ for (SessionMode v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown SessionMode value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionModeChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionModeChangedEvent.java
index 82ae9ff39c..c997f9850d 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionModeChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionModeChangedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.mode_changed} session event.
+ * Session event "session.mode_changed". Agent mode change details including previous and new modes
*
* @since 1.0.0
*/
@@ -35,10 +35,10 @@ public final class SessionModeChangedEvent extends SessionEvent {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public record SessionModeChangedEventData(
- /** Agent mode before the change (e.g., "interactive", "plan", "autopilot") */
- @JsonProperty("previousMode") String previousMode,
- /** Agent mode after the change (e.g., "interactive", "plan", "autopilot") */
- @JsonProperty("newMode") String newMode
+ /** The session mode the agent is operating in */
+ @JsonProperty("previousMode") SessionMode previousMode,
+ /** The session mode the agent is operating in */
+ @JsonProperty("newMode") SessionMode newMode
) {
}
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionModelChangeEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionModelChangeEvent.java
index 812cff0e81..8225fc78f9 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionModelChangeEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionModelChangeEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.model_change} session event.
+ * Session event "session.model_change". Model change details including previous and new model identifiers
*
* @since 1.0.0
*/
@@ -43,6 +43,10 @@ public record SessionModelChangeEventData(
@JsonProperty("previousReasoningEffort") String previousReasoningEffort,
/** Reasoning effort level after the model change, if applicable */
@JsonProperty("reasoningEffort") String reasoningEffort,
+ /** Reasoning summary mode before the model change, if applicable */
+ @JsonProperty("previousReasoningSummary") ReasoningSummary previousReasoningSummary,
+ /** Reasoning summary mode after the model change, if applicable */
+ @JsonProperty("reasoningSummary") ReasoningSummary reasoningSummary,
/** Reason the change happened, when not user-initiated. Currently `"rate_limit_auto_switch"` for changes triggered by the auto-mode-switch rate-limit recovery path. UI clients can use this to render contextual copy. */
@JsonProperty("cause") String cause
) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionPlanChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionPlanChangedEvent.java
index 4677d1cdb3..266ec307dc 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionPlanChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionPlanChangedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.plan_changed} session event.
+ * Session event "session.plan_changed". Plan file operation details indicating what changed
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionRemoteSteerableChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionRemoteSteerableChangedEvent.java
index ba752f4c62..5ba9423155 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionRemoteSteerableChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionRemoteSteerableChangedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.remote_steerable_changed} session event.
+ * Session event "session.remote_steerable_changed". Notifies that the session's remote steering capability has changed
*
* @since 1.0.0
*/
@@ -35,7 +35,7 @@ public final class SessionRemoteSteerableChangedEvent extends SessionEvent {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public record SessionRemoteSteerableChangedEventData(
- /** Whether this session now supports remote steering via Mission Control */
+ /** Whether this session now supports remote steering via GitHub */
@JsonProperty("remoteSteerable") Boolean remoteSteerable
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionResumeEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionResumeEvent.java
index 31bd3b4c36..93316117ba 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionResumeEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionResumeEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.resume} session event.
+ * Session event "session.resume". Session resume metadata including current context and event count
*
* @since 1.0.0
*/
@@ -42,15 +42,17 @@ public record SessionResumeEventData(
@JsonProperty("eventCount") Double eventCount,
/** Model currently selected at resume time */
@JsonProperty("selectedModel") String selectedModel,
- /** Reasoning effort level used for model calls, if applicable (e.g. "low", "medium", "high", "xhigh") */
+ /** Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max") */
@JsonProperty("reasoningEffort") String reasoningEffort,
+ /** Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed") */
+ @JsonProperty("reasoningSummary") ReasoningSummary reasoningSummary,
/** Updated working directory and git context at resume time */
@JsonProperty("context") WorkingDirectoryContext context,
/** Whether the session was already in use by another client at resume time */
@JsonProperty("alreadyInUse") Boolean alreadyInUse,
/** True when this resume attached to a session that the runtime already had running in-memory (for example, an extension joining a session another client was actively driving). False (or omitted) for cold resumes — the runtime had to reconstitute the session from its persisted event log. */
@JsonProperty("sessionWasActive") Boolean sessionWasActive,
- /** Whether this session supports remote steering via Mission Control */
+ /** Whether this session supports remote steering via GitHub */
@JsonProperty("remoteSteerable") Boolean remoteSteerable,
/** When true, tool calls and permission requests left in flight by the previous session lifetime remain pending after resume and the agentic loop awaits their results. User sends are queued behind the pending work until all such requests reach a terminal state. When false (the default), any such tool calls and permission requests are immediately marked as interrupted on resume. */
@JsonProperty("continuePendingWork") Boolean continuePendingWork
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCancelledEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCancelledEvent.java
index 01cd6e4619..2c480a7575 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCancelledEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCancelledEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.schedule_cancelled} session event.
+ * Session event "session.schedule_cancelled". Scheduled prompt cancelled from the schedule manager dialog
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCreatedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCreatedEvent.java
index bf0be67caf..eb051a0142 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCreatedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionScheduleCreatedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.schedule_created} session event.
+ * Session event "session.schedule_created". Scheduled prompt registered via /every or /after
*
* @since 1.0.0
*/
@@ -42,7 +42,9 @@ public record SessionScheduleCreatedEventData(
/** Prompt text that gets enqueued on every tick */
@JsonProperty("prompt") String prompt,
/** Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`) */
- @JsonProperty("recurring") Boolean recurring
+ @JsonProperty("recurring") Boolean recurring,
+ /** Optional user-facing label shown in the timeline instead of the actual prompt (e.g. `/skill-name args` when the prompt is a skill invocation expansion) */
+ @JsonProperty("displayPrompt") String displayPrompt
) {
}
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionShutdownEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionShutdownEvent.java
index 97d5060d32..269416994b 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionShutdownEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionShutdownEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.shutdown} session event.
+ * Session event "session.shutdown". Session termination metrics including usage statistics, code changes, and shutdown reason
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionSkillsLoadedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionSkillsLoadedEvent.java
index b5e64465df..c429125bf8 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionSkillsLoadedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionSkillsLoadedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.skills_loaded} session event.
+ * Session event "session.skills_loaded".
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionSnapshotRewindEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionSnapshotRewindEvent.java
index 8842827fbc..0b564f2910 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionSnapshotRewindEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionSnapshotRewindEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.snapshot_rewind} session event.
+ * Session event "session.snapshot_rewind". Session rewind details including target event and count of removed events
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionStartEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionStartEvent.java
index f5d6378fcd..d3484b3e14 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionStartEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionStartEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.start} session event.
+ * Session event "session.start". Session initialization metadata including context and configuration
*
* @since 1.0.0
*/
@@ -48,13 +48,15 @@ public record SessionStartEventData(
@JsonProperty("startTime") OffsetDateTime startTime,
/** Model selected at session creation time, if any */
@JsonProperty("selectedModel") String selectedModel,
- /** Reasoning effort level used for model calls, if applicable (e.g. "low", "medium", "high", "xhigh") */
+ /** Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max") */
@JsonProperty("reasoningEffort") String reasoningEffort,
+ /** Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed") */
+ @JsonProperty("reasoningSummary") ReasoningSummary reasoningSummary,
/** Working directory and git context at session start */
@JsonProperty("context") WorkingDirectoryContext context,
/** Whether the session was already in use by another client at start time */
@JsonProperty("alreadyInUse") Boolean alreadyInUse,
- /** Whether this session supports remote steering via Mission Control */
+ /** Whether this session supports remote steering via GitHub */
@JsonProperty("remoteSteerable") Boolean remoteSteerable,
/** When set, identifies a parent session whose context this session continues — e.g., a detached headless rem-agent run launched on the parent's interactive shutdown. Telemetry from this session is reported under the parent's session_id. */
@JsonProperty("detachedFromSpawningParentSessionId") String detachedFromSpawningParentSessionId
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionTaskCompleteEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionTaskCompleteEvent.java
index 1af7e699bf..f114ff82b3 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionTaskCompleteEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionTaskCompleteEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.task_complete} session event.
+ * Session event "session.task_complete". Task completion notification with summary from the agent
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionTitleChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionTitleChangedEvent.java
index 3093301883..4d6086bf3e 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionTitleChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionTitleChangedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.title_changed} session event.
+ * Session event "session.title_changed". Session title change payload containing the new display title
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionToolsUpdatedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionToolsUpdatedEvent.java
index a3b5313cf7..0cb8614c7a 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionToolsUpdatedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionToolsUpdatedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.tools_updated} session event.
+ * Session event "session.tools_updated".
*
* @since 1.0.0
*/
@@ -35,6 +35,7 @@ public final class SessionToolsUpdatedEvent extends SessionEvent {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public record SessionToolsUpdatedEventData(
+ /** Identifier of the model the resolved tools apply to. */
@JsonProperty("model") String model
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionTruncationEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionTruncationEvent.java
index 103d1d0173..b2ffad48f0 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionTruncationEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionTruncationEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.truncation} session event.
+ * Session event "session.truncation". Conversation truncation statistics including token counts and removed content metrics
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionUsageInfoEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionUsageInfoEvent.java
index f83c360246..7c9c19eafd 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionUsageInfoEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionUsageInfoEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.usage_info} session event.
+ * Session event "session.usage_info". Current context window usage statistics including token and message counts
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionWarningEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionWarningEvent.java
index 1870a26e8a..fc0a0778e6 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionWarningEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionWarningEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.warning} session event.
+ * Session event "session.warning". Warning message for timeline display with categorization
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SessionWorkspaceFileChangedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SessionWorkspaceFileChangedEvent.java
index 9dedc7a5e3..ba9032664d 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SessionWorkspaceFileChangedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SessionWorkspaceFileChangedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code session.workspace_file_changed} session event.
+ * Session event "session.workspace_file_changed". Workspace file change details including path and operation type
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ShutdownModelMetric.java b/src/generated/java/com/github/copilot/sdk/generated/ShutdownModelMetric.java
index e7a831ca67..bc7d41d8b3 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ShutdownModelMetric.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ShutdownModelMetric.java
@@ -13,6 +13,11 @@
import java.util.Map;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `ShutdownModelMetric` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ShutdownModelMetricTokenDetail.java b/src/generated/java/com/github/copilot/sdk/generated/ShutdownModelMetricTokenDetail.java
index 9f7cde6301..658efe35a7 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ShutdownModelMetricTokenDetail.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ShutdownModelMetricTokenDetail.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `ShutdownModelMetricTokenDetail` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ShutdownTokenDetail.java b/src/generated/java/com/github/copilot/sdk/generated/ShutdownTokenDetail.java
index ec51804886..6a9b3188a5 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ShutdownTokenDetail.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ShutdownTokenDetail.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `ShutdownTokenDetail` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SkillInvokedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SkillInvokedEvent.java
index e6c696eb0b..6aa2385443 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SkillInvokedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SkillInvokedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code skill.invoked} session event.
+ * Session event "skill.invoked". Skill invocation details including content, allowed tools, and plugin metadata
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SkillSource.java b/src/generated/java/com/github/copilot/sdk/generated/SkillSource.java
new file mode 100644
index 0000000000..9951c1da93
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/SkillSource.java
@@ -0,0 +1,45 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: session-events.schema.json
+
+package com.github.copilot.sdk.generated;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Source location type (e.g., project, personal-copilot, plugin, builtin)
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum SkillSource {
+ /** The {@code project} variant. */
+ PROJECT("project"),
+ /** The {@code inherited} variant. */
+ INHERITED("inherited"),
+ /** The {@code personal-copilot} variant. */
+ PERSONAL_COPILOT("personal-copilot"),
+ /** The {@code personal-agents} variant. */
+ PERSONAL_AGENTS("personal-agents"),
+ /** The {@code plugin} variant. */
+ PLUGIN("plugin"),
+ /** The {@code custom} variant. */
+ CUSTOM("custom"),
+ /** The {@code builtin} variant. */
+ BUILTIN("builtin");
+
+ private final String value;
+ SkillSource(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static SkillSource fromValue(String value) {
+ for (SkillSource v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown SkillSource value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SkillsLoadedSkill.java b/src/generated/java/com/github/copilot/sdk/generated/SkillsLoadedSkill.java
index 2183dad5c4..21f0dc0f45 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SkillsLoadedSkill.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SkillsLoadedSkill.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `SkillsLoadedSkill` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -20,8 +25,8 @@ public record SkillsLoadedSkill(
@JsonProperty("name") String name,
/** Description of what the skill does */
@JsonProperty("description") String description,
- /** Source location type of the skill (e.g., project, personal, plugin) */
- @JsonProperty("source") String source,
+ /** Source location type (e.g., project, personal-copilot, plugin, builtin) */
+ @JsonProperty("source") SkillSource source,
/** Whether the skill can be invoked by the user as a slash command */
@JsonProperty("userInvocable") Boolean userInvocable,
/** Whether the skill is currently enabled */
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SubagentCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SubagentCompletedEvent.java
index b2cce20c31..f61235b4a8 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SubagentCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SubagentCompletedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code subagent.completed} session event.
+ * Session event "subagent.completed". Sub-agent completion details for successful execution
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SubagentDeselectedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SubagentDeselectedEvent.java
index 3db9429dbf..391df6d49a 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SubagentDeselectedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SubagentDeselectedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code subagent.deselected} session event.
+ * Session event "subagent.deselected". Empty payload; the event signals that the custom agent was deselected, returning to the default agent
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SubagentFailedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SubagentFailedEvent.java
index 490532fc38..19644eee15 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SubagentFailedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SubagentFailedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code subagent.failed} session event.
+ * Session event "subagent.failed". Sub-agent failure details including error message and agent information
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SubagentSelectedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SubagentSelectedEvent.java
index e910bc9c27..b342e4230c 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SubagentSelectedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SubagentSelectedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code subagent.selected} session event.
+ * Session event "subagent.selected". Custom agent selection details including name and available tools
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SubagentStartedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SubagentStartedEvent.java
index 4bc945c9c0..737d773f12 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SubagentStartedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SubagentStartedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code subagent.started} session event.
+ * Session event "subagent.started". Sub-agent startup details including parent tool call and agent information
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SystemMessageEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SystemMessageEvent.java
index 07ae27000b..82976c0044 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SystemMessageEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SystemMessageEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code system.message} session event.
+ * Session event "system.message". System/developer instruction content with role and optional template metadata
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/SystemNotificationEvent.java b/src/generated/java/com/github/copilot/sdk/generated/SystemNotificationEvent.java
index 877b3db984..ba11910e03 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/SystemNotificationEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/SystemNotificationEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code system.notification} session event.
+ * Session event "system.notification". System-generated notification for runtime events like background task completion
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionCompleteEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionCompleteEvent.java
index a1deeeab56..b4ac9b7999 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionCompleteEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionCompleteEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code tool.execution_complete} session event.
+ * Session event "tool.execution_complete". Tool execution completion results including success status, detailed output, and error information
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionPartialResultEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionPartialResultEvent.java
index 5fbddc5cca..e548cc1b03 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionPartialResultEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionPartialResultEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code tool.execution_partial_result} session event.
+ * Session event "tool.execution_partial_result". Streaming tool execution output for incremental result display
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionProgressEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionProgressEvent.java
index 2a77c05ffe..d2b20312a3 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionProgressEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionProgressEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code tool.execution_progress} session event.
+ * Session event "tool.execution_progress". Tool execution progress notification with status message
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionStartEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionStartEvent.java
index 5a48cdd977..a98f7dec3d 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionStartEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ToolExecutionStartEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code tool.execution_start} session event.
+ * Session event "tool.execution_start". Tool execution startup details including MCP server information when applicable
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/ToolUserRequestedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/ToolUserRequestedEvent.java
index ac798fd3f3..ffd69535dd 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/ToolUserRequestedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/ToolUserRequestedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code tool.user_requested} session event.
+ * Session event "tool.user_requested". User-initiated tool invocation request with tool name and arguments
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/UserInputCompletedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/UserInputCompletedEvent.java
index 7b69bfd926..66883aa629 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/UserInputCompletedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/UserInputCompletedEvent.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code user_input.completed} session event.
+ * Session event "user_input.completed". User input request completion with the user's response
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/UserInputRequestedEvent.java b/src/generated/java/com/github/copilot/sdk/generated/UserInputRequestedEvent.java
index 69581e20a2..bb903191b3 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/UserInputRequestedEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/UserInputRequestedEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code user_input.requested} session event.
+ * Session event "user_input.requested". User input request notification with question and optional predefined choices
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/UserMessageEvent.java b/src/generated/java/com/github/copilot/sdk/generated/UserMessageEvent.java
index fa680d3e64..bf30633b04 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/UserMessageEvent.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/UserMessageEvent.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * The {@code user.message} session event.
+ * Session event "user.message".
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/AccountGetQuotaResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/AccountGetQuotaResult.java
index 47e3b55ee6..4685196234 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/AccountGetQuotaResult.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/AccountGetQuotaResult.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * Result for the {@code account.getQuota} RPC method.
+ * Quota usage snapshots for the resolved user, keyed by quota type.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/AccountQuotaSnapshot.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/AccountQuotaSnapshot.java
index c6d8149300..2bd1ac2f6b 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/AccountQuotaSnapshot.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/AccountQuotaSnapshot.java
@@ -10,15 +10,21 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.time.OffsetDateTime;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `AccountQuotaSnapshot` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public record AccountQuotaSnapshot(
/** Whether the user has an unlimited usage entitlement */
@JsonProperty("isUnlimitedEntitlement") Boolean isUnlimitedEntitlement,
- /** Number of requests included in the entitlement */
+ /** Number of requests included in the entitlement, or -1 for unlimited entitlements */
@JsonProperty("entitlementRequests") Long entitlementRequests,
/** Number of requests used so far this period */
@JsonProperty("usedRequests") Long usedRequests,
@@ -31,6 +37,6 @@ public record AccountQuotaSnapshot(
/** Whether overage is allowed when quota is exhausted */
@JsonProperty("overageAllowedWithExhaustedQuota") Boolean overageAllowedWithExhaustedQuota,
/** Date when the quota resets (ISO 8601 string) */
- @JsonProperty("resetDate") String resetDate
+ @JsonProperty("resetDate") OffsetDateTime resetDate
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/AgentInfo.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/AgentInfo.java
index 4695ff9fb9..66493bce29 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/AgentInfo.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/AgentInfo.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `AgentInfo` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectParams.java
index 665cd9694c..b22245ed93 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectParams.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * Request parameters for the {@code connect} RPC method.
+ * Optional connection token presented by the SDK client during the handshake.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectResult.java
index 56666b2523..f51b1a9c39 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectResult.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectResult.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * Result for the {@code connect} RPC method.
+ * Handshake result reporting the server's protocol version and package version on success.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadata.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadata.java
new file mode 100644
index 0000000000..006b750c17
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadata.java
@@ -0,0 +1,48 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.time.OffsetDateTime;
+import javax.annotation.processing.Generated;
+
+/**
+ * Metadata for a connected remote session.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record ConnectedRemoteSessionMetadata(
+ /** SDK session ID for the connected remote session. */
+ @JsonProperty("sessionId") String sessionId,
+ /** Optional friendly session name. */
+ @JsonProperty("name") String name,
+ /** Optional session summary. */
+ @JsonProperty("summary") String summary,
+ /** Session start time as an ISO 8601 string. */
+ @JsonProperty("startTime") OffsetDateTime startTime,
+ /** Last session update time as an ISO 8601 string. */
+ @JsonProperty("modifiedTime") OffsetDateTime modifiedTime,
+ /** Repository associated with the connected remote session. */
+ @JsonProperty("repository") ConnectedRemoteSessionMetadataRepository repository,
+ /** Pull request number associated with the session. */
+ @JsonProperty("pullRequestNumber") Long pullRequestNumber,
+ /** Original remote resource identifier. */
+ @JsonProperty("resourceId") String resourceId,
+ /** Neutral SDK discriminator for the connected remote session kind. */
+ @JsonProperty("kind") ConnectedRemoteSessionMetadataKind kind,
+ /** Remote session staleness deadline as an ISO 8601 string. */
+ @JsonProperty("staleAt") OffsetDateTime staleAt,
+ /** Remote session state returned by the backing service. */
+ @JsonProperty("state") String state
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadataKind.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadataKind.java
new file mode 100644
index 0000000000..14e4e4b22a
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadataKind.java
@@ -0,0 +1,35 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Neutral SDK discriminator for the connected remote session kind.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum ConnectedRemoteSessionMetadataKind {
+ /** The {@code remote-session} variant. */
+ REMOTE_SESSION("remote-session"),
+ /** The {@code coding-agent} variant. */
+ CODING_AGENT("coding-agent");
+
+ private final String value;
+ ConnectedRemoteSessionMetadataKind(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static ConnectedRemoteSessionMetadataKind fromValue(String value) {
+ for (ConnectedRemoteSessionMetadataKind v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown ConnectedRemoteSessionMetadataKind value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadataRepository.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadataRepository.java
new file mode 100644
index 0000000000..562dfba8ab
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ConnectedRemoteSessionMetadataRepository.java
@@ -0,0 +1,31 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.annotation.processing.Generated;
+
+/**
+ * Repository associated with the connected remote session.
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public record ConnectedRemoteSessionMetadataRepository(
+ /** Repository owner or organization login. */
+ @JsonProperty("owner") String owner,
+ /** Repository name. */
+ @JsonProperty("name") String name,
+ /** Branch associated with the remote session. */
+ @JsonProperty("branch") String branch
+) {
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/DiscoveredMcpServer.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/DiscoveredMcpServer.java
index 0429b26e13..2cfe49334d 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/DiscoveredMcpServer.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/DiscoveredMcpServer.java
@@ -12,16 +12,21 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `DiscoveredMcpServer` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public record DiscoveredMcpServer(
/** Server name (config key) */
@JsonProperty("name") String name,
- /** Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio) */
+ /** Server transport type: stdio, http, sse, or memory */
@JsonProperty("type") DiscoveredMcpServerType type,
- /** Configuration source */
- @JsonProperty("source") DiscoveredMcpServerSource source,
+ /** Configuration source: user, workspace, plugin, or builtin */
+ @JsonProperty("source") McpServerSource source,
/** Whether the server is enabled (not in the disabled list) */
@JsonProperty("enabled") Boolean enabled
) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/DiscoveredMcpServerType.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/DiscoveredMcpServerType.java
index 1ed5520217..0d4293d9a9 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/DiscoveredMcpServerType.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/DiscoveredMcpServerType.java
@@ -10,7 +10,7 @@
import javax.annotation.processing.Generated;
/**
- * Server transport type: stdio, http, sse, or memory (local configs are normalized to stdio)
+ * Server transport type: stdio, http, sse, or memory
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/Extension.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/Extension.java
index 14af4c77d8..7784fa5a44 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/Extension.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/Extension.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `Extension` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/InstructionsSources.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/InstructionsSources.java
index 7ca267a1b8..d0a23b337d 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/InstructionsSources.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/InstructionsSources.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `InstructionsSources` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigAddParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigAddParams.java
index 0f33fdcdad..a865e900e4 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigAddParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigAddParams.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * Request parameters for the {@code mcp.config.add} RPC method.
+ * MCP server name and configuration to add to user configuration.
*
* @since 1.0.0
*/
@@ -23,7 +23,7 @@
public record McpConfigAddParams(
/** Unique name for the MCP server */
@JsonProperty("name") String name,
- /** MCP server configuration (local/stdio or remote/http) */
+ /** MCP server configuration (stdio process or remote HTTP/SSE) */
@JsonProperty("config") Object config
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigDisableParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigDisableParams.java
index cef02e1ae8..49664f8e86 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigDisableParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigDisableParams.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * Request parameters for the {@code mcp.config.disable} RPC method.
+ * MCP server names to disable for new sessions.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigEnableParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigEnableParams.java
index 78ba76b7b8..4bf6284655 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigEnableParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigEnableParams.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * Request parameters for the {@code mcp.config.enable} RPC method.
+ * MCP server names to enable for new sessions.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigListResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigListResult.java
index 1391b451cb..f2be8641a9 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigListResult.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigListResult.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * Result for the {@code mcp.config.list} RPC method.
+ * User-configured MCP servers, keyed by server name.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigRemoveParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigRemoveParams.java
index 6c24be4311..9e87063c4b 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigRemoveParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigRemoveParams.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * Request parameters for the {@code mcp.config.remove} RPC method.
+ * MCP server name to remove from user configuration.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigUpdateParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigUpdateParams.java
index 327234515f..8c2df60725 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigUpdateParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpConfigUpdateParams.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * Request parameters for the {@code mcp.config.update} RPC method.
+ * MCP server name and replacement configuration to write to user configuration.
*
* @since 1.0.0
*/
@@ -23,7 +23,7 @@
public record McpConfigUpdateParams(
/** Name of the MCP server to update */
@JsonProperty("name") String name,
- /** MCP server configuration (local/stdio or remote/http) */
+ /** MCP server configuration (stdio process or remote HTTP/SSE) */
@JsonProperty("config") Object config
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpDiscoverParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpDiscoverParams.java
index 24d52cffcd..29b3860520 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpDiscoverParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpDiscoverParams.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * Request parameters for the {@code mcp.discover} RPC method.
+ * Optional working directory used as context for MCP server discovery.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpDiscoverResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpDiscoverResult.java
index 3f107275bf..074aedc613 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpDiscoverResult.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpDiscoverResult.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * Result for the {@code mcp.discover} RPC method.
+ * MCP servers discovered from user, workspace, plugin, and built-in sources.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpServer.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpServer.java
index 2f4b2b36ef..e8b71f7e8f 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/McpServer.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/McpServer.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `McpServer` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/Model.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/Model.java
index 9bda6a3007..1a808911ca 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/Model.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/Model.java
@@ -13,6 +13,11 @@
import java.util.List;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `Model` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideLimits.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideLimits.java
index 8794ae2589..f5b0b4e5e8 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideLimits.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideLimits.java
@@ -21,10 +21,13 @@
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public record ModelCapabilitiesOverrideLimits(
+ /** Maximum number of prompt/input tokens */
@JsonProperty("max_prompt_tokens") Long maxPromptTokens,
+ /** Maximum number of output/completion tokens */
@JsonProperty("max_output_tokens") Long maxOutputTokens,
/** Maximum total context window size in tokens */
@JsonProperty("max_context_window_tokens") Long maxContextWindowTokens,
+ /** Vision-specific limits */
@JsonProperty("vision") ModelCapabilitiesOverrideLimitsVision vision
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideLimitsVision.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideLimitsVision.java
index 5d53ca6b82..0d53e85321 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideLimitsVision.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideLimitsVision.java
@@ -13,6 +13,11 @@
import java.util.List;
import javax.annotation.processing.Generated;
+/**
+ * Vision-specific limits
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideSupports.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideSupports.java
index bc8e3f4952..23304c82d8 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideSupports.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelCapabilitiesOverrideSupports.java
@@ -21,7 +21,9 @@
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public record ModelCapabilitiesOverrideSupports(
+ /** Whether this model supports vision/image input */
@JsonProperty("vision") Boolean vision,
+ /** Whether this model supports reasoning effort configuration */
@JsonProperty("reasoningEffort") Boolean reasoningEffort
) {
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPolicy.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPolicy.java
index d3d218bec2..a6cdeb5d56 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPolicy.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPolicy.java
@@ -22,7 +22,7 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public record ModelPolicy(
/** Current policy state for this model */
- @JsonProperty("state") String state,
+ @JsonProperty("state") ModelPolicyState state,
/** Usage terms or conditions for this model */
@JsonProperty("terms") String terms
) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPolicyState.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPolicyState.java
new file mode 100644
index 0000000000..1673080d0d
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelPolicyState.java
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Current policy state for this model
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum ModelPolicyState {
+ /** The {@code enabled} variant. */
+ ENABLED("enabled"),
+ /** The {@code disabled} variant. */
+ DISABLED("disabled"),
+ /** The {@code unconfigured} variant. */
+ UNCONFIGURED("unconfigured");
+
+ private final String value;
+ ModelPolicyState(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static ModelPolicyState fromValue(String value) {
+ for (ModelPolicyState v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown ModelPolicyState value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelsListResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelsListResult.java
index a56eeb9d6e..db9dd791a2 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelsListResult.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ModelsListResult.java
@@ -14,7 +14,7 @@
import javax.annotation.processing.Generated;
/**
- * Result for the {@code models.list} RPC method.
+ * List of Copilot models available to the resolved user, including capabilities and billing metadata.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/PingParams.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/PingParams.java
index 892d5cbb2d..564478b175 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/PingParams.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/PingParams.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * Request parameters for the {@code ping} RPC method.
+ * Optional message to echo back to the caller.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/PingResult.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/PingResult.java
index b91b2fb02b..299d8f3584 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/PingResult.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/PingResult.java
@@ -13,7 +13,7 @@
import javax.annotation.processing.Generated;
/**
- * Result for the {@code ping} RPC method.
+ * Server liveness response, including the echoed message, current timestamp, and protocol version.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/Plugin.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/Plugin.java
index 64edf086ec..1b09c22cee 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/Plugin.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/Plugin.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `Plugin` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ReasoningSummary.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ReasoningSummary.java
new file mode 100644
index 0000000000..5e534e214c
--- /dev/null
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ReasoningSummary.java
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+// AUTO-GENERATED FILE - DO NOT EDIT
+// Generated from: api.schema.json
+
+package com.github.copilot.sdk.generated.rpc;
+
+import javax.annotation.processing.Generated;
+
+/**
+ * Reasoning summary mode to request for supported model clients
+ *
+ * @since 1.0.0
+ */
+@javax.annotation.processing.Generated("copilot-sdk-codegen")
+public enum ReasoningSummary {
+ /** The {@code none} variant. */
+ NONE("none"),
+ /** The {@code concise} variant. */
+ CONCISE("concise"),
+ /** The {@code detailed} variant. */
+ DETAILED("detailed");
+
+ private final String value;
+ ReasoningSummary(String value) { this.value = value; }
+ @com.fasterxml.jackson.annotation.JsonValue
+ public String getValue() { return value; }
+ @com.fasterxml.jackson.annotation.JsonCreator
+ public static ReasoningSummary fromValue(String value) {
+ for (ReasoningSummary v : values()) {
+ if (v.value.equals(value)) return v;
+ }
+ throw new IllegalArgumentException("Unknown ReasoningSummary value: " + value);
+ }
+}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/RemoteSessionMode.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/RemoteSessionMode.java
index 4f659bb6b6..93238eef44 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/RemoteSessionMode.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/RemoteSessionMode.java
@@ -10,7 +10,7 @@
import javax.annotation.processing.Generated;
/**
- * Per-session remote mode. "off" disables remote, "export" exports session events to Mission Control without enabling remote steering, "on" enables both export and remote steering.
+ * Per-session remote mode. "off" disables remote, "export" exports session events to GitHub without enabling remote steering, "on" enables both export and remote steering.
*
* @since 1.0.0
*/
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerAccountApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerAccountApi.java
index ecbe8a1057..583e110851 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerAccountApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerAccountApi.java
@@ -26,7 +26,7 @@ public final class ServerAccountApi {
}
/**
- * Invokes {@code account.getQuota}.
+ * Optional GitHub token used to look up quota for a specific user instead of the global auth context.
* @since 1.0.0
*/
public CompletableFuture getQuota() {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerMcpApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerMcpApi.java
index 6c376d0fe9..db70171c97 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerMcpApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerMcpApi.java
@@ -30,7 +30,7 @@ public final class ServerMcpApi {
}
/**
- * Invokes {@code mcp.discover}.
+ * Optional working directory used as context for MCP server discovery.
* @since 1.0.0
*/
public CompletableFuture discover(McpDiscoverParams params) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerMcpConfigApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerMcpConfigApi.java
index 9e9677e42a..cec231c61c 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerMcpConfigApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerMcpConfigApi.java
@@ -26,7 +26,7 @@ public final class ServerMcpConfigApi {
}
/**
- * Invokes {@code mcp.config.list}.
+ * User-configured MCP servers, keyed by server name.
* @since 1.0.0
*/
public CompletableFuture list() {
@@ -34,7 +34,7 @@ public CompletableFuture list() {
}
/**
- * Invokes {@code mcp.config.add}.
+ * MCP server name and configuration to add to user configuration.
* @since 1.0.0
*/
public CompletableFuture add(McpConfigAddParams params) {
@@ -42,7 +42,7 @@ public CompletableFuture add(McpConfigAddParams params) {
}
/**
- * Invokes {@code mcp.config.update}.
+ * MCP server name and replacement configuration to write to user configuration.
* @since 1.0.0
*/
public CompletableFuture update(McpConfigUpdateParams params) {
@@ -50,7 +50,7 @@ public CompletableFuture update(McpConfigUpdateParams params) {
}
/**
- * Invokes {@code mcp.config.remove}.
+ * MCP server name to remove from user configuration.
* @since 1.0.0
*/
public CompletableFuture remove(McpConfigRemoveParams params) {
@@ -58,7 +58,7 @@ public CompletableFuture remove(McpConfigRemoveParams params) {
}
/**
- * Invokes {@code mcp.config.enable}.
+ * MCP server names to enable for new sessions.
* @since 1.0.0
*/
public CompletableFuture enable(McpConfigEnableParams params) {
@@ -66,7 +66,7 @@ public CompletableFuture enable(McpConfigEnableParams params) {
}
/**
- * Invokes {@code mcp.config.disable}.
+ * MCP server names to disable for new sessions.
* @since 1.0.0
*/
public CompletableFuture disable(McpConfigDisableParams params) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerModelsApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerModelsApi.java
index c3f83b45cc..e062c6f0a4 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerModelsApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerModelsApi.java
@@ -26,7 +26,7 @@ public final class ServerModelsApi {
}
/**
- * Invokes {@code models.list}.
+ * Optional GitHub token used to list models for a specific user instead of the global auth context.
* @since 1.0.0
*/
public CompletableFuture list() {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerRpc.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerRpc.java
index b82c49ec23..9de3df51c4 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerRpc.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerRpc.java
@@ -56,7 +56,7 @@ public ServerRpc(RpcCaller caller) {
}
/**
- * Invokes {@code ping}.
+ * Optional message to echo back to the caller.
* @since 1.0.0
*/
public CompletableFuture ping(PingParams params) {
@@ -64,7 +64,7 @@ public CompletableFuture ping(PingParams params) {
}
/**
- * Invokes {@code connect}.
+ * Optional connection token presented by the SDK client during the handshake.
* @since 1.0.0
*/
public CompletableFuture connect(ConnectParams params) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSessionFsApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSessionFsApi.java
index 068ff939f7..25aefcf252 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSessionFsApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSessionFsApi.java
@@ -26,7 +26,7 @@ public final class ServerSessionFsApi {
}
/**
- * Invokes {@code sessionFs.setProvider}.
+ * Initial working directory, session-state path layout, and path conventions used to register the calling SDK client as the session filesystem provider.
* @since 1.0.0
*/
public CompletableFuture setProvider(SessionFsSetProviderParams params) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSessionsApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSessionsApi.java
index 6d1aa06519..a78a2fbf55 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSessionsApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSessionsApi.java
@@ -26,7 +26,7 @@ public final class ServerSessionsApi {
}
/**
- * Invokes {@code sessions.fork}.
+ * Source session identifier to fork from, optional event-ID boundary, and optional friendly name for the new session.
*
* @apiNote This method is experimental and may change in a future version.
* @since 1.0.0
@@ -35,4 +35,14 @@ public CompletableFuture fork(SessionsForkParams params) {
return caller.invoke("sessions.fork", params, SessionsForkResult.class);
}
+ /**
+ * Remote session connection parameters.
+ *
+ * @apiNote This method is experimental and may change in a future version.
+ * @since 1.0.0
+ */
+ public CompletableFuture connect() {
+ return caller.invoke("sessions.connect", java.util.Map.of(), SessionsConnectResult.class);
+ }
+
}
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkill.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkill.java
index 6cb4327176..92f9e0ccca 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkill.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkill.java
@@ -12,6 +12,11 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import javax.annotation.processing.Generated;
+/**
+ * Schema for the `ServerSkill` type.
+ *
+ * @since 1.0.0
+ */
@javax.annotation.processing.Generated("copilot-sdk-codegen")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -21,7 +26,7 @@ public record ServerSkill(
/** Description of what the skill does */
@JsonProperty("description") String description,
/** Source location type (e.g., project, personal-copilot, plugin, builtin) */
- @JsonProperty("source") String source,
+ @JsonProperty("source") SkillSource source,
/** Whether the skill can be invoked by the user as a slash command */
@JsonProperty("userInvocable") Boolean userInvocable,
/** Whether the skill is currently enabled (based on global config) */
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkillsApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkillsApi.java
index 943f682584..8884edc979 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkillsApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkillsApi.java
@@ -30,7 +30,7 @@ public final class ServerSkillsApi {
}
/**
- * Invokes {@code skills.discover}.
+ * Optional project paths and additional skill directories to include in discovery.
* @since 1.0.0
*/
public CompletableFuture discover(SkillsDiscoverParams params) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkillsConfigApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkillsConfigApi.java
index 41eaeab01e..a0236fd333 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkillsConfigApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerSkillsConfigApi.java
@@ -26,7 +26,7 @@ public final class ServerSkillsConfigApi {
}
/**
- * Invokes {@code skills.config.setDisabledSkills}.
+ * Skill names to mark as disabled in global configuration, replacing any previous list.
* @since 1.0.0
*/
public CompletableFuture setDisabledSkills(SkillsConfigSetDisabledSkillsParams params) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerToolsApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerToolsApi.java
index 2eb2a90f54..81bbaece6d 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerToolsApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/ServerToolsApi.java
@@ -26,7 +26,7 @@ public final class ServerToolsApi {
}
/**
- * Invokes {@code tools.list}.
+ * Optional model identifier whose tool overrides should be applied to the listing.
* @since 1.0.0
*/
public CompletableFuture list(ToolsListParams params) {
diff --git a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionAgentApi.java b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionAgentApi.java
index 47192e6310..ab91fe3ae7 100644
--- a/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionAgentApi.java
+++ b/src/generated/java/com/github/copilot/sdk/generated/rpc/SessionAgentApi.java
@@ -30,7 +30,7 @@ public final class SessionAgentApi {
}
/**
- * Invokes {@code session.agent.list}.
+ * Identifies the target session.
*
* @apiNote This method is experimental and may change in a future version.
* @since 1.0.0
@@ -40,7 +40,7 @@ public CompletableFuture list() {
}
/**
- * Invokes {@code session.agent.getCurrent}.
+ * Identifies the target session.
*
* @apiNote This method is experimental and may change in a future version.
* @since 1.0.0
@@ -50,7 +50,7 @@ public CompletableFuture