Skip to content

all SDKs: add EnableExperimentalMode to session create/resume wire with mode-aware defaults - #1600

Merged
SteveSandersonMS merged 1 commit into
mainfrom
jmoseley/rust-sdk-is-experimental-mode
Aug 3, 2026
Merged

all SDKs: add EnableExperimentalMode to session create/resume wire with mode-aware defaults#1600
SteveSandersonMS merged 1 commit into
mainfrom
jmoseley/rust-sdk-is-experimental-mode

Conversation

@jmoseley

@jmoseley jmoseley commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds per-session EnableExperimentalMode support across all SDKs so a consumer can control whether a session enables experimental features.

This pairs with a companion copilot-agent-runtime change that adds an optional isExperimentalMode?: boolean field to the classic --server SessionCreateRequest / SessionResumeRequest.

SDK semantics are now mode-aware and consistent across languages:

  • in copilot-cli mode, the SDK leaves the field unset by default so the runtime decides
  • in empty mode, the SDK sends false by default unless the developer explicitly opts in with true

The motivating consumer is the GitHub desktop app, which spawns copilot --server and needs per-session control over the experimental tier.

Changes

  • Rust

    • rust/src/wire.rs: Add is_experimental_mode: Option<bool> (with skip_serializing_if = "Option::is_none") to SessionCreateWire and SessionResumeWire. Serializes as isExperimentalMode via the existing rename_all = "camelCase".
    • rust/src/types.rs:
      • Add pub enable_experimental_mode: Option<bool> to SessionConfig and ResumeSessionConfig.
      • Wire it through the manual Debug impls, Default/new constructors, and both into_wire mappings.
      • Add with_enable_experimental_mode(bool) builders to both.
      • Update the public docs to consistently describe this as controlling whether the session enables experimental features, with empty-mode vs copilot-cli defaults.
    • rust/src/mode.rs / rust/src/session.rs: Apply mode-aware defaulting so unset values become false in ClientMode::Empty and remain unset in ClientMode::CopilotCli.
  • Node.js / TypeScript

    • Add optional enableExperimentalMode?: boolean to the public session config surface.
    • Forward it through session.create and session.resume request payloads as wire field isExperimentalMode.
    • Apply mode-aware defaulting so "empty" mode sends false when unset, while "copilot-cli" leaves it unset.
    • Update public docs to use the consistent wording and default behavior.
  • Python

    • Add optional enable_experimental_mode: bool | None to create_session / resume_session.
    • Forward it as isExperimentalMode in session.create and session.resume.
    • Apply mode-aware defaulting so mode="empty" sends False when unset, while mode="copilot-cli" leaves it unset.
    • Update public docs to use the consistent wording and default behavior.
  • Go

    • Add EnableExperimentalMode *bool to SessionConfig and ResumeSessionConfig.
    • Thread it through the hand-written createSessionRequest / resumeSessionRequest wire structs and request building, keeping the wire field name isExperimentalMode.
    • Apply empty-mode defaults in applyConfigDefaultsForMode / applyResumeDefaultsForMode so unset values become false only in ModeEmpty.
    • Update public comments to use the consistent wording and default behavior.
  • .NET

    • Add nullable EnableExperimentalMode to SessionConfigBase.
    • Forward it through CreateSessionRequest / ResumeSessionRequest and clone logic, while keeping the wire field name unchanged.
    • Apply empty-mode defaults in ApplyConfigDefaultsForMode so unset values become false only in CopilotClientMode.Empty.
    • Update public XML docs to use the consistent wording and default behavior.
  • Java

    • Add nullable enableExperimentalMode support to SessionConfig and ResumeSessionConfig with getter/setter/clear methods and clone wiring.
    • Forward it through SessionRequestBuilder into CreateSessionRequest / ResumeSessionRequest, keeping the wire field name isExperimentalMode.
    • Make SessionRequestBuilder mode-aware so empty mode defaults unset values to false, while copilot-cli leaves them unset.
    • Update Javadocs to use the consistent wording and default behavior.

Tests

Added or updated focused tests in each SDK to verify EnableExperimentalMode is forwarded when set and that the default behavior is mode-aware while the wire payload still uses isExperimentalMode:

  • Rust: unit tests covering create/resume serialize-present and omitted-when-None, plus mode-default helper tests
  • Node.js: client request-forwarding test for create/resume plus empty-vs-copilot-cli defaulting coverage
  • Python: client request-forwarding test for create/resume plus empty-vs-copilot-cli defaulting coverage
  • Go: request serialization tests for explicit present/omitted cases plus mode-default tests
  • .NET: request serialization, clone, and mode-default tests
  • Java: SessionRequestBuilderTest coverage for create/resume set, omitted, and empty-mode default cases

Validation

  • Rust: targeted cargo test experimental_mode passes locally with COPILOT_SKIP_CLI_DOWNLOAD=1
  • Node.js: targeted client forwarding/defaulting tests for enableExperimentalMode pass
  • Python: targeted uv run pytest test_client.py -k "enable_experimental_mode" passes
  • Go: targeted request serialization and mode-default tests pass
  • .NET: targeted SerializationTests coverage for EnableExperimentalMode and mode defaults passes
  • Java: mvn -Denforcer.skip=true test -Dtest=SessionRequestBuilderTest passes locally

No schema codegen needed for this change path.

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

@jmoseley
jmoseley requested a review from a team as a code owner June 8, 2026 17:32
Copilot AI review requested due to automatic review settings June 8, 2026 17:32

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.

Pull request overview

Adds per-session control of the Copilot CLI experimental feature-flag tier to the Rust SDK by threading an optional is_experimental_mode: Option<bool> through the user-facing config types into the JSON-RPC session.create / session.resume wire payloads (camelCased as isExperimentalMode and omitted when None for backwards compatibility).

Changes:

  • Add is_experimental_mode: Option<bool> to SessionCreateWire and SessionResumeWire with skip_serializing_if = "Option::is_none".
  • Add is_experimental_mode: Option<bool> to SessionConfig and ResumeSessionConfig, wire it through defaults/debug/into_wire, and add with_is_experimental_mode(bool) builders.
  • Add unit tests asserting isExperimentalMode serializes when set and is omitted when None for both create and resume paths.
Show a summary per file
File Description
rust/src/wire.rs Extends create/resume JSON wire structs to include optional isExperimentalMode when provided.
rust/src/types.rs Exposes is_experimental_mode on public config types, maps it into wire payloads, and adds serialization/omission tests.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment thread rust/src/types.rs Outdated
@stephentoub

Copy link
Copy Markdown
Collaborator

We will want to add this to all 6 SDKs, not just Rust.

@SteveSandersonMS

Copy link
Copy Markdown
Contributor

@copilot Continue this PR by adding support for the other 5 languages in addition to Rust

Copilot AI commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

@copilot Continue this PR by adding support for the other 5 languages in addition to Rust

Addressed in c70d1da. Added isExperimentalMode support for session create/resume in Node, Python, Go, .NET, and Java, including focused tests for each SDK.

Copilot AI changed the title rust: add isExperimentalMode to session create/resume wire all SDKs: add isExperimentalMode to session create/resume wire Jun 12, 2026
Copilot AI requested a review from SteveSandersonMS June 12, 2026 13:38
Comment thread dotnet/src/Client.cs
Comment thread dotnet/src/Types.cs Outdated
@github-actions

This comment has been minimized.

@github-actions github-actions Bot 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.

Generated by SDK Consistency Review Agent for issue #1600 · sonnet46 1.5M

Comment thread python/copilot/client.py Outdated
Comment thread rust/src/types.rs Outdated
Copilot AI changed the title all SDKs: add isExperimentalMode to session create/resume wire all SDKs: add EnableExperimentalMode to session create/resume wire Jun 12, 2026
Copilot AI requested a review from SteveSandersonMS June 12, 2026 16:06
Copilot AI changed the title all SDKs: add EnableExperimentalMode to session create/resume wire all SDKs: add EnableExperimentalMode to session create/resume wire with mode-aware defaults Jun 12, 2026
@SteveSandersonMS

Copy link
Copy Markdown
Contributor

@copilot Fix all the CI errors

@github-actions

This comment has been minimized.

@github-actions github-actions Bot 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.

Generated by SDK Consistency Review Agent for issue #1600 · sonnet46 1.8M

Comment thread java/src/main/java/com/github/copilot/CopilotClient.java
Copilot AI review requested due to automatic review settings August 3, 2026 12:13
@SteveSandersonMS
SteveSandersonMS force-pushed the jmoseley/rust-sdk-is-experimental-mode branch from 1a39b41 to 096aede Compare August 3, 2026 12:13
@SteveSandersonMS

Copy link
Copy Markdown
Contributor

Removed the two redundant getIsExperimentalMode() == null null-checks from CopilotClient.java (create and resume paths) in 096aede. SessionRequestBuilder.experimentalModeForMode for EMPTY mode always returns a non-empty Optional, so ifPresent(request::setIsExperimentalMode) always fires — the null-checks in CopilotClient were unreachable.

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.

Review details

Suppressed comments (1)

dotnet/test/Unit/SerializationTests.cs:1130

  • These tests invoke a private implementation method via reflection, so they bypass the public create/resume pipeline and would still pass if the default were never included in the outgoing RPC. Please cover the mode default through CreateSessionAsync/ResumeSessionAsync with a captured request instead; .NET tests in this repository are required to exercise public APIs only.
        var method = typeof(CopilotClient).GetMethod(
            "ApplyConfigDefaultsForMode",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        Assert.NotNull(method);
        method!.Invoke(client, [config]);
  • Files reviewed: 25/25 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

This comment has been minimized.

Copilot AI review requested due to automatic review settings August 3, 2026 12:25
@SteveSandersonMS
SteveSandersonMS force-pushed the jmoseley/rust-sdk-is-experimental-mode branch from 096aede to acdffac Compare August 3, 2026 12:25
@SteveSandersonMS

Copy link
Copy Markdown
Contributor

Addressed in acdffac: replaced the two ApplyConfigDefaultsForMode_* reflection-based tests in SerializationTests.cs with two proper async tests in GitHubTelemetryTests.cs (CreateSession_EmptyMode_Sends_IsExperimentalMode_False_By_Default and ResumeSession_EmptyMode_Sends_IsExperimentalMode_False_By_Default). These go through the public CreateSessionAsync/ResumeSessionAsync path using the existing FakeTelemetryServer and assert that isExperimentalMode: false is present in the captured wire params. The private reflection helper InvokeApplyConfigDefaultsForMode was also removed.

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.

Review details

  • Files reviewed: 26/26 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

This comment has been minimized.

Copilot AI review requested due to automatic review settings August 3, 2026 12:49
@SteveSandersonMS
SteveSandersonMS force-pushed the jmoseley/rust-sdk-is-experimental-mode branch from acdffac to c23d6fa Compare August 3, 2026 12:49

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.

Review details

  • Files reviewed: 26/26 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

This comment has been minimized.

Copilot AI review requested due to automatic review settings August 3, 2026 13:56
@SteveSandersonMS
SteveSandersonMS force-pushed the jmoseley/rust-sdk-is-experimental-mode branch from c23d6fa to 0cc82e9 Compare August 3, 2026 13:56

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.

Review details

  • Files reviewed: 26/26 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

This comment has been minimized.

Adds per-session EnableExperimentalMode (enableExperimentalMode /
enable_experimental_mode) to all SDK languages. The flag controls whether
the session enables experimental features.

Semantics are mode-aware and consistent across languages:
- In "empty" mode the SDK sends false unless the caller explicitly sets
  true, so headless integrations are not silently opted into experimental
  behaviour.
- In "copilot-cli" mode the field is omitted from the wire when nil/null/
  None, letting the runtime decide (e.g. based on staff-user flags).

Wire field is isExperimentalMode on both session.create and session.resume.

Changes per language:
- Rust:  enable_experimental_mode on SessionConfig / ResumeSessionConfig,
         experimental_mode_for_mode helper in mode.rs, 6 new unit tests
- .NET:  EnableExperimentalMode on SessionOptions / SessionResumeOptions,
         mode-aware default in Client.CreateSessionAsync/ResumeSessionAsync
- Node:  enableExperimentalMode on SessionOptions / SessionResumeOptions
- Python: enable_experimental_mode param on create_session/resume_session,
          _enable_experimental_mode_default helper in _mode.py
- Go:    EnableExperimentalMode on SessionConfig / ResumeSessionConfig,
         empty-mode default in mode_empty.go
- Java:  enableExperimentalMode on SessionConfig / ResumeSessionConfig,
         experimentalModeForMode helper in SessionRequestBuilder

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 3, 2026 14:20
@SteveSandersonMS
SteveSandersonMS force-pushed the jmoseley/rust-sdk-is-experimental-mode branch from 0cc82e9 to d802925 Compare August 3, 2026 14:20

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.

Review details

  • Files reviewed: 26/26 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Cross-SDK Consistency Review ✅

This PR adds EnableExperimentalMode to session create/resume across all six SDK implementations. The changes are consistent in:

  • API naming: follows each language's conventions (enableExperimentalMode in Node.js/Java, enable_experimental_mode in Python/Rust, EnableExperimentalMode in Go/.NET)
  • Wire format: all SDKs serialize as isExperimentalMode in the JSON payload
  • Mode-aware defaults: all SDKs send false in empty mode and leave unset in copilot-cli mode
  • Type: nullable/optional boolean in all languages (bool? in .NET/Go, Option<bool> in Rust, Boolean in Java, bool | None in Python, boolean | undefined in TypeScript)
  • Coverage: all 6 SDKs (Node.js, Python, Go, .NET, Java, Rust) have both source and test changes

No consistency issues found. The feature parity looks complete and well-implemented.

Generated by SDK Consistency Review Agent for #1600 · sonnet46 24.4 AIC · ⌖ 4.05 AIC · ⊞ 6.6K ·

@SteveSandersonMS
SteveSandersonMS merged commit eea0c98 into main Aug 3, 2026
65 checks passed
@SteveSandersonMS
SteveSandersonMS deleted the jmoseley/rust-sdk-is-experimental-mode branch August 3, 2026 14:51
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.

6 participants