Skip to content

[java] Add linux-x64 implementation of in process Copilot CLI - #2295

Open
edburns wants to merge 1042 commits into
mainfrom
edburns/1917-java-embed-rust-cli-runtime-dd-3042873-seeking-review-02
Open

[java] Add linux-x64 implementation of in process Copilot CLI#2295
edburns wants to merge 1042 commits into
mainfrom
edburns/1917-java-embed-rust-cli-runtime-dd-3042873-seeking-review-02

Conversation

@edburns

@edburns edburns commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

This PR is the roll up of the agentic work done in the subtasks of #2166 . At each step of those subtasks, the CI was clean and all reviews were applied as appropriate.

PR 2295 — Reviewer's guide: In-process FFI runtime for the Java SDK

TL;DR

This PR does for the Java SDK what #1901 did for .NET and #1915 did for Rust: it adds an in-process connection mode that loads the Copilot runtime (runtime.node cdylib) as a native library via JNA, eliminating the need for a separate CLI child process. Currently scoped to linux-x64 only; the entire in-process API surface is marked @CopilotExperimental.

The PR also restructures the Java Maven project from a single module into a multi-module reactor to support publishing the native runtime binaries as separate classifier JARs alongside the existing SDK JAR.


What's in the native binary, where does it come from, and how is it loaded?

The binary: runtime.node

Despite the .node extension (a napi-rs naming convention), runtime.node is an ordinary platform-specific shared library (.so on Linux). It is a Rust cdylib produced by the src/runtime crate in github/copilot-agent-runtime. It exposes two front doors:

  • napi front door — loaded by Node.js as a native addon (existing CLI path).
  • C ABI front door — 5 extern "C" lifecycle/transport entry points callable by any language via FFI without Node.js.

The 5 C ABI entry points are:

Entry point Purpose
copilot_runtime_host_start Start the runtime host. Blocks up to ~30s while the worker boots. Returns a server handle (0 = failure).
copilot_runtime_host_shutdown Shut down a runtime host by server handle.
copilot_runtime_connection_open Open a bidirectional connection; registers an on_outbound callback for runtime→SDK data delivery.
copilot_runtime_connection_write Write a JSON-RPC frame from the SDK into the runtime.
copilot_runtime_connection_close Close a connection.

All JSON-RPC methods travel as data through this fixed 5-function transport; the export surface never changes as the method set grows.

Where it comes from (build-time)

The copilot-native Maven module's build fetches the binary from npm during generate-resources:

  1. fetch-native.mjs reads the pinned version and SHA-512 integrity hash for @github/copilot-linux-x64 from nodejs/package-lock.json.
  2. Runs npm pack to download the exact tarball, verifies it against the integrity hash.
  3. Extracts runtime.node and the copilot CLI executable into a staging directory.
  4. maven-jar-plugin packages them into a classifier JAR (copilot-sdk-java-runtime-<version>-linux-x64.jar) with the layout native/linux-x64/runtime.node.

How it's loaded (runtime)

  1. PlatformDetector (303 lines) determines the classifier using os.name, os.arch, and on Linux, ELF PT_INTERP parsing to distinguish glibc vs musl — no subprocesses, no heuristics.
  2. NativeRuntimeLoader (466 lines) resolves the binary in this order:
    • COPILOT_CLI_PATH env var → checks for runtime.node alongside the CLI.
    • Classpath resource native/<classifier>/runtime.node → extracts atomically to ~/.copilot/runtime-cache/<version>/<classifier>/runtime.node.
    • Falls back to runtime.node alongside the bundled copilot executable.
  3. JnaNativeBinding (253 lines) loads the library by absolute path via JNA and maps each C ABI export. Enforces a one-library-per-process invariant (library handle is static, never unloaded). Duplicate loads from the same path are silently accepted; different paths are rejected.
  4. FfiRuntimeHost (349 lines) orchestrates the lifecycle: starts the host, opens a connection, bridges the bidirectional JSON-RPC transport. The on_outbound callback (invoked by native threads) feeds received data into a QueueInputStream that the SDK's existing JsonRpcClient reads from.

Structural changes

Multi-module Maven reactor

The single-module java/pom.xml is now a parent POM (pom packaging) with two submodules:

Module Artifact ID Purpose
java/pom.xml copilot-sdk-java-parent Reactor parent. Not published to Maven Central (maven.deploy.skip=true). Holds the release profile (GPG signing) inherited by all submodules.
java/sdk/ copilot-sdk-java The existing SDK JAR (~1.5 MB). All existing source moved here from java/src/java/sdk/src/.
java/copilot-native/ copilot-sdk-java-runtime Native runtime module. Produces classifier JARs (currently linux-x64 only, ~20-26 MB).

Consumer dependency declaration

<dependencies>
    <!-- Pure-Java SDK (~1.5 MB) -->
    <dependency>
        <groupId>com.github</groupId>
        <artifactId>copilot-sdk-java</artifactId>
        <version>${copilot.version}</version>
    </dependency>
    <!-- Native runtime for linux-x64 (~20-26 MB) — needed only for in-process mode -->
    <dependency>
        <groupId>com.github</groupId>
        <artifactId>copilot-sdk-java-runtime</artifactId>
        <version>${copilot.version}</version>
        <classifier>linux-x64</classifier>
    </dependency>
</dependencies>

Consumer usage

CopilotClientOptions options = new CopilotClientOptions()
    .setConnection(RuntimeConnection.forInProcess());

CopilotClient client = new CopilotClient(options);
client.start().get();

New public API surface (all @CopilotExperimental)

Type Description
RuntimeConnection (sealed class) Base type for connection configuration. Factory methods: forStdio(), forTcp(), forUri(String), forInProcess().
StdioRuntimeConnection Spawns a runtime child process, communicates over stdin/stdout (the default).
TcpRuntimeConnection Spawns a runtime child process listening on a TCP socket.
UriRuntimeConnection Connects to an already-running runtime at a URL.
InProcessRuntimeConnection Loads the native library in-process — no child process spawned.
CopilotClientOptions.setConnection() / getConnection() Entry point for selecting a connection type.

The RuntimeConnection API replaces the previous pattern of setting cliUrl, cliPath, useStdio, port, and tcpConnectionToken individually. When a RuntimeConnection is set, it takes precedence; conflicting legacy options cause IllegalArgumentException.


New internal packages

com.github.copilot.ffi (9 classes, ~1,752 lines)

Class Lines Role
FfiRuntimeHost 349 Lifecycle manager: start host → open connection → bridge I/O → shutdown.
JnaNativeBinding 253 JNA bindings for the 5 C ABI exports. Static library handle, one-per-process guard.
NativeBinding 131 Abstract contract for native operations (enables testing without real native library).
NativeRuntimeLoader 466 Locates runtime.node: env var → classpath → cache. Atomic extraction with file locking.
PlatformDetector 303 Determines platform classifier. ELF PT_INTERP parsing for glibc/musl detection on Linux.
QueueInputStream 119 Thread-safe bridge: native callback thread writes → SDK reader thread reads.
FfiOutputStream 63 Writes JSON-RPC frames from the SDK into the native runtime via connection_write.
OutboundCallback 46 JNA callback implementation for on_outbound.
ReaderThreadFactory 22 Named daemon thread factory for the reader executor.

Tests for FFI (6 files, ~2,054 lines)

Test class What it covers
FfiRuntimeHostTest Lifecycle, error handling, concurrent shutdown, callback drain.
JnaNativeBindingTest Load guard, duplicate-path acceptance, different-path rejection, active callback tracking.
NativeRuntimeLoaderTest Resolution order, atomic extraction, COPILOT_CLI_PATH override, cache reuse.
PlatformDetectorTest All 8 platform classifiers, ELF parsing, edge cases.
QueueInputStreamTest Thread-safe read/write, close semantics.
InProcessTransportIT End-to-end integration test using the replay proxy with in-process transport.

CI/workflow changes

  • New job java-sdk-inprocess in java-sdk-tests.yml: runs mvn clean verify -Pinprocess on ubuntu-latest (linux-x64). Uses continue-on-error: true while experimental.
  • Path updates in existing jobs: java/target/java/sdk/target/ for surefire/failsafe reports and coverage data.
  • JDK 17 cross-test: added -pl sdk to restrict to the SDK module (the native module requires JDK 25 build tools).
  • Codegen workflows: adjusted working directories for the java/sdk/ module layout.

✅ Note that the existing java publishing jobs will continue to work as currently written.


Key design decisions (from ADR-007)

  1. JNA over Panama FFM: JNA supports the Java 17 baseline with zero consumer configuration. Panama FFM requires Java 22+ and --enable-native-access flags. Performance difference is irrelevant (JSON-RPC I/O dominates).

  2. Per-platform classifier JARs over monolithic JAR: A monolithic JAR with all 6 common platforms would be ~132 MB. Classifier JARs let consumers pull only their target platform (~20-26 MB each). An uber-JAR can be assembled via maven-assembly-plugin if needed.

  3. Library-never-unloads pattern: The loaded native library is held in a static field and never released. Native worker threads outlive any individual FfiRuntimeHost instance; unloading would crash.

  4. One library per process: Enforced by a process-wide guard, consistent with Rust, .NET, Go, and Python SDK implementations.


Diff statistics

  • 107 commits, 1,582 files changed (mostly renames from java/src/java/sdk/src/)
  • ~6,624 insertions, ~825 deletions
  • New production code: ~2,117 lines (FFI + RuntimeConnection API)
  • New test code: ~2,054 lines
  • New build infrastructure: copilot-native/pom.xml (214 lines), fetch-native.mjs (114 lines)

Recommended review order

  1. ADR-007: java/docs/adr/adr-007-native-bundling-strategy.md — context, options considered, decision rationale.
  2. RuntimeConnection API: rpc/RuntimeConnection.java, rpc/InProcessRuntimeConnection.java, and rpc/CopilotClientOptions.java (the setConnection/getConnection methods).
  3. FFI bridge (bottom-up): NativeBinding.javaJnaNativeBinding.javaFfiRuntimeHost.javaNativeRuntimeLoader.javaPlatformDetector.java.
  4. Native module build: copilot-native/pom.xml and copilot-native/scripts/fetch-native.mjs.
  5. Multi-module restructure: java/pom.xml (parent) and java/sdk/pom.xml (child).
  6. CI: .github/workflows/java-sdk-tests.yml (new inprocess job, path updates).
  7. Tests: ffi/ test package and e2e/InProcessTransportIT.java.

Implementation details.

Implemented agentically using https://aka.ms/coreai/shepherd-task/slides .

github-actions Bot and others added 30 commits July 11, 2026 01:03
* Update @github/copilot to 1.0.71-0

- Updated nodejs and test harness dependencies
- Re-ran code generators
- Formatted generated code

* Fix Java billing coverage test

Exercise the new promotion field when constructing ModelBilling.

Generated by Copilot

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 93b921d6-55b4-4fdc-9583-17a69ad39d54

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Tool search configuration support

* Fix ResumeSessionConfig

* Fix spotless check

* Fix Copilot comments

* Fetch available tools for tool search

* Addressing CI and alerts

* Addressing review comments

* Fix formatting

* Fix spotless check
PR #1952 updated sample code from gpt-4.1 to gpt-5.4 but left behind references in source code docstrings/comments across all SDKs. This updates the remaining occurrences in SetModel/setModel/set_model API documentation.

Co-authored-by: j-zhangyiyuan <j-zhangyiyuan@microsoft.com>
Apply the docs style guide (.github/instructions/docs-style.instructions.md):
- Replace 'etc.' with 'and more' (4 occurrences across 3 files)
- Replace 'e.g.' with 'For example' (1 occurrence in code comment)
- Remove trailing whitespace (3 occurrences across 3 files)

Only safe files with no open PR conflicts were modified.

Co-authored-by: j-zhangyiyuan <j-zhangyiyuan@microsoft.com>
* Update @github/copilot to 1.0.71-2

- Updated nodejs and test harness dependencies
- Re-ran code generators
- Formatted generated code

* Address generated SDK review feedback

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 217cbb68-9e90-4cf7-a02a-45e93f6938dd

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The HMAC key auth method (CAPI_HMAC_KEY / COPILOT_HMAC_KEY) should not be
documented publicly; it was re-added by doc automation. Removes it from the
authentication priority list in authenticate.md and the summary in README.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add opaque metadata passthrough to SDK tool definitions

Add an optional, opaque `metadata` bag to tool definitions across all SDK
languages and forward it verbatim over the session.create/resume RPC. This
lets hosts attach namespaced metadata to tools without expanding the typed
public contract; the runtime may recognize specific keys to inform
host-specific behavior. Unknown keys are round-tripped untouched.

Languages: nodejs (Tool.metadata + defineTool), python (Tool.metadata +
define_tool), go (Tool.Metadata), rust (Tool.metadata + with_metadata),
java (ToolDefinition.metadata + createWithMetadata), dotnet
(CopilotToolOptions.Metadata + wire ToolDefinition.Metadata). Tests added
per language for wire/serialization forwarding and omission when unset.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address review feedback on tool metadata passthrough

- dotnet: change Metadata value type to IDictionary<string, JsonNode?> for
  NativeAOT-safe serialization (CopilotToolOptions + wire ToolDefinition,
  FromAIFunction cast, unit test); drop redundant [JsonPropertyName("metadata")]
  since the Web camelCase policy already maps it; remove the <remarks> block
  from the Metadata property.
- Reword metadata doc comments across nodejs/python/go/rust/java to describe
  the bag opaquely without the SDK-vs-runtime/CLI distinction.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f

* Java: enable tool metadata for @copilotTool + compat constructor

Address Java SME feedback so annotation-based tools reach parity with the
programmatic API and existing constructor call sites keep compiling.

- ToolDefinition: add a backward-compatible 7-arg constructor delegating to
  the canonical 8-arg with metadata=null.
- CopilotTool: add metadata() plus nested MetadataEntry/MetadataValue/
  MetadataFlag annotations (@target({})) with a shallow bool|str|flag-map
  representation, documenting the programmatic API for richer values.
- CopilotToolProcessor: generate the metadata constructor argument
  (Map.<String, Object>of(...) with an explicit type witness) instead of a
  hardcoded null; null when no metadata is present.
- Tests: processor generation cases (nested flags, absent, combined flags),
  ToolDefinition 7-arg/.metadata(...) copy/flag-chaining cases, and a
  fromObject metadata assertion; extend the SimpleTools fixture pair to emit
  a safeForTelemetry metadata map.
- ADR-005: update the generated snippet to the 8-arg shape and document the
  @copilotTool(metadata = ...) syntax and emitted shape.

Note: mvn verify / spotless:apply not run locally (no JDK/Maven in the dev
environment); relies on PR CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f

* Apply spotless formatting to Java metadata changes

Reflow javadoc and wrap annotation/constructor args per the Eclipse
formatter (mvn spotless:apply). No behavioral change.

Verified locally: mvn spotless:check clean; ToolDefinitionTest (8),
ToolDefinitionFromObjectTest (31), CopilotToolProcessorTest (37) all pass on
JDK 26.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f

* test: assert null metadata arg in generated tool definition

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: ab2c14cd-d2e1-4524-a6dc-e9c10899343c

* docs: describe the metadata-less ToolDefinition overload by its steady state

Reword the 7-arg constructor's Javadoc to describe what the overload is (a
convenience constructor equivalent to the canonical one with metadata=null)
rather than its relationship to a specific change ("backward-compatible",
"retained so ... keep compiling after metadata was added"), which is only
meaningful in the context of the PR that introduced it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f

* rust: use IndexMap for tool metadata to serialize deterministically

HashMap serializes keys in a randomized order, unlike the sibling `parameters`
field (IndexMap) and the other SDKs (nodejs/python insertion order, Go sorted).
Switch the tool `metadata` bag to IndexMap<String, Value> so key order is
deterministic and consistent, avoiding non-reproducible wire output. No new
dependency; indexmap is already used by this struct.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: bf2bf0dd-ec9f-42f5-a6e1-4f2a9e562d5f

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Ed Burns <edburns@microsoft.com>
* Instrument Node in-process test stalls

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e902b9a-5527-4a32-a5a3-e0bf5bfef3f7

* Trace runtime and proxy during Node stalls

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e902b9a-5527-4a32-a5a3-e0bf5bfef3f7

* Create focused Windows in-process stress run

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e902b9a-5527-4a32-a5a3-e0bf5bfef3f7

* Measure Windows test resource pressure

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 6e902b9a-5527-4a32-a5a3-e0bf5bfef3f7

* Preserve runtime diagnostics on failure

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 6e902b9a-5527-4a32-a5a3-e0bf5bfef3f7

* Trace Windows session database locks

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 6e902b9a-5527-4a32-a5a3-e0bf5bfef3f7

* Avoid perturbing runtime lock timing

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 6e902b9a-5527-4a32-a5a3-e0bf5bfef3f7

* Avoid Windows in-process teardown deadlock

Do not retry removal of the in-process runtime's session home while its Vitest worker still owns a locked session database. Retrying until the hook timeout prevents the worker from exiting and releasing the lock.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 6e902b9a-5527-4a32-a5a3-e0bf5bfef3f7

* Clarify Windows teardown deadlock

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 6e902b9a-5527-4a32-a5a3-e0bf5bfef3f7

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Update @github/copilot to 1.0.71

- Updated nodejs and test harness dependencies
- Re-ran code generators
- Formatted generated code

* Route Python hooks.invoke through generated client-global handler

CLI 1.0.71 promoted hooks.invoke to a client-global RPC method with a
generated HooksHandler interface. The handwritten SDK still registered its
own hooks.invoke handler, which only avoided colliding with the generated
one because global handlers were skipped when no LLM/telemetry adapter was
set.

Make the wiring intentional: add _HooksAdapter implementing the generated
HooksHandler protocol (routing HookInvokeRequest.sessionId to the matching
session's dispatcher), always register the client-global handlers with the
hooks adapter, and remove the redundant handwritten hooks.invoke
registrations and dead client-level handler.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae226b7f-caf9-46f3-b8c5-b9a21c5d7951

* Route Node hooks.invoke through generated client-global handler

CLI 1.0.71 promoted hooks.invoke to a client-global RPC method with a
generated HooksHandler interface. The handwritten SDK registered its own
hooks.invoke handler on the connection, which the generated
registerClientGlobalApiHandlers then shadowed with an unwired handler that
threw "No hooks client-global handler registered" — so hooks never fired.

Wire the existing handleHooksInvoke routing into the generated
clientGlobalHandlers.hooks slot and drop the redundant handwritten
connection.onRequest("hooks.invoke") registration. Behavior is unchanged;
the dispatcher and its payload validation are reused as-is.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae226b7f-caf9-46f3-b8c5-b9a21c5d7951

* Route Go hooks.invoke through generated client-global handler

CLI 1.0.71 promoted hooks.invoke to a client-global RPC method whose
generated registration installs a hooks.invoke handler that rejects all
invocations unless the Hooks slot is populated. Whenever an LLM inference
or telemetry adapter was configured, that generated handler overrode the
handwritten hooks.invoke registration and hooks stopped firing (e.g. the
sub-agent hook test).

Always register the client-global handlers with a hooksAdapter that
delegates to the existing per-session dispatcher, and drop the redundant
handwritten hooks.invoke registration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae226b7f-caf9-46f3-b8c5-b9a21c5d7951

* Fix Rust hook input deserialization for float timestamps

The Copilot CLI serializes hook input `timestamp` as a JSON float
(e.g. `1784203878038.0`). Rust's hand-authored hook input structs typed
`timestamp` as `i64`, so `serde_json::from_value` rejected the float,
`dispatch_hook` returned an error, and the session handler fell back to
an empty `{ "output": {} }` response. Hooks therefore never fired: e.g. a
preToolUse deny was dropped, the CLI executed the tool, and the replayed
conversation diverged ("No cached response" -> 500).

Other SDKs tolerate this incidentally (Go decodes `input` into `any` and
re-marshals, dropping the `.0`); Rust decodes strictly. Type the hook
input `timestamp` fields as `f64` to match the shape the runtime sends.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ae226b7f-caf9-46f3-b8c5-b9a21c5d7951

* Fix .NET build break and float hook timestamps for hooks.invoke

CLI 1.0.71 promoted hooks.invoke to an internal client-global RPC method.
The C# codegen still emitted its internal request/result DTOs behind a public
IHooksHandler surface, producing CS0050/CS0051 inconsistent-accessibility
errors that broke the entire .NET build. It also registered a second, unwired
hooks.invoke handler that would shadow the working handwritten one.

Filter internal client-global and client-session methods in the C# code
generator so no generated interface, handler property, or RPC registration is
emitted for internal methods like hooks.invoke. The handwritten
SetLocalRpcMethod(hooks.invoke, ...) registration continues to serve hooks.
This mirrors, for .NET's static typing, the routing fixes already applied to
Node, Python, and Go.

Also tolerate hook timestamp epoch milliseconds encoded as either JSON
integers or floats in UnixMillisecondsDateTimeOffsetConverter, covering the
CLI 1.0.71 float serialization (matching the Rust fix).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 94a20428-6b0e-4733-a354-0abf2d186320

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Steve Sanderson <SteveSandersonMS@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Stephen Toub <stoub@microsoft.com>
* Enable issue intents on issue-triage workflow

Recompile issue-triage.lock.yml with gh-aw v0.82.1 to wire
GH_AW_RUNTIME_FEATURES=${{ vars.GH_AW_RUNTIME_FEATURES }}, enabling native
issue intents (rationale/confidence) for the workflow's add-labels safe
output. No behavior change: the trigger, permissions, prompt, and safe
outputs are unchanged, and the source .md is untouched.

The actions-lock.json pin bump (github/gh-aw-actions/setup v0.82.1) is
required by the recompiled lock.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Bump verify-compiled gh-aw pin to v0.82.1 and recompile locks

The verify-compiled workflow pinned gh-aw v0.77.5 while issue-triage.lock.yml
was compiled with v0.82.1, so CI recompiled at v0.77.5 and the byte diff failed
the check. Bump the pin to v0.82.1 to match, and recompile all lock files at
v0.82.1 so they are consistent with the pinned compiler.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* chore(aw): upgrade aw workflows with latest pre-release

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* fix(ci): align verify workflow gh-aw toolchain

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Add generated agentics-maintenance workflow (gh-aw v0.82.10)

`gh aw compile` with the v0.82.10 toolchain introduced by this PR emits
`.github/workflows/agentics-maintenance.yml`. Commit the generated file
so it is tracked alongside the recompiled locks.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 004ba78d-3cf4-41ab-8647-180e683460f0

* Enable org billing (copilot-requests) for agentic workflows

Add `permissions.copilot-requests: write` to all 11 agentic (gh-aw)
workflows so their Copilot usage is billed to the org, and recompile the
lock files. The compiled workflows now authenticate the Copilot CLI with
the GitHub Actions token and set S2STOKENS=true.

Authored by adding `features.copilot-requests: true`, migrating it with
`gh aw fix --write` (the deprecated flag maps to the permission), and
recompiling with gh-aw v0.82.10.

Rebased onto #1880 (issue-intents), which bumps the pinned gh-aw CLI to
v0.82.10.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 004ba78d-3cf4-41ab-8647-180e683460f0

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Steve Sanderson <SteveSandersonMS@users.noreply.github.com>
When a model calls a nonexistent tool, the runtime replies with
"Available tools that can be called are <list>." The E2E replay proxy
embedded that literal enumeration in ~54 snapshots, so any change to the
built-in tool set (e.g. the new write_agent tool) broke snapshot matching
and caused the copilot-agent-runtime C# SDK canary to retry forever until
the 45m timeout.

Collapse the entire enumeration to a stable ${available_tools} placeholder
on both the live-request side (normalizeAvailableToolNames) and the stored
snapshot side (new normalizeStoredToolMessages applied at load time), so
snapshots keep matching as the built-in tool set evolves across runtime
versions and platforms.


Copilot-Session: fa431f41-c7dc-4580-9cba-274170ee64df

Co-authored-by: TestUser <test@example.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add custom agent reasoning effort

Expose an optional per-agent reasoning effort across every SDK binding while preserving omission semantics and the reasoningEffort wire name. Add focused serialization, cloning, builder, and DTO coverage plus custom-agent documentation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 32727fc4-2ac8-41eb-a68a-e74674ecf155

* Clarify custom agent effort inheritance

Document that omitted per-agent reasoning effort inherits an explicit parent session effort, while omission at both levels leaves the backend to choose.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 32727fc4-2ac8-41eb-a68a-e74674ecf155

* Clarify custom agent effort API docs

Align every binding's CustomAgentConfig description with runtime inheritance semantics for omitted reasoning effort.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 32727fc4-2ac8-41eb-a68a-e74674ecf155

* Test custom agent effort through client

Capture session.create requests through the public .NET client path instead of reflecting into private serializer options.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 32727fc4-2ac8-41eb-a68a-e74674ecf155

* Clarify custom agent effort omission

Document that omitted per-agent reasoning effort sends no override and lets the backend choose its default rather than inheriting the parent session effort.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 32727fc4-2ac8-41eb-a68a-e74674ecf155
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bumps the java-codegen-deps group with 1 update in the /java/scripts/codegen directory: [tsx](https://github.com/privatenumber/tsx).


Updates `tsx` from 4.22.4 to 4.23.1
- [Release notes](https://github.com/privatenumber/tsx/releases)
- [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs)
- [Commits](privatenumber/tsx@v4.22.4...v4.23.1)

---
updated-dependencies:
- dependency-name: tsx
  dependency-version: 4.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: java-codegen-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Update SDK E2E tests for canonical exit_plan_mode action order

The runtime now canonicalizes the exit_plan_mode action menu to
[autopilot, interactive, exit_only] regardless of the order the model
passes in the tool call. Update the mode_handlers E2E assertions in all
five SDK suites (C#, Go, Node, Python, Rust) to expect the canonical
order so the shared snapshot test passes against the current runtime.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 9e36340e-3d37-46ed-ac6f-3989fea57dc7

* Update mode_handlers snapshot to canonical exit_plan_mode action order

The E2E tests were updated to expect the canonical action order
[autopilot, interactive, exit_only], but the replay snapshot still
supplied [interactive, autopilot, exit_only] as the model's
exit_plan_mode tool-call arguments, which the CLI forwards verbatim to
the SDK handler. Align the snapshot with the tests so request.actions
matches across all language SDKs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 446b10a1-29f6-4155-bf3a-ac1241c742f3

---------

Co-authored-by: TestUser <test@example.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Add .NET BYOK E2E coverage

Reuse conceptual replay snapshots across Anthropic Messages, OpenAI Responses, and OpenAI Chat Completions, and add three Ubuntu in-process CI legs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c

* Normalize Anthropic adjacent user turns

Collapse runtime-specific blank-line expansion so conceptual replay snapshots match recovery turns consistently.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c

* Document potential BYOK E2E gaps

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c

* Restore workflow path quoting

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c

* Preserve the .NET test matrix

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c

* Clarify replay harness test leg

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c

* Use existing replay harness test coverage

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c

* Simplify BYOK replay harness

Make non-CAPI replay explicitly read-only so provider response parsing and SSE aggregation are unnecessary. Keep protocol-complete forward rendering, clarify backend trait naming, and rename the .NET proxy wrapper to reflect its protocol-neutral role.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c

* Unify replay protocol paths

Select a protocol descriptor once per backend so CAPI and BYOK share routing, canonical matching, errors, JSON/SSE responses, and exchange inspection. Replay compaction directly from canonical snapshots instead of synthesizing provider-specific responses.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c

* Fix Responses replay stream lifecycle

Keep initial Responses events in progress and empty until their matching delta and done events, and use the isolated E2E context when injecting a BYOK provider.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 85a40918-bd95-440b-b6e9-97c757a71f8c
* Harden MCP OAuth cancel E2E tests against create/interest race

The MCP OAuth "cancel" E2E tests sampled the host auth callback the instant
the server reached `needs-auth`, which is racy: `session.create` kicks off the
MCP connection, but the SDK only registers its `mcp.oauth_required` event
interest after create returns. When the server's initial 401 wins that race,
the runtime records `needs-auth` without invoking the host callback, so the
callback observation was intermittently empty (e.g. the flaky C# CI leg in
copilot-agent-runtime).

Wait for the callback to be invoked (bounded, reusing each suite's existing
wait-for-condition helper) instead of sampling it immediately. A later runtime
auth retry fires the callback with the same `initial` reason, so the assertions
stay valid. Applied uniformly to C#, Go, Python, Java, and Rust; the Go change
also guards the observed request with a mutex to fix a latent data race.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f7849882-a2a2-4587-a602-da7718889a8c

* Use TaskCompletionSource for thread-safe callback wait in C# cancel test

Addresses review feedback: the previous poll read observedRequest (written by the callback thread) from the test continuation without synchronization. Switch to the TaskCompletionSource pattern already used by the direct-RPC test in this file, so the callback result is handed off safely and awaited with a timeout.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: f7849882-a2a2-4587-a602-da7718889a8c

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Mirror Node SDK releases internally

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b6e76edd-7acc-4681-a884-56d16967c048

* Simplify release retry handling

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b6e76edd-7acc-4681-a884-56d16967c048

* Handle Azure feed conflict prefix

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b6e76edd-7acc-4681-a884-56d16967c048

* Fix Windows release helper parsing

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b6e76edd-7acc-4681-a884-56d16967c048

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
* Strongly type expAssignments session config across all SDKs

Replace the opaque JSON typing of the internal `expAssignments`
session-config field with a strongly-typed `CopilotExpAssignmentResponse`
(plus `ExpConfigEntry`) in every SDK, mirroring the runtime contract.

Wire keys remain PascalCase (Features, Flights, Configs, Id, Parameters,
...), optional fields are omitted when null, and the field keeps its
internal/hidden posture in each language.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 43d7a02b-08ff-4e7d-a8c0-afa6dfbe94b0

* Address review: normalize required exp-assignment fields

- Go: add MarshalJSON to CopilotExpAssignmentResponse/ExpConfigEntry so
  nil Features/Flights/Configs/Parameters serialize as []/{} instead of
  null, matching the Python/Rust/.NET reference behavior; add a test.
- Java: default AssignmentContext to "" so the required field is not
  dropped by NON_NULL when unset.
- .NET: tighten ExpConfigEntry.Parameters value type from JsonNode? to
  JsonValue? to constrain values to JSON scalars.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 43d7a02b-08ff-4e7d-a8c0-afa6dfbe94b0

* Default ExpConfigEntry.Id to "" in Java

The Id field is required by the wire contract, but defaulting to null let
class-level NON_NULL drop the key for a zero-value entry. Default it to ""
so the required key is always emitted, matching the Go and .NET defaults.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 43d7a02b-08ff-4e7d-a8c0-afa6dfbe94b0

* Fix stale "opaque JSON" comment in Python exp wiring

The expAssignments path now serializes a concrete CopilotExpAssignmentResponse,
so drop the outdated "opaque JSON" wording from the adjacent comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 43d7a02b-08ff-4e7d-a8c0-afa6dfbe94b0

* Fix nightly rustfmt import grouping in types.rs tests

Move `use std::collections::HashMap;` into the std import block so
`cargo fmt --check` with the nightly group_imports config passes in CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 43d7a02b-08ff-4e7d-a8c0-afa6dfbe94b0

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Update @github/copilot to 1.0.72

- Updated nodejs and test harness dependencies
- Re-ran code generators
- Formatted generated code

* Fix Copilot 1.0.72 E2E compatibility

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b518a351-2110-47a8-98be-371b1e8e5608

* Fix abort recovery E2E tests

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b518a351-2110-47a8-98be-371b1e8e5608

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Mackinnon Buck <mackinnon.buck@gmail.com>
edburns and others added 17 commits August 7, 2026 18:42
The WebSocket protocol (RFC 6455 §4.2.2) mandates SHA-1 for computing
the Sec-WebSocket-Accept header. This is not used for security purposes.
Added both @SuppressWarnings and lgtm suppression comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c4e523e3-9d39-4598-90ec-54d959c44ce8
The java-sdk-inprocess CI job set COPILOT_SDK_DEFAULT_CONNECTION=inprocess
as a step-level environment variable, which leaked into surefire unit tests.
The Maven inprocess profile already configures this env var only in
failsafe's <environmentVariables>, per the design: 'Leave Surefire on its
standard transport; only Failsafe ITs use InProcess.' Removing the
redundant step-level env var fixes all 195 surefire test errors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c4e523e3-9d39-4598-90ec-54d959c44ce8
Use absolute paths for system commands (cat → /usr/bin/cat, cmd →
COMSPEC env var) and resolve npx via PATH search in CapiProxy to
avoid executing commands with relative paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c4e523e3-9d39-4598-90ec-54d959c44ce8
- JnaNativeBinding.trackedCallbacks: suppress with @SuppressWarnings;
  this is a GC-root pattern — values are intentionally never read, the
  map exists solely to prevent garbage collection of JNA callback
  function pointers while native code holds them.
- ErrorHandlingTest: access errorEvents via LOG.info after session close
  (events may or may not be emitted depending on CLI version/scenario).
- SessionEventsE2ETest: add assertTrue on usageEvents.size() to access
  the collected list (events are backend-dependent).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c4e523e3-9d39-4598-90ec-54d959c44ce8
- SessionEventsE2ETest: replace trivially-true size >= 0 assertion with
  conditional content access (getData() assertion when events present).
- InProcessEnvGuard: suppress StringEquality warning on intentional
  identity comparison with ABSENT_SENTINEL (unique instance used as a
  null-alternative sentinel to distinguish absent vs empty env vars).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c4e523e3-9d39-4598-90ec-54d959c44ce8
The lgtm[java/reference-equality-on-strings] comment suppresses CodeQL
for the ABSENT_SENTINEL identity check. Java's @SuppressWarnings is not
honored by CodeQL's analysis engine.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c4e523e3-9d39-4598-90ec-54d959c44ce8
Use .equals() instead of == for the sentinel check. The sentinel value
contains null bytes that cannot appear in real environment variables,
making .equals() safe and eliminating the CodeQL string-identity alert.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c4e523e3-9d39-4598-90ec-54d959c44ce8
Author: Ed Burns <edburns@microsoft.com>
Date:   Fri Aug 7 17:29:06 2026 +0000

    Fix Java in-process test lifecycle and parity
    
    Prevent the Java in-process test profile from corrupting Surefire control
    streams or poisoning later tests through the runtime's process-global LLM
    provider registration. Preserve explicit subprocess and TCP transport choices,
    sanitize process-only options before constructing in-process clients, and run
    request-handler tests over their required isolated stdio runtime.
    
    Fix the remaining test-contract issues by making fake socket RPC handler
    registration atomic with reader startup, honoring the configured CLI
    entrypoint when runtime.node is in a prebuilds directory, and isolating the
    streaming model-cache scenario. Remove in-process skip annotations from tests
    that already exercise an explicit subprocess transport.
    
    The complete `mvn clean verify -Pinprocess` run now finishes successfully
    without hangs, transport timeouts, provider-ownership failures, or Surefire
    stream corruption.
    
    File-by-file manifest:
    
    - `java/sdk/pom.xml`: use Surefire's TCP fork channel for unit and integration
      tests so native runtime output cannot corrupt Maven's process-pipe protocol.
    - `java/sdk/src/main/java/com/github/copilot/CopilotClient.java`: preserve
      explicitly selected TCP options when the default connection environment
      requests in-process transport.
    - `java/sdk/src/main/java/com/github/copilot/JsonRpcClient.java`: add a socket
      construction hook that registers handlers before the reader thread starts.
    - `java/sdk/src/main/java/com/github/copilot/ffi/NativeRuntimeLoader.java`:
      resolve the configured Copilot executable separately from runtime.node when
      the native library uses the package's prebuilds layout.
    - `java/sdk/src/main/java/com/github/copilot/rpc/CopilotClientOptions.java`:
      allow `setCwd(null)` to clear a previously configured working directory.
    - `java/sdk/src/test/java/com/github/copilot/ClientOptionsE2ETest.java`: run
      explicit fake-stdio option forwarding tests under the in-process profile.
    - `java/sdk/src/test/java/com/github/copilot/ConfigCloneTest.java`: cover
      clearing a configured working directory.
    - `java/sdk/src/test/java/com/github/copilot/CopilotClientTest.java`: remove
      obsolete in-process skips from explicit subprocess and TCP lifecycle tests.
    - `java/sdk/src/test/java/com/github/copilot/CopilotClientTransportTest.java`:
      test explicit transport precedence, in-process option sanitization, and TCP
      token selection under the profile default.
    - `java/sdk/src/test/java/com/github/copilot/CopilotRequestTestSupport.java`:
      explicitly select stdio for request-handler tests that register the
      process-global LLM inference provider.
    - `java/sdk/src/test/java/com/github/copilot/E2ETestContext.java`: honor
      explicit transports, route request-handler clients to subprocess isolation,
      and clear environment, cwd, and CLI arguments before in-process client
      construction.
    - `java/sdk/src/test/java/com/github/copilot/GitHubTelemetryTest.java`: register
      fake runtime RPC handlers before socket message processing begins.
    - `java/sdk/src/test/java/com/github/copilot/MetadataApiTest.java`: run explicit
      stdio metadata tests instead of skipping them under the profile.
    - `java/sdk/src/test/java/com/github/copilot/PerSessionAuthTest.java`: run the
      explicit subprocess unauthenticated case under the profile.
    - `java/sdk/src/test/java/com/github/copilot/RpcServerMiscE2ETest.java`: run the
      explicit subprocess account lifecycle case under the profile.
    - `java/sdk/src/test/java/com/github/copilot/StreamingFidelityTest.java`: give
      the gpt-5.4 reasoning/streaming scenario an isolated proxy and runtime model
      cache.
    - `java/sdk/src/test/java/com/github/copilot/ffi/FfiRuntimeHostTest.java`: cover
      failed connection-open cleanup followed by successful sequential startup.
    - `java/sdk/src/test/java/com/github/copilot/ffi/NativeRuntimeLoaderTest.java`:
      cover resolving a configured CLI beside a prebuilds runtime.
    
    Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
    Copilot-Session: e03c4e94-97b0-41ad-9f4e-c01633dc0bf7
Copilot AI balanced review requested due to automatic review settings August 7, 2026 19:23
@edburns
edburns requested a review from a team as a code owner August 7, 2026 19:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

Comment thread java/sdk/src/main/java/com/github/copilot/CopilotClient.java Fixed
Comment thread java/sdk/src/main/java/com/github/copilot/ffi/JnaNativeBinding.java Dismissed
Comment thread java/sdk/src/main/java/com/github/copilot/ffi/JnaNativeBinding.java Dismissed
Comment thread java/sdk/src/main/java/com/github/copilot/ffi/JnaNativeBinding.java Dismissed
Comment thread java/sdk/src/main/java/com/github/copilot/ffi/JnaNativeBinding.java Dismissed
Comment thread java/sdk/src/main/java/com/github/copilot/ffi/JnaNativeBinding.java Dismissed
Comment thread java/sdk/src/main/java/com/github/copilot/ffi/QueueInputStream.java Dismissed
Comment thread java/sdk/src/main/java/com/github/copilot/ffi/QueueInputStream.java Dismissed
Comment thread java/sdk/src/test/java/com/github/copilot/CopilotClientTransportTest.java Dismissed
Comment thread java/sdk/src/test/java/com/github/copilot/ffi/InProcessEnvGuard.java Dismissed
@github-actions

This comment has been minimized.

…Connection APIs as @CopilotExperimental

- Move GPG signing release profile from sdk/pom.xml to parent pom.xml so
  all reactor modules (sdk + copilot-native) are signed on publish.
- Move README.md from java/sdk/ to java/ top level and fix relative paths.
- Add in-process mode (experimental) section to README documenting the
  copilot-sdk-java-runtime classifier dependency and RuntimeConnection usage.
- Annotate RuntimeConnection, StdioRuntimeConnection, TcpRuntimeConnection,
  UriRuntimeConnection, and CopilotClientOptions.get/setConnection() with
  @CopilotExperimental.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 35ff58dd-bfec-40bc-981d-d3c82174511d
@github-actions

This comment has been minimized.

The README was moved from java/sdk/ to java/ but the test still
resolved it relative to the sdk module directory. Update the path
to ../README.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 35ff58dd-bfec-40bc-981d-d3c82174511d
@github-actions

This comment has been minimized.

NativeRuntimeLoader.resolveEntrypoint() handles COPILOT_CLI_PATH
resolution internally, making the CopilotClientOptions parameter
redundant.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 35ff58dd-bfec-40bc-981d-d3c82174511d
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review ✅

This PR adds Java in-process FFI support (RuntimeConnection.forInProcess() / InProcessRuntimeConnection), completing feature parity across all six SDK implementations.

Status across SDKs:

SDK In-process transport Factory method
Node.js ✅ (pre-existing) RuntimeConnection.forInProcess()
Python ✅ (pre-existing) RuntimeConnection.for_inprocess()
Go ✅ (pre-existing) InProcessConnection{} (idiomatic Go struct literal)
.NET ✅ (pre-existing, PR #1901) RuntimeConnection.ForInProcess()
Rust ✅ (pre-existing, PR #1915) Transport::InProcess
Java added by this PR RuntimeConnection.forInProcess()

No consistency issues found. The Java API naming follows Java conventions (camelCase methods, PascalCase types) and is semantically parallel to all other SDK implementations. The RuntimeConnection sealed-class hierarchy with forStdio(), forTcp(), forUri(), and forInProcess() factory methods mirrors the .NET and Node.js patterns exactly.

The multi-module Maven restructure (java/src/java/sdk/src/) is Java-internal build infrastructure and does not affect the public API surface.

Generated by SDK Consistency Review Agent for #2295 · sonnet46 35 AIC · ⌖ 5.43 AIC · ⊞ 6.6K ·

@edburns
edburns force-pushed the edburns/1917-java-embed-rust-cli-runtime-dd-3042873-seeking-review-02 branch from e27e834 to d66ea1a Compare August 7, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.