Upstream sync: Port 39 new commits from copilot-sdk (2026-03-24)#20
Upstream sync: Port 39 new commits from copilot-sdk (2026-03-24)#20
Conversation
…ission, blob, CUSTOMIZE mode, TelemetryConfig Co-authored-by: edburns <75821+edburns@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/405da6c3-54b8-42e2-9577-e4959467224f
Co-authored-by: edburns <75821+edburns@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/405da6c3-54b8-42e2-9577-e4959467224f
|
@copilot I have added |
Checkstyle passes with 0 violations — |
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
|
@copilot investigate and push additional commits to fix this failure in the "Build & Test" workflow: https://github.com/github/copilot-sdk-java/actions/runs/23471384285/job/68294676620?pr=20 |
…onstructor/getValue Co-authored-by: edburns <75821+edburns@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/bd5aed59-ed6b-446f-b070-7f09633c74cd
…n enum Co-authored-by: edburns <75821+edburns@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/c0de7d0c-70f8-4bbd-96ef-e82c0f62b3a8
Fixed in a912420. The two compilation errors were caused by treating
Build passes: 448 tests, 0 failures. |
…github-actions-workflow-failure
PromptThe current state of this branch I am a human reviewer reviewing this PR. I have a worktree branch checked out at Compare this branch with the main branch and help me understand the changes. Rank them from most controversial or risky to least. ResponseAuthor: copilot-swe-agent | +1448 / -37 across 27 files | Self-declares a breaking change 1. BREAKING:
|
…w-failure Fix compilation errors from PermissionRequestResultKind enum-to-class refactor
|
@copilot Consider this change you made:
Now consider this statement about the reference implementation.
The Java PR currently uses I do not accept this loss of type safety. Here's the minimal type-safe alternative that mirrors the .NET approach using Java idioms. Analyze and think about these suggestions in the context of your PR. I want you to apply these changes. Update and/or add tests to cover and assert correctness for your changes. 1. New sealed interface:
|
Co-authored-by: edburns <75821+edburns@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/0a17d674-e8bf-4cae-9736-b66b80c5ec7e
Applied in 727e767. Introduced
460 tests pass, 0 failures. No breaking change — existing |
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
…formCallbacks` returns `Object[]`** — MEDIUM-HIGH RISK" Your branch is up to date with 'upstream/copilot/sync-upstream-39-new-commits'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: .gitignore modified: src/main/java/com/github/copilot/sdk/CopilotClient.java modified: src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java modified: src/test/java/com/github/copilot/sdk/SessionRequestBuilderTest.java Untracked files: (use "git add <file>..." to include in what will be committed) src/main/java/com/github/copilot/sdk/ExtractedTransforms.java no changes added to commit (use "git add" and/or "git commit -a")
…g — silent no-op** — MEDIUM RISK" modified: .gitignore modified: src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java modified: src/main/java/com/github/copilot/sdk/json/PermissionRequestResultKind.java modified: src/test/java/com/github/copilot/sdk/RpcHandlerDispatcherTest.java modified: src/test/java/com/github/copilot/sdk/SessionHandlerTest.java
|
@copilot I observe that https://github.com/github/copilot-sdk-java/actions/runs/23513530134/job/68440337356?pr=20 had Spotless check failures. Please re-run spotless, fix those failures and push commits, and ensure the "Build & Test" check has passed. If not, keep working until you have a clean run. |
Co-authored-by: edburns <75821+edburns@users.noreply.github.com> Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/475d0c56-2512-48aa-8cf0-49249c795c94
Fixed in 698da99. The Spotless failure was a line-ending mismatch ( |
There was a problem hiding this comment.
Pull request overview
Ports 39 upstream commits from the official github/copilot-sdk into the Java SDK to improve forward compatibility, expand system message customization, add new attachment and telemetry capabilities, and align protocol behavior changes.
Changes:
- Add forward-compatible
UnknownSessionEventhandling so unknown CLI event types are dispatched instead of dropped. - Introduce
SystemMessageMode.CUSTOMIZEwith per-section overrides + optional async transform callbacks wired throughsystemMessage.transform. - Expand SDK surface with
NO_RESULTpermission abstention (v3), toolskipPermission, blob attachments, model reasoning-effort overload, and OpenTelemetry CLI startup configuration.
Reviewed changes
Copilot reviewed 33 out of 34 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/test/java/com/github/copilot/sdk/SessionRequestBuilderTest.java | Adds unit tests for extracting system message transform callbacks. |
| src/test/java/com/github/copilot/sdk/SessionHandlerTest.java | Adds test coverage for v3 NO_RESULT permission handling behavior. |
| src/test/java/com/github/copilot/sdk/SessionEventParserTest.java | Updates expectations for unknown event types to return UnknownSessionEvent. |
| src/test/java/com/github/copilot/sdk/RpcHandlerDispatcherTest.java | Adds coverage for v2 behavior when handler returns NO_RESULT. |
| src/test/java/com/github/copilot/sdk/PermissionRequestResultKindTest.java | Extends kind/value and JSON round-trip tests to include NO_RESULT. |
| src/test/java/com/github/copilot/sdk/MessageAttachmentTest.java | Introduces tests for MessageAttachment polymorphism and attachment list type-safety. |
| src/test/java/com/github/copilot/sdk/ForwardCompatibilityTest.java | Adds focused tests for unknown event forward-compat behavior and metadata preservation. |
| src/site/markdown/advanced.md | Documents new safe-tool skipping, CUSTOMIZE system messages, blob attachments, and telemetry. |
| src/main/java/com/github/copilot/sdk/json/ToolDefinition.java | Adds skipPermission field and createSkipPermission() factory. |
| src/main/java/com/github/copilot/sdk/json/TelemetryConfig.java | Adds telemetry configuration DTO for CLI startup env var wiring. |
| src/main/java/com/github/copilot/sdk/json/SystemPromptSections.java | Adds constants for well-known system prompt section identifiers. |
| src/main/java/com/github/copilot/sdk/json/SystemMessageConfig.java | Adds sections map for CUSTOMIZE mode section-level overrides. |
| src/main/java/com/github/copilot/sdk/json/SendMessageRequest.java | Updates request DTO to use List<MessageAttachment> for attachments. |
| src/main/java/com/github/copilot/sdk/json/SectionOverrideAction.java | Adds enum describing section override operations including transform. |
| src/main/java/com/github/copilot/sdk/json/SectionOverride.java | Adds per-section override type with optional async transform callback (SDK-local). |
| src/main/java/com/github/copilot/sdk/json/PermissionRequestResultKind.java | Adds NO_RESULT constant and documentation for abstention behavior. |
| src/main/java/com/github/copilot/sdk/json/MessageOptions.java | Updates attachments API to accept polymorphic MessageAttachment and copy lists defensively. |
| src/main/java/com/github/copilot/sdk/json/MessageAttachment.java | Introduces sealed interface + Jackson polymorphic annotations for attachments. |
| src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java | Deprecates autoRestart (no-op) and adds telemetry configuration property. |
| src/main/java/com/github/copilot/sdk/json/BlobAttachment.java | Adds inline base64 blob attachment type. |
| src/main/java/com/github/copilot/sdk/json/Attachment.java | Updates file attachment record to implement MessageAttachment. |
| src/main/java/com/github/copilot/sdk/events/UnknownSessionEvent.java | Adds forward-compat placeholder event type retaining base metadata + original type. |
| src/main/java/com/github/copilot/sdk/events/SessionEventParser.java | Returns UnknownSessionEvent for unknown types instead of null. |
| src/main/java/com/github/copilot/sdk/events/AbstractSessionEvent.java | Permits UnknownSessionEvent in the sealed event hierarchy. |
| src/main/java/com/github/copilot/sdk/SystemMessageMode.java | Adds CUSTOMIZE enum value. |
| src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java | Adds transform-callback extraction producing a wire-safe system message config. |
| src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java | Registers systemMessage.transform and enforces v2 NO_RESULT rejection behavior. |
| src/main/java/com/github/copilot/sdk/ExtractedTransforms.java | Adds small carrier type for wire config + extracted transform callbacks. |
| src/main/java/com/github/copilot/sdk/CopilotSession.java | Implements transform callback registry/handler, v3 permission abstention, model + log overloads. |
| src/main/java/com/github/copilot/sdk/CopilotClient.java | Wires transform callback extraction + registration into session create/resume flows. |
| src/main/java/com/github/copilot/sdk/CliServerManager.java | Sets CLI OpenTelemetry-related environment variables at process startup. |
| CHANGELOG.md | Updates upstream sync hash and documents newly added/changed/deprecated features. |
| .lastmerge | Updates the recorded upstream merge commit hash. |
| .gitignore | Adds ignore entries for temporary prompt artifacts. |
Comments suppressed due to low confidence (1)
src/site/markdown/advanced.md:49
- The table of contents lists “OpenTelemetry” twice (also appears earlier). Remove this duplicate TOC line to avoid repeated entries.
- [OpenTelemetry](#OpenTelemetry)
| }); | ||
| futures.add(f); | ||
| } else { | ||
| result.put(sectionId, Map.of("content", content)); |
There was a problem hiding this comment.
handleSystemMessageTransform() writes to result from async completion handlers (synchronized) but also writes to result in the else branch without synchronization. If any transform callback completes on another thread while iteration is still running, this can cause concurrent modification of the non-thread-safe LinkedHashMap (and nondeterministic output). Consider synchronizing all writes to result (including the else branch) or using a concurrent map / collecting results after all futures complete.
| result.put(sectionId, Map.of("content", content)); | |
| synchronized (result) { | |
| result.put(sectionId, Map.of("content", content)); | |
| } |
| - [Fine-grained Customization](#Fine-grained_Customization) | ||
| - [File Attachments](#File_Attachments) | ||
| - [Inline Blob Attachments](#Inline_Blob_Attachments) | ||
| - [OpenTelemetry](#OpenTelemetry) |
There was a problem hiding this comment.
The table of contents lists “OpenTelemetry” twice, which will create duplicate entries/anchors in the rendered docs. Remove one of the duplicate TOC lines.
This issue also appears on line 49 of the same file.
| @JsonProperty("overridesBuiltInTool") Boolean overridesBuiltInTool, | ||
| @JsonProperty("skipPermission") Boolean skipPermission) { | ||
|
|
||
| /** |
There was a problem hiding this comment.
Adding skipPermission as a new record component changes the canonical constructor signature, which is source-breaking for any callers doing new ToolDefinition(...). To preserve source compatibility, consider adding an overloaded 5-arg constructor delegating to the 6-arg canonical one (defaulting skipPermission to null) while still keeping the factories.
| /** | |
| /** | |
| * Backwards-compatible constructor that matches the original 5-argument | |
| * signature before {@code skipPermission} was added as a record component. | |
| * <p> | |
| * This constructor delegates to the canonical 6-argument constructor with | |
| * {@code skipPermission} defaulted to {@code null}. | |
| * | |
| * @param name | |
| * the unique name of the tool | |
| * @param description | |
| * a description of what the tool does | |
| * @param parameters | |
| * the JSON Schema defining the tool's parameters | |
| * @param handler | |
| * the handler function to execute when invoked | |
| * @param overridesBuiltInTool | |
| * when {@code true}, indicates that this tool intentionally | |
| * overrides a built-in CLI tool with the same name | |
| */ | |
| public ToolDefinition(String name, String description, Object parameters, ToolHandler handler, | |
| Boolean overridesBuiltInTool) { | |
| this(name, description, parameters, handler, overridesBuiltInTool, null); | |
| } | |
| /** |
| * <li>{@link Attachment} — file, directory, code selection, or GitHub | ||
| * reference</li> | ||
| * <li>{@link BlobAttachment} — inline base64-encoded binary data (e.g. images) | ||
| * </li> | ||
| * </ul> | ||
| * |
There was a problem hiding this comment.
The Javadoc claims Attachment supports “directory, code selection, or GitHub reference”, but Attachment only has path/displayName and the polymorphic mapping in MessageAttachment only registers it under the type id "file". Either narrow the docs to the supported attachment types/values, or expand the attachment model + subtype mapping to actually support the additional kinds.
| * <li>{@link Attachment} — file, directory, code selection, or GitHub | |
| * reference</li> | |
| * <li>{@link BlobAttachment} — inline base64-encoded binary data (e.g. images) | |
| * </li> | |
| * </ul> | |
| * | |
| * <li>{@link Attachment} — file reference (path-based file attachment)</li> | |
| * <li>{@link BlobAttachment} — inline base64-encoded binary data (e.g. images) | |
| * </li> | |
| * </ul> | |
| * | |
| * |
| * (broadcast permission model). When connected to a protocol v2 server, the SDK | ||
| * will throw {@link IllegalStateException} because v2 expects exactly one | ||
| * response per permission request. |
There was a problem hiding this comment.
PermissionRequestResultKind.NO_RESULT Javadoc says the SDK will throw IllegalStateException when connected to a protocol v2 server, but the v2 dispatcher path converts this into a denied response instead. Update the Javadoc to match the actual behavior (e.g., treated as denied / cannot be used with v2).
| * (broadcast permission model). When connected to a protocol v2 server, the SDK | |
| * will throw {@link IllegalStateException} because v2 expects exactly one | |
| * response per permission request. | |
| * (broadcast permission model). When connected to a protocol v2 server, this | |
| * kind cannot be honored and will be treated as a denied response instead, | |
| * because v2 expects exactly one concrete outcome per permission request. |
Ports 39 upstream commits (062b61c → 40887393) from the official Copilot SDK to the Java SDK.
Before the change?
nullfrom parser)setModel()had no reasoning effort parameterautoRestartoption was still active (upstream removed it)After the change?
Forward compatibility
UnknownSessionEvent(preserves id/timestamp/parentId) instead ofnull, so handlers receive all events from newer CLI versionsPermission handling
PermissionRequestResultKind.NO_RESULT— handler abstains, leaving the request for another client; SDK skips the RPC response in both v2 and v3 protocol pathsTool definitions
ToolDefinition.skipPermissionfield +createSkipPermission()factory — CLI bypasses permission prompt for the toolSystem message fine-grained customization (
SystemMessageMode.CUSTOMIZE)SectionOverrideActionenum (replace,remove,append,prepend,transform)SectionOverrideclass — per-section override with optional async transform callbackSystemPromptSections— well-known section identifier constantsSystemMessageConfig.setSections(Map<String, SectionOverride>)— section-level overridessystemMessage.transformRPC handler registered automatically when transform callbacks are presentModel switching
CopilotSession.setModel(String model, String reasoningEffort)— new overload; existingsetModel(String)delegates to itAttachments — type-safe polymorphic hierarchy
MessageAttachmentsealed interface — Java equivalent of the .NET SDK'sUserMessageDataAttachmentsItempolymorphic base class, with Jackson@JsonTypeInfo/@JsonSubTypesannotations for polymorphic serializationAttachmentrecord now implementsMessageAttachment(withgetType()bridge method)BlobAttachment—finalclass implementingMessageAttachmentfor inline base64-encoded binary (e.g. images)MessageOptions.setAttachments(List<? extends MessageAttachment>)— acceptsList<Attachment>,List<BlobAttachment>, orList<MessageAttachment>with full compile-time safetySendMessageRequestusesList<MessageAttachment>internallyObservability
TelemetryConfigclass +CopilotClientOptions.setTelemetry(TelemetryConfig)— setsCOPILOT_OTEL_*env vars on CLI process startupDeprecations
CopilotClientOptions.autoRestart— marked@Deprecated, no-opBug fixes
NO_RESULTpermission handling:PermissionRequestResultKindis a string-backed value class (not an enum), so replacedvalueOf()with constructor call inCopilotSessionand.name()with.getValue()inRpcHandlerDispatcherPull request checklist
mvn spotless:applyhas been run to format the codemvn clean verifypasses locallyDoes this introduce a breaking change?
Attachmentnow implements the newMessageAttachmentsealed interface andMessageOptions.setAttachmentsacceptsList<? extends MessageAttachment>. All existing caller code compiles unchanged:List.of(new Attachment(...))infersList<Attachment>which matchesList<? extends MessageAttachment>. No casts required.💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.