From 5873839232c9127640496b6415b07f3bf5c688e0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 15:35:03 +0000 Subject: [PATCH 1/2] Update @github/copilot to 1.0.55-5 - Updated nodejs and test harness dependencies - Re-ran code generators - Formatted generated code --- dotnet/src/Generated/Rpc.cs | 72 +++++++++- go/rpc/zrpc.go | 100 +++++++------ go/rpc/zrpc_encoding.go | 64 +++------ nodejs/package-lock.json | 72 +++++----- nodejs/package.json | 2 +- nodejs/samples/package-lock.json | 2 +- nodejs/src/generated/rpc.ts | 79 +++++------ python/copilot/generated/rpc.py | 235 ++++++++++++++++--------------- rust/src/generated/api_types.rs | 39 ++++- test/harness/package-lock.json | 72 +++++----- test/harness/package.json | 2 +- 11 files changed, 394 insertions(+), 345 deletions(-) diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index a717bcf4a..760a7af99 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -4649,6 +4649,10 @@ internal sealed class SessionUpdateOptionsParams [JsonPropertyName("skipCustomInstructions")] public bool? SkipCustomInstructions { get; set; } + /// Controls how availableTools (allowlist) and excludedTools (denylist) combine when both are set. + [JsonPropertyName("toolFilterPrecedence")] + public OptionsUpdateToolFilterPrecedence? ToolFilterPrecedence { get; set; } + /// Optional path for trajectory output. [JsonPropertyName("trajectoryFile")] public string? TrajectoryFile { get; set; } @@ -10940,6 +10944,69 @@ public override void Write(Utf8JsonWriter writer, OptionsUpdateEnvValueMode valu } +/// Controls how availableTools (allowlist) and excludedTools (denylist) combine when both are set. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct OptionsUpdateToolFilterPrecedence : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public OptionsUpdateToolFilterPrecedence(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// If availableTools is set, it is the only constraint that applies (excludedTools is ignored). Preserves CLI / pre-existing client behavior. Default. + public static OptionsUpdateToolFilterPrecedence Available { get; } = new("available"); + + /// A tool is enabled if and only if it matches the allowlist (or the allowlist is unset) AND it does not match the denylist. Makes 'all except X' expressible by combining the two lists. + public static OptionsUpdateToolFilterPrecedence Excluded { get; } = new("excluded"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(OptionsUpdateToolFilterPrecedence left, OptionsUpdateToolFilterPrecedence right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(OptionsUpdateToolFilterPrecedence left, OptionsUpdateToolFilterPrecedence right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is OptionsUpdateToolFilterPrecedence other && Equals(other); + + /// + public bool Equals(OptionsUpdateToolFilterPrecedence other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override OptionsUpdateToolFilterPrecedence Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, OptionsUpdateToolFilterPrecedence value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(OptionsUpdateToolFilterPrecedence)); + } + } +} + + /// Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/). [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] @@ -14364,6 +14431,7 @@ internal OptionsApi(CopilotSession session) /// Absolute working-directory path for shell tools. /// Allowlist of tool names available to this session. /// Denylist of tool names for this session. + /// Controls how availableTools (allowlist) and excludedTools (denylist) combine when both are set. /// Whether shell-script safety heuristics are enabled. /// Shell init profile (`None` or `NonInteractive`). /// Per-shell process flags (e.g., `pwsh` arguments). @@ -14391,11 +14459,11 @@ internal OptionsApi(CopilotSession session) /// Whether to expose the `manage_schedule` tool to the agent. The runtime always owns the per-session schedule registry; this flag only controls tool exposure (typically gated to staff users). /// The to monitor for cancellation requests. The default is . /// Indicates whether the session options patch was applied successfully. - public async Task UpdateAsync(string? model = null, string? reasoningEffort = null, string? clientName = null, string? lspClientName = null, string? integrationId = null, IDictionary? featureFlags = null, bool? isExperimentalMode = null, object? provider = null, string? workingDirectory = null, IList? availableTools = null, IList? excludedTools = null, bool? enableScriptSafety = null, string? shellInitProfile = null, IList? shellProcessFlags = null, object? sandboxConfig = null, bool? logInteractiveShells = null, OptionsUpdateEnvValueMode? envValueMode = null, IList? skillDirectories = null, IList? disabledSkills = null, bool? enableOnDemandInstructionDiscovery = null, IList? installedPlugins = null, bool? customAgentsLocalOnly = null, bool? skipCustomInstructions = null, IList? disabledInstructionSources = null, bool? coauthorEnabled = null, string? trajectoryFile = null, bool? enableStreaming = null, string? copilotUrl = null, bool? askUserDisabled = null, bool? continueOnAutoMode = null, bool? runningInInteractiveMode = null, bool? enableReasoningSummaries = null, string? agentContext = null, string? eventsLogDirectory = null, IList? additionalContentExclusionPolicies = null, bool? manageScheduleEnabled = null, CancellationToken cancellationToken = default) + public async Task UpdateAsync(string? model = null, string? reasoningEffort = null, string? clientName = null, string? lspClientName = null, string? integrationId = null, IDictionary? featureFlags = null, bool? isExperimentalMode = null, object? provider = null, string? workingDirectory = null, IList? availableTools = null, IList? excludedTools = null, OptionsUpdateToolFilterPrecedence? toolFilterPrecedence = null, bool? enableScriptSafety = null, string? shellInitProfile = null, IList? shellProcessFlags = null, object? sandboxConfig = null, bool? logInteractiveShells = null, OptionsUpdateEnvValueMode? envValueMode = null, IList? skillDirectories = null, IList? disabledSkills = null, bool? enableOnDemandInstructionDiscovery = null, IList? installedPlugins = null, bool? customAgentsLocalOnly = null, bool? skipCustomInstructions = null, IList? disabledInstructionSources = null, bool? coauthorEnabled = null, string? trajectoryFile = null, bool? enableStreaming = null, string? copilotUrl = null, bool? askUserDisabled = null, bool? continueOnAutoMode = null, bool? runningInInteractiveMode = null, bool? enableReasoningSummaries = null, string? agentContext = null, string? eventsLogDirectory = null, IList? additionalContentExclusionPolicies = null, bool? manageScheduleEnabled = null, CancellationToken cancellationToken = default) { _session.ThrowIfDisposed(); - var request = new SessionUpdateOptionsParams { SessionId = _session.SessionId, Model = model, ReasoningEffort = reasoningEffort, ClientName = clientName, LspClientName = lspClientName, IntegrationId = integrationId, FeatureFlags = featureFlags, IsExperimentalMode = isExperimentalMode, Provider = CopilotClient.ToJsonElementForWire(provider), WorkingDirectory = workingDirectory, AvailableTools = availableTools, ExcludedTools = excludedTools, EnableScriptSafety = enableScriptSafety, ShellInitProfile = shellInitProfile, ShellProcessFlags = shellProcessFlags, SandboxConfig = CopilotClient.ToJsonElementForWire(sandboxConfig), LogInteractiveShells = logInteractiveShells, EnvValueMode = envValueMode, SkillDirectories = skillDirectories, DisabledSkills = disabledSkills, EnableOnDemandInstructionDiscovery = enableOnDemandInstructionDiscovery, InstalledPlugins = installedPlugins, CustomAgentsLocalOnly = customAgentsLocalOnly, SkipCustomInstructions = skipCustomInstructions, DisabledInstructionSources = disabledInstructionSources, CoauthorEnabled = coauthorEnabled, TrajectoryFile = trajectoryFile, EnableStreaming = enableStreaming, CopilotUrl = copilotUrl, AskUserDisabled = askUserDisabled, ContinueOnAutoMode = continueOnAutoMode, RunningInInteractiveMode = runningInInteractiveMode, EnableReasoningSummaries = enableReasoningSummaries, AgentContext = agentContext, EventsLogDirectory = eventsLogDirectory, AdditionalContentExclusionPolicies = additionalContentExclusionPolicies?.Select(static v => CopilotClient.ToJsonElementForWire(v)!.Value).ToList(), ManageScheduleEnabled = manageScheduleEnabled }; + var request = new SessionUpdateOptionsParams { SessionId = _session.SessionId, Model = model, ReasoningEffort = reasoningEffort, ClientName = clientName, LspClientName = lspClientName, IntegrationId = integrationId, FeatureFlags = featureFlags, IsExperimentalMode = isExperimentalMode, Provider = CopilotClient.ToJsonElementForWire(provider), WorkingDirectory = workingDirectory, AvailableTools = availableTools, ExcludedTools = excludedTools, ToolFilterPrecedence = toolFilterPrecedence, EnableScriptSafety = enableScriptSafety, ShellInitProfile = shellInitProfile, ShellProcessFlags = shellProcessFlags, SandboxConfig = CopilotClient.ToJsonElementForWire(sandboxConfig), LogInteractiveShells = logInteractiveShells, EnvValueMode = envValueMode, SkillDirectories = skillDirectories, DisabledSkills = disabledSkills, EnableOnDemandInstructionDiscovery = enableOnDemandInstructionDiscovery, InstalledPlugins = installedPlugins, CustomAgentsLocalOnly = customAgentsLocalOnly, SkipCustomInstructions = skipCustomInstructions, DisabledInstructionSources = disabledInstructionSources, CoauthorEnabled = coauthorEnabled, TrajectoryFile = trajectoryFile, EnableStreaming = enableStreaming, CopilotUrl = copilotUrl, AskUserDisabled = askUserDisabled, ContinueOnAutoMode = continueOnAutoMode, RunningInInteractiveMode = runningInInteractiveMode, EnableReasoningSummaries = enableReasoningSummaries, AgentContext = agentContext, EventsLogDirectory = eventsLogDirectory, AdditionalContentExclusionPolicies = additionalContentExclusionPolicies?.Select(static v => CopilotClient.ToJsonElementForWire(v)!.Value).ToList(), ManageScheduleEnabled = manageScheduleEnabled }; return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.options.update", [request], cancellationToken); } } diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go index b196ce4ab..b07952cd6 100644 --- a/go/rpc/zrpc.go +++ b/go/rpc/zrpc.go @@ -2003,6 +2003,23 @@ type McpServer struct { Status McpServerStatus `json:"status"` } +// Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. +type McpServerAuthConfig interface { + mcpServerAuthConfig() +} + +type McpServerAuthConfigBoolean bool + +func (McpServerAuthConfigBoolean) mcpServerAuthConfig() {} + +func (McpServerAuthConfigRedirectPort) mcpServerAuthConfig() {} + +// Authentication settings with optional redirect port configuration. +type McpServerAuthConfigRedirectPort struct { + // Fixed port for the OAuth redirect callback server. + RedirectPort *int32 `json:"redirectPort,omitempty"` +} + // MCP server configuration (stdio process or remote HTTP/SSE) type McpServerConfig interface { mcpServerConfig() @@ -2016,8 +2033,8 @@ func (RawMcpServerConfigData) mcpServerConfig() {} // Remote MCP server configuration accessed over HTTP or SSE. type McpServerConfigHTTP struct { - // Additional authentication configuration for this server. - Auth *McpServerConfigHTTPAuth `json:"auth,omitempty"` + // Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. + Auth McpServerAuthConfig `json:"auth,omitempty"` // Content filtering mode to apply to all tools, or a map of tool name to content filtering // mode. FilterMapping FilterMapping `json:"filterMapping,omitempty"` @@ -2032,8 +2049,8 @@ type McpServerConfigHTTP struct { OauthGrantType *McpServerConfigHTTPOauthGrantType `json:"oauthGrantType,omitempty"` // Whether the configured OAuth client is public and does not require a client secret. OauthPublicClient *bool `json:"oauthPublicClient,omitempty"` - // OIDC token configuration. When truthy, a token is automatically gathered. - Oidc McpServerConfigHTTPOidc `json:"oidc,omitempty"` + // Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. + Oidc McpServerAuthConfig `json:"oidc,omitempty"` // Timeout in milliseconds for tool calls to this server. Timeout *int64 `json:"timeout,omitempty"` // Tools to include. Defaults to all tools if not specified. @@ -2050,8 +2067,8 @@ func (McpServerConfigHTTP) mcpServerConfig() {} type McpServerConfigStdio struct { // Command-line arguments passed to the Stdio MCP server process. Args []string `json:"args,omitempty"` - // Authentication configuration for this server. - Auth McpServerConfigStdioAuth `json:"auth,omitempty"` + // Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. + Auth McpServerAuthConfig `json:"auth,omitempty"` // Executable command used to start the Stdio MCP server process. Command string `json:"command"` // Working directory for the Stdio MCP server process. @@ -2064,8 +2081,8 @@ type McpServerConfigStdio struct { // Whether this server is a built-in fallback used when the user has not configured their // own server. IsDefaultServer *bool `json:"isDefaultServer,omitempty"` - // OIDC token configuration. When truthy, a token is automatically gathered. - Oidc McpServerConfigStdioOidc `json:"oidc,omitempty"` + // Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. + Oidc McpServerAuthConfig `json:"oidc,omitempty"` // Timeout in milliseconds for tool calls to this server. Timeout *int64 `json:"timeout,omitempty"` // Tools to include. Defaults to all tools if not specified. @@ -2074,51 +2091,6 @@ type McpServerConfigStdio struct { func (McpServerConfigStdio) mcpServerConfig() {} -// Additional authentication configuration for this server. -type McpServerConfigHTTPAuth struct { - // Fixed port for the OAuth redirect callback server. - RedirectPort *int32 `json:"redirectPort,omitempty"` -} - -// OIDC token configuration. When truthy, a token is automatically gathered. -type McpServerConfigHTTPOidc interface { - mcpServerConfigHTTPOidc() -} - -type McpServerConfigHTTPOidcAnyMap map[string]any - -func (McpServerConfigHTTPOidcAnyMap) mcpServerConfigHTTPOidc() {} - -type McpServerConfigHTTPOidcBoolean bool - -func (McpServerConfigHTTPOidcBoolean) mcpServerConfigHTTPOidc() {} - -// Authentication configuration for this server. -type McpServerConfigStdioAuth interface { - mcpServerConfigStdioAuth() -} - -type McpServerConfigStdioAuthAnyMap map[string]any - -func (McpServerConfigStdioAuthAnyMap) mcpServerConfigStdioAuth() {} - -type McpServerConfigStdioAuthBoolean bool - -func (McpServerConfigStdioAuthBoolean) mcpServerConfigStdioAuth() {} - -// OIDC token configuration. When truthy, a token is automatically gathered. -type McpServerConfigStdioOidc interface { - mcpServerConfigStdioOidc() -} - -type McpServerConfigStdioOidcAnyMap map[string]any - -func (McpServerConfigStdioOidcAnyMap) mcpServerConfigStdioOidc() {} - -type McpServerConfigStdioOidcBoolean bool - -func (McpServerConfigStdioOidcBoolean) mcpServerConfigStdioOidc() {} - // MCP servers configured for the session, with their connection status. // Experimental: McpServerList is part of an experimental API and may change or be removed. type McpServerList struct { @@ -5133,6 +5105,9 @@ type SessionUpdateOptionsParams struct { SkillDirectories []string `json:"skillDirectories,omitempty"` // Whether to skip loading custom instruction sources. SkipCustomInstructions *bool `json:"skipCustomInstructions,omitempty"` + // Controls how availableTools (allowlist) and excludedTools (denylist) combine when both + // are set. + ToolFilterPrecedence *OptionsUpdateToolFilterPrecedence `json:"toolFilterPrecedence,omitempty"` // Optional path for trajectory output. TrajectoryFile *string `json:"trajectoryFile,omitempty"` // Absolute working-directory path for shell tools. @@ -7311,6 +7286,22 @@ const ( OptionsUpdateEnvValueModeIndirect OptionsUpdateEnvValueMode = "indirect" ) +// Controls how availableTools (allowlist) and excludedTools (denylist) combine when both +// are set. +// Experimental: OptionsUpdateToolFilterPrecedence is part of an experimental API and may +// change or be removed. +type OptionsUpdateToolFilterPrecedence string + +const ( + // If availableTools is set, it is the only constraint that applies (excludedTools is + // ignored). Preserves CLI / pre-existing client behavior. Default. + OptionsUpdateToolFilterPrecedenceAvailable OptionsUpdateToolFilterPrecedence = "available" + // A tool is enabled if and only if it matches the allowlist (or the allowlist is unset) AND + // it does not match the denylist. Makes 'all except X' expressible by combining the two + // lists. + OptionsUpdateToolFilterPrecedenceExcluded OptionsUpdateToolFilterPrecedence = "excluded" +) + // Kind discriminator for PermissionDecisionApproveForLocationApproval. type PermissionDecisionApproveForLocationApprovalKind string @@ -10383,6 +10374,9 @@ func (a *OptionsApi) Update(ctx context.Context, params *SessionUpdateOptionsPar if params.SkipCustomInstructions != nil { req["skipCustomInstructions"] = *params.SkipCustomInstructions } + if params.ToolFilterPrecedence != nil { + req["toolFilterPrecedence"] = *params.ToolFilterPrecedence + } if params.TrajectoryFile != nil { req["trajectoryFile"] = *params.TrajectoryFile } diff --git a/go/rpc/zrpc_encoding.go b/go/rpc/zrpc_encoding.go index a9c758989..370a2df91 100644 --- a/go/rpc/zrpc_encoding.go +++ b/go/rpc/zrpc_encoding.go @@ -765,28 +765,28 @@ func (r RawMcpServerConfigData) MarshalJSON() ([]byte, error) { return []byte("null"), nil } -func unmarshalMcpServerConfigHTTPOidc(data []byte) (McpServerConfigHTTPOidc, error) { +func unmarshalMcpServerAuthConfig(data []byte) (McpServerAuthConfig, error) { if string(data) == "null" { return nil, nil } { var value bool if err := json.Unmarshal(data, &value); err == nil { - return McpServerConfigHTTPOidcBoolean(value), nil + return McpServerAuthConfigBoolean(value), nil } } { - var value McpServerConfigHTTPOidcAnyMap + var value McpServerAuthConfigRedirectPort if err := json.Unmarshal(data, &value); err == nil { - return value, nil + return &value, nil } } - return nil, errors.New("data did not match any union variant for McpServerConfigHTTPOidc") + return nil, errors.New("data did not match any union variant for McpServerAuthConfig") } func (r *McpServerConfigHTTP) UnmarshalJSON(data []byte) error { type rawMcpServerConfigHTTP struct { - Auth *McpServerConfigHTTPAuth `json:"auth,omitempty"` + Auth json.RawMessage `json:"auth,omitempty"` FilterMapping json.RawMessage `json:"filterMapping,omitempty"` Headers map[string]string `json:"headers,omitempty"` IsDefaultServer *bool `json:"isDefaultServer,omitempty"` @@ -803,7 +803,13 @@ func (r *McpServerConfigHTTP) UnmarshalJSON(data []byte) error { if err := json.Unmarshal(data, &raw); err != nil { return err } - r.Auth = raw.Auth + if raw.Auth != nil { + value, err := unmarshalMcpServerAuthConfig(raw.Auth) + if err != nil { + return err + } + r.Auth = value + } if raw.FilterMapping != nil { value, err := unmarshalFilterMapping(raw.FilterMapping) if err != nil { @@ -817,7 +823,7 @@ func (r *McpServerConfigHTTP) UnmarshalJSON(data []byte) error { r.OauthGrantType = raw.OauthGrantType r.OauthPublicClient = raw.OauthPublicClient if raw.Oidc != nil { - value, err := unmarshalMcpServerConfigHTTPOidc(raw.Oidc) + value, err := unmarshalMcpServerAuthConfig(raw.Oidc) if err != nil { return err } @@ -830,44 +836,6 @@ func (r *McpServerConfigHTTP) UnmarshalJSON(data []byte) error { return nil } -func unmarshalMcpServerConfigStdioAuth(data []byte) (McpServerConfigStdioAuth, error) { - if string(data) == "null" { - return nil, nil - } - { - var value bool - if err := json.Unmarshal(data, &value); err == nil { - return McpServerConfigStdioAuthBoolean(value), nil - } - } - { - var value McpServerConfigStdioAuthAnyMap - if err := json.Unmarshal(data, &value); err == nil { - return value, nil - } - } - return nil, errors.New("data did not match any union variant for McpServerConfigStdioAuth") -} - -func unmarshalMcpServerConfigStdioOidc(data []byte) (McpServerConfigStdioOidc, error) { - if string(data) == "null" { - return nil, nil - } - { - var value bool - if err := json.Unmarshal(data, &value); err == nil { - return McpServerConfigStdioOidcBoolean(value), nil - } - } - { - var value McpServerConfigStdioOidcAnyMap - if err := json.Unmarshal(data, &value); err == nil { - return value, nil - } - } - return nil, errors.New("data did not match any union variant for McpServerConfigStdioOidc") -} - func (r *McpServerConfigStdio) UnmarshalJSON(data []byte) error { type rawMcpServerConfigStdio struct { Args []string `json:"args,omitempty"` @@ -887,7 +855,7 @@ func (r *McpServerConfigStdio) UnmarshalJSON(data []byte) error { } r.Args = raw.Args if raw.Auth != nil { - value, err := unmarshalMcpServerConfigStdioAuth(raw.Auth) + value, err := unmarshalMcpServerAuthConfig(raw.Auth) if err != nil { return err } @@ -905,7 +873,7 @@ func (r *McpServerConfigStdio) UnmarshalJSON(data []byte) error { } r.IsDefaultServer = raw.IsDefaultServer if raw.Oidc != nil { - value, err := unmarshalMcpServerConfigStdioOidc(raw.Oidc) + value, err := unmarshalMcpServerAuthConfig(raw.Oidc) if err != nil { return err } diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json index 7afbdbc65..124f66c0c 100644 --- a/nodejs/package-lock.json +++ b/nodejs/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.8", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.55-4", + "@github/copilot": "^1.0.55-5", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, @@ -663,9 +663,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.55-4.tgz", - "integrity": "sha512-998fK3QIrajrUV94l8piSjDD8wnOGosCWE/0YBKoyOhvlqAKAN0smmgizu4unj8fGZKaX1uBNT+qOrxAS9tY/g==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.55-5.tgz", + "integrity": "sha512-n6Vr876Iz41PW8pSpOa7SbrNCqaV+6HDLNf/n8V4gIwwlOlIz7Jb00r/fboXZFIT+0dyAGGLoGgd7xUujVL/Xw==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "detect-libc": "^2.1.2" @@ -674,20 +674,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.55-4", - "@github/copilot-darwin-x64": "1.0.55-4", - "@github/copilot-linux-arm64": "1.0.55-4", - "@github/copilot-linux-x64": "1.0.55-4", - "@github/copilot-linuxmusl-arm64": "1.0.55-4", - "@github/copilot-linuxmusl-x64": "1.0.55-4", - "@github/copilot-win32-arm64": "1.0.55-4", - "@github/copilot-win32-x64": "1.0.55-4" + "@github/copilot-darwin-arm64": "1.0.55-5", + "@github/copilot-darwin-x64": "1.0.55-5", + "@github/copilot-linux-arm64": "1.0.55-5", + "@github/copilot-linux-x64": "1.0.55-5", + "@github/copilot-linuxmusl-arm64": "1.0.55-5", + "@github/copilot-linuxmusl-x64": "1.0.55-5", + "@github/copilot-win32-arm64": "1.0.55-5", + "@github/copilot-win32-x64": "1.0.55-5" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.55-4.tgz", - "integrity": "sha512-byEpmUpmFnVfDNONaseG/hKBqQWnyRElViu1d+MpoupzOHlfo8/O2ZA7Fq8RkkqrXcCipjhUDBNavdl7j6EbrA==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.55-5.tgz", + "integrity": "sha512-Mult62GJVnxR3MOP2QNiVU5RRGXPJ+7BpjEMIvkoaMuWX6J7F4bz7N+HUXVHJUiGUp3hnL3M16kjkewWfNdoNg==", "cpu": [ "arm64" ], @@ -701,9 +701,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.55-4.tgz", - "integrity": "sha512-4/+tldImEu4tLo9x+wiY/7pnOLlJ8GkgUG23izMqIQ1I9otM85irfIrtNHy/bvvT+RQ/HYikNlGv00H2nhIuhw==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.55-5.tgz", + "integrity": "sha512-IfY3WhNvHwXHldI2ARsiAYuPlKWlI07Fo1ALq+SViHhn0Zfp2yIr9laJRofyj0G1EbyUxkbNlqQm7UrXhkEVeg==", "cpu": [ "x64" ], @@ -717,9 +717,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.55-4.tgz", - "integrity": "sha512-LwDvphIUMs94HShErbDu0foeasqi/IqIUDo4azWqUFrAp4n4jsiH3MBpC8UwvlSBJSSsND3zGxMrCD/fptqWjA==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.55-5.tgz", + "integrity": "sha512-UPZ5Y5QotcZvo3f4yFwJVOtAgUT3mq+q2fim82kWa/MA0+EkkADZ3kb+R4OnV1Nqv5EaoZiCFh0Ukk++IMSYwQ==", "cpu": [ "arm64" ], @@ -733,9 +733,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.55-4.tgz", - "integrity": "sha512-lp8Ae3V/8hB6HuUdWGrdm8au+HyfkFzrvf/rxk7YJe+zkq4D0O+WLi/7JbG8oZ5spQhzSyac/9gUu830nQu2WA==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.55-5.tgz", + "integrity": "sha512-Fdwiir53Ogg8C9xv6sTc7/C4vFfQHt6VWFB74kojbDgIbYEpm57wNygQVwJvrwtVW3w/b1MLtGGTp7pEvUBACQ==", "cpu": [ "x64" ], @@ -749,9 +749,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.55-4.tgz", - "integrity": "sha512-4xJCXKHw9OZba+1ysUNxcdkRXK4Mf6s8VA9klcCAnY4bSvkTDVNQVGQuonxjvLGjagyORLymINbKRg6GnrKK/Q==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.55-5.tgz", + "integrity": "sha512-NqPmeAA1+iI8Xd4wJUHNNCmVTmHCl+R3nqdXhEVQDLIau9ouGqGGay/91d2ZIgFXJn7J0UTAEdHbdBcfhbnhvg==", "cpu": [ "arm64" ], @@ -765,9 +765,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.55-4.tgz", - "integrity": "sha512-z3U6LsXcBssAeolWNlcw+nUm3cSKHvYDSGynvdYVORaEMNN/qemx4ICRAFNfTVRmP+t/3IWtTpCtHm2U7pSO9A==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.55-5.tgz", + "integrity": "sha512-bOB4vKw1R7Mekn8z34xpNViYUQ4LQAEFzpkyxhc0uOliFmfku/YcIgo42aMWFzf/Bi3iBazBNfCN+L2lz/Jc9A==", "cpu": [ "x64" ], @@ -781,9 +781,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.55-4.tgz", - "integrity": "sha512-j2kqG0c2JJvOZS2O5E/Ye8F6htA7o7UHpJ55vH6USfzColL0YI51yrP3fZVrDC0nhhtfLnVBK6Q0nv+riZnaew==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.55-5.tgz", + "integrity": "sha512-pR2KaiXUanjxolaWgRPlFdeTEpb7jcN1Rk8xVnBCD2ORwERXdYrqXaLCyDbgdplI9mI6IjM+kkUbyXzXoWz/HQ==", "cpu": [ "arm64" ], @@ -797,9 +797,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.55-4.tgz", - "integrity": "sha512-4za8pRAEO6z9SOPP3IYVpZHn4yvPtjAMH17XKYEVYFHTZ+NNHjzYYfyqwhZfJlGgvOOkuh3kYbNWms5a2DW/Jg==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.55-5.tgz", + "integrity": "sha512-EuQBgqSnRFjavgeFifbnSYUJ4elTQBLC/kf+WHolrHR2oUGyiqCQZz/cV2DYVSLP1TGxDKAV4AQCM1AdUT1xEA==", "cpu": [ "x64" ], diff --git a/nodejs/package.json b/nodejs/package.json index 22ab2fc8d..2025e85fd 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -56,7 +56,7 @@ "author": "GitHub", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.55-4", + "@github/copilot": "^1.0.55-5", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/samples/package-lock.json b/nodejs/samples/package-lock.json index 95f31608f..7c478a327 100644 --- a/nodejs/samples/package-lock.json +++ b/nodejs/samples/package-lock.json @@ -18,7 +18,7 @@ "version": "0.1.8", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.55-4", + "@github/copilot": "^1.0.55-5", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts index 90d8f90bf..ebfcfbdd2 100644 --- a/nodejs/src/generated/rpc.ts +++ b/nodejs/src/generated/rpc.ts @@ -587,27 +587,12 @@ export type McpAppsSetHostContextDetailsPlatform = */ export type McpServerConfig = McpServerConfigStdio | McpServerConfigHttp; /** - * OIDC token configuration. When truthy, a token is automatically gathered. + * Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "McpServerConfigStdioOidc". + * via the `definition` "McpServerAuthConfig". */ -export type McpServerConfigStdioOidc = - | boolean - | { - [k: string]: unknown | undefined; - }; -/** - * Authentication configuration for this server. - * - * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "McpServerConfigStdioAuth". - */ -export type McpServerConfigStdioAuth = - | boolean - | { - [k: string]: unknown | undefined; - }; +export type McpServerAuthConfig = boolean | McpServerAuthConfigRedirectPort; /** * Remote transport type. Defaults to "http" when omitted. * @@ -619,17 +604,6 @@ export type McpServerConfigHttpType = | "http" /** Server-Sent Events transport. */ | "sse"; -/** - * OIDC token configuration. When truthy, a token is automatically gathered. - * - * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "McpServerConfigHttpOidc". - */ -export type McpServerConfigHttpOidc = - | boolean - | { - [k: string]: unknown | undefined; - }; /** * OAuth grant type to use when authenticating to the remote MCP server. * @@ -803,6 +777,18 @@ export type OptionsUpdateEnvValueMode = | "direct" /** Resolve MCP server environment values from host-side references. */ | "indirect"; +/** + * Controls how availableTools (allowlist) and excludedTools (denylist) combine when both are set. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "OptionsUpdateToolFilterPrecedence". + */ +/** @experimental */ +export type OptionsUpdateToolFilterPrecedence = + /** If availableTools is set, it is the only constraint that applies (excludedTools is ignored). Preserves CLI / pre-existing client behavior. Default. */ + | "available" + /** A tool is enabled if and only if it matches the allowlist (or the allowlist is unset) AND it does not match the denylist. Makes 'all except X' expressible by combining the two lists. */ + | "excluded"; /** * The client's response to the pending permission prompt * @@ -4016,8 +4002,8 @@ export interface McpServerConfigStdio { * Timeout in milliseconds for tool calls to this server. */ timeout?: number; - oidc?: McpServerConfigStdioOidc; - auth?: McpServerConfigStdioAuth; + oidc?: McpServerAuthConfig; + auth?: McpServerAuthConfig; /** * Executable command used to start the Stdio MCP server process. */ @@ -4037,6 +4023,19 @@ export interface McpServerConfigStdio { [k: string]: string | undefined; }; } +/** + * Authentication settings with optional redirect port configuration. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "McpServerAuthConfigRedirectPort". + */ +export interface McpServerAuthConfigRedirectPort { + /** + * Fixed port for the OAuth redirect callback server. + */ + redirectPort?: number; + [k: string]: unknown | undefined; +} /** * Remote MCP server configuration accessed over HTTP or SSE. * @@ -4058,8 +4057,8 @@ export interface McpServerConfigHttp { * Timeout in milliseconds for tool calls to this server. */ timeout?: number; - oidc?: McpServerConfigHttpOidc; - auth?: McpServerConfigHttpAuth; + oidc?: McpServerAuthConfig; + auth?: McpServerAuthConfig; /** * URL of the remote MCP server endpoint. */ @@ -4080,19 +4079,6 @@ export interface McpServerConfigHttp { oauthPublicClient?: boolean; oauthGrantType?: McpServerConfigHttpOauthGrantType; } -/** - * Additional authentication configuration for this server. - * - * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "McpServerConfigHttpAuth". - */ -export interface McpServerConfigHttpAuth { - /** - * Fixed port for the OAuth redirect callback server. - */ - redirectPort?: number; - [k: string]: unknown | undefined; -} /** * MCP server names to disable for new sessions. * @@ -8157,6 +8143,7 @@ export interface SessionUpdateOptionsParams { * Denylist of tool names for this session. */ excludedTools?: string[]; + toolFilterPrecedence?: OptionsUpdateToolFilterPrecedence; /** * Whether shell-script safety heuristics are enabled. */ diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py index 138a81970..ea2d20d88 100644 --- a/python/copilot/generated/rpc.py +++ b/python/copilot/generated/rpc.py @@ -1988,17 +1988,17 @@ def to_dict(self) -> dict: return result @dataclass -class AuthAuth: - """Additional authentication configuration for this server.""" +class MCPServerAuthConfigRedirectPort: + """Authentication settings with optional redirect port configuration.""" redirect_port: int | None = None """Fixed port for the OAuth redirect callback server.""" @staticmethod - def from_dict(obj: Any) -> 'AuthAuth': + def from_dict(obj: Any) -> 'MCPServerAuthConfigRedirectPort': assert isinstance(obj, dict) redirect_port = from_union([from_int, from_none], obj.get("redirectPort")) - return AuthAuth(redirect_port) + return MCPServerAuthConfigRedirectPort(redirect_port) def to_dict(self) -> dict: result: dict = {} @@ -2873,6 +2873,14 @@ def to_dict(self) -> dict: result["name"] = from_str(self.name) return result +# Experimental: this type is part of an experimental API and may change or be removed. +class OptionsUpdateToolFilterPrecedence(Enum): + """Controls how availableTools (allowlist) and excludedTools (denylist) combine when both + are set. + """ + AVAILABLE = "available" + EXCLUDED = "excluded" + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class PendingPermissionRequest: @@ -7356,80 +7364,6 @@ def to_dict(self) -> dict: result["summary"] = from_union([from_str, from_none], self.summary) return result -@dataclass -class MCPServerConfigStdio: - """Stdio MCP server configuration launched as a child process.""" - - command: str - """Executable command used to start the Stdio MCP server process.""" - - args: list[str] | None = None - """Command-line arguments passed to the Stdio MCP server process.""" - - auth: bool | dict[str, Any] | None = None - """Authentication configuration for this server.""" - - cwd: str | None = None - """Working directory for the Stdio MCP server process.""" - - env: dict[str, str] | None = None - """Environment variables to pass to the Stdio MCP server process.""" - - filter_mapping: dict[str, ContentFilterMode] | ContentFilterMode | None = None - """Content filtering mode to apply to all tools, or a map of tool name to content filtering - mode. - """ - is_default_server: bool | None = None - """Whether this server is a built-in fallback used when the user has not configured their - own server. - """ - oidc: bool | dict[str, Any] | None = None - """OIDC token configuration. When truthy, a token is automatically gathered.""" - - timeout: int | None = None - """Timeout in milliseconds for tool calls to this server.""" - - tools: list[str] | None = None - """Tools to include. Defaults to all tools if not specified.""" - - @staticmethod - def from_dict(obj: Any) -> 'MCPServerConfigStdio': - assert isinstance(obj, dict) - command = from_str(obj.get("command")) - args = from_union([lambda x: from_list(from_str, x), from_none], obj.get("args")) - auth = from_union([from_bool, lambda x: from_dict(lambda x: x, x), from_none], obj.get("auth")) - cwd = from_union([from_str, from_none], obj.get("cwd")) - env = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("env")) - filter_mapping = from_union([lambda x: from_dict(ContentFilterMode, x), ContentFilterMode, from_none], obj.get("filterMapping")) - is_default_server = from_union([from_bool, from_none], obj.get("isDefaultServer")) - oidc = from_union([from_bool, lambda x: from_dict(lambda x: x, x), from_none], obj.get("oidc")) - timeout = from_union([from_int, from_none], obj.get("timeout")) - tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("tools")) - return MCPServerConfigStdio(command, args, auth, cwd, env, filter_mapping, is_default_server, oidc, timeout, tools) - - def to_dict(self) -> dict: - result: dict = {} - result["command"] = from_str(self.command) - if self.args is not None: - result["args"] = from_union([lambda x: from_list(from_str, x), from_none], self.args) - if self.auth is not None: - result["auth"] = from_union([from_bool, lambda x: from_dict(lambda x: x, x), from_none], self.auth) - if self.cwd is not None: - result["cwd"] = from_union([from_str, from_none], self.cwd) - if self.env is not None: - result["env"] = from_union([lambda x: from_dict(from_str, x), from_none], self.env) - if self.filter_mapping is not None: - result["filterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(ContentFilterMode, x), x), lambda x: to_enum(ContentFilterMode, x), from_none], self.filter_mapping) - if self.is_default_server is not None: - result["isDefaultServer"] = from_union([from_bool, from_none], self.is_default_server) - if self.oidc is not None: - result["oidc"] = from_union([from_bool, lambda x: from_dict(lambda x: x, x), from_none], self.oidc) - if self.timeout is not None: - result["timeout"] = from_union([from_int, from_none], self.timeout) - if self.tools is not None: - result["tools"] = from_union([lambda x: from_list(from_str, x), from_none], self.tools) - return result - # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CanvasHostContextCapabilities: @@ -8430,6 +8364,80 @@ def to_dict(self) -> dict: result["contents"] = from_list(lambda x: to_class(MCPAppsResourceContent, x), self.contents) return result +@dataclass +class MCPServerConfigStdio: + """Stdio MCP server configuration launched as a child process.""" + + command: str + """Executable command used to start the Stdio MCP server process.""" + + args: list[str] | None = None + """Command-line arguments passed to the Stdio MCP server process.""" + + auth: bool | MCPServerAuthConfigRedirectPort | None = None + """Set to `true` to use defaults, or provide an object with additional auth or OIDC settings.""" + + cwd: str | None = None + """Working directory for the Stdio MCP server process.""" + + env: dict[str, str] | None = None + """Environment variables to pass to the Stdio MCP server process.""" + + filter_mapping: dict[str, ContentFilterMode] | ContentFilterMode | None = None + """Content filtering mode to apply to all tools, or a map of tool name to content filtering + mode. + """ + is_default_server: bool | None = None + """Whether this server is a built-in fallback used when the user has not configured their + own server. + """ + oidc: bool | MCPServerAuthConfigRedirectPort | None = None + """Set to `true` to use defaults, or provide an object with additional auth or OIDC settings.""" + + timeout: int | None = None + """Timeout in milliseconds for tool calls to this server.""" + + tools: list[str] | None = None + """Tools to include. Defaults to all tools if not specified.""" + + @staticmethod + def from_dict(obj: Any) -> 'MCPServerConfigStdio': + assert isinstance(obj, dict) + command = from_str(obj.get("command")) + args = from_union([lambda x: from_list(from_str, x), from_none], obj.get("args")) + auth = from_union([from_bool, MCPServerAuthConfigRedirectPort.from_dict, from_none], obj.get("auth")) + cwd = from_union([from_str, from_none], obj.get("cwd")) + env = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("env")) + filter_mapping = from_union([lambda x: from_dict(ContentFilterMode, x), ContentFilterMode, from_none], obj.get("filterMapping")) + is_default_server = from_union([from_bool, from_none], obj.get("isDefaultServer")) + oidc = from_union([from_bool, MCPServerAuthConfigRedirectPort.from_dict, from_none], obj.get("oidc")) + timeout = from_union([from_int, from_none], obj.get("timeout")) + tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("tools")) + return MCPServerConfigStdio(command, args, auth, cwd, env, filter_mapping, is_default_server, oidc, timeout, tools) + + def to_dict(self) -> dict: + result: dict = {} + result["command"] = from_str(self.command) + if self.args is not None: + result["args"] = from_union([lambda x: from_list(from_str, x), from_none], self.args) + if self.auth is not None: + result["auth"] = from_union([from_bool, lambda x: to_class(MCPServerAuthConfigRedirectPort, x), from_none], self.auth) + if self.cwd is not None: + result["cwd"] = from_union([from_str, from_none], self.cwd) + if self.env is not None: + result["env"] = from_union([lambda x: from_dict(from_str, x), from_none], self.env) + if self.filter_mapping is not None: + result["filterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(ContentFilterMode, x), x), lambda x: to_enum(ContentFilterMode, x), from_none], self.filter_mapping) + if self.is_default_server is not None: + result["isDefaultServer"] = from_union([from_bool, from_none], self.is_default_server) + if self.oidc is not None: + result["oidc"] = from_union([from_bool, lambda x: to_class(MCPServerAuthConfigRedirectPort, x), from_none], self.oidc) + if self.timeout is not None: + result["timeout"] = from_union([from_int, from_none], self.timeout) + if self.tools is not None: + result["tools"] = from_union([lambda x: from_list(from_str, x), from_none], self.tools) + return result + @dataclass class MCPServerConfig: """MCP server configuration (stdio process or remote HTTP/SSE) @@ -8441,11 +8449,9 @@ class MCPServerConfig: args: list[str] | None = None """Command-line arguments passed to the Stdio MCP server process.""" - auth: bool | AuthAuth | None = None - """Authentication configuration for this server. + auth: bool | MCPServerAuthConfigRedirectPort | None = None + """Set to `true` to use defaults, or provide an object with additional auth or OIDC settings.""" - Additional authentication configuration for this server. - """ command: str | None = None """Executable command used to start the Stdio MCP server process.""" @@ -8463,8 +8469,8 @@ class MCPServerConfig: """Whether this server is a built-in fallback used when the user has not configured their own server. """ - oidc: bool | dict[str, Any] | None = None - """OIDC token configuration. When truthy, a token is automatically gathered.""" + oidc: bool | MCPServerAuthConfigRedirectPort | None = None + """Set to `true` to use defaults, or provide an object with additional auth or OIDC settings.""" timeout: int | None = None """Timeout in milliseconds for tool calls to this server.""" @@ -8494,13 +8500,13 @@ class MCPServerConfig: def from_dict(obj: Any) -> 'MCPServerConfig': assert isinstance(obj, dict) args = from_union([lambda x: from_list(from_str, x), from_none], obj.get("args")) - auth = from_union([from_bool, AuthAuth.from_dict, from_none], obj.get("auth")) + auth = from_union([from_bool, MCPServerAuthConfigRedirectPort.from_dict, from_none], obj.get("auth")) command = from_union([from_str, from_none], obj.get("command")) cwd = from_union([from_str, from_none], obj.get("cwd")) env = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("env")) filter_mapping = from_union([lambda x: from_dict(ContentFilterMode, x), ContentFilterMode, from_none], obj.get("filterMapping")) is_default_server = from_union([from_bool, from_none], obj.get("isDefaultServer")) - oidc = from_union([from_bool, lambda x: from_dict(lambda x: x, x), from_none], obj.get("oidc")) + oidc = from_union([from_bool, MCPServerAuthConfigRedirectPort.from_dict, from_none], obj.get("oidc")) timeout = from_union([from_int, from_none], obj.get("timeout")) tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("tools")) headers = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("headers")) @@ -8516,7 +8522,7 @@ def to_dict(self) -> dict: if self.args is not None: result["args"] = from_union([lambda x: from_list(from_str, x), from_none], self.args) if self.auth is not None: - result["auth"] = from_union([from_bool, lambda x: to_class(AuthAuth, x), from_none], self.auth) + result["auth"] = from_union([from_bool, lambda x: to_class(MCPServerAuthConfigRedirectPort, x), from_none], self.auth) if self.command is not None: result["command"] = from_union([from_str, from_none], self.command) if self.cwd is not None: @@ -8528,7 +8534,7 @@ def to_dict(self) -> dict: if self.is_default_server is not None: result["isDefaultServer"] = from_union([from_bool, from_none], self.is_default_server) if self.oidc is not None: - result["oidc"] = from_union([from_bool, lambda x: from_dict(lambda x: x, x), from_none], self.oidc) + result["oidc"] = from_union([from_bool, lambda x: to_class(MCPServerAuthConfigRedirectPort, x), from_none], self.oidc) if self.timeout is not None: result["timeout"] = from_union([from_int, from_none], self.timeout) if self.tools is not None: @@ -8554,8 +8560,8 @@ class MCPServerConfigHTTP: url: str """URL of the remote MCP server endpoint.""" - auth: AuthAuth | None = None - """Additional authentication configuration for this server.""" + auth: bool | MCPServerAuthConfigRedirectPort | None = None + """Set to `true` to use defaults, or provide an object with additional auth or OIDC settings.""" filter_mapping: dict[str, ContentFilterMode] | ContentFilterMode | None = None """Content filtering mode to apply to all tools, or a map of tool name to content filtering @@ -8577,8 +8583,8 @@ class MCPServerConfigHTTP: oauth_public_client: bool | None = None """Whether the configured OAuth client is public and does not require a client secret.""" - oidc: bool | dict[str, Any] | None = None - """OIDC token configuration. When truthy, a token is automatically gathered.""" + oidc: bool | MCPServerAuthConfigRedirectPort | None = None + """Set to `true` to use defaults, or provide an object with additional auth or OIDC settings.""" timeout: int | None = None """Timeout in milliseconds for tool calls to this server.""" @@ -8593,14 +8599,14 @@ class MCPServerConfigHTTP: def from_dict(obj: Any) -> 'MCPServerConfigHTTP': assert isinstance(obj, dict) url = from_str(obj.get("url")) - auth = from_union([AuthAuth.from_dict, from_none], obj.get("auth")) + auth = from_union([from_bool, MCPServerAuthConfigRedirectPort.from_dict, from_none], obj.get("auth")) filter_mapping = from_union([lambda x: from_dict(ContentFilterMode, x), ContentFilterMode, from_none], obj.get("filterMapping")) headers = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("headers")) is_default_server = from_union([from_bool, from_none], obj.get("isDefaultServer")) oauth_client_id = from_union([from_str, from_none], obj.get("oauthClientId")) oauth_grant_type = from_union([MCPServerConfigHTTPOauthGrantType, from_none], obj.get("oauthGrantType")) oauth_public_client = from_union([from_bool, from_none], obj.get("oauthPublicClient")) - oidc = from_union([from_bool, lambda x: from_dict(lambda x: x, x), from_none], obj.get("oidc")) + oidc = from_union([from_bool, MCPServerAuthConfigRedirectPort.from_dict, from_none], obj.get("oidc")) timeout = from_union([from_int, from_none], obj.get("timeout")) tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("tools")) type = from_union([MCPServerConfigHTTPType, from_none], obj.get("type")) @@ -8610,7 +8616,7 @@ def to_dict(self) -> dict: result: dict = {} result["url"] = from_str(self.url) if self.auth is not None: - result["auth"] = from_union([lambda x: to_class(AuthAuth, x), from_none], self.auth) + result["auth"] = from_union([from_bool, lambda x: to_class(MCPServerAuthConfigRedirectPort, x), from_none], self.auth) if self.filter_mapping is not None: result["filterMapping"] = from_union([lambda x: from_dict(lambda x: to_enum(ContentFilterMode, x), x), lambda x: to_enum(ContentFilterMode, x), from_none], self.filter_mapping) if self.headers is not None: @@ -8624,7 +8630,7 @@ def to_dict(self) -> dict: if self.oauth_public_client is not None: result["oauthPublicClient"] = from_union([from_bool, from_none], self.oauth_public_client) if self.oidc is not None: - result["oidc"] = from_union([from_bool, lambda x: from_dict(lambda x: x, x), from_none], self.oidc) + result["oidc"] = from_union([from_bool, lambda x: to_class(MCPServerAuthConfigRedirectPort, x), from_none], self.oidc) if self.timeout is not None: result["timeout"] = from_union([from_int, from_none], self.timeout) if self.tools is not None: @@ -14665,6 +14671,10 @@ class SessionUpdateOptionsParams: skip_custom_instructions: bool | None = None """Whether to skip loading custom instruction sources.""" + tool_filter_precedence: OptionsUpdateToolFilterPrecedence | None = None + """Controls how availableTools (allowlist) and excludedTools (denylist) combine when both + are set. + """ trajectory_file: str | None = None """Optional path for trajectory output.""" @@ -14708,9 +14718,10 @@ def from_dict(obj: Any) -> 'SessionUpdateOptionsParams': shell_process_flags = from_union([lambda x: from_list(from_str, x), from_none], obj.get("shellProcessFlags")) skill_directories = from_union([lambda x: from_list(from_str, x), from_none], obj.get("skillDirectories")) skip_custom_instructions = from_union([from_bool, from_none], obj.get("skipCustomInstructions")) + tool_filter_precedence = from_union([OptionsUpdateToolFilterPrecedence, from_none], obj.get("toolFilterPrecedence")) trajectory_file = from_union([from_str, from_none], obj.get("trajectoryFile")) working_directory = from_union([from_str, from_none], obj.get("workingDirectory")) - return SessionUpdateOptionsParams(additional_content_exclusion_policies, agent_context, ask_user_disabled, available_tools, client_name, coauthor_enabled, continue_on_auto_mode, copilot_url, custom_agents_local_only, disabled_instruction_sources, disabled_skills, enable_on_demand_instruction_discovery, enable_reasoning_summaries, enable_script_safety, enable_streaming, env_value_mode, events_log_directory, excluded_tools, feature_flags, installed_plugins, integration_id, is_experimental_mode, log_interactive_shells, lsp_client_name, manage_schedule_enabled, model, provider, reasoning_effort, running_in_interactive_mode, sandbox_config, shell_init_profile, shell_process_flags, skill_directories, skip_custom_instructions, trajectory_file, working_directory) + return SessionUpdateOptionsParams(additional_content_exclusion_policies, agent_context, ask_user_disabled, available_tools, client_name, coauthor_enabled, continue_on_auto_mode, copilot_url, custom_agents_local_only, disabled_instruction_sources, disabled_skills, enable_on_demand_instruction_discovery, enable_reasoning_summaries, enable_script_safety, enable_streaming, env_value_mode, events_log_directory, excluded_tools, feature_flags, installed_plugins, integration_id, is_experimental_mode, log_interactive_shells, lsp_client_name, manage_schedule_enabled, model, provider, reasoning_effort, running_in_interactive_mode, sandbox_config, shell_init_profile, shell_process_flags, skill_directories, skip_custom_instructions, tool_filter_precedence, trajectory_file, working_directory) def to_dict(self) -> dict: result: dict = {} @@ -14782,6 +14793,8 @@ def to_dict(self) -> dict: result["skillDirectories"] = from_union([lambda x: from_list(from_str, x), from_none], self.skill_directories) if self.skip_custom_instructions is not None: result["skipCustomInstructions"] = from_union([from_bool, from_none], self.skip_custom_instructions) + if self.tool_filter_precedence is not None: + result["toolFilterPrecedence"] = from_union([lambda x: to_enum(OptionsUpdateToolFilterPrecedence, x), from_none], self.tool_filter_precedence) if self.trajectory_file is not None: result["trajectoryFile"] = from_union([from_str, from_none], self.trajectory_file) if self.working_directory is not None: @@ -15607,15 +15620,13 @@ class RPC: mcp_sampling_execution_action: MCPSamplingExecutionAction mcp_sampling_execution_result: MCPSamplingExecutionResult mcp_server: MCPServer + mcp_server_auth_config: bool | MCPServerAuthConfigRedirectPort + mcp_server_auth_config_redirect_port: MCPServerAuthConfigRedirectPort mcp_server_config: MCPServerConfig mcp_server_config_http: MCPServerConfigHTTP - mcp_server_config_http_auth: AuthAuth mcp_server_config_http_oauth_grant_type: MCPServerConfigHTTPOauthGrantType - mcp_server_config_http_oidc: bool | dict[str, Any] mcp_server_config_http_type: MCPServerConfigHTTPType mcp_server_config_stdio: MCPServerConfigStdio - mcp_server_config_stdio_auth: bool | dict[str, Any] - mcp_server_config_stdio_oidc: bool | dict[str, Any] mcp_server_list: MCPServerList mcp_set_env_value_mode_details: MCPSetEnvValueModeDetails mcp_set_env_value_mode_params: MCPSetEnvValueModeParams @@ -15662,6 +15673,7 @@ class RPC: name_set_request: NameSetRequest open_canvas_instance: OpenCanvasInstance options_update_env_value_mode: MCPSetEnvValueModeDetails + options_update_tool_filter_precedence: OptionsUpdateToolFilterPrecedence pending_permission_request: PendingPermissionRequest pending_permission_request_list: PendingPermissionRequestList permission_decision: PermissionDecision @@ -16188,15 +16200,13 @@ def from_dict(obj: Any) -> 'RPC': mcp_sampling_execution_action = MCPSamplingExecutionAction(obj.get("McpSamplingExecutionAction")) mcp_sampling_execution_result = MCPSamplingExecutionResult.from_dict(obj.get("McpSamplingExecutionResult")) mcp_server = MCPServer.from_dict(obj.get("McpServer")) + mcp_server_auth_config = from_union([from_bool, MCPServerAuthConfigRedirectPort.from_dict], obj.get("McpServerAuthConfig")) + mcp_server_auth_config_redirect_port = MCPServerAuthConfigRedirectPort.from_dict(obj.get("McpServerAuthConfigRedirectPort")) mcp_server_config = MCPServerConfig.from_dict(obj.get("McpServerConfig")) mcp_server_config_http = MCPServerConfigHTTP.from_dict(obj.get("McpServerConfigHttp")) - mcp_server_config_http_auth = AuthAuth.from_dict(obj.get("McpServerConfigHttpAuth")) mcp_server_config_http_oauth_grant_type = MCPServerConfigHTTPOauthGrantType(obj.get("McpServerConfigHttpOauthGrantType")) - mcp_server_config_http_oidc = from_union([from_bool, lambda x: from_dict(lambda x: x, x)], obj.get("McpServerConfigHttpOidc")) mcp_server_config_http_type = MCPServerConfigHTTPType(obj.get("McpServerConfigHttpType")) mcp_server_config_stdio = MCPServerConfigStdio.from_dict(obj.get("McpServerConfigStdio")) - mcp_server_config_stdio_auth = from_union([from_bool, lambda x: from_dict(lambda x: x, x)], obj.get("McpServerConfigStdioAuth")) - mcp_server_config_stdio_oidc = from_union([from_bool, lambda x: from_dict(lambda x: x, x)], obj.get("McpServerConfigStdioOidc")) mcp_server_list = MCPServerList.from_dict(obj.get("McpServerList")) mcp_set_env_value_mode_details = MCPSetEnvValueModeDetails(obj.get("McpSetEnvValueModeDetails")) mcp_set_env_value_mode_params = MCPSetEnvValueModeParams.from_dict(obj.get("McpSetEnvValueModeParams")) @@ -16243,6 +16253,7 @@ def from_dict(obj: Any) -> 'RPC': name_set_request = NameSetRequest.from_dict(obj.get("NameSetRequest")) open_canvas_instance = OpenCanvasInstance.from_dict(obj.get("OpenCanvasInstance")) options_update_env_value_mode = MCPSetEnvValueModeDetails(obj.get("OptionsUpdateEnvValueMode")) + options_update_tool_filter_precedence = OptionsUpdateToolFilterPrecedence(obj.get("OptionsUpdateToolFilterPrecedence")) pending_permission_request = PendingPermissionRequest.from_dict(obj.get("PendingPermissionRequest")) pending_permission_request_list = PendingPermissionRequestList.from_dict(obj.get("PendingPermissionRequestList")) permission_decision = _load_PermissionDecision(obj.get("PermissionDecision")) @@ -16586,7 +16597,7 @@ def from_dict(obj: Any) -> 'RPC': session_context_info = from_union([SessionContextInfo.from_dict, from_none], obj.get("SessionContextInfo")) task_progress = from_union([TaskProgress.from_dict, from_none], obj.get("TaskProgress")) workspace_summary = from_union([WorkspaceSummary.from_dict, from_none], obj.get("WorkspaceSummary")) - return RPC(abort_request, abort_result, account_get_quota_request, account_get_quota_result, account_quota_snapshot, agent_get_current_result, agent_info, agent_info_source, agent_list, agent_registry_live_target_entry, agent_registry_live_target_entry_attention_kind, agent_registry_live_target_entry_kind, agent_registry_live_target_entry_last_terminal_event, agent_registry_live_target_entry_status, agent_registry_log_capture, agent_registry_log_capture_open_error_reason, agent_registry_spawn_error, agent_registry_spawn_permission_mode, agent_registry_spawn_registry_timeout, agent_registry_spawn_request, agent_registry_spawn_result, agent_registry_spawn_spawned, agent_registry_spawn_validation_error, agent_registry_spawn_validation_error_field, agent_registry_spawn_validation_error_reason, agent_reload_result, agent_select_request, agent_select_result, allow_all_permission_set_result, allow_all_permission_state, api_key_auth_info, auth_info, auth_info_type, canvas_action, canvas_close_request, canvas_host_context, canvas_host_context_capabilities, canvas_instance_availability, canvas_invoke_action_request, canvas_invoke_action_result, canvas_json_schema, canvas_list, canvas_list_open_result, canvas_open_request, canvas_provider_close_request, canvas_provider_invoke_action_request, canvas_provider_open_request, canvas_provider_open_result, canvas_session_context, command_list, commands_handle_pending_command_request, commands_handle_pending_command_result, commands_invoke_request, commands_list_request, commands_respond_to_queued_command_request, commands_respond_to_queued_command_result, connected_remote_session_metadata, connected_remote_session_metadata_kind, connected_remote_session_metadata_repository, connect_remote_session_params, connect_request, connect_result, content_filter_mode, copilot_api_token_auth_info, copilot_user_response, copilot_user_response_endpoints, copilot_user_response_quota_snapshots, copilot_user_response_quota_snapshots_chat, copilot_user_response_quota_snapshots_completions, copilot_user_response_quota_snapshots_premium_interactions, current_model, discovered_canvas, discovered_mcp_server, discovered_mcp_server_type, enqueue_command_params, enqueue_command_result, env_auth_info, event_log_read_request, event_log_release_interest_result, event_log_tail_result, event_log_types, events_agent_scope, events_cursor_status, events_read_result, execute_command_params, execute_command_result, extension, extension_list, extensions_disable_request, extensions_enable_request, extension_source, extension_status, external_tool_result, external_tool_text_result_for_llm, external_tool_text_result_for_llm_binary_results_for_llm, external_tool_text_result_for_llm_binary_results_for_llm_type, external_tool_text_result_for_llm_content, external_tool_text_result_for_llm_content_audio, external_tool_text_result_for_llm_content_image, external_tool_text_result_for_llm_content_resource, external_tool_text_result_for_llm_content_resource_details, external_tool_text_result_for_llm_content_resource_link, external_tool_text_result_for_llm_content_resource_link_icon, external_tool_text_result_for_llm_content_resource_link_icon_theme, external_tool_text_result_for_llm_content_terminal, external_tool_text_result_for_llm_content_text, filter_mapping, fleet_start_request, fleet_start_result, folder_trust_add_params, folder_trust_check_params, folder_trust_check_result, gh_cli_auth_info, handle_pending_tool_call_request, handle_pending_tool_call_result, history_abort_manual_compaction_result, history_cancel_background_compaction_result, history_compact_context_window, history_compact_request, history_compact_result, history_summarize_for_handoff_result, history_truncate_request, history_truncate_result, hmac_auth_info, installed_plugin, installed_plugin_source, installed_plugin_source_github, installed_plugin_source_local, installed_plugin_source_url, instructions_get_sources_result, instructions_sources, instructions_sources_location, instructions_sources_type, log_request, log_result, lsp_initialize_request, mcp_apps_call_tool_request, mcp_apps_diagnose_capability, mcp_apps_diagnose_request, mcp_apps_diagnose_result, mcp_apps_diagnose_server, mcp_apps_host_context, mcp_apps_host_context_details, mcp_apps_host_context_details_available_display_mode, mcp_apps_host_context_details_display_mode, mcp_apps_host_context_details_platform, mcp_apps_host_context_details_theme, mcp_apps_list_tools_request, mcp_apps_list_tools_result, mcp_apps_read_resource_request, mcp_apps_read_resource_result, mcp_apps_resource_content, mcp_apps_set_host_context_details, mcp_apps_set_host_context_details_available_display_mode, mcp_apps_set_host_context_details_display_mode, mcp_apps_set_host_context_details_platform, mcp_apps_set_host_context_details_theme, mcp_apps_set_host_context_request, mcp_cancel_sampling_execution_params, mcp_cancel_sampling_execution_result, mcp_config_add_request, mcp_config_disable_request, mcp_config_enable_request, mcp_config_list, mcp_config_remove_request, mcp_config_update_request, mcp_disable_request, mcp_discover_request, mcp_discover_result, mcp_enable_request, mcp_execute_sampling_params, mcp_execute_sampling_request, mcp_execute_sampling_result, mcp_oauth_login_request, mcp_oauth_login_result, mcp_remove_git_hub_result, mcp_sampling_execution_action, mcp_sampling_execution_result, mcp_server, mcp_server_config, mcp_server_config_http, mcp_server_config_http_auth, mcp_server_config_http_oauth_grant_type, mcp_server_config_http_oidc, mcp_server_config_http_type, mcp_server_config_stdio, mcp_server_config_stdio_auth, mcp_server_config_stdio_oidc, mcp_server_list, mcp_set_env_value_mode_details, mcp_set_env_value_mode_params, mcp_set_env_value_mode_result, metadata_context_info_request, metadata_context_info_result, metadata_is_processing_result, metadata_recompute_context_tokens_request, metadata_recompute_context_tokens_result, metadata_record_context_change_request, metadata_record_context_change_result, metadata_set_working_directory_request, metadata_set_working_directory_result, metadata_snapshot_current_mode, metadata_snapshot_remote_metadata, metadata_snapshot_remote_metadata_repository, metadata_snapshot_remote_metadata_task_type, model, model_billing, model_billing_token_prices, model_billing_token_prices_long_context, model_capabilities, model_capabilities_limits, model_capabilities_limits_vision, model_capabilities_override, model_capabilities_override_limits, model_capabilities_override_limits_vision, model_capabilities_override_supports, model_capabilities_supports, model_list, model_picker_category, model_picker_price_category, model_policy, model_policy_state, model_set_reasoning_effort_request, model_set_reasoning_effort_result, models_list_request, model_switch_to_request, model_switch_to_result, mode_set_request, name_get_result, name_set_auto_request, name_set_auto_result, name_set_request, open_canvas_instance, options_update_env_value_mode, pending_permission_request, pending_permission_request_list, permission_decision, permission_decision_approved, permission_decision_approved_for_location, permission_decision_approved_for_session, permission_decision_approve_for_location, permission_decision_approve_for_location_approval, permission_decision_approve_for_location_approval_commands, permission_decision_approve_for_location_approval_custom_tool, permission_decision_approve_for_location_approval_extension_management, permission_decision_approve_for_location_approval_extension_permission_access, permission_decision_approve_for_location_approval_mcp, permission_decision_approve_for_location_approval_mcp_sampling, permission_decision_approve_for_location_approval_memory, permission_decision_approve_for_location_approval_read, permission_decision_approve_for_location_approval_write, permission_decision_approve_for_session, permission_decision_approve_for_session_approval, permission_decision_approve_for_session_approval_commands, permission_decision_approve_for_session_approval_custom_tool, permission_decision_approve_for_session_approval_extension_management, permission_decision_approve_for_session_approval_extension_permission_access, permission_decision_approve_for_session_approval_mcp, permission_decision_approve_for_session_approval_mcp_sampling, permission_decision_approve_for_session_approval_memory, permission_decision_approve_for_session_approval_read, permission_decision_approve_for_session_approval_write, permission_decision_approve_once, permission_decision_approve_permanently, permission_decision_cancelled, permission_decision_denied_by_content_exclusion_policy, permission_decision_denied_by_permission_request_hook, permission_decision_denied_by_rules, permission_decision_denied_interactively_by_user, permission_decision_denied_no_approval_rule_and_could_not_request_from_user, permission_decision_reject, permission_decision_request, permission_decision_user_not_available, permission_location_add_tool_approval_params, permission_location_apply_params, permission_location_apply_result, permission_location_resolve_params, permission_location_resolve_result, permission_location_type, permission_paths_add_params, permission_paths_allowed_check_params, permission_paths_allowed_check_result, permission_paths_config, permission_paths_list, permission_paths_update_primary_params, permission_paths_workspace_check_params, permission_paths_workspace_check_result, permission_prompt_shown_notification, permission_request_result, permission_rules_set, permissions_configure_additional_content_exclusion_policy, permissions_configure_additional_content_exclusion_policy_rule, permissions_configure_additional_content_exclusion_policy_rule_source, permissions_configure_additional_content_exclusion_policy_scope, permissions_configure_params, permissions_configure_result, permissions_folder_trust_add_trusted_result, permissions_get_allow_all_request, permissions_locations_add_tool_approval_details, permissions_locations_add_tool_approval_details_commands, permissions_locations_add_tool_approval_details_custom_tool, permissions_locations_add_tool_approval_details_extension_management, permissions_locations_add_tool_approval_details_extension_permission_access, permissions_locations_add_tool_approval_details_mcp, permissions_locations_add_tool_approval_details_mcp_sampling, permissions_locations_add_tool_approval_details_memory, permissions_locations_add_tool_approval_details_read, permissions_locations_add_tool_approval_details_write, permissions_locations_add_tool_approval_result, permissions_modify_rules_params, permissions_modify_rules_result, permissions_modify_rules_scope, permissions_notify_prompt_shown_result, permissions_paths_add_result, permissions_paths_list_request, permissions_paths_update_primary_result, permissions_pending_requests_request, permissions_reset_session_approvals_request, permissions_reset_session_approvals_result, permissions_set_allow_all_request, permissions_set_approve_all_request, permissions_set_approve_all_result, permissions_set_approve_all_source, permissions_set_required_request, permissions_set_required_result, permissions_urls_set_unrestricted_mode_result, permission_urls_config, permission_urls_set_unrestricted_mode_params, ping_request, ping_result, plan_read_result, plan_update_request, plugin, plugin_list, queued_command_handled, queued_command_not_handled, queued_command_result, queue_pending_items, queue_pending_items_kind, queue_pending_items_result, queue_remove_most_recent_result, register_event_interest_params, register_event_interest_result, release_event_interest_params, remote_enable_request, remote_enable_result, remote_notify_steerable_changed_request, remote_notify_steerable_changed_result, remote_session_connection_result, remote_session_mode, schedule_entry, schedule_list, schedule_stop_request, schedule_stop_result, secrets_add_filter_values_request, secrets_add_filter_values_result, send_agent_mode, send_attachment, send_attachment_blob, send_attachment_directory, send_attachment_file, send_attachment_file_line_range, send_attachment_github_reference, send_attachment_github_reference_type, send_attachment_selection, send_attachment_selection_details, send_attachment_selection_details_end, send_attachment_selection_details_start, send_mode, send_request, send_result, server_skill, server_skill_list, session_auth_status, session_bulk_delete_result, session_context, session_context_host_type, session_enrich_metadata_result, session_fs_append_file_request, session_fs_error, session_fs_error_code, session_fs_exists_request, session_fs_exists_result, session_fs_mkdir_request, session_fs_readdir_request, session_fs_readdir_result, session_fs_readdir_with_types_entry, session_fs_readdir_with_types_entry_type, session_fs_readdir_with_types_request, session_fs_readdir_with_types_result, session_fs_read_file_request, session_fs_read_file_result, session_fs_rename_request, session_fs_rm_request, session_fs_set_provider_capabilities, session_fs_set_provider_conventions, session_fs_set_provider_request, session_fs_set_provider_result, session_fs_sqlite_exists_request, session_fs_sqlite_exists_result, session_fs_sqlite_query_request, session_fs_sqlite_query_result, session_fs_sqlite_query_type, session_fs_stat_request, session_fs_stat_result, session_fs_write_file_request, session_installed_plugin, session_installed_plugin_source, session_installed_plugin_source_github, session_installed_plugin_source_local, session_installed_plugin_source_url, session_list, session_list_filter, session_load_deferred_repo_hooks_result, session_log_level, session_mcp_apps_call_tool_result, session_metadata, session_metadata_snapshot, session_mode, session_prune_result, sessions_bulk_delete_request, sessions_check_in_use_request, sessions_check_in_use_result, sessions_close_request, sessions_close_result, sessions_enrich_metadata_request, session_set_credentials_params, session_set_credentials_result, sessions_find_by_prefix_request, sessions_find_by_prefix_result, sessions_find_by_task_id_request, sessions_find_by_task_id_result, sessions_fork_request, sessions_fork_result, sessions_get_event_file_path_request, sessions_get_event_file_path_result, sessions_get_last_for_context_request, sessions_get_last_for_context_result, sessions_get_persisted_remote_steerable_request, sessions_get_persisted_remote_steerable_result, session_sizes, sessions_list_request, sessions_load_deferred_repo_hooks_request, sessions_prune_old_request, sessions_release_lock_request, sessions_release_lock_result, sessions_reload_plugin_hooks_request, sessions_reload_plugin_hooks_result, sessions_save_request, sessions_save_result, sessions_set_additional_plugins_request, sessions_set_additional_plugins_result, session_update_options_params, session_update_options_result, session_working_directory_context, session_working_directory_context_host_type, shell_exec_request, shell_exec_result, shell_kill_request, shell_kill_result, shell_kill_signal, shutdown_request, skill, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_invoked_result, skills_invoked_skill, skills_load_diagnostics, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_select_subcommand_option, slash_command_select_subcommand_result, slash_command_text_result, task_agent_info, task_agent_progress, task_execution_mode, task_info, task_list, task_progress_line, tasks_cancel_request, tasks_cancel_result, tasks_get_current_promotable_result, tasks_get_progress_request, tasks_get_progress_result, task_shell_info, task_shell_info_attachment_mode, task_shell_progress, tasks_promote_current_to_background_result, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_refresh_result, tasks_remove_request, tasks_remove_result, tasks_send_message_request, tasks_send_message_result, tasks_start_agent_request, tasks_start_agent_result, task_status, tasks_wait_for_pending_result, telemetry_set_feature_overrides_request, token_auth_info, tool, tool_list, tools_initialize_and_validate_result, tools_list_request, ui_auto_mode_switch_response, ui_elicitation_array_any_of_field, ui_elicitation_array_any_of_field_items, ui_elicitation_array_any_of_field_items_any_of, ui_elicitation_array_enum_field, ui_elicitation_array_enum_field_items, ui_elicitation_field_value, ui_elicitation_request, ui_elicitation_response, ui_elicitation_response_action, ui_elicitation_response_content, ui_elicitation_result, ui_elicitation_schema, ui_elicitation_schema_property, ui_elicitation_schema_property_boolean, ui_elicitation_schema_property_number, ui_elicitation_schema_property_number_type, ui_elicitation_schema_property_string, ui_elicitation_schema_property_string_format, ui_elicitation_string_enum_field, ui_elicitation_string_one_of_field, ui_elicitation_string_one_of_field_one_of, ui_exit_plan_mode_action, ui_exit_plan_mode_response, ui_handle_pending_auto_mode_switch_request, ui_handle_pending_elicitation_request, ui_handle_pending_exit_plan_mode_request, ui_handle_pending_result, ui_handle_pending_sampling_request, ui_handle_pending_sampling_response, ui_handle_pending_user_input_request, ui_register_direct_auto_mode_switch_handler_result, ui_unregister_direct_auto_mode_switch_handler_request, ui_unregister_direct_auto_mode_switch_handler_result, ui_user_input_response, usage_get_metrics_result, usage_metrics_code_changes, usage_metrics_model_metric, usage_metrics_model_metric_requests, usage_metrics_model_metric_token_detail, usage_metrics_model_metric_usage, usage_metrics_token_detail, user_auth_info, workspace_diff_file_change, workspace_diff_file_change_type, workspace_diff_mode, workspace_diff_result, workspaces_checkpoints, workspaces_create_file_request, workspaces_diff_request, workspaces_get_workspace_result, workspaces_list_checkpoints_result, workspaces_list_files_result, workspaces_read_checkpoint_request, workspaces_read_checkpoint_result, workspaces_read_file_request, workspaces_read_file_result, workspaces_save_large_paste_request, workspaces_save_large_paste_result, workspace_summary_host_type, workspaces_workspace_details_host_type, session_context_info, task_progress, workspace_summary) + return RPC(abort_request, abort_result, account_get_quota_request, account_get_quota_result, account_quota_snapshot, agent_get_current_result, agent_info, agent_info_source, agent_list, agent_registry_live_target_entry, agent_registry_live_target_entry_attention_kind, agent_registry_live_target_entry_kind, agent_registry_live_target_entry_last_terminal_event, agent_registry_live_target_entry_status, agent_registry_log_capture, agent_registry_log_capture_open_error_reason, agent_registry_spawn_error, agent_registry_spawn_permission_mode, agent_registry_spawn_registry_timeout, agent_registry_spawn_request, agent_registry_spawn_result, agent_registry_spawn_spawned, agent_registry_spawn_validation_error, agent_registry_spawn_validation_error_field, agent_registry_spawn_validation_error_reason, agent_reload_result, agent_select_request, agent_select_result, allow_all_permission_set_result, allow_all_permission_state, api_key_auth_info, auth_info, auth_info_type, canvas_action, canvas_close_request, canvas_host_context, canvas_host_context_capabilities, canvas_instance_availability, canvas_invoke_action_request, canvas_invoke_action_result, canvas_json_schema, canvas_list, canvas_list_open_result, canvas_open_request, canvas_provider_close_request, canvas_provider_invoke_action_request, canvas_provider_open_request, canvas_provider_open_result, canvas_session_context, command_list, commands_handle_pending_command_request, commands_handle_pending_command_result, commands_invoke_request, commands_list_request, commands_respond_to_queued_command_request, commands_respond_to_queued_command_result, connected_remote_session_metadata, connected_remote_session_metadata_kind, connected_remote_session_metadata_repository, connect_remote_session_params, connect_request, connect_result, content_filter_mode, copilot_api_token_auth_info, copilot_user_response, copilot_user_response_endpoints, copilot_user_response_quota_snapshots, copilot_user_response_quota_snapshots_chat, copilot_user_response_quota_snapshots_completions, copilot_user_response_quota_snapshots_premium_interactions, current_model, discovered_canvas, discovered_mcp_server, discovered_mcp_server_type, enqueue_command_params, enqueue_command_result, env_auth_info, event_log_read_request, event_log_release_interest_result, event_log_tail_result, event_log_types, events_agent_scope, events_cursor_status, events_read_result, execute_command_params, execute_command_result, extension, extension_list, extensions_disable_request, extensions_enable_request, extension_source, extension_status, external_tool_result, external_tool_text_result_for_llm, external_tool_text_result_for_llm_binary_results_for_llm, external_tool_text_result_for_llm_binary_results_for_llm_type, external_tool_text_result_for_llm_content, external_tool_text_result_for_llm_content_audio, external_tool_text_result_for_llm_content_image, external_tool_text_result_for_llm_content_resource, external_tool_text_result_for_llm_content_resource_details, external_tool_text_result_for_llm_content_resource_link, external_tool_text_result_for_llm_content_resource_link_icon, external_tool_text_result_for_llm_content_resource_link_icon_theme, external_tool_text_result_for_llm_content_terminal, external_tool_text_result_for_llm_content_text, filter_mapping, fleet_start_request, fleet_start_result, folder_trust_add_params, folder_trust_check_params, folder_trust_check_result, gh_cli_auth_info, handle_pending_tool_call_request, handle_pending_tool_call_result, history_abort_manual_compaction_result, history_cancel_background_compaction_result, history_compact_context_window, history_compact_request, history_compact_result, history_summarize_for_handoff_result, history_truncate_request, history_truncate_result, hmac_auth_info, installed_plugin, installed_plugin_source, installed_plugin_source_github, installed_plugin_source_local, installed_plugin_source_url, instructions_get_sources_result, instructions_sources, instructions_sources_location, instructions_sources_type, log_request, log_result, lsp_initialize_request, mcp_apps_call_tool_request, mcp_apps_diagnose_capability, mcp_apps_diagnose_request, mcp_apps_diagnose_result, mcp_apps_diagnose_server, mcp_apps_host_context, mcp_apps_host_context_details, mcp_apps_host_context_details_available_display_mode, mcp_apps_host_context_details_display_mode, mcp_apps_host_context_details_platform, mcp_apps_host_context_details_theme, mcp_apps_list_tools_request, mcp_apps_list_tools_result, mcp_apps_read_resource_request, mcp_apps_read_resource_result, mcp_apps_resource_content, mcp_apps_set_host_context_details, mcp_apps_set_host_context_details_available_display_mode, mcp_apps_set_host_context_details_display_mode, mcp_apps_set_host_context_details_platform, mcp_apps_set_host_context_details_theme, mcp_apps_set_host_context_request, mcp_cancel_sampling_execution_params, mcp_cancel_sampling_execution_result, mcp_config_add_request, mcp_config_disable_request, mcp_config_enable_request, mcp_config_list, mcp_config_remove_request, mcp_config_update_request, mcp_disable_request, mcp_discover_request, mcp_discover_result, mcp_enable_request, mcp_execute_sampling_params, mcp_execute_sampling_request, mcp_execute_sampling_result, mcp_oauth_login_request, mcp_oauth_login_result, mcp_remove_git_hub_result, mcp_sampling_execution_action, mcp_sampling_execution_result, mcp_server, mcp_server_auth_config, mcp_server_auth_config_redirect_port, mcp_server_config, mcp_server_config_http, mcp_server_config_http_oauth_grant_type, mcp_server_config_http_type, mcp_server_config_stdio, mcp_server_list, mcp_set_env_value_mode_details, mcp_set_env_value_mode_params, mcp_set_env_value_mode_result, metadata_context_info_request, metadata_context_info_result, metadata_is_processing_result, metadata_recompute_context_tokens_request, metadata_recompute_context_tokens_result, metadata_record_context_change_request, metadata_record_context_change_result, metadata_set_working_directory_request, metadata_set_working_directory_result, metadata_snapshot_current_mode, metadata_snapshot_remote_metadata, metadata_snapshot_remote_metadata_repository, metadata_snapshot_remote_metadata_task_type, model, model_billing, model_billing_token_prices, model_billing_token_prices_long_context, model_capabilities, model_capabilities_limits, model_capabilities_limits_vision, model_capabilities_override, model_capabilities_override_limits, model_capabilities_override_limits_vision, model_capabilities_override_supports, model_capabilities_supports, model_list, model_picker_category, model_picker_price_category, model_policy, model_policy_state, model_set_reasoning_effort_request, model_set_reasoning_effort_result, models_list_request, model_switch_to_request, model_switch_to_result, mode_set_request, name_get_result, name_set_auto_request, name_set_auto_result, name_set_request, open_canvas_instance, options_update_env_value_mode, options_update_tool_filter_precedence, pending_permission_request, pending_permission_request_list, permission_decision, permission_decision_approved, permission_decision_approved_for_location, permission_decision_approved_for_session, permission_decision_approve_for_location, permission_decision_approve_for_location_approval, permission_decision_approve_for_location_approval_commands, permission_decision_approve_for_location_approval_custom_tool, permission_decision_approve_for_location_approval_extension_management, permission_decision_approve_for_location_approval_extension_permission_access, permission_decision_approve_for_location_approval_mcp, permission_decision_approve_for_location_approval_mcp_sampling, permission_decision_approve_for_location_approval_memory, permission_decision_approve_for_location_approval_read, permission_decision_approve_for_location_approval_write, permission_decision_approve_for_session, permission_decision_approve_for_session_approval, permission_decision_approve_for_session_approval_commands, permission_decision_approve_for_session_approval_custom_tool, permission_decision_approve_for_session_approval_extension_management, permission_decision_approve_for_session_approval_extension_permission_access, permission_decision_approve_for_session_approval_mcp, permission_decision_approve_for_session_approval_mcp_sampling, permission_decision_approve_for_session_approval_memory, permission_decision_approve_for_session_approval_read, permission_decision_approve_for_session_approval_write, permission_decision_approve_once, permission_decision_approve_permanently, permission_decision_cancelled, permission_decision_denied_by_content_exclusion_policy, permission_decision_denied_by_permission_request_hook, permission_decision_denied_by_rules, permission_decision_denied_interactively_by_user, permission_decision_denied_no_approval_rule_and_could_not_request_from_user, permission_decision_reject, permission_decision_request, permission_decision_user_not_available, permission_location_add_tool_approval_params, permission_location_apply_params, permission_location_apply_result, permission_location_resolve_params, permission_location_resolve_result, permission_location_type, permission_paths_add_params, permission_paths_allowed_check_params, permission_paths_allowed_check_result, permission_paths_config, permission_paths_list, permission_paths_update_primary_params, permission_paths_workspace_check_params, permission_paths_workspace_check_result, permission_prompt_shown_notification, permission_request_result, permission_rules_set, permissions_configure_additional_content_exclusion_policy, permissions_configure_additional_content_exclusion_policy_rule, permissions_configure_additional_content_exclusion_policy_rule_source, permissions_configure_additional_content_exclusion_policy_scope, permissions_configure_params, permissions_configure_result, permissions_folder_trust_add_trusted_result, permissions_get_allow_all_request, permissions_locations_add_tool_approval_details, permissions_locations_add_tool_approval_details_commands, permissions_locations_add_tool_approval_details_custom_tool, permissions_locations_add_tool_approval_details_extension_management, permissions_locations_add_tool_approval_details_extension_permission_access, permissions_locations_add_tool_approval_details_mcp, permissions_locations_add_tool_approval_details_mcp_sampling, permissions_locations_add_tool_approval_details_memory, permissions_locations_add_tool_approval_details_read, permissions_locations_add_tool_approval_details_write, permissions_locations_add_tool_approval_result, permissions_modify_rules_params, permissions_modify_rules_result, permissions_modify_rules_scope, permissions_notify_prompt_shown_result, permissions_paths_add_result, permissions_paths_list_request, permissions_paths_update_primary_result, permissions_pending_requests_request, permissions_reset_session_approvals_request, permissions_reset_session_approvals_result, permissions_set_allow_all_request, permissions_set_approve_all_request, permissions_set_approve_all_result, permissions_set_approve_all_source, permissions_set_required_request, permissions_set_required_result, permissions_urls_set_unrestricted_mode_result, permission_urls_config, permission_urls_set_unrestricted_mode_params, ping_request, ping_result, plan_read_result, plan_update_request, plugin, plugin_list, queued_command_handled, queued_command_not_handled, queued_command_result, queue_pending_items, queue_pending_items_kind, queue_pending_items_result, queue_remove_most_recent_result, register_event_interest_params, register_event_interest_result, release_event_interest_params, remote_enable_request, remote_enable_result, remote_notify_steerable_changed_request, remote_notify_steerable_changed_result, remote_session_connection_result, remote_session_mode, schedule_entry, schedule_list, schedule_stop_request, schedule_stop_result, secrets_add_filter_values_request, secrets_add_filter_values_result, send_agent_mode, send_attachment, send_attachment_blob, send_attachment_directory, send_attachment_file, send_attachment_file_line_range, send_attachment_github_reference, send_attachment_github_reference_type, send_attachment_selection, send_attachment_selection_details, send_attachment_selection_details_end, send_attachment_selection_details_start, send_mode, send_request, send_result, server_skill, server_skill_list, session_auth_status, session_bulk_delete_result, session_context, session_context_host_type, session_enrich_metadata_result, session_fs_append_file_request, session_fs_error, session_fs_error_code, session_fs_exists_request, session_fs_exists_result, session_fs_mkdir_request, session_fs_readdir_request, session_fs_readdir_result, session_fs_readdir_with_types_entry, session_fs_readdir_with_types_entry_type, session_fs_readdir_with_types_request, session_fs_readdir_with_types_result, session_fs_read_file_request, session_fs_read_file_result, session_fs_rename_request, session_fs_rm_request, session_fs_set_provider_capabilities, session_fs_set_provider_conventions, session_fs_set_provider_request, session_fs_set_provider_result, session_fs_sqlite_exists_request, session_fs_sqlite_exists_result, session_fs_sqlite_query_request, session_fs_sqlite_query_result, session_fs_sqlite_query_type, session_fs_stat_request, session_fs_stat_result, session_fs_write_file_request, session_installed_plugin, session_installed_plugin_source, session_installed_plugin_source_github, session_installed_plugin_source_local, session_installed_plugin_source_url, session_list, session_list_filter, session_load_deferred_repo_hooks_result, session_log_level, session_mcp_apps_call_tool_result, session_metadata, session_metadata_snapshot, session_mode, session_prune_result, sessions_bulk_delete_request, sessions_check_in_use_request, sessions_check_in_use_result, sessions_close_request, sessions_close_result, sessions_enrich_metadata_request, session_set_credentials_params, session_set_credentials_result, sessions_find_by_prefix_request, sessions_find_by_prefix_result, sessions_find_by_task_id_request, sessions_find_by_task_id_result, sessions_fork_request, sessions_fork_result, sessions_get_event_file_path_request, sessions_get_event_file_path_result, sessions_get_last_for_context_request, sessions_get_last_for_context_result, sessions_get_persisted_remote_steerable_request, sessions_get_persisted_remote_steerable_result, session_sizes, sessions_list_request, sessions_load_deferred_repo_hooks_request, sessions_prune_old_request, sessions_release_lock_request, sessions_release_lock_result, sessions_reload_plugin_hooks_request, sessions_reload_plugin_hooks_result, sessions_save_request, sessions_save_result, sessions_set_additional_plugins_request, sessions_set_additional_plugins_result, session_update_options_params, session_update_options_result, session_working_directory_context, session_working_directory_context_host_type, shell_exec_request, shell_exec_result, shell_kill_request, shell_kill_result, shell_kill_signal, shutdown_request, skill, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_invoked_result, skills_invoked_skill, skills_load_diagnostics, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_select_subcommand_option, slash_command_select_subcommand_result, slash_command_text_result, task_agent_info, task_agent_progress, task_execution_mode, task_info, task_list, task_progress_line, tasks_cancel_request, tasks_cancel_result, tasks_get_current_promotable_result, tasks_get_progress_request, tasks_get_progress_result, task_shell_info, task_shell_info_attachment_mode, task_shell_progress, tasks_promote_current_to_background_result, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_refresh_result, tasks_remove_request, tasks_remove_result, tasks_send_message_request, tasks_send_message_result, tasks_start_agent_request, tasks_start_agent_result, task_status, tasks_wait_for_pending_result, telemetry_set_feature_overrides_request, token_auth_info, tool, tool_list, tools_initialize_and_validate_result, tools_list_request, ui_auto_mode_switch_response, ui_elicitation_array_any_of_field, ui_elicitation_array_any_of_field_items, ui_elicitation_array_any_of_field_items_any_of, ui_elicitation_array_enum_field, ui_elicitation_array_enum_field_items, ui_elicitation_field_value, ui_elicitation_request, ui_elicitation_response, ui_elicitation_response_action, ui_elicitation_response_content, ui_elicitation_result, ui_elicitation_schema, ui_elicitation_schema_property, ui_elicitation_schema_property_boolean, ui_elicitation_schema_property_number, ui_elicitation_schema_property_number_type, ui_elicitation_schema_property_string, ui_elicitation_schema_property_string_format, ui_elicitation_string_enum_field, ui_elicitation_string_one_of_field, ui_elicitation_string_one_of_field_one_of, ui_exit_plan_mode_action, ui_exit_plan_mode_response, ui_handle_pending_auto_mode_switch_request, ui_handle_pending_elicitation_request, ui_handle_pending_exit_plan_mode_request, ui_handle_pending_result, ui_handle_pending_sampling_request, ui_handle_pending_sampling_response, ui_handle_pending_user_input_request, ui_register_direct_auto_mode_switch_handler_result, ui_unregister_direct_auto_mode_switch_handler_request, ui_unregister_direct_auto_mode_switch_handler_result, ui_user_input_response, usage_get_metrics_result, usage_metrics_code_changes, usage_metrics_model_metric, usage_metrics_model_metric_requests, usage_metrics_model_metric_token_detail, usage_metrics_model_metric_usage, usage_metrics_token_detail, user_auth_info, workspace_diff_file_change, workspace_diff_file_change_type, workspace_diff_mode, workspace_diff_result, workspaces_checkpoints, workspaces_create_file_request, workspaces_diff_request, workspaces_get_workspace_result, workspaces_list_checkpoints_result, workspaces_list_files_result, workspaces_read_checkpoint_request, workspaces_read_checkpoint_result, workspaces_read_file_request, workspaces_read_file_result, workspaces_save_large_paste_request, workspaces_save_large_paste_result, workspace_summary_host_type, workspaces_workspace_details_host_type, session_context_info, task_progress, workspace_summary) def to_dict(self) -> dict: result: dict = {} @@ -16769,15 +16780,13 @@ def to_dict(self) -> dict: result["McpSamplingExecutionAction"] = to_enum(MCPSamplingExecutionAction, self.mcp_sampling_execution_action) result["McpSamplingExecutionResult"] = to_class(MCPSamplingExecutionResult, self.mcp_sampling_execution_result) result["McpServer"] = to_class(MCPServer, self.mcp_server) + result["McpServerAuthConfig"] = from_union([from_bool, lambda x: to_class(MCPServerAuthConfigRedirectPort, x)], self.mcp_server_auth_config) + result["McpServerAuthConfigRedirectPort"] = to_class(MCPServerAuthConfigRedirectPort, self.mcp_server_auth_config_redirect_port) result["McpServerConfig"] = to_class(MCPServerConfig, self.mcp_server_config) result["McpServerConfigHttp"] = to_class(MCPServerConfigHTTP, self.mcp_server_config_http) - result["McpServerConfigHttpAuth"] = to_class(AuthAuth, self.mcp_server_config_http_auth) result["McpServerConfigHttpOauthGrantType"] = to_enum(MCPServerConfigHTTPOauthGrantType, self.mcp_server_config_http_oauth_grant_type) - result["McpServerConfigHttpOidc"] = from_union([from_bool, lambda x: from_dict(lambda x: x, x)], self.mcp_server_config_http_oidc) result["McpServerConfigHttpType"] = to_enum(MCPServerConfigHTTPType, self.mcp_server_config_http_type) result["McpServerConfigStdio"] = to_class(MCPServerConfigStdio, self.mcp_server_config_stdio) - result["McpServerConfigStdioAuth"] = from_union([from_bool, lambda x: from_dict(lambda x: x, x)], self.mcp_server_config_stdio_auth) - result["McpServerConfigStdioOidc"] = from_union([from_bool, lambda x: from_dict(lambda x: x, x)], self.mcp_server_config_stdio_oidc) result["McpServerList"] = to_class(MCPServerList, self.mcp_server_list) result["McpSetEnvValueModeDetails"] = to_enum(MCPSetEnvValueModeDetails, self.mcp_set_env_value_mode_details) result["McpSetEnvValueModeParams"] = to_class(MCPSetEnvValueModeParams, self.mcp_set_env_value_mode_params) @@ -16824,6 +16833,7 @@ def to_dict(self) -> dict: result["NameSetRequest"] = to_class(NameSetRequest, self.name_set_request) result["OpenCanvasInstance"] = to_class(OpenCanvasInstance, self.open_canvas_instance) result["OptionsUpdateEnvValueMode"] = to_enum(MCPSetEnvValueModeDetails, self.options_update_env_value_mode) + result["OptionsUpdateToolFilterPrecedence"] = to_enum(OptionsUpdateToolFilterPrecedence, self.options_update_tool_filter_precedence) result["PendingPermissionRequest"] = to_class(PendingPermissionRequest, self.pending_permission_request) result["PendingPermissionRequestList"] = to_class(PendingPermissionRequestList, self.pending_permission_request_list) result["PermissionDecision"] = (self.permission_decision).to_dict() @@ -17361,10 +17371,7 @@ def _load_TaskInfo(obj: Any) -> "TaskInfo": McpAppsSetHostContextDetailsTheme = Theme McpExecuteSamplingRequest = dict McpExecuteSamplingResult = dict -McpServerConfigHttpAuth = AuthAuth -McpServerConfigHttpOidc = bool -McpServerConfigStdioAuth = bool -McpServerConfigStdioOidc = bool +McpServerAuthConfig = bool OptionsUpdateEnvValueMode = MCPSetEnvValueModeDetails SessionContextHostType = HostType SessionMcpAppsCallToolResult = dict diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index fcef87982..184f5bf40 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -3301,10 +3301,10 @@ pub struct McpServer { pub status: McpServerStatus, } -/// Additional authentication configuration for this server. +/// Authentication settings with optional redirect port configuration. #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct McpServerConfigHttpAuth { +pub struct McpServerAuthConfigRedirectPort { /// Fixed port for the OAuth redirect callback server. #[serde(skip_serializing_if = "Option::is_none")] pub redirect_port: Option, @@ -3314,9 +3314,9 @@ pub struct McpServerConfigHttpAuth { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct McpServerConfigHttp { - /// Additional authentication configuration for this server. + /// Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. #[serde(skip_serializing_if = "Option::is_none")] - pub auth: Option, + pub auth: Option, /// Content filtering mode to apply to all tools, or a map of tool name to content filtering mode. #[serde(skip_serializing_if = "Option::is_none")] pub filter_mapping: Option, @@ -3335,7 +3335,7 @@ pub struct McpServerConfigHttp { /// Whether the configured OAuth client is public and does not require a client secret. #[serde(skip_serializing_if = "Option::is_none")] pub oauth_public_client: Option, - /// OIDC token configuration. When truthy, a token is automatically gathered. + /// Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. #[serde(skip_serializing_if = "Option::is_none")] pub oidc: Option, /// Timeout in milliseconds for tool calls to this server. @@ -3358,7 +3358,7 @@ pub struct McpServerConfigStdio { /// Command-line arguments passed to the Stdio MCP server process. #[serde(default)] pub args: Vec, - /// Authentication configuration for this server. + /// Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. #[serde(skip_serializing_if = "Option::is_none")] pub auth: Option, /// Executable command used to start the Stdio MCP server process. @@ -3375,7 +3375,7 @@ pub struct McpServerConfigStdio { /// Whether this server is a built-in fallback used when the user has not configured their own server. #[serde(skip_serializing_if = "Option::is_none")] pub is_default_server: Option, - /// OIDC token configuration. When truthy, a token is automatically gathered. + /// Set to `true` to use defaults, or provide an object with additional auth or OIDC settings. #[serde(skip_serializing_if = "Option::is_none")] pub oidc: Option, /// Timeout in milliseconds for tool calls to this server. @@ -7635,6 +7635,9 @@ pub struct SessionUpdateOptionsParams { /// Whether to skip loading custom instruction sources. #[serde(skip_serializing_if = "Option::is_none")] pub skip_custom_instructions: Option, + /// Controls how availableTools (allowlist) and excludedTools (denylist) combine when both are set. + #[serde(skip_serializing_if = "Option::is_none")] + pub tool_filter_precedence: Option, /// Optional path for trajectory output. #[serde(skip_serializing_if = "Option::is_none")] pub trajectory_file: Option, @@ -13742,6 +13745,28 @@ pub enum OptionsUpdateEnvValueMode { Unknown, } +/// Controls how availableTools (allowlist) and excludedTools (denylist) combine when both are set. +/// +///
+/// +/// **Experimental.** This type is part of an experimental wire-protocol surface +/// and may change or be removed in future SDK or CLI releases. +/// +///
+#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum OptionsUpdateToolFilterPrecedence { + /// If availableTools is set, it is the only constraint that applies (excludedTools is ignored). Preserves CLI / pre-existing client behavior. Default. + #[serde(rename = "available")] + Available, + /// A tool is enabled if and only if it matches the allowlist (or the allowlist is unset) AND it does not match the denylist. Makes 'all except X' expressible by combining the two lists. + #[serde(rename = "excluded")] + Excluded, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + /// Approve this single request only #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum PermissionDecisionApproveOnceKind { diff --git a/test/harness/package-lock.json b/test/harness/package-lock.json index 903a12d1a..fea6ff417 100644 --- a/test/harness/package-lock.json +++ b/test/harness/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "devDependencies": { - "@github/copilot": "^1.0.55-4", + "@github/copilot": "^1.0.55-5", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "@types/node-forge": "^1.3.14", @@ -464,9 +464,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.55-4.tgz", - "integrity": "sha512-998fK3QIrajrUV94l8piSjDD8wnOGosCWE/0YBKoyOhvlqAKAN0smmgizu4unj8fGZKaX1uBNT+qOrxAS9tY/g==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.55-5.tgz", + "integrity": "sha512-n6Vr876Iz41PW8pSpOa7SbrNCqaV+6HDLNf/n8V4gIwwlOlIz7Jb00r/fboXZFIT+0dyAGGLoGgd7xUujVL/Xw==", "dev": true, "license": "SEE LICENSE IN LICENSE.md", "dependencies": { @@ -476,20 +476,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.55-4", - "@github/copilot-darwin-x64": "1.0.55-4", - "@github/copilot-linux-arm64": "1.0.55-4", - "@github/copilot-linux-x64": "1.0.55-4", - "@github/copilot-linuxmusl-arm64": "1.0.55-4", - "@github/copilot-linuxmusl-x64": "1.0.55-4", - "@github/copilot-win32-arm64": "1.0.55-4", - "@github/copilot-win32-x64": "1.0.55-4" + "@github/copilot-darwin-arm64": "1.0.55-5", + "@github/copilot-darwin-x64": "1.0.55-5", + "@github/copilot-linux-arm64": "1.0.55-5", + "@github/copilot-linux-x64": "1.0.55-5", + "@github/copilot-linuxmusl-arm64": "1.0.55-5", + "@github/copilot-linuxmusl-x64": "1.0.55-5", + "@github/copilot-win32-arm64": "1.0.55-5", + "@github/copilot-win32-x64": "1.0.55-5" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.55-4.tgz", - "integrity": "sha512-byEpmUpmFnVfDNONaseG/hKBqQWnyRElViu1d+MpoupzOHlfo8/O2ZA7Fq8RkkqrXcCipjhUDBNavdl7j6EbrA==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.55-5.tgz", + "integrity": "sha512-Mult62GJVnxR3MOP2QNiVU5RRGXPJ+7BpjEMIvkoaMuWX6J7F4bz7N+HUXVHJUiGUp3hnL3M16kjkewWfNdoNg==", "cpu": [ "arm64" ], @@ -504,9 +504,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.55-4.tgz", - "integrity": "sha512-4/+tldImEu4tLo9x+wiY/7pnOLlJ8GkgUG23izMqIQ1I9otM85irfIrtNHy/bvvT+RQ/HYikNlGv00H2nhIuhw==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.55-5.tgz", + "integrity": "sha512-IfY3WhNvHwXHldI2ARsiAYuPlKWlI07Fo1ALq+SViHhn0Zfp2yIr9laJRofyj0G1EbyUxkbNlqQm7UrXhkEVeg==", "cpu": [ "x64" ], @@ -521,9 +521,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.55-4.tgz", - "integrity": "sha512-LwDvphIUMs94HShErbDu0foeasqi/IqIUDo4azWqUFrAp4n4jsiH3MBpC8UwvlSBJSSsND3zGxMrCD/fptqWjA==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.55-5.tgz", + "integrity": "sha512-UPZ5Y5QotcZvo3f4yFwJVOtAgUT3mq+q2fim82kWa/MA0+EkkADZ3kb+R4OnV1Nqv5EaoZiCFh0Ukk++IMSYwQ==", "cpu": [ "arm64" ], @@ -538,9 +538,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.55-4.tgz", - "integrity": "sha512-lp8Ae3V/8hB6HuUdWGrdm8au+HyfkFzrvf/rxk7YJe+zkq4D0O+WLi/7JbG8oZ5spQhzSyac/9gUu830nQu2WA==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.55-5.tgz", + "integrity": "sha512-Fdwiir53Ogg8C9xv6sTc7/C4vFfQHt6VWFB74kojbDgIbYEpm57wNygQVwJvrwtVW3w/b1MLtGGTp7pEvUBACQ==", "cpu": [ "x64" ], @@ -555,9 +555,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.55-4.tgz", - "integrity": "sha512-4xJCXKHw9OZba+1ysUNxcdkRXK4Mf6s8VA9klcCAnY4bSvkTDVNQVGQuonxjvLGjagyORLymINbKRg6GnrKK/Q==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.55-5.tgz", + "integrity": "sha512-NqPmeAA1+iI8Xd4wJUHNNCmVTmHCl+R3nqdXhEVQDLIau9ouGqGGay/91d2ZIgFXJn7J0UTAEdHbdBcfhbnhvg==", "cpu": [ "arm64" ], @@ -572,9 +572,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.55-4.tgz", - "integrity": "sha512-z3U6LsXcBssAeolWNlcw+nUm3cSKHvYDSGynvdYVORaEMNN/qemx4ICRAFNfTVRmP+t/3IWtTpCtHm2U7pSO9A==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.55-5.tgz", + "integrity": "sha512-bOB4vKw1R7Mekn8z34xpNViYUQ4LQAEFzpkyxhc0uOliFmfku/YcIgo42aMWFzf/Bi3iBazBNfCN+L2lz/Jc9A==", "cpu": [ "x64" ], @@ -589,9 +589,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.55-4.tgz", - "integrity": "sha512-j2kqG0c2JJvOZS2O5E/Ye8F6htA7o7UHpJ55vH6USfzColL0YI51yrP3fZVrDC0nhhtfLnVBK6Q0nv+riZnaew==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.55-5.tgz", + "integrity": "sha512-pR2KaiXUanjxolaWgRPlFdeTEpb7jcN1Rk8xVnBCD2ORwERXdYrqXaLCyDbgdplI9mI6IjM+kkUbyXzXoWz/HQ==", "cpu": [ "arm64" ], @@ -606,9 +606,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.55-4", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.55-4.tgz", - "integrity": "sha512-4za8pRAEO6z9SOPP3IYVpZHn4yvPtjAMH17XKYEVYFHTZ+NNHjzYYfyqwhZfJlGgvOOkuh3kYbNWms5a2DW/Jg==", + "version": "1.0.55-5", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.55-5.tgz", + "integrity": "sha512-EuQBgqSnRFjavgeFifbnSYUJ4elTQBLC/kf+WHolrHR2oUGyiqCQZz/cV2DYVSLP1TGxDKAV4AQCM1AdUT1xEA==", "cpu": [ "x64" ], diff --git a/test/harness/package.json b/test/harness/package.json index 3b1c589fe..29c0603a9 100644 --- a/test/harness/package.json +++ b/test/harness/package.json @@ -11,7 +11,7 @@ "test": "vitest run" }, "devDependencies": { - "@github/copilot": "^1.0.55-4", + "@github/copilot": "^1.0.55-5", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "@types/node-forge": "^1.3.14", From 799a7159484c79b6bb29b535d433ac08fd4f529d Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 27 May 2026 13:13:00 -0400 Subject: [PATCH 2/2] Fix flaky E2E CI tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/test/E2E/SessionE2ETests.cs | 23 +-- go/internal/e2e/session_e2e_test.go | 11 +- nodejs/test/e2e/session.e2e.test.ts | 55 +++---- python/e2e/test_multi_client_e2e.py | 215 +++++++++++++++++----------- python/e2e/test_session_e2e.py | 18 +-- 5 files changed, 186 insertions(+), 136 deletions(-) diff --git a/dotnet/test/E2E/SessionE2ETests.cs b/dotnet/test/E2E/SessionE2ETests.cs index 77827f413..fa56415b5 100644 --- a/dotnet/test/E2E/SessionE2ETests.cs +++ b/dotnet/test/E2E/SessionE2ETests.cs @@ -110,16 +110,19 @@ public async Task Should_Create_A_Session_With_Customized_SystemMessage_Config() } }); - await session.SendAsync(new MessageOptions { Prompt = "Who are you?" }); - var assistantMessage = await TestHelper.GetFinalAssistantMessageAsync(session); - Assert.NotNull(assistantMessage); - - var traffic = await Ctx.GetExchangesAsync(); - Assert.NotEmpty(traffic); - var systemMessage = GetSystemMessage(traffic[0]); - Assert.Contains(customTone, systemMessage); - Assert.Contains(appendedContent, systemMessage); - Assert.DoesNotContain("", systemMessage); + try + { + await session.SendAsync(new MessageOptions { Prompt = "Who are you?" }); + var traffic = await WaitForExchangesAsync(); + var systemMessage = GetSystemMessage(traffic[0]); + Assert.Contains(customTone, systemMessage); + Assert.Contains(appendedContent, systemMessage); + Assert.DoesNotContain("", systemMessage); + } + finally + { + await session.DisposeAsync(); + } } [Fact] diff --git a/go/internal/e2e/session_e2e_test.go b/go/internal/e2e/session_e2e_test.go index ab4d9fab4..c2b9f57c9 100644 --- a/go/internal/e2e/session_e2e_test.go +++ b/go/internal/e2e/session_e2e_test.go @@ -209,20 +209,15 @@ func TestSessionE2E(t *testing.T) { if err != nil { t.Fatalf("Failed to create session: %v", err) } + t.Cleanup(func() { _ = session.Disconnect() }) - _, err = session.SendAndWait(t.Context(), copilot.MessageOptions{Prompt: "Who are you?"}) + _, err = session.Send(t.Context(), copilot.MessageOptions{Prompt: "Who are you?"}) if err != nil { t.Fatalf("Failed to send message: %v", err) } // Validate the system message sent to the model - traffic, err := ctx.GetExchanges() - if err != nil { - t.Fatalf("Failed to get exchanges: %v", err) - } - if len(traffic) == 0 { - t.Fatal("Expected at least one exchange") - } + traffic := ctx.WaitForExchanges(t, 1) systemMessage := getSystemMessage(traffic[0]) if !strings.Contains(systemMessage, customTone) { t.Errorf("Expected system message to contain custom tone, got %q", systemMessage) diff --git a/nodejs/test/e2e/session.e2e.test.ts b/nodejs/test/e2e/session.e2e.test.ts index b529eb2bd..5e7766752 100644 --- a/nodejs/test/e2e/session.e2e.test.ts +++ b/nodejs/test/e2e/session.e2e.test.ts @@ -212,32 +212,39 @@ describe("Sessions", async () => { expect(systemMessage).toEqual(testSystemMessage); // Exact match }); - it("should create a session with customized systemMessage config", async () => { - const customTone = "Respond in a warm, professional tone. Be thorough in explanations."; - const appendedContent = "Always mention quarterly earnings."; - const session = await client.createSession({ - onPermissionRequest: approveAll, - systemMessage: { - mode: "customize", - sections: { - tone: { action: "replace", content: customTone }, - code_change_rules: { action: "remove" }, + it( + "should create a session with customized systemMessage config", + { timeout: 90_000 }, + async () => { + const customTone = "Respond in a warm, professional tone. Be thorough in explanations."; + const appendedContent = "Always mention quarterly earnings."; + const session = await client.createSession({ + onPermissionRequest: approveAll, + systemMessage: { + mode: "customize", + sections: { + tone: { action: "replace", content: customTone }, + code_change_rules: { action: "remove" }, + }, + content: appendedContent, }, - content: appendedContent, - }, - }); - - const assistantMessage = await session.sendAndWait({ prompt: "Who are you?" }); - expect(assistantMessage?.data.content).toBeDefined(); + }); - // Validate the system message sent to the model - const traffic = await openAiEndpoint.getExchanges(); - const systemMessage = getSystemMessage(traffic[0]); - expect(systemMessage).toContain(customTone); - expect(systemMessage).toContain(appendedContent); - // The code_change_rules section should have been removed - expect(systemMessage).not.toContain(""); - }); + try { + await session.send({ prompt: "Who are you?" }); + + // Validate the system message sent to the model + const traffic = await waitForExchanges(); + const systemMessage = getSystemMessage(traffic[0]); + expect(systemMessage).toContain(customTone); + expect(systemMessage).toContain(appendedContent); + // The code_change_rules section should have been removed + expect(systemMessage).not.toContain(""); + } finally { + await session.disconnect(); + } + } + ); it("should create a session with availableTools", async () => { const session = await client.createSession({ diff --git a/python/e2e/test_multi_client_e2e.py b/python/e2e/test_multi_client_e2e.py index deadbfc86..90492e883 100644 --- a/python/e2e/test_multi_client_e2e.py +++ b/python/e2e/test_multi_client_e2e.py @@ -184,6 +184,25 @@ async def configure_multi_test(request, mctx): yield +def wait_for_event(session, predicate, timeout: float = 30.0): + loop = asyncio.get_running_loop() + future = loop.create_future() + + def on_event(event): + if not future.done() and predicate(event): + future.set_result(event) + + unsubscribe = session.on(on_event) + + async def wait(): + try: + return await asyncio.wait_for(future, timeout=timeout) + finally: + unsubscribe() + + return loop.create_task(wait()) + + class TestMultiClientBroadcast: async def test_both_clients_see_tool_request_and_completion_events( self, mctx: MultiClientContext @@ -206,30 +225,38 @@ def magic_number(params: SeedParams, invocation: ToolInvocation) -> str: session2 = await mctx.client2.resume_session( session1.session_id, on_permission_request=PermissionHandler.approve_all ) - client1_events = [] - client2_events = [] - session1.on(lambda event: client1_events.append(event)) - session2.on(lambda event: client2_events.append(event)) - - # Send a prompt that triggers the custom tool - await session1.send("Use the magic_number tool with seed 'hello' and tell me the result") - # Use a longer timeout: first multi-client TCP test on Windows CI needs extra time - response = await get_final_assistant_message(session1, timeout=30.0) - assert "MAGIC_hello_42" in (response.data.content or "") - - # Both clients should have seen the external_tool.requested event - c1_tool_requested = [e for e in client1_events if e.type.value == "external_tool.requested"] - c2_tool_requested = [e for e in client2_events if e.type.value == "external_tool.requested"] - assert len(c1_tool_requested) > 0 - assert len(c2_tool_requested) > 0 - - # Both clients should have seen the external_tool.completed event - c1_tool_completed = [e for e in client1_events if e.type.value == "external_tool.completed"] - c2_tool_completed = [e for e in client2_events if e.type.value == "external_tool.completed"] - assert len(c1_tool_completed) > 0 - assert len(c2_tool_completed) > 0 + waiters = [] + try: + client1_requested = wait_for_event( + session1, lambda event: event.type.value == "external_tool.requested" + ) + client2_requested = wait_for_event( + session2, lambda event: event.type.value == "external_tool.requested" + ) + client1_completed = wait_for_event( + session1, lambda event: event.type.value == "external_tool.completed" + ) + client2_completed = wait_for_event( + session2, lambda event: event.type.value == "external_tool.completed" + ) + waiters = [client1_requested, client2_requested, client1_completed, client2_completed] - await session2.disconnect() + # Send a prompt that triggers the custom tool + await session1.send( + "Use the magic_number tool with seed 'hello' and tell me the result" + ) + # Use a longer timeout: first multi-client TCP test on Windows CI needs extra time + response = await get_final_assistant_message(session1, timeout=30.0) + assert "MAGIC_hello_42" in (response.data.content or "") + + # Both clients should have seen the external_tool.requested and completed events + await asyncio.gather(*waiters) + finally: + for waiter in waiters: + if not waiter.done(): + waiter.cancel() + await asyncio.gather(*waiters, return_exceptions=True) + await session2.disconnect() async def test_one_client_approves_permission_and_both_see_the_result( self, mctx: MultiClientContext @@ -249,35 +276,43 @@ async def test_one_client_approves_permission_and_both_see_the_result( session1.session_id, on_permission_request=lambda request, invocation: PermissionNoResult(), ) - - client1_events = [] - client2_events = [] - session1.on(lambda event: client1_events.append(event)) - session2.on(lambda event: client2_events.append(event)) - - # Send a prompt that triggers a write operation (requires permission) - await session1.send("Create a file called hello.txt containing the text 'hello world'") - response = await get_final_assistant_message(session1) - assert response.data.content - - # Client 1 should have handled permission requests - assert len(permission_requests) > 0 - - # Both clients should have seen permission.requested events - c1_perm_requested = [e for e in client1_events if e.type.value == "permission.requested"] - c2_perm_requested = [e for e in client2_events if e.type.value == "permission.requested"] - assert len(c1_perm_requested) > 0 - assert len(c2_perm_requested) > 0 - - # Both clients should have seen permission.completed events with approved result - c1_perm_completed = [e for e in client1_events if e.type.value == "permission.completed"] - c2_perm_completed = [e for e in client2_events if e.type.value == "permission.completed"] - assert len(c1_perm_completed) > 0 - assert len(c2_perm_completed) > 0 - for event in c1_perm_completed + c2_perm_completed: - assert event.data.result.kind == "approved" - - await session2.disconnect() + waiters = [] + try: + client1_requested = wait_for_event( + session1, lambda event: event.type.value == "permission.requested" + ) + client2_requested = wait_for_event( + session2, lambda event: event.type.value == "permission.requested" + ) + client1_completed = wait_for_event( + session1, lambda event: event.type.value == "permission.completed" + ) + client2_completed = wait_for_event( + session2, lambda event: event.type.value == "permission.completed" + ) + waiters = [client1_requested, client2_requested, client1_completed, client2_completed] + + # Send a prompt that triggers a write operation (requires permission) + await session1.send("Create a file called hello.txt containing the text 'hello world'") + response = await get_final_assistant_message(session1) + assert response.data.content + + # Client 1 should have handled permission requests + assert len(permission_requests) > 0 + + # Both clients should have seen permission.requested events + await asyncio.gather(client1_requested, client2_requested) + + # Both clients should have seen permission.completed events with approved result + completed_events = await asyncio.gather(client1_completed, client2_completed) + for event in completed_events: + assert event.data.result.kind == "approved" + finally: + for waiter in waiters: + if not waiter.done(): + waiter.cancel() + await asyncio.gather(*waiters, return_exceptions=True) + await session2.disconnect() async def test_one_client_rejects_permission_and_both_see_the_result( self, mctx: MultiClientContext @@ -293,40 +328,48 @@ async def test_one_client_rejects_permission_and_both_see_the_result( session1.session_id, on_permission_request=lambda request, invocation: PermissionNoResult(), ) - - client1_events = [] - client2_events = [] - session1.on(lambda event: client1_events.append(event)) - session2.on(lambda event: client2_events.append(event)) - - # Create a file that the agent will try to edit - test_file = os.path.join(mctx.work_dir, "protected.txt") - with open(test_file, "w") as f: - f.write("protected content") - - await session1.send("Edit protected.txt and replace 'protected' with 'hacked'.") - await get_final_assistant_message(session1) - - # Verify the file was NOT modified (permission was denied) - with open(test_file) as f: - content = f.read() - assert content == "protected content" - - # Both clients should have seen permission.requested and permission.completed - c1_perm_requested = [e for e in client1_events if e.type.value == "permission.requested"] - c2_perm_requested = [e for e in client2_events if e.type.value == "permission.requested"] - assert len(c1_perm_requested) > 0 - assert len(c2_perm_requested) > 0 - - # Both clients should see the denial - c1_perm_completed = [e for e in client1_events if e.type.value == "permission.completed"] - c2_perm_completed = [e for e in client2_events if e.type.value == "permission.completed"] - assert len(c1_perm_completed) > 0 - assert len(c2_perm_completed) > 0 - for event in c1_perm_completed + c2_perm_completed: - assert event.data.result.kind == "denied-interactively-by-user" - - await session2.disconnect() + waiters = [] + try: + client1_requested = wait_for_event( + session1, lambda event: event.type.value == "permission.requested" + ) + client2_requested = wait_for_event( + session2, lambda event: event.type.value == "permission.requested" + ) + client1_completed = wait_for_event( + session1, lambda event: event.type.value == "permission.completed" + ) + client2_completed = wait_for_event( + session2, lambda event: event.type.value == "permission.completed" + ) + waiters = [client1_requested, client2_requested, client1_completed, client2_completed] + + # Create a file that the agent will try to edit + test_file = os.path.join(mctx.work_dir, "protected.txt") + with open(test_file, "w") as f: + f.write("protected content") + + await session1.send("Edit protected.txt and replace 'protected' with 'hacked'.") + await get_final_assistant_message(session1) + + # Verify the file was NOT modified (permission was denied) + with open(test_file) as f: + content = f.read() + assert content == "protected content" + + # Both clients should have seen permission.requested and permission.completed + await asyncio.gather(client1_requested, client2_requested) + + # Both clients should see the denial + completed_events = await asyncio.gather(client1_completed, client2_completed) + for event in completed_events: + assert event.data.result.kind == "denied-interactively-by-user" + finally: + for waiter in waiters: + if not waiter.done(): + waiter.cancel() + await asyncio.gather(*waiters, return_exceptions=True) + await session2.disconnect() @pytest.mark.timeout(90) async def test_two_clients_register_different_tools_and_agent_uses_both( diff --git a/python/e2e/test_session_e2e.py b/python/e2e/test_session_e2e.py index a6044a203..ddc429a2e 100644 --- a/python/e2e/test_session_e2e.py +++ b/python/e2e/test_session_e2e.py @@ -103,15 +103,17 @@ async def test_should_create_a_session_with_customized_systemMessage_config( }, ) - assistant_message = await session.send_and_wait("Who are you?") - assert assistant_message is not None + try: + await session.send("Who are you?") - # Validate the system message sent to the model - traffic = await ctx.get_exchanges() - system_message = _get_system_message(traffic[0]) - assert custom_tone in system_message - assert appended_content in system_message - assert "" not in system_message + # Validate the system message sent to the model + traffic = await ctx.wait_for_exchanges() + system_message = _get_system_message(traffic[0]) + assert custom_tone in system_message + assert appended_content in system_message + assert "" not in system_message + finally: + await session.disconnect() async def test_should_create_a_session_with_availableTools(self, ctx: E2ETestContext): session = await ctx.client.create_session(