Port exit-plan-mode and auto-mode-switch handler APIs from reference implementation#185
Conversation
…implementation Adds ExitPlanModeHandler and AutoModeSwitchHandler support matching the reference implementation commit 671b50a (Restore mode handler APIs across SDKs). New types: - ExitPlanModeHandler, ExitPlanModeRequest, ExitPlanModeResult, ExitPlanModeInvocation - AutoModeSwitchHandler, AutoModeSwitchRequest, AutoModeSwitchResponse, AutoModeSwitchInvocation Updated: - SessionConfig/ResumeSessionConfig: onExitPlanMode, onAutoModeSwitch fields - CreateSessionRequest/ResumeSessionRequest: requestExitPlanMode, requestAutoModeSwitch flags - CopilotSession: handler registration and dispatch methods - RpcHandlerDispatcher: exitPlanMode.request, autoModeSwitch.request handlers - SessionRequestBuilder: wiring for new handlers and capability flags Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
…om.xml CLI version, and update scripts/codegen @github/copilot version Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Auto-committed by codegen-check workflow.
|
Warning The Codegen Fix Applied ✅Fixed 3 compilation errors in
All three constructor call sites in the test were updated to pass the correct number of Warning
|
…cross all RPC handlers Prompted by github-code-quality review comments on PR #185 (#185 (comment)). 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 <edburns@microsoft.com>
…cross all RPC handlers Prompted by github-code-quality review comments on PR #185 (#185 (comment)). 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 <edburns@microsoft.com>
There was a problem hiding this comment.
Pull request overview
Ports the reference implementation’s “mode handler” callback APIs into the Java SDK, wiring them through session configuration, JSON-RPC dispatch, and session lifecycle handling so Java hosts can respond to exitPlanMode and autoModeSwitch requests.
Changes:
- Added
ExitPlanMode*andAutoModeSwitch*handler/request/response/invocation types and exposed them onSessionConfig/ResumeSessionConfig. - Wired new RPC callbacks (
exitPlanMode.request,autoModeSwitch.request) throughRpcHandlerDispatcher,SessionRequestBuilder, andCopilotSession. - Updated docs and tests, plus synced reference-impl metadata and codegen inputs/outputs.
Show a summary per file
| File | Description |
|---|---|
| src/main/java/com/github/copilot/sdk/CopilotSession.java | Stores/clears mode handlers and dispatches requests with default behaviors when absent. |
| src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java | Registers and handles the new incoming RPC request methods for mode handlers. |
| src/main/java/com/github/copilot/sdk/SessionRequestBuilder.java | Sets capability flags and registers handlers when present in session configs. |
| src/main/java/com/github/copilot/sdk/json/SessionConfig.java | Adds onExitPlanMode / onAutoModeSwitch config hooks and clones them. |
| src/main/java/com/github/copilot/sdk/json/ResumeSessionConfig.java | Adds onExitPlanMode / onAutoModeSwitch config hooks and clones them. |
| src/main/java/com/github/copilot/sdk/json/CreateSessionRequest.java | Adds requestExitPlanMode / requestAutoModeSwitch request flags. |
| src/main/java/com/github/copilot/sdk/json/ResumeSessionRequest.java | Adds requestExitPlanMode / requestAutoModeSwitch request flags. |
| src/main/java/com/github/copilot/sdk/json/ExitPlanModeHandler.java | New functional interface for exit-plan-mode requests. |
| src/main/java/com/github/copilot/sdk/json/ExitPlanModeInvocation.java | New invocation context for exit-plan-mode handlers. |
| src/main/java/com/github/copilot/sdk/json/ExitPlanModeRequest.java | New request DTO for exit-plan-mode callbacks. |
| src/main/java/com/github/copilot/sdk/json/ExitPlanModeResult.java | New result DTO returned to the CLI for exit-plan-mode decisions. |
| src/main/java/com/github/copilot/sdk/json/AutoModeSwitchHandler.java | New functional interface for auto-mode-switch requests. |
| src/main/java/com/github/copilot/sdk/json/AutoModeSwitchInvocation.java | New invocation context for auto-mode-switch handlers. |
| src/main/java/com/github/copilot/sdk/json/AutoModeSwitchRequest.java | New request DTO for auto-mode-switch callbacks. |
| src/main/java/com/github/copilot/sdk/json/AutoModeSwitchResponse.java | New wire enum for auto-mode-switch decisions. |
| src/test/java/com/github/copilot/sdk/ModeHandlersTest.java | New E2E coverage for both handler APIs. |
| src/test/java/com/github/copilot/sdk/SessionRequestBuilderTest.java | Unit tests ensuring capability flags are set/omitted and serializable. |
| src/test/java/com/github/copilot/sdk/ConfigCloneTest.java | Verifies handler fields are preserved by config cloning. |
| src/test/java/com/github/copilot/sdk/SessionEventHandlingTest.java | Updates test event construction to match regenerated event record shapes. |
| src/site/markdown/advanced.md | Documents both mode handler APIs with examples and default behavior. |
| src/generated/java/com/github/copilot/sdk/generated/AssistantMessageEvent.java | Regenerated event type with additional fields. |
| src/generated/java/com/github/copilot/sdk/generated/SessionStartEvent.java | Regenerated event type with an additional field. |
| src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java | Regenerated RPC API including respondToQueuedCommand. |
| src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandParams.java | New generated params record. |
| src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsRespondToQueuedCommandResult.java | New generated result record. |
| src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksApi.java | Regenerated RPC API including sendMessage. |
| src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageParams.java | New generated params record. |
| src/generated/java/com/github/copilot/sdk/generated/rpc/SessionTasksSendMessageResult.java | New generated result record. |
| src/generated/java/com/github/copilot/sdk/generated/rpc/SessionWorkspacesGetWorkspaceResult.java | Regenerated schema removing fields/types no longer present. |
| scripts/codegen/package.json | Bumps the @github/copilot dependency range used for schema/codegen. |
| scripts/codegen/package-lock.json | Updates locked Node dependencies for code generation. |
| pom.xml | Updates the recorded reference-impl @github/copilot version range. |
| .lastmerge | Advances the recorded reference implementation sync commit. |
Copilot's findings
Files not reviewed (1)
- scripts/codegen/package-lock.json: Language not supported
- Files reviewed: 23/33 changed files
- Comments generated: 0
* Address review feedback: add parser tests for new fields, fix Javadoc @see refs
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* Update docs and samples for required permission handlers
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* Port session.setModel() and built-in tool override support from upstream
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* Harden documentation sample API guard test
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* Potential fix for pull request finding 'Useless parameter'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Run spotless apply on documentation samples test
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* Initial plan
* Initial plan
* docs: update version references to 1.0.10
* Port upstream changes: PermissionRequestResultKind, CI detection fix, E2E test updates
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* On branch edburns/dd-2785864-pre-public-non-code-changes
modified: .github/release.yml
modified: .github/templates/index.html
modified: .github/workflows/deploy-site.yml
modified: .github/workflows/notes.template
modified: .github/workflows/publish-maven.yml
modified: README.md
modified: jbang-example.java
modified: pom.xml
modified: src/main/java/com/github/copilot/sdk/package-info.java
modified: src/site/markdown/cookbook/error-handling.md
modified: src/site/markdown/cookbook/managing-local-files.md
modified: src/site/markdown/cookbook/multiple-sessions.md
modified: src/site/markdown/cookbook/persisting-sessions.md
modified: src/site/markdown/cookbook/pr-visualization.md
modified: src/site/markdown/getting-started.md
modified: src/site/markdown/index.md
modified: src/site/site.xml
On branch edburns/dd-2785864-pre-public-non-code-changes
modified: .github/release.yml
modified: .github/templates/index.html
modified: .github/workflows/deploy-site.yml
modified: .github/workflows/notes.template
modified: .github/workflows/publish-maven.yml
modified: README.md
modified: jbang-example.java
modified: pom.xml
modified: src/main/java/com/github/copilot/sdk/package-info.java
modified: src/site/markdown/cookbook/error-handling.md
modified: src/site/markdown/cookbook/managing-local-files.md
modified: src/site/markdown/cookbook/multiple-sessions.md
modified: src/site/markdown/cookbook/persisting-sessions.md
modified: src/site/markdown/cookbook/pr-visualization.md
modified: src/site/markdown/getting-started.md
modified: src/site/markdown/index.md
modified: src/site/site.xml
Signed-off-by: Ed Burns <edburns@microsoft.com>
* docs: clarify session close vs delete semantics (upstream sync #599)
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* On branch edburns/dd-2785864-pre-public-non-code-changes
modified: README.md
modified: jbang-example.java
modified: src/site/markdown/cookbook/error-handling.md
modified: src/site/markdown/cookbook/managing-local-files.md
modified: src/site/markdown/cookbook/multiple-sessions.md
modified: src/site/markdown/cookbook/persisting-sessions.md
modified: src/site/markdown/cookbook/pr-visualization.md
Fixed comment from @brunoborges:
> The pin snapshot version is 0.1.30, therefore all places that reference a version that is supposed to be on Maven Central, must be 0.1.29 (as if it was there already).
* On branch edburns/dd-2785864-pre-public-non-code-changes Reference impl is at 0.1.32.
modified: README.md
modified: jbang-example.java
modified: pom.xml
modified: src/site/markdown/cookbook/error-handling.md
modified: src/site/markdown/cookbook/managing-local-files.md
modified: src/site/markdown/cookbook/multiple-sessions.md
modified: src/site/markdown/cookbook/persisting-sessions.md
modified: src/site/markdown/cookbook/pr-visualization.md
no changes added to commit (use "git add" and/or "git commit -a")
* Initial plan
* Port upstream sync: protocol v3, OnListModels, agent, onEvent, new events, register-before-RPC
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* Refactor handleBroadcastEventAsync to use Java 21 pattern matching switch; bump minimum Java to 21
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Revert Java 21 bump and pattern-matching switch; restore Java 17 and if/else instanceof
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix: use correct permission denial kind and send errors back via RPC (ported from #185)
* docs: update version references to 1.0.11
* On branch edburns/dd-2785864-pre-public-non-code-changes
Your branch is up to date with 'origin/edburns/dd-2785864-pre-public-non-code-changes'.
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: src/main/java/com/github/copilot/sdk/package-info.java
no changes added to commit (use "git add" and/or "git commit -a")
* Fix flaky CompactionTest: wait for compaction complete event with CountDownLatch
The testShouldTriggerCompactionWithLowThresholdAndEmitEvents test was failing
with compactionCompleteCount == 0 because the SessionCompactionCompleteEvent
may arrive slightly after sendAndWait returns due to async event delivery from
the Copilot CLI. Added a CountDownLatch that waits up to 10 seconds for the
event after the third sendAndWait call completes, making the test resilient to
minor timing differences across CI environments.
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* On branch edburns/dd-2785864-pre-public-non-code-changes The artifactId in jbang dependency lines like //DEPS should point to copilot-sdk-java
modified: jbang-example.java
modified: src/site/markdown/cookbook/error-handling.md
modified: src/site/markdown/cookbook/managing-local-files.md
modified: src/site/markdown/cookbook/multiple-sessions.md
modified: src/site/markdown/cookbook/persisting-sessions.md
modified: src/site/markdown/cookbook/pr-visualization.md
modified: src/site/markdown/getting-started.md
modified: src/site/markdown/index.md
@brunoborges wrote:
> The artifactId in jbang dependency lines like //DEPS should point to copilot-sdk-java
* Port upstream changes: forward compat, no-result permission, skipPermission, 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
* Update tests, docs, CHANGELOG, and .lastmerge for upstream sync
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
* Fix for pull request finding 'Missing catch of NumberFormatException'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Avoid ambiguity in comparison.
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Fix for pull request finding 'Equals on incomparable types'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Initial plan
* Fix compilation errors: PermissionRequestResultKind valueOf/name to constructor/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
* Fix compilation errors: PermissionRequestResultKind is a class, not an 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
* Introduce MessageAttachment sealed interface for type-safe attachments
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
* Add 'Missing Override annotation'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* On branch copilot-pr-20 Fix "2. **`SessionRequestBuilder.extractTransformCallbacks` 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")
* On branch copilot-pr-20 Address "5. **`NO_RESULT` permission handling — 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
* Fix Spotless line-ending violation in ExtractedTransforms.java
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
* Replace wildcard imports with explicit imports in all documentation and example files
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/e64d87ca-6bc9-49cb-9074-2ad5864ff11f
* Update jbang-example.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* On branch edburns/dd-2758695-virtual-threads Add **Shared `ScheduledExecutorService`** for timeouts
## CopilotSession.java
- Added `ScheduledExecutorService` import.
- New field `timeoutScheduler`: shared single-thread scheduler, daemon thread named `sendAndWait-timeout`.
- Initialized in 3-arg constructor.
- `sendAndWait()`: replaced per-call `Executors.newSingleThreadScheduledExecutor()` with `timeoutScheduler.schedule()`. Cleanup calls `timeoutTask.cancel(false)` instead of `scheduler.shutdown()`.
- `close()`: added `timeoutScheduler.shutdownNow()` before the blocking `session.destroy` RPC call so stale timeouts cannot fire after close.
## TimeoutEdgeCaseTest.java (new)
- `testTimeoutDoesNotFireAfterSessionClose`: proves close() cancels pending timeouts (future not completed by stale TimeoutException).
- `testSendAndWaitReusesTimeoutThread`: proves two sendAndWait calls share one scheduler thread instead of spawning two.
- Uses reflection to construct a hanging `JsonRpcClient` (blocking InputStream, sink OutputStream).
Signed-off-by: Ed Burns <edburns@microsoft.com>
* On branch edburns/dd-2758695-virtual-threads Add **Shared `ScheduledExecutorService`** for timeouts
## CopilotSession.java
- Added `ScheduledExecutorService` import.
- New field `timeoutScheduler`: shared single-thread scheduler, daemon thread named `sendAndWait-timeout`.
- Initialized in 3-arg constructor.
- `sendAndWait()`: replaced per-call `Executors.newSingleThreadScheduledExecutor()` with `timeoutScheduler.schedule()`. Cleanup calls `timeoutTask.cancel(false)` instead of `scheduler.shutdown()`.
- `close()`: added `timeoutScheduler.shutdownNow()` before the blocking `session.destroy` RPC call so stale timeouts cannot fire after close.
## TimeoutEdgeCaseTest.java (new)
- `testTimeoutDoesNotFireAfterSessionClose`: proves close() cancels pending timeouts (future not completed by stale TimeoutException).
- `testSendAndWaitReusesTimeoutThread`: proves two sendAndWait calls share one scheduler thread instead of spawning two.
- Uses reflection to construct a hanging `JsonRpcClient` (blocking InputStream, sink OutputStream).
Signed-off-by: Ed Burns <edburns@microsoft.com>
* Fix memory leak from cancelled timeout tasks in CopilotSession
Replace Executors.newSingleThreadScheduledExecutor with an explicit
ScheduledThreadPoolExecutor so we can enable removeOnCancelPolicy(true).
Without this, each call to sendAndWait() that completes normally cancels
its timeout task, but the cancelled task remains in the scheduler's work
queue, leaking memory over the lifetime of the session.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Ed Burns <edburns@microsoft.com>
* Fix scheduler memory leak and close() race condition in CopilotSession
pom.xml
Add mockito-core 5.17.0 as a test dependency.
src/main/java/com/github/copilot/sdk/CopilotSession.java
Replace Executors.newSingleThreadScheduledExecutor with explicit
ScheduledThreadPoolExecutor and enable removeOnCancelPolicy(true) so
cancelled timeout tasks are purged from the work queue immediately.
Wrap timeoutScheduler.schedule() in a try-catch for
RejectedExecutionException. On rejection (close() race), the event
subscription is cleaned up and the returned future completes
exceptionally instead of throwing uncaught.
src/test/java/com/github/copilot/sdk/SchedulerShutdownRaceTest.java (new)
TDD test that reproduces the scheduler shutdown race. Uses Mockito to
stub JsonRpcClient.invoke(), then shuts down the scheduler without
setting isTerminated, and asserts sendAndWait() returns a failed future
rather than throwing RejectedExecutionException.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Ed Burns <edburns@microsoft.com>
* Honor documented contract: timeoutMs <= 0 means no timeout in sendAndWait
src/main/java/com/github/copilot/sdk/CopilotSession.java
Skip scheduling the timeout task when timeoutMs <= 0, matching the
Javadoc contract that 0 or negative means "no timeout". Previously,
timeoutMs=0 would schedule an immediate timeout, contradicting the
docs. The timeout cancel in the whenComplete cleanup is now guarded
for the null case.
src/test/java/com/github/copilot/sdk/ZeroTimeoutContractTest.java (new)
TDD test that asserts the documented contract: calling sendAndWait
with timeoutMs=0 should not cause the future to complete with a
TimeoutException. Uses Mockito to stub JsonRpcClient.invoke().
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Prevent CopilotSession leak on assertion failure in TimeoutEdgeCaseTest
src/test/java/com/github/copilot/sdk/TimeoutEdgeCaseTest.java
Wrap CopilotSession in try-with-resources in both tests so the session
and its scheduler thread are always cleaned up, even if an assertion
fails before the explicit close() call. In test 1, the explicit
session.close() is kept because it is the action under test; the
try-with-resources provides a safety net via idempotent double-close.
In test 2, the explicit session.close() is removed since it was purely
cleanup.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* spotless
* Update src/test/java/com/github/copilot/sdk/ZeroTimeoutContractTest.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* increase timeout in compaction test
* Update Javadoc in TimeoutEdgeCaseTest and SchedulerShutdownRaceTest to use contract/regression language
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/82d9999d-8d2f-4ccc-b0a9-0dfe932f8f78
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Add optional Executor to CopilotClientOptions; wire all internal *Async calls through it; shared timeout scheduler.
src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
- Added `Executor` field, `getExecutor()`, fluent `setExecutor(Executor)` with pending-null guard, and clone support.
src/main/java/com/github/copilot/sdk/CopilotClient.java
- Extracted `startCoreBody()` from `startCore()` lambda; `supplyAsync` uses provided executor when non-null.
- `stop()` routes session-close `runAsync` through provided executor when non-null.
- Passes executor to `RpcHandlerDispatcher` constructor.
- Sets executor on new sessions via `session.setExecutor()` in `createSession` and `resumeSession`.
src/main/java/com/github/copilot/sdk/RpcHandlerDispatcher.java
- Added `Executor` field and 3-arg constructor.
- All 5 `CompletableFuture.runAsync()` calls now go through private `runAsync(Runnable)` helper that uses executor when non-null.
src/main/java/com/github/copilot/sdk/CopilotSession.java
- Added `Executor` field and package-private `setExecutor()`.
- Replaced per-call `ScheduledExecutorService` with shared `timeoutScheduler` (daemon thread, shut down in `close()`).
- `executeToolAndRespondAsync` and `executePermissionAndRespondAsync` use executor when non-null.
src/test/java/com/github/copilot/sdk/ExecutorWiringTest.java (new)
- 6 E2E tests using `TrackingExecutor` decorator to verify all `*Async` paths route through the provided executor: client start, tool call, permission, user input, hooks, and client stop.
src/test/java/com/github/copilot/sdk/RpcHandlerDispatcherTest.java
- Updated constructor call to pass `null` for new executor parameter.
* On branch edburns/dd-2758695-virtual-threads-accept-executor
modified: src/main/java/com/github/copilot/sdk/CopilotClient.java
- Spotless.
modified: src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
- Remove stub from TDD red phase.
modified: src/site/markdown/cookbook/multiple-sessions.md
- Document new feature.
modified: src/test/java/com/github/copilot/sdk/ExecutorWiringTest.java
- Update test documentation.
Signed-off-by: Ed Burns <edburns@microsoft.com>
* Remove "TDD red-phase" from ExecutorWiringTest Javadoc
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/93199b25-7c90-4c45-9540-527396b8990c
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Handle RejectedExecutionException in all async submission sites
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/63b9b09f-f1f4-44d3-8e34-ad01e355cc6a
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Align RejectedExecutionException log message formatting in CopilotSession
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/63b9b09f-f1f4-44d3-8e34-ad01e355cc6a
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* On branch edburns/dd-2758695-virtual-threads-accept-executor
modified: README.md
- Use the "uncomment these three lines to get Virtual Threads" approach
modified: src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
- Cleanup. Sorting.
Signed-off-by: Ed Burns <edburns@microsoft.com>
* Add null checks to all reference-type setters in CopilotClientOptions
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/019cc9a8-a29a-49a5-a7ac-aa573931dfb8
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* On branch edburns/dd-2758695-virtual-threads-accept-executor
modified: src/main/java/com/github/copilot/sdk/CopilotSession.java
modified: src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
- Spotless apply.
- Sync javadoc to behavior.
* On branch edburns/dd-2758695-virtual-threads-accept-executor
modified: src/main/java/com/github/copilot/sdk/json/CopilotClientOptions.java
- Correctly implement the semantic of "null argument to setExecutor means use the default executor."
modified: src/test/java/com/github/copilot/sdk/ConfigCloneTest.java
- Adjust test based on defensive copy changes.
* Initial plan
* Port Commands, Elicitation, and Capabilities features from upstream
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/16d575c4-83f4-4d20-99d9-b48635b3791d
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Add tests, documentation, and update .lastmerge to f7fd757
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/16d575c4-83f4-4d20-99d9-b48635b3791d
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix code review issues: duplicate assertion, copyright header, Javadoc example
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/16d575c4-83f4-4d20-99d9-b48635b3791d
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Update src/main/java/com/github/copilot/sdk/CopilotSession.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix invalid Java ?. operator in SessionUiApi Javadoc prose
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/b5d79053-ae26-4c98-9047-b2457c08b0b8
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* Add tests to increase JaCoCo coverage from 78.7% to 85.2%
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/ee2608f6-2d6c-477e-9f79-a2968dec2436
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix jbang-example.java to use actual version instead of Maven placeholder
Replace ${project.version} with a real version number (0.2.2-java.1) in
jbang-example.java since this file is not Maven-filtered. Also add a
fallback sed pattern in the release workflow to handle the placeholder
during the transition.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix cross-platform process creation in tests: use cmd /c more on Windows
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/a5638a0d-f412-4810-b724-45bc5f10438d
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix Windows test compatibility for ProcessBuilder usage
On Windows, Java's ProcessBuilder cannot directly run shell wrappers
like `npx` (installed as npx.cmd) or Unix commands like `cat`. Tests
that used these commands failed with "Cannot run program" errors.
Additionally, Unix-style paths like "/nonexistent/copilot" are not
absolute on Windows, causing assertThrows(IOException) tests to pass
unexpectedly when CliServerManager wrapped them with "cmd /c".
Changes:
- CapiProxy: use "cmd /c npx" on Windows to launch the test harness
- CliServerManagerTest: replace "cat" with cross-platform dummy process;
use a platform-appropriate nonexistent absolute path so IOException
is thrown on all platforms
- JsonRpcClientTest: replace "cat" with cross-platform dummy process
All changes use runtime os.name detection and preserve existing
behavior on Linux and macOS. Full test suite passes on all platforms
(556 tests, 0 failures, 0 errors).
* Replace upstream terminology with reference implementation
Rebase the topic branch onto current main and preserve the original intent:
replace "upstream" naming with "reference implementation" across the repo.
- Update docs, prompts, workflows, and release automation wording
- Remove legacy upstream-sync assets superseded by reference-impl-sync assets
- Update references in tests and project guidance content
- Keep behavior aligned while clarifying terminology
- Apply Spotless formatting updates in touched Java test files
* Add classical code generation workflow for typed event and RPC classes
Introduces a TypeScript-based code generator (scripts/codegen/java.ts) that reads
api.schema.json and session-events.schema.json to produce:
- Typed session event classes (sealed hierarchy under AbstractSessionEvent)
- Typed RPC wrapper classes (ServerRpc, SessionRpc) for JSON-RPC methods
- Jackson-annotated records with @JsonCreator, @JsonProperty, @JsonInclude
Migrates the hand-written events package to auto-generated types, wires the
generated RPC wrappers into CopilotClient and CopilotSession, and adds
comprehensive tests including E2E coverage.
Also includes: Windows CLI path resolution fixes, shared TestUtil extraction,
lazy getRpc() initialization, race condition fix in SessionEventsE2ETest, and
a guard preventing agentic sync from modifying src/generated/java/ files.
Fix review comments: getRpc() IllegalStateException, UnknownSessionEvent wire type, anyOf heuristic, remove unused var
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/9b8b782c-22ad-450f-885d-2b11d5808a0c
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
Revert "Fix review comments: getRpc() IllegalStateException, UnknownSessionEvent wire type, anyOf heuristic, remove unused var"
This reverts commit ef1de834e6c54daca56ecb326263841087995fe0.
Fix Big Risk 1. `sendExpandedToolResult()` bypasses the typed wrapper (HIGH)
scripts/codegen/java.ts
- Remove the special-case `anyOf` rule that picked `String` when exactly 2 non-null branches included a string type. Multi-branch `anyOf` now falls through to `Object`, matching the C# reference generator's behavior.
src/generated/java/com/github/copilot/sdk/generated/rpc/SessionToolsHandlePendingToolCallParams.java
- Change the `result` field type from `String` to `Object` (regenerated output reflecting the `anyOf` rule fix in `java.ts`).
src/main/java/com/github/copilot/sdk/CopilotSession.java
- Replace the `sendExpandedToolResult(requestId, toolResult)` call with a direct typed-wrapper call: `getRpc().tools.handlePendingToolCall(new SessionToolsHandlePendingToolCallParams(...))`.
- Delete the `sendExpandedToolResult()` private method and its Javadoc block, which are no longer needed now that the `result` field accepts `Object`.
Signed-off-by: Ed Burns <edburns@microsoft.com>
On branch copilot/add-classical-code-gen-workflow-ready-for-review
modified: scripts/codegen/java.ts
- Put `visible = true` on `SessionEventEvent`.
- Add `type` property. on `UnknownSessionEvent`.
modified: src/generated/java/com/github/copilot/sdk/generated/SessionEvent.java
modified: src/generated/java/com/github/copilot/sdk/generated/UnknownSessionEvent.java
- Regenerated.
modified: src/main/java/com/github/copilot/sdk/CopilotSession.java
- Use Double Check Locked to fix Big Risk #2 2. Lazy `SessionRpc` initialization is not thread-safe (HIGH)
modified: src/test/java/com/github/copilot/sdk/ForwardCompatibilityTest.java
modified: src/test/java/com/github/copilot/sdk/SessionEventDeserializationTest.java
- Refine tests based on changes.
Signed-off-by: Ed Burns <edburns@microsoft.com>
On branch copilot/add-classical-code-gen-workflow-ready-for-review
modified: pom.xml
- Add profiles for generating code and updating the schemas from which the code is generated.
modified: scripts/codegen/java.ts
- Address copilot comment:
> requiredSet is computed but never used in renderNestedType(), which makes the generator harder to maintain (and can confuse future changes around nullability/boxing). Remove it or use it to drive required-vs-optional component typing if that’s the intent.
Signed-off-by: Ed Burns <edburns@microsoft.com>
Add AI code review to update-copilot-dependency workflow
* Apply Copilot review comments.
modified: scripts/codegen/java.ts
### 18:24 Prompt
Consider these Copilot review comments, all about `java.ts`
- Lines 167 - 178
> The generator passes required=true when generating container element/value types (List<T>, Map<String, V>). This can produce illegal Java generic types like List<long> / Map<String, boolean> when the schema item type is integer/boolean/number, causing generated code not to compile. Fix by ensuring container element/value types are always boxed (e.g., call schemaTypeToJava(..., false, ...) for items and additionalProperties value schemas, or add a dedicated “box primitives in generics” step).
### 18:29 Prompt
Consider these Copilot review comments, all about `java.ts`
- Lines 193 - 201
> The generator passes required=true when generating container element/value types (List<T>, Map<String, V>). This can produce illegal Java generic types like List<long> / Map<String, boolean> when the schema item type is integer/boolean/number, causing generated code not to compile. Fix by ensuring container element/value types are always boxed (e.g., call schemaTypeToJava(..., false, ...) for items and additionalProperties value schemas, or add a dedicated “box primitives in generics” step).
### 18:31 Prompt
Consider these Copilot review comments, all about `java.ts`
- Lines 1258 - 1261
> RpcMapper.INSTANCE is a plain new ObjectMapper() with no modules. Generated RPC DTOs can include OffsetDateTime (your type mapping emits it for format: date-time), and ObjectMapper.valueToTree(...) used by session wrappers can fail without JavaTimeModule registered. Fix by configuring this shared mapper consistently (e.g., register com.fasterxml.jackson.datatype.jsr310.JavaTimeModule, and align any other ObjectMapper features needed by the SDK).
### 18:34 Prompt
Consider these Copilot review comments, all about `java.ts`
- Lines 1202 - 1207
> This comment is likely incorrect/misleading: Java lambdas can generally target a functional interface whose single abstract method is generic (the compiler can still infer the type parameter from the call site). Consider removing this claim or rephrasing it to a neutral recommendation (e.g., “method reference is typical/clear”) so consumers aren’t discouraged from valid usage.
Copilot suggests:
```typescript
lines.push(` * (e.g., a {@code JsonRpcClient} instance). A method reference is typically the clearest`);
lines.push(` * way to adapt a generic {@code invoke} method to this interface:`);
lines.push(` * <pre>{@code`);
lines.push(` * RpcCaller caller = jsonRpcClient::invoke;`);
lines.push(` * }</pre>`);
```
What can we do about this?
### 18:36 Prompt
Consider these Copilot review comments, all about `java.ts`
- Lines 848 - 854
> For session-scoped RPC methods with additional params, the generated *Params records still include a sessionId field (because they’re generated directly from the schema), but the wrapper then overwrites sessionId via _p.put("sessionId", this.sessionId). This duplication is confusing for API consumers and makes the param records look “callable” with arbitrary session IDs when they are not. Consider adjusting generation so sessionId is omitted from session-scoped params records (and only injected by SessionRpc), or documenting clearly in the generated Javadoc that any provided sessionId is ignored/overridden.
Copilot suggests:
```typescript
* Return the wrapper-visible parameter property names for a method.
* For session-scoped wrappers, sessionId is injected by SessionRpc and is not
* considered a user-supplied parameter.
*/
function wrapperParamPropertyNames(method: RpcMethodNode, isSession: boolean): string[] {
if (!method.params || typeof method.params !== "object") return [];
const props = method.params.properties ?? {};
return Object.keys(props).filter((k) => !(isSession && k === "sessionId"));
}
/**
* Return the params class name if the method has wrapper-visible properties
* (i.e. user-supplied parameters after filtering out injected sessionId for
* session-scoped wrappers).
*/
function wrapperParamsClassName(method: RpcMethodNode, isSession: boolean): string | null {
const userProps = wrapperParamPropertyNames(method, isSession);
```
What can we do about this?
### 18:40 Prompt
Consider these Copilot review comments, all about `java.ts`
- Lines 903 - 915
> For session-scoped RPC methods with additional params, the generated *Params records still include a sessionId field (because they’re generated directly from the schema), but the wrapper then overwrites sessionId via _p.put("sessionId", this.sessionId). This duplication is confusing for API consumers and makes the param records look “callable” with arbitrary session IDs when they are not. Consider adjusting generation so sessionId is omitted from session-scoped params records (and only injected by SessionRpc), or documenting clearly in the generated Javadoc that any provided sessionId is ignored/overridden.
What can we do about this? This seems the same as the previous comment. No?
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/RpcCaller.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/RpcMapper.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionAgentApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionCommandsApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionExtensionsApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionFleetApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionHistoryApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionMcpApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionModeApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionModelApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionPermissionsApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionPlanApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionRpc.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionShellApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionSkillsApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionToolsApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionUiApi.java
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/SessionWorkspaceApi.java
- Regenerated.
Signed-off-by: Ed Burns <edburns@microsoft.com>
* Fix compilation failure.
modified: scripts/codegen/java.ts
modified: src/generated/java/com/github/copilot/sdk/generated/rpc/RpcMapper.java
Clean run. The fix was: RpcMapper now constructs its own ObjectMapper with the same configuration as JsonRpcClient's mapper, instead of trying to call JsonRpcClient.getObjectMapper() across packages (which failed because JsonRpcClient is package-private).
Signed-off-by: Ed Burns <edburns@microsoft.com>
* Initial plan
* Fix (int) cast incompatibility with boxed Double in Quick Start code
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/51184227-fc7a-4a39-9032-b9b3da932569
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Initial plan
* Add comprehensive test coverage for generated RPC code
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/bb9210b4-2aa3-475c-9c4f-5b2318a436f5
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Potential fix for pull request finding 'Unread local variable'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Move test files to match generated package structure
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/0c4c84ed-1cb5-4e79-954f-633c61e99a87
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix POSIXisms: use TestUtil.tempPath() for cross-platform temp paths
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/b7de171b-6625-4ab4-b222-4858b0cacfc2
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix race condition in sendAndWait: use whenCompleteAsync to prevent test-thread wakeup mid-dispatch
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/e7c09bc7-4fc9-4619-a0d9-d1bed96104b9
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Port reference implementation sync: McpServerConfig types, ModelCapabilitiesOverride, agent skills, per-request headers
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/514da8aa-3336-46ca-b39a-48faabcbb354
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix limits mapping in setModel and fix import order in ProviderConfig
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/c48ff7e5-7e42-43e6-a3df-42fe0004aa91
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* docs: update version references to 0.3.0-java-preview.0
* docs: update version references to 0.3.0-java-preview.1
* Revert "docs: update version references to 0.3.0-java-preview.1"
This reverts commit de3fb899d764d5a1ecd4778a3c3e87c11bc1a8ad.
* docs: update version references to 0.3.0-java-preview.1
* Fix corrupted version strings and update release workflow to handle -java-preview.N format
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/f0073ec1-6192-4879-953c-26576dbb61b6
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
* Fix codegen and handwritten code for @github/copilot 1.0.35 $ref schema changes
---
## Summary
Updates the Java code generator and handwritten SDK/test code to handle the
`@github/copilot` 1.0.35 schema format, which changed from inline nested type
definitions to `$ref` references pointing to `#/definitions/` entries. Without
this fix, regenerated types were missing fields and the build failed.
75 files changed, 616 insertions(+), 1836 deletions(-)
## Changes
### Code generator (`scripts/codegen/java.ts`)
- Added `resolveRef()` helper to dereference `$ref` pointers in JSON schemas.
- Added `pendingStandaloneTypes` map to collect types referenced via `$ref` and
generate them as top-level Java files instead of nested records.
- Added `generatePendingStandaloneTypes()`, `generateStandaloneEnum()`, and
`generateStandaloneRecord()` to emit the new standalone types.
- Updated all property/field generation paths to resolve `$ref` before
inspecting type, enum, or nested-object shapes.
### Regenerated files (`src/generated/java/`)
- ~65 generated source files updated — nested inner records/enums replaced by
standalone types (e.g. `McpServer`, `Plugin`, `Skill`, `Tool`, `Model`,
`AccountQuotaSnapshot`, `DiscoveredMcpServer`, `UIElicitationSchema`,
`UIElicitationResponseAction`, `ModelCapabilitiesOverride`, etc.).
- Several numeric fields changed from `double` to `Long` (`PingResult`,
`SessionShellExecParams`, model capability limits).
- New RPC API class `ServerMcpConfigApi` and `SessionPermissionsApi` added.
### Handwritten source (`CopilotSession.java`)
- Updated all type references from old nested types to new standalone types
(e.g. `SessionMcpListResultServersItem` → `McpServer`).
### Test files (5 files)
- **`GeneratedRpcRecordsCoverageTest.java`** — Replaced all nested type
references with standalone types; fixed `double` → `Long` constructors.
- **`GeneratedEventTypesCoverageTest.java`** — Updated event type name set.
- **`GeneratedRpcApiCoverageTest.java`** — Updated `workspace` → `workspaces`,
added `SessionLogLevel`, new API classes.
- **`RpcWrappersTest.java`** — `session.workspace` → `session.workspaces`.
- **`SessionEventDeserializationTest.java`** — Updated JSON keys for
`compactionTokensUsed` (`input` → `inputTokens`, `output` → `outputTokens`,
`cachedInput` → `cacheReadTokens`).
### Dependency bump
- `@github/copilot` 1.0.24 → 1.0.35 in `scripts/codegen/package.json`.
- **`.github/workflows/update-copilot-dependency.yml`** — After codegen and PR creation, `mvn verify` is run. On failure, the agentic fix workflow is triggered. Includes a polling loop that waits for the fix to complete and runs a final verification.
## Design
The pipeline follows a two-workflow pattern:
1. **Trigger workflows** (`codegen-check.yml`, `update-copilot-dependency.yml`) detect failures and dispatch the agentic fix.
2. **Fix workflow** (`codegen-agentic-fix.lock.yml`) runs under gh-aw guardrails with scoped permissions, network firewall, and MCP gateway. It checks out the branch, reproduces the failure, applies fixes to handwritten code only, and pushes via `push-to-pull-request-branch` safe-output.
Key constraints enforced on the agent:
- Never modify `src/generated/java/`, `pom.xml`, `scripts/codegen/`, or `.github/`
- Maximum 3 fix attempts before escalating via PR comment
- Must run `mvn spotless:apply` before committing
- Only pushes if `mvn verify` passes
## Testing
- All workflow files pass `actionlint` with zero errors
- The `codegen-agentic-fix.lock.yml` was successfully compiled by `gh aw compile v0.68.3`
- End-to-end testing will occur when this PR and #94 are both merged — Dependabot PR #99 (bump `@github/copilot` 1.0.24 → 1.0.35) already exists and its Codegen Check is failing as expected
* Port 4 reference implementation commits: per-session auth, idle timeout, defaultAgent.excludedTools, permission kind values
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/34e41e1a-798d-4058-87fa-d6e929b2f783
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix permission kind values to match CLI v1.0.32 protocol changes
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/6e6133f4-9ebc-4ee5-b0cd-a8bccfb8e03b
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix 3 CI test failures: PerSessionAuth proxy init, McpAndAgents prompt/tool mismatch, session destroy before resume
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/1cce7322-6672-4e54-be77-b026e33610d7
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Address PR #122 review feedback: ensureProxyAlive, Javadoc constants, advanced.md table
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/a4ec83e7-4677-4d1f-a323-5de8dbfa2ce2
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* docs: update version references to 0.3.0-java.2
* Fix jbang-example.java shebang line and dependency version
The first line was a bare '!' instead of the proper JBang shebang
'///usr/bin/env jbang'. Also updated the dependency version from
0.3.0-java.2 to the current 0.3.1-java.1-SNAPSHOT.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Initial plan
* Regenerate codegen output
Auto-committed by codegen-check workflow.
* Fix AgentInfo test compilation: add 4th 'path' parameter
AgentInfo record gained a 'path' field in the generated code. Update
GeneratedRpcRecordsCoverageTest to pass the 4th parameter in all
constructor calls.
* Initial plan
* Port SetForegroundSessionRequest bug fix and add COPILOT_HOME to test harness
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/a61a1c47-9550-486c-800b-6deeeadaadbf
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* On branch main Use latest non-SNAPSHOT version for jbang example.
modified: jbang-example.java
* Port copilotHome, tcpConnectionToken, and instructionDirectories from reference implementation
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Add tests for copilotHome, tcpConnectionToken, and instructionDirectories
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Regenerate codegen output
Auto-committed by codegen-check workflow.
* Fix test compilation errors for updated generated record signatures
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Enable instructionDirectories E2E tests and fix getSystemMessage exchange parsing
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/cad2855d-0ec3-43e1-acef-49e96848b902
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Address review feedback: use generated ConnectParams/ConnectResult, allow null copilotHome, strengthen permission test assertion, add instructionDirectories unit tests
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/bf21fd78-4e30-40e7-8e6b-536294818f16
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Port reference implementation changes: process cleanup, connect fallback, and E2E test coverage
Source changes from c063458 (Expand SDK E2E runtime coverage):
- Add waitFor() after destroyForcibly() in process cleanup
- Expand connect method fallback to match 'Unhandled method connect' message
- Extract formatCliExitedMessage helper for consistent error formatting
- Wait for stderr reader before throwing in port announcement
New E2E tests ported:
- EventFidelityTest: assistant.usage and session.usage_info event tests
- ToolResultsTest: rejected and denied resultType handling
- StreamingFidelityTest: streaming disabled on resume, reasoning effort
- ToolsTest: parallel tools, availableTools/excludedTools combined
- PermissionsTest: noResult kind, setApproveAll, slow handler
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Address PR review feedback on cleanup and tests
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/38b90523-b5be-4dbd-9d33-36361110399b
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Refine timeout constants from validation feedback
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/38b90523-b5be-4dbd-9d33-36361110399b
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Initial plan
* Fix flaky parallel tools test by removing non-deterministic synchronization
The testShouldExecuteMultipleCustomToolsInParallelSingleTurn test used
CountDownLatch barriers to verify that tool handlers overlapped in
execution. This caused a race condition: both handlers completed
simultaneously after the barrier was released, and the order in which
tool results were sent back to the CLI was non-deterministic. When
results arrived in a different order than the snapshot expected
(toolcall_1 before toolcall_0), the proxy returned a 500 error.
The fix simplifies the test to match the reference implementation
approach: tools return immediately, and we verify both tools were
called and the response contains both results. The SDK still dispatches
tools concurrently via its executor; the test just no longer forces
a specific timing that causes ordering issues.
Fixes #158
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* docs: update version references to 1.0.0-beta-java.1
* Port reference implementation changes: remote sessions, provider model overrides, startup cleanup race fix
- Add Remote option to CopilotClientOptions with --remote CLI flag
- Add modelId, wireModel, maxPromptTokens, maxOutputTokens to ProviderConfig
- Fix client startup cleanup race condition (process cleanup on failure)
- Update E2E test harness for CONNECT proxy metadata
- Add unit tests for new provider config fields and clone
- Add E2E tests for provider wire model feature
- Document remote sessions and model overrides in advanced.md
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Regenerate codegen output
Auto-committed by codegen-check workflow.
* Fix version drift between pom.xml and scripts/codegen/package.json
The sync-codegen-version.sh script used `npm install` which normalizes
semver ranges, stripping prerelease suffixes (e.g. ^1.0.43-0 → ^1.0.43).
Fix by writing the version directly into package.json before running
npm install, matching how sync-cli-version-from-reference-impl.sh
updates pom.xml.
Also fix CapiProxy inconsistent state: defer proxyUrl assignment until
after metadata parsing succeeds.
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/243ea08c-366e-4ac4-bdb6-939a59a1e755
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* On branch edburns/resolve-fake-test-time-token-failures
modified: src/test/java/com/github/copilot/sdk/E2ETestContext.java
modified: src/test/java/com/github/copilot/sdk/ExecutorWiringTest.java
Given that the live API was never used, I see no reason why we should condition the setting of fake tokens on the runtime environment (CI vs local).
The replaying proxy intercepts everything regardless of environment. The fake token just satisfies the CLI's startup check — it's never sent to a real API. The `GITHUB_ACTIONS` guard is unnecessary and is what broke local runs.
* On branch edburns/resolve-fake-test-time-token-failures
modified: pom.xml
- Force deterministic ordering.
modified: src/test/java/com/github/copilot/sdk/CapiProxy.java
- Pass through the fake token concept.
modified: src/test/java/com/github/copilot/sdk/CompactionTest.java
- Skip flaky test, see https://github.com/github/copilot-sdk/issues/1227
Signed-off-by: Ed Burns <edburns@microsoft.com>
* Port enableSessionTelemetry option and SDK tracing diagnostics from reference implementation
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* On branch edburns/resolve-fake-test-time-token-failures
Your branch is up to date with 'origin/edburns/resolve-fake-test-time-token-failures'.
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: src/test/java/com/github/copilot/sdk/CompactionTest.java
no changes added to commit (use "git add" and/or "git commit -a")
Signed-off-by: Ed Burns <edburns@microsoft.com>
* Regenerate codegen output
Auto-committed by codegen-check workflow.
* On branch edburns/resolve-fake-test-time-token-failures
modified: src/test/java/com/github/copilot/sdk/E2ETestContext.java
modified: src/test/java/com/github/copilot/sdk/ExecutorWiringTest.java
Given that the live API was never used, I see no reason why we should condition the setting of fake tokens on the runtime environment (CI vs local).
The replaying proxy intercepts everything regardless of environment. The fake token just satisfies the CLI's startup check — it's never sent to a real API. The `GITHUB_ACTIONS` guard is unnecessary and is what broke local runs.
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* On branch edburns/resolve-fake-test-time-token-failures
modified: pom.xml
- Force deterministic ordering.
modified: src/test/java/com/github/copilot/sdk/CapiProxy.java
- Pass through the fake token concept.
modified: src/test/java/com/github/copilot/sdk/CompactionTest.java
- Skip flaky test, see https://github.com/github/copilot-sdk/issues/1227
Signed-off-by: Ed Burns <edburns@microsoft.com>
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* On branch edburns/resolve-fake-test-time-token-failures
Your branch is up to date with 'origin/edburns/resolve-fake-test-time-token-failures'.
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: src/test/java/com/github/copilot/sdk/CompactionTest.java
no changes added to commit (use "git add" and/or "git commit -a")
Signed-off-by: Ed Burns <edburns@microsoft.com>
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Initial plan
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Disable flaky multi-client session resume tests that time out in test harness
These 3 tests consistently time out on main as well — the snapshot-based
test harness does not properly handle multi-client resume scenarios.
Marking as @Disabled to unblock CI.
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Fix AbortEvent tests to use valid AbortReason enum values after codegen update
The codegen regeneration changed AbortEvent.data.reason from a free-form
String to a strict AbortReason enum. Updated tests to use valid values
(user_initiated, user_abort) instead of the old strings.
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Address PR review feedback: fix invoke logging order, fix Javadoc, update @Disabled messages
- Move success log in JsonRpcClient.invoke after treeToValue deserialization
so that a schema mismatch triggers only the failure log, not both
- Fix Javadoc link text from "CopilotClientOptions.Telemetry" to
"CopilotClientOptions.TelemetryConfig" in SessionConfig and
ResumeSessionConfig
- Update @Disabled annotations with accurate root cause: tests pass in
isolation but time out in full suite due to test interaction (confirmed
by running full suite with tests re-enabled)
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Deduplicate success log in JsonRpcClient.invoke
Log success once after deserialization (or null for Void) rather than
duplicating the logTiming call in both branches.
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Re-enable 3 flaky multi-client session resume tests via isolated Surefire execution
The tests were @Disabled in PR 171 due to timeouts, but pass reliably in
isolation. Rather than leaving them disabled, use a JUnit 5 @Tag and a
separate Surefire execution to run them in their own forked JVM, avoiding
harness state leakage from the main test suite.
pom.xml:
- Add <executions> block to maven-surefire-plugin with two executions:
1. "default-test": runs all tests EXCEPT those tagged "isolated-resume"
2. "isolated-resume-tests": runs ONLY tests tagged "isolated-resume"
- Each execution forks a separate JVM, providing process-level isolation.
src/test/java/com/github/copilot/sdk/CopilotSessionTest.java:
- Remove @Disabled annotation from testShouldResumeSessionUsingNewClient
- Add @Tag("isolated-resume") to the test method
- Replace 'import Disabled' with 'import Tag'
src/test/java/com/github/copilot/sdk/StreamingFidelityTest.java:
- Remove @Disabled from testShouldProduceDeltasAfterSessionResume
- Remove @Disabled from testShouldNotProduceDeltasAfterSessionResumeWithStreamingDisabled
- Add @Tag("isolated-resume") to both test methods
- Replace 'import Disabled' with 'import Tag'
* Restore missing DTO coverage tests from 71272ec
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Initial plan
* docs: update version references to 1.0.0-beta-java.2
* Port exit-plan-mode and auto-mode-switch handler APIs from reference implementation
Adds ExitPlanModeHandler and AutoModeSwitchHandler support matching the
reference implementation commit 671b50a (Restore mode handler APIs across SDKs).
New types:
- ExitPlanModeHandler, ExitPlanModeRequest, ExitPlanModeResult, ExitPlanModeInvocation
- AutoModeSwitchHandler, AutoModeSwitchRequest, AutoModeSwitchResponse, AutoModeSwitchInvocation
Updated:
- SessionConfig/ResumeSessionConfig: onExitPlanMode, onAutoModeSwitch fields
- CreateSessionRequest/ResumeSessionRequest: requestExitPlanMode, requestAutoModeSwitch flags
- CopilotSession: handler registration and dispatch methods
- RpcHandlerDispatcher: exitPlanMode.request, autoModeSwitch.request handlers
- SessionRequestBuilder: wiring for new handlers and capability flags
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Add unit/E2E tests and documentation for mode handler APIs
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* Regenerate codegen output
Auto-committed by codegen-check workflow.
* fix version
* Centralize `requestId` parsing to fix `NumberFormatException` risks across all RPC handlers
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 <edburns@microsoft.com>
* Centralize `requestId` parsing to fix `NumberFormatException` risks across all RPC handlers
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 <edburns@microsoft.com>
* docs: update version references to 1.0.0-beta-java.3
* refactor: use Optional return types instead of nullable boxed primitives in public API
Change getter return types from nullable Boolean/Integer/Double to
Optional<Boolean>/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>
* fix: remove accidentally committed temp file and rename test method
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* 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>
* fix: add @JsonIgnore to InputOptions, rollback McpServerConfig/ModelLimits changes
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* test: add comprehensive clearXxx() and Jackson serialization roundtrip tests
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* fix: remove duplicate comment block in OptionalApiAndJacksonTest
Co-authored-by: edburns <75821+edburns@users.noreply.github.com>
* 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>
* 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>
* refactor: revert Optional usage, use plain nullable fields with @JsonInclude(NON_NULL)
Remove all Optional<T>/OptionalInt/OptionalDouble usage from DTOs.
R…
Resolves #179
Before the change?
066a69c..4a0437b)exitPlanModeorautoModeSwitchhandler APIs (added in ref-impl671b50a)@github/copilotpinned at previous versionAfter the change?
ExitPlanModeHandler,AutoModeSwitchHandlerfollowing existing@FunctionalInterfacepatterns (8 new files: handler, request, result/response, invocation for each)SessionConfig/ResumeSessionConfiggainonExitPlanModeandonAutoModeSwitchfields;CopilotSessionhandles registration, dispatch, and cleanupRpcHandlerDispatcherregistersexitPlanMode.requestandautoModeSwitch.request;SessionRequestBuildersetsrequestExitPlanMode/requestAutoModeSwitchcapability flags when handlers are presentapproved=true), decline auto mode switch (NO).lastmerge→4a0437bb, pom.xml and codegen synced to@github/copilot@^1.0.44-3Skipped commits (not applicable to Java): Rust SDK (4a0437b, 8794594, 55b3b1c, b0d1c8e), Go SDK (d5c8db4, 30a76a5, 4901dff), CI workflows (97f505c, 299ea21), .NET enums (e759700), E2E snapshots (f625779), doc typos (ce56eb8 — no matches in Java docs), Maven badge (f72bf0f — already present), Node pkg update (ac55e9a — handled by finish script).
Pull request checklist
mvn spotless:applyhas been run to format the codemvn clean verifypasses locallyDoes this introduce a breaking change?