diff --git a/dotnet/src/Client.cs b/dotnet/src/Client.cs index 94b092199..56e0a4d29 100644 --- a/dotnet/src/Client.cs +++ b/dotnet/src/Client.cs @@ -1147,6 +1147,7 @@ public async Task CreateSessionAsync(SessionConfig config, Cance Models: config.Models, ToolFilterPrecedence: toolFilter.ToolFilterPrecedence, ExpAssignments: config.ExpAssignments, + EnableManagedSettings: config.EnableManagedSettings, EnableGitHubTelemetryForwarding: _options.OnGitHubTelemetry != null ? true : null); var rpcTimestamp = Stopwatch.GetTimestamp(); @@ -1357,6 +1358,7 @@ public async Task ResumeSessionAsync(string sessionId, ResumeSes Models: config.Models, ToolFilterPrecedence: toolFilter.ToolFilterPrecedence, ExpAssignments: config.ExpAssignments, + EnableManagedSettings: config.EnableManagedSettings, EnableGitHubTelemetryForwarding: _options.OnGitHubTelemetry != null ? true : null); var rpcTimestamp = Stopwatch.GetTimestamp(); @@ -2696,6 +2698,7 @@ internal record CreateSessionRequest( IList? Models = null, OptionsUpdateToolFilterPrecedence? ToolFilterPrecedence = null, [property: JsonPropertyName("expAssignments")] JsonElement? ExpAssignments = null, + [property: JsonPropertyName("enableManagedSettings")] bool? EnableManagedSettings = null, bool? EnableGitHubTelemetryForwarding = null); #pragma warning restore GHCP001 @@ -2796,6 +2799,7 @@ internal record ResumeSessionRequest( IList? Models = null, OptionsUpdateToolFilterPrecedence? ToolFilterPrecedence = null, [property: JsonPropertyName("expAssignments")] JsonElement? ExpAssignments = null, + [property: JsonPropertyName("enableManagedSettings")] bool? EnableManagedSettings = null, bool? EnableGitHubTelemetryForwarding = null); #pragma warning restore GHCP001 diff --git a/dotnet/src/Types.cs b/dotnet/src/Types.cs index 65295d3d2..63e39a2c5 100644 --- a/dotnet/src/Types.cs +++ b/dotnet/src/Types.cs @@ -2861,6 +2861,7 @@ protected SessionConfigBase(SessionConfigBase? other) GitHubToken = other.GitHubToken; RemoteSession = other.RemoteSession; ExpAssignments = other.ExpAssignments; + EnableManagedSettings = other.EnableManagedSettings; #pragma warning disable GHCP001 Canvases = other.Canvases is not null ? [.. other.Canvases] : null; RequestCanvasRenderer = other.RequestCanvasRenderer; @@ -3285,6 +3286,16 @@ protected SessionConfigBase(SessionConfigBase? other) [EditorBrowsable(EditorBrowsableState.Never)] public JsonElement? ExpAssignments { get; set; } + /// + /// Opt-in: when true, the runtime self-fetches enterprise managed + /// settings (bypass-permissions policy) at session bootstrap using the + /// session's . Requires to + /// be set; if omitted, the runtime is expected to reject session creation + /// (fail-closed). When unset, behaves exactly as before. Serialized on the + /// wire as enableManagedSettings. + /// + public bool? EnableManagedSettings { get; set; } + #pragma warning disable GHCP001 /// /// Canvas declarations advertised by this connection. The runtime forwards diff --git a/go/client.go b/go/client.go index 5b8dabf8f..31163efa8 100644 --- a/go/client.go +++ b/go/client.go @@ -732,6 +732,7 @@ func (c *Client) CreateSession(ctx context.Context, config *SessionConfig) (*Ses req.ExtensionSDKPath = config.ExtensionSDKPath req.ExtensionInfo = config.ExtensionInfo req.ExpAssignments = config.ExpAssignments + req.EnableManagedSettings = config.EnableManagedSettings if len(config.Commands) > 0 { cmds := make([]wireCommand, 0, len(config.Commands)) @@ -1095,6 +1096,7 @@ func (c *Client) ResumeSessionWithOptions(ctx context.Context, sessionID string, req.ExtensionSDKPath = config.ExtensionSDKPath req.ExtensionInfo = config.ExtensionInfo req.ExpAssignments = config.ExpAssignments + req.EnableManagedSettings = config.EnableManagedSettings if config.OnPermissionRequest != nil { req.RequestPermission = Bool(true) } diff --git a/go/types.go b/go/types.go index 1e424514e..6111b7be4 100644 --- a/go/types.go +++ b/go/types.go @@ -1247,6 +1247,12 @@ type SessionConfig struct { // intended for trusted out-of-process integrators, and is not intended for // general external use. ExpAssignments any + // EnableManagedSettings, when set to true, opts the runtime into + // self-fetching enterprise managed settings (bypass-permissions policy) at + // session bootstrap using the session's GitHubToken. Requires GitHubToken to + // be set; if omitted, the runtime is expected to reject session creation + // (fail-closed). Unset behaves exactly as before. + EnableManagedSettings *bool } // ToolDefer controls whether a tool may be deferred (loaded lazily via tool @@ -1668,6 +1674,10 @@ type ResumeSessionConfig struct { // intended for trusted out-of-process integrators, and is not intended for // general external use. ExpAssignments any + // EnableManagedSettings injects the same opt-in flag on resume. See + // SessionConfig.EnableManagedSettings. Re-supply on resume so the runtime + // re-applies the managed-settings self-fetch after a CLI process restart. + EnableManagedSettings *bool } // ProviderTokenArgs carries the context passed to a [BearerTokenProvider] callback @@ -2122,6 +2132,7 @@ type createSessionRequest struct { ExtensionSDKPath *string `json:"extensionSdkPath,omitempty"` ExtensionInfo *ExtensionInfo `json:"extensionInfo,omitempty"` ExpAssignments any `json:"expAssignments,omitempty"` + EnableManagedSettings *bool `json:"enableManagedSettings,omitempty"` Traceparent string `json:"traceparent,omitempty"` Tracestate string `json:"tracestate,omitempty"` } @@ -2211,6 +2222,7 @@ type resumeSessionRequest struct { ExtensionSDKPath *string `json:"extensionSdkPath,omitempty"` ExtensionInfo *ExtensionInfo `json:"extensionInfo,omitempty"` ExpAssignments any `json:"expAssignments,omitempty"` + EnableManagedSettings *bool `json:"enableManagedSettings,omitempty"` Traceparent string `json:"traceparent,omitempty"` Tracestate string `json:"tracestate,omitempty"` } diff --git a/java/src/main/java/com/github/copilot/SessionRequestBuilder.java b/java/src/main/java/com/github/copilot/SessionRequestBuilder.java index f88bf2a85..5fe5aa51e 100644 --- a/java/src/main/java/com/github/copilot/SessionRequestBuilder.java +++ b/java/src/main/java/com/github/copilot/SessionRequestBuilder.java @@ -185,6 +185,7 @@ static CreateSessionRequest buildCreateRequest(SessionConfig config, String sess request.setRemoteSession(config.getRemoteSession()); request.setCloud(config.getCloud()); request.setExpAssignments(config.getExpAssignments()); + config.getEnableManagedSettings().ifPresent(request::setEnableManagedSettings); return request; } @@ -306,6 +307,7 @@ static ResumeSessionRequest buildResumeRequest(String sessionId, ResumeSessionCo request.setGitHubToken(config.getGitHubToken()); request.setRemoteSession(config.getRemoteSession()); request.setExpAssignments(config.getExpAssignments()); + config.getEnableManagedSettings().ifPresent(request::setEnableManagedSettings); return request; } diff --git a/java/src/main/java/com/github/copilot/rpc/CreateSessionRequest.java b/java/src/main/java/com/github/copilot/rpc/CreateSessionRequest.java index 2510b0bd6..bec5b626d 100644 --- a/java/src/main/java/com/github/copilot/rpc/CreateSessionRequest.java +++ b/java/src/main/java/com/github/copilot/rpc/CreateSessionRequest.java @@ -212,6 +212,10 @@ public final class CreateSessionRequest { @JsonProperty("expAssignments") private JsonNode expAssignments; + @JsonProperty("enableManagedSettings") + @JsonInclude(JsonInclude.Include.NON_NULL) + private Boolean enableManagedSettings; + /** Gets the model name. @return the model */ public String getModel() { return model; @@ -966,4 +970,27 @@ public JsonNode getExpAssignments() { public void setExpAssignments(JsonNode expAssignments) { this.expAssignments = expAssignments; } + + /** + * Gets the self-fetch managed settings flag. @return the flag, or {@code null} + * if not set + */ + public Boolean getEnableManagedSettings() { + return enableManagedSettings; + } + + /** + * Sets the self-fetch managed settings flag. @param enableManagedSettings the + * flag + */ + public void setEnableManagedSettings(boolean enableManagedSettings) { + this.enableManagedSettings = enableManagedSettings; + } + + /** + * Clears the enableManagedSettings setting, reverting to the default behavior. + */ + public void clearEnableManagedSettings() { + this.enableManagedSettings = null; + } } diff --git a/java/src/main/java/com/github/copilot/rpc/ResumeSessionConfig.java b/java/src/main/java/com/github/copilot/rpc/ResumeSessionConfig.java index 83b365a41..0efe1c5c6 100644 --- a/java/src/main/java/com/github/copilot/rpc/ResumeSessionConfig.java +++ b/java/src/main/java/com/github/copilot/rpc/ResumeSessionConfig.java @@ -102,6 +102,7 @@ public class ResumeSessionConfig { private String gitHubToken; private String remoteSession; private JsonNode expAssignments; + private Boolean enableManagedSettings; /** * Gets the AI model to use. @@ -1745,6 +1746,36 @@ public ResumeSessionConfig setExpAssignments(JsonNode expAssignments) { return this; } + /** + * Gets whether the runtime self-fetches enterprise managed settings at session + * bootstrap on resume. + * + * @return an {@link java.util.Optional} containing {@code true} to opt into + * self-fetching managed settings, or {@link java.util.Optional#empty()} + * to use the default behavior + */ + @JsonIgnore + public Optional getEnableManagedSettings() { + return Optional.ofNullable(enableManagedSettings); + } + + /** + * Opts the runtime into self-fetching enterprise managed settings on resume. + *

+ * See {@link SessionConfig#setEnableManagedSettings(boolean)} for details. + * Re-supply on resume so the runtime re-applies the managed-settings self-fetch + * after a CLI process restart. Serialized on the wire as + * {@code enableManagedSettings}. + * + * @param enableManagedSettings + * {@code true} to opt into self-fetching managed settings + * @return this config for method chaining + */ + public ResumeSessionConfig setEnableManagedSettings(boolean enableManagedSettings) { + this.enableManagedSettings = enableManagedSettings; + return this; + } + /** * Creates a shallow clone of this {@code ResumeSessionConfig} instance. *

@@ -1819,6 +1850,7 @@ public ResumeSessionConfig clone() { copy.gitHubToken = this.gitHubToken; copy.remoteSession = this.remoteSession; copy.expAssignments = this.expAssignments; + copy.enableManagedSettings = this.enableManagedSettings; return copy; } } diff --git a/java/src/main/java/com/github/copilot/rpc/ResumeSessionRequest.java b/java/src/main/java/com/github/copilot/rpc/ResumeSessionRequest.java index 4917f1d8c..20a870b46 100644 --- a/java/src/main/java/com/github/copilot/rpc/ResumeSessionRequest.java +++ b/java/src/main/java/com/github/copilot/rpc/ResumeSessionRequest.java @@ -214,6 +214,10 @@ public final class ResumeSessionRequest { @JsonProperty("expAssignments") private JsonNode expAssignments; + @JsonProperty("enableManagedSettings") + @JsonInclude(JsonInclude.Include.NON_NULL) + private Boolean enableManagedSettings; + /** Gets the session ID. @return the session ID */ public String getSessionId() { return sessionId; @@ -981,4 +985,27 @@ public JsonNode getExpAssignments() { public void setExpAssignments(JsonNode expAssignments) { this.expAssignments = expAssignments; } + + /** + * Gets the self-fetch managed settings flag. @return the flag, or {@code null} + * if not set + */ + public Boolean getEnableManagedSettings() { + return enableManagedSettings; + } + + /** + * Sets the self-fetch managed settings flag. @param enableManagedSettings the + * flag + */ + public void setEnableManagedSettings(boolean enableManagedSettings) { + this.enableManagedSettings = enableManagedSettings; + } + + /** + * Clears the enableManagedSettings setting, reverting to the default behavior. + */ + public void clearEnableManagedSettings() { + this.enableManagedSettings = null; + } } diff --git a/java/src/main/java/com/github/copilot/rpc/SessionConfig.java b/java/src/main/java/com/github/copilot/rpc/SessionConfig.java index cc27386c0..3533ceefa 100644 --- a/java/src/main/java/com/github/copilot/rpc/SessionConfig.java +++ b/java/src/main/java/com/github/copilot/rpc/SessionConfig.java @@ -103,6 +103,7 @@ public class SessionConfig { private String remoteSession; private CloudSessionOptions cloud; private JsonNode expAssignments; + private Boolean enableManagedSettings; /** * Gets the custom session ID. @@ -1876,6 +1877,38 @@ public SessionConfig setExpAssignments(JsonNode expAssignments) { return this; } + /** + * Gets whether the runtime self-fetches enterprise managed settings at session + * bootstrap. + * + * @return an {@link java.util.Optional} containing {@code true} to opt into + * self-fetching managed settings, or {@link java.util.Optional#empty()} + * to use the default behavior + */ + @JsonIgnore + public Optional getEnableManagedSettings() { + return Optional.ofNullable(enableManagedSettings); + } + + /** + * Opts the runtime into self-fetching enterprise managed settings + * (bypass-permissions policy) at session bootstrap. + *

+ * When {@code true}, the runtime self-fetches enterprise managed settings using + * the session's {@link #getGitHubToken() gitHubToken}. Requires + * {@code gitHubToken} to be set; if omitted, the runtime is expected to reject + * session creation (fail-closed). When unset, behaves exactly as before. + * Serialized on the wire as {@code enableManagedSettings}. + * + * @param enableManagedSettings + * {@code true} to opt into self-fetching managed settings + * @return this config instance for method chaining + */ + public SessionConfig setEnableManagedSettings(boolean enableManagedSettings) { + this.enableManagedSettings = enableManagedSettings; + return this; + } + /** * Creates a shallow clone of this {@code SessionConfig} instance. *

@@ -1955,6 +1988,7 @@ public SessionConfig clone() { copy.remoteSession = this.remoteSession; copy.cloud = this.cloud; copy.expAssignments = this.expAssignments; + copy.enableManagedSettings = this.enableManagedSettings; return copy; } } diff --git a/nodejs/src/client.ts b/nodejs/src/client.ts index 9f430600c..8f4d3ff2d 100644 --- a/nodejs/src/client.ts +++ b/nodejs/src/client.ts @@ -1472,6 +1472,7 @@ export class CopilotClient { remoteSession: config.remoteSession, cloud: config.cloud, expAssignments: config.expAssignments, + enableManagedSettings: config.enableManagedSettings, }); const { @@ -1683,6 +1684,7 @@ export class CopilotClient { remoteSession: config.remoteSession, openCanvases: config.openCanvases, expAssignments: config.expAssignments, + enableManagedSettings: config.enableManagedSettings, }); const { workspacePath, capabilities, openCanvases } = response as { diff --git a/nodejs/src/types.ts b/nodejs/src/types.ts index 97182b5f1..65fc00cfe 100644 --- a/nodejs/src/types.ts +++ b/nodejs/src/types.ts @@ -2189,6 +2189,14 @@ export interface SessionConfigBase { */ gitHubToken?: string; + /** + * Opt-in: when true, the runtime self-fetches enterprise managed settings + * (bypass-permissions policy) at session bootstrap using the session's + * `gitHubToken`. Requires {@link SessionConfigBase.gitHubToken} to be set; + * if omitted, the runtime is expected to reject session creation (fail-closed). + */ + enableManagedSettings?: boolean; + /** * When true, skips embedding-based retrieval for this session. * Use in multitenant deployments to prevent cross-session information leakage diff --git a/python/copilot/client.py b/python/copilot/client.py index 55d01c5b5..dbe808bed 100644 --- a/python/copilot/client.py +++ b/python/copilot/client.py @@ -1756,6 +1756,7 @@ async def create_session( extension_info: ExtensionInfo | None = None, canvas_handler: CanvasHandler | None = None, exp_assignments: dict[str, Any] | None = None, + enable_managed_settings: bool | None = None, ) -> CopilotSession: """ Create a new conversation session with the Copilot CLI. @@ -1887,6 +1888,13 @@ async def create_session( malformed payloads are dropped by the runtime (fail-open). This is an internal/trusted-integrator option. Sent on the wire as ``expAssignments``. + enable_managed_settings: Opt-in flag. When ``True``, the runtime + self-fetches enterprise managed settings (bypass-permissions + policy) at session bootstrap using the session's ``github_token``. + Requires ``github_token`` to be set; if omitted, the runtime is + expected to reject session creation (fail-closed). When unset, + behaves exactly as before. Sent on the wire as + ``enableManagedSettings``. Returns: A :class:`CopilotSession` instance for the new session. @@ -2018,6 +2026,10 @@ async def create_session( if exp_assignments is not None: payload["expAssignments"] = exp_assignments + # Opt the runtime into self-fetching enterprise managed settings + if enable_managed_settings is not None: + payload["enableManagedSettings"] = enable_managed_settings + # Add working directory if provided if working_directory: payload["workingDirectory"] = working_directory @@ -2408,6 +2420,7 @@ async def resume_session( canvas_handler: CanvasHandler | None = None, open_canvases: list[OpenCanvasInstance] | None = None, exp_assignments: dict[str, Any] | None = None, + enable_managed_settings: bool | None = None, ) -> CopilotSession: """ Resume an existing conversation session by its ID. @@ -2540,6 +2553,13 @@ async def resume_session( malformed payloads are dropped by the runtime (fail-open). This is an internal/trusted-integrator option. Sent on the wire as ``expAssignments``. + enable_managed_settings: Opt-in flag. When ``True``, the runtime + self-fetches enterprise managed settings (bypass-permissions + policy) at session bootstrap using the session's ``github_token``. + Requires ``github_token`` to be set; if omitted, the runtime is + expected to reject session creation (fail-closed). When unset, + behaves exactly as before. Sent on the wire as + ``enableManagedSettings``. Returns: A :class:`CopilotSession` instance for the resumed session. @@ -2695,6 +2715,10 @@ async def resume_session( if exp_assignments is not None: payload["expAssignments"] = exp_assignments + # Opt the runtime into self-fetching enterprise managed settings + if enable_managed_settings is not None: + payload["enableManagedSettings"] = enable_managed_settings + if working_directory: payload["workingDirectory"] = working_directory if config_directory: diff --git a/rust/src/types.rs b/rust/src/types.rs index e5ba28a56..6ccb43c85 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -1770,6 +1770,13 @@ pub struct SessionConfig { /// [`with_exp_assignments`](Self::with_exp_assignments). #[doc(hidden)] pub exp_assignments: Option, + /// Opt-in: when `Some(true)`, the runtime self-fetches enterprise managed + /// settings (bypass-permissions policy) at session bootstrap using the + /// session's [`github_token`](Self::github_token). Requires `github_token` + /// to be set; if omitted, the runtime is expected to reject session creation + /// (fail-closed). When `None`, behaves exactly as before. Set via + /// [`with_enable_managed_settings`](Self::with_enable_managed_settings). + pub enable_managed_settings: Option, /// Custom session filesystem provider for this session. Required when /// the [`Client`](crate::Client) was started with /// [`ClientOptions::session_fs`](crate::ClientOptions::session_fs) set. @@ -1905,6 +1912,7 @@ impl std::fmt::Debug for SessionConfig { ) .field("commands", &self.commands) .field("exp_assignments", &self.exp_assignments) + .field("enable_managed_settings", &self.enable_managed_settings) .field( "session_fs_provider", &self.session_fs_provider.as_ref().map(|_| ""), @@ -2010,6 +2018,7 @@ impl Default for SessionConfig { include_sub_agent_streaming_events: None, commands: None, exp_assignments: None, + enable_managed_settings: None, session_fs_provider: None, permission_handler: None, elicitation_handler: None, @@ -2166,6 +2175,7 @@ impl SessionConfig { enable_github_telemetry_forwarding: None, commands: wire_commands, exp_assignments: self.exp_assignments, + enable_managed_settings: self.enable_managed_settings, }; let runtime = SessionConfigRuntime { @@ -2732,6 +2742,16 @@ impl SessionConfig { self.exp_assignments = Some(assignments); self } + + /// Opt the runtime into self-fetching enterprise managed settings + /// (bypass-permissions policy) at session bootstrap using the session's + /// [`github_token`](Self::github_token). Requires `github_token` to be set; + /// if omitted, the runtime is expected to reject session creation + /// (fail-closed). + pub fn with_enable_managed_settings(mut self, enabled: bool) -> Self { + self.enable_managed_settings = Some(enabled); + self + } } /// /// See [`SessionConfig`] for the construction patterns (chained `with_*` @@ -2900,6 +2920,12 @@ pub struct ResumeSessionConfig { /// [`with_exp_assignments`](Self::with_exp_assignments). #[doc(hidden)] pub exp_assignments: Option, + /// Opt-in flag injected on resume. See + /// [`SessionConfig::enable_managed_settings`]. Re-supply on resume so + /// the runtime re-applies the managed-settings self-fetch after a CLI + /// process restart. Set via + /// [`with_enable_managed_settings`](Self::with_enable_managed_settings). + pub enable_managed_settings: Option, /// Custom session filesystem provider. Required on resume when the /// [`Client`](crate::Client) was started with /// [`ClientOptions::session_fs`](crate::ClientOptions::session_fs). @@ -3028,6 +3054,7 @@ impl std::fmt::Debug for ResumeSessionConfig { ) .field("commands", &self.commands) .field("exp_assignments", &self.exp_assignments) + .field("enable_managed_settings", &self.enable_managed_settings) .field( "session_fs_provider", &self.session_fs_provider.as_ref().map(|_| ""), @@ -3177,6 +3204,7 @@ impl ResumeSessionConfig { enable_github_telemetry_forwarding: None, commands: wire_commands, exp_assignments: self.exp_assignments, + enable_managed_settings: self.enable_managed_settings, suppress_resume_event: self.suppress_resume_event, continue_pending_work: self.continue_pending_work, }; @@ -3264,6 +3292,7 @@ impl ResumeSessionConfig { include_sub_agent_streaming_events: None, commands: None, exp_assignments: None, + enable_managed_settings: None, session_fs_provider: None, suppress_resume_event: None, continue_pending_work: None, @@ -3813,6 +3842,13 @@ impl ResumeSessionConfig { self.exp_assignments = Some(assignments); self } + + /// Opt the runtime into self-fetching enterprise managed settings on resume. + /// See [`SessionConfig::with_enable_managed_settings`]. + pub fn with_enable_managed_settings(mut self, enabled: bool) -> Self { + self.enable_managed_settings = Some(enabled); + self + } } /// Controls how the system message is constructed. diff --git a/rust/src/wire.rs b/rust/src/wire.rs index f73870fa5..829723a1c 100644 --- a/rust/src/wire.rs +++ b/rust/src/wire.rs @@ -169,6 +169,8 @@ pub(crate) struct SessionCreateWire { pub commands: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub exp_assignments: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub enable_managed_settings: Option, } /// The exact JSON shape sent on the `session.resume` JSON-RPC request. @@ -302,4 +304,6 @@ pub(crate) struct SessionResumeWire { pub continue_pending_work: Option, #[serde(skip_serializing_if = "Option::is_none")] pub exp_assignments: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub enable_managed_settings: Option, }