Skip to content

Rust SDK: add typed per-session capability controls#1455

Draft
Morabbin wants to merge 1 commit into
github:mainfrom
Morabbin:morabbin/rust-typed-session-capabilities
Draft

Rust SDK: add typed per-session capability controls#1455
Morabbin wants to merge 1 commit into
github:mainfrom
Morabbin:morabbin/rust-typed-session-capabilities

Conversation

@Morabbin
Copy link
Copy Markdown
Contributor

@Morabbin Morabbin commented May 27, 2026

Summary

Adds a typed SessionCapability enum with matching SessionConfig and ResumeSessionConfig fields and builder methods, so callers can express capability opt-in / opt-out / provider registration without stringly-typed flags.

This is a per-session API -- the capability fields are sent as JSON-RPC wire parameters on session.create and session.resume, so it works for every transport including Transport::External (Desktop app / shared CLI server).

Why

Part of the fix for github/agents#981 (Desktop app missing memory capability). The Desktop app uses Transport::External, so spawn-time CLI flags have no effect -- a per-session wire API is the correct approach.

What

SessionCapability enum (rust/src/lib.rs)

  • 10 typed variants (Memory, PlanMode, CanvasRenderer, Elicitation, McpApps, TuiHints, CliDocumentation, AskUser, InteractiveMode, SystemNotifications) plus Other(String) escape hatch for forward compatibility.
  • #[non_exhaustive], #[serde(rename_all = "kebab-case")].
  • Display, FromStr (Infallible), From<&str>, From<String>, as_str(&self) impls.

SessionConfig and ResumeSessionConfig (rust/src/types.rs)

New fields:

  • enabled_capabilities: Vec<SessionCapability> -- opt this session into additional capabilities (extends the SDK_CAPABILITIES baseline).
  • disabled_capabilities: Vec<SessionCapability> -- opt this session out of capabilities; disable wins over enable on overlap.
  • capability_providers: Vec<SessionCapability> -- declare which capabilities this client actively provides (e.g. canvas renderer, elicitation driver).

Four builders on each config type: with_enable_capability, with_disable_capability, with_enabled_capabilities, with_disabled_capabilities, plus with_capability_provider / with_capability_providers.

Wire serialization (rust/src/wire.rs)

SessionCreateWire and SessionResumeWire gain:

  • enabledCapabilities?: string[]
  • disabledCapabilities?: string[]
  • capabilityProviders?: string[]

All three fields are #[serde(skip_serializing_if = "Option::is_none")] -- omitted from the wire when empty.

Runtime dependency

Requires github/copilot-agent-runtime#8918 for full runtime support. On older runtimes the fields are silently ignored.

Pairs with github/agents#981.

Tests

12 new unit tests covering:

  • SessionCapability Display, FromStr, From<&str>, From<String>, serde round-trip.
  • SessionConfig and ResumeSessionConfig wire serialization for all three capability fields.
  • Empty fields are omitted from the wire.
  • Builder replace semantics.

Fmt / clippy / lib / doc tests all pass. cargo build passes.

Pre-existing test breakage

rust/tests/session_test.rs and rust/tests/protocol_version_test.rs have pre-existing clippy errors on main (they reference methods removed in upstream refactors). These are unrelated to this PR. The CI for this PR uses --lib --tests which excludes those files.

Copilot AI review requested due to automatic review settings May 27, 2026 14:47
@Morabbin Morabbin requested a review from a team as a code owner May 27, 2026 14:47
@Morabbin Morabbin marked this pull request as draft May 27, 2026 15:06
@Morabbin Morabbin changed the title rust: add typed SessionCapability enum and ClientOptions builders Rust SDK: add typed SessionCapability enum and ClientOptions builders May 27, 2026
@Morabbin Morabbin changed the title Rust SDK: add typed SessionCapability enum and ClientOptions builders Rust SDK: add typed per-session capability controls May 27, 2026
@Morabbin Morabbin force-pushed the morabbin/rust-typed-session-capabilities branch 3 times, most recently from 23133c4 to aa73621 Compare May 28, 2026 16:01
Adds a typed `SessionCapability` enum and matching `SessionConfig` /
`ResumeSessionConfig` fields plus builder methods, so callers can express
"enable memory", "disable plan-mode", etc. as a per-session wire parameter
rather than a spawn-time CLI flag.

- `SessionCapability` is `#[non_exhaustive]`, kebab-case-serialized (via
  `Display` / `FromStr` / `From<&str>` / `From<String>`), and carries an
  `Other(String)` escape hatch for forward compatibility with capabilities
  the runtime adds without requiring an SDK rebuild.
- `SessionConfig` and `ResumeSessionConfig` each gain
  `enabled_capabilities` / `disabled_capabilities` vectors and four
  builders: `with_enable_capability`, `with_disable_capability`,
  `with_enabled_capabilities`, `with_disabled_capabilities`.
- `SessionConfig::into_wire` and `ResumeSessionConfig::into_wire` convert
  the vecs to `Option<Vec<String>>` and emit them as
  `enabledCapabilities` / `disabledCapabilities` in the `session.create`
  and `session.resume` JSON-RPC payloads. Empty vecs are serialised as
  `None` (field omitted). Disable wins over enable on conflict (the runtime
  applies enable first, then disable).
- Works for every transport -- including `Transport::External` (Desktop app
  / shared CLI server) -- because it does not rely on CLI spawn arguments.

Pairs with github/copilot-agent-runtime#8918 (per-session capability API)
and github/agents#981 (Desktop missing memory capability).

10 new unit tests: 3 enum-level tests (Display / FromStr / From conversions)
and 7 wire-serialisation tests in a dedicated `capability_tests` module in
`types.rs` (empty omitted, single enable, single disable, bulk-replace,
Other round-trip, resume empty, resume enable+disable).

Pre-existing test breakage: rust/tests/session_test.rs and
rust/tests/protocol_version_test.rs reference removed API methods on main
and are unrelated to this change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Morabbin Morabbin force-pushed the morabbin/rust-typed-session-capabilities branch from aa73621 to 37fd3e9 Compare May 28, 2026 16:05
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.

1 participant