diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index 3a9fcf9cde..ba55e09e76 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -149,6 +149,10 @@ public sealed class ModelBillingTokenPrices /// Billing information. public sealed class ModelBilling { + /// Whole-number percentage discount (0-100) applied to usage billed through this model. Populated for the synthetic `auto` model, where requests routed by auto-mode are billed at a reduced rate; absent for concrete models. + [JsonPropertyName("discountPercent")] + public int? DiscountPercent { get; set; } + /// Billing cost multiplier relative to the base rate. [JsonPropertyName("multiplier")] public double? Multiplier { get; set; } @@ -1065,6 +1069,10 @@ internal sealed class McpConfigDisableRequest [Experimental(Diagnostics.Experimental)] public sealed class InstalledPluginInfo { + /// Opaque, stable hash identifying a direct (non-marketplace) install source. Present only for direct repo / URL / local installs; absent for marketplace plugins. Same source yields the same id; distinct sources never collide. + [JsonPropertyName("directSourceId")] + public string? DirectSourceId { get; set; } + /// Whether the plugin is currently enabled for new sessions. [JsonPropertyName("enabled")] public bool Enabled { get; set; } @@ -1129,6 +1137,10 @@ internal sealed class PluginsInstallRequest [Experimental(Diagnostics.Experimental)] internal sealed class PluginsUninstallRequest { + /// Stable source identity for a direct (non-marketplace) install. Disambiguates uninstall when multiple installed plugins share the same name. + [JsonPropertyName("directSourceId")] + public string? DirectSourceId { get; set; } + /// Plugin name or "plugin@marketplace" spec to uninstall. When ambiguous, prefer the fully-qualified spec. [JsonPropertyName("name")] public string Name { get; set; } = string.Empty; @@ -3368,7 +3380,7 @@ public sealed class SessionAuthStatus /// Identifies the target session. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionAuthGetStatusRequest +internal sealed class SessionGitHubAuthGetStatusRequest { /// Target session identifier. [JsonPropertyName("sessionId")] @@ -3379,6 +3391,10 @@ internal sealed class SessionAuthGetStatusRequest [Experimental(Diagnostics.Experimental)] public sealed class SessionSetCredentialsResult { + /// Whether the session ended up with a populated `copilotUser` for the installed credentials. `true` when the supplied credential already carried `copilotUser` or it was successfully re-resolved server-side. `false` when the credential is installed without `copilotUser` — either re-resolution failed, or the variant cannot be re-resolved from the credential alone (only the raw-token variants `token`, `env`, and `gh-cli` can). In both `false` cases the token swap still applied, but plan/quota/billing metadata is degraded. Present whenever a credential was supplied; omitted only when no credential was supplied (no-op call). + [JsonPropertyName("copilotUserResolved")] + public bool? CopilotUserResolved { get; set; } + /// Whether the operation succeeded. [JsonPropertyName("success")] public bool Success { get; set; } @@ -3388,7 +3404,7 @@ public sealed class SessionSetCredentialsResult [Experimental(Diagnostics.Experimental)] internal sealed class SessionSetCredentialsParams { - /// The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime stores the value verbatim and uses it for outbound model/API requests; it does NOT re-validate or re-fetch the associated Copilot user response. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. + /// The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime installs the supplied value immediately for outbound model/API requests. When the credential carries a raw token (`token`, `env`, or `gh-cli`) but no `copilotUser`, the runtime additionally re-resolves `copilotUser` server-side (best-effort, asynchronously, after the synchronous install) so plan/quota/billing metadata regains fidelity; on resolution failure the verbatim credential remains installed. It does NOT otherwise validate the credential. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. [JsonPropertyName("credentials")] public AuthInfo? Credentials { get; set; } @@ -5612,11 +5628,6 @@ public partial class McpOauthPendingRequestResponseToken : McpOauthPendingReques [JsonPropertyName("expiresIn")] public long? ExpiresIn { get; set; } - /// Refresh token supplied by the host, if available. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("refreshToken")] - public string? RefreshToken { get; set; } - /// OAuth token type. Defaults to Bearer when omitted. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("tokenType")] @@ -5704,6 +5715,70 @@ internal sealed class McpOauthLoginRequest public string SessionId { get; set; } = string.Empty; } +/// Indicates whether the pending MCP headers refresh response was accepted. +[Experimental(Diagnostics.Experimental)] +public sealed class McpHeadersHandlePendingHeadersRefreshRequestResult +{ + /// Whether the response was accepted. False if the request was unknown, timed out, or already resolved. + [JsonPropertyName("success")] + public bool Success { get; set; } +} + +/// Host response: supply dynamic headers or decline this refresh. +/// Polymorphic base type discriminated by kind. +[Experimental(Diagnostics.Experimental)] +[JsonPolymorphic( + TypeDiscriminatorPropertyName = "kind", + UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] +[JsonDerivedType(typeof(McpHeadersHandlePendingHeadersRefreshRequestHeaders), "headers")] +[JsonDerivedType(typeof(McpHeadersHandlePendingHeadersRefreshRequestNone), "none")] +public partial class McpHeadersHandlePendingHeadersRefreshRequest +{ + /// The type discriminator. + [JsonPropertyName("kind")] + public virtual string Kind { get; set; } = string.Empty; +} + + +/// The headers variant of . +[Experimental(Diagnostics.Experimental)] +public partial class McpHeadersHandlePendingHeadersRefreshRequestHeaders : McpHeadersHandlePendingHeadersRefreshRequest +{ + /// + [JsonIgnore] + public override string Kind => "headers"; + + /// Headers to overlay onto the MCP request. Dynamic headers override static config headers but do not replace SDK-managed request headers. + [JsonPropertyName("headers")] + public required IDictionary Headers { get; set; } +} + +/// The none variant of . +[Experimental(Diagnostics.Experimental)] +public partial class McpHeadersHandlePendingHeadersRefreshRequestNone : McpHeadersHandlePendingHeadersRefreshRequest +{ + /// + [JsonIgnore] + public override string Kind => "none"; +} + +/// MCP headers refresh request id and the host response. +[Experimental(Diagnostics.Experimental)] +internal sealed class McpHeadersHandlePendingHeadersRefreshRequestRequest +{ + /// Headers refresh request identifier from mcp.headers_refresh_required. + [JsonPropertyName("requestId")] + public string RequestId { get; set; } = string.Empty; + + /// Host response: supply dynamic headers or decline this refresh. + [JsonPropertyName("result")] + public McpHeadersHandlePendingHeadersRefreshRequest Result { get => field ??= new(); set; } + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + /// Schema for the `McpAppsResourceContent` type. [Experimental(Diagnostics.Experimental)] public sealed class McpAppsResourceContent @@ -6552,6 +6627,10 @@ internal sealed class SessionUpdateOptionsParams [JsonPropertyName("agentContext")] public string? AgentContext { get; set; } + /// Whether to include instructions from every MCP server in the system prompt instead of only allowlisted servers. + [JsonPropertyName("allowAllMcpServerInstructions")] + public bool? AllowAllMcpServerInstructions { get; set; } + /// Whether to disable the `ask_user` tool (encourages autonomous behavior). [JsonPropertyName("askUserDisabled")] public bool? AskUserDisabled { get; set; } @@ -6696,6 +6775,10 @@ internal sealed class SessionUpdateOptionsParams [JsonPropertyName("reasoningSummary")] public OptionsUpdateReasoningSummary? ReasoningSummary { get; set; } + /// Optional response budget limits. Pass null to clear the response budget. + [JsonPropertyName("responseBudget")] + public ResponseBudgetConfig? ResponseBudget { get; set; } + /// Whether the session is running in an interactive UI. [JsonPropertyName("runningInInteractiveMode")] public bool? RunningInInteractiveMode { get; set; } @@ -6858,6 +6941,15 @@ internal sealed class SessionExtensionsReloadRequest [JsonDerivedType(typeof(PushAttachmentDirectory), "directory")] [JsonDerivedType(typeof(PushAttachmentSelection), "selection")] [JsonDerivedType(typeof(PushAttachmentGitHubReference), "github_reference")] +[JsonDerivedType(typeof(PushAttachmentGitHubCommit), "github_commit")] +[JsonDerivedType(typeof(PushAttachmentGitHubRelease), "github_release")] +[JsonDerivedType(typeof(PushAttachmentGitHubActionsJob), "github_actions_job")] +[JsonDerivedType(typeof(PushAttachmentGitHubRepository), "github_repository")] +[JsonDerivedType(typeof(PushAttachmentGitHubFileDiff), "github_file_diff")] +[JsonDerivedType(typeof(PushAttachmentGitHubTreeComparison), "github_tree_comparison")] +[JsonDerivedType(typeof(PushAttachmentGitHubUrl), "github_url")] +[JsonDerivedType(typeof(PushAttachmentGitHubFile), "github_file")] +[JsonDerivedType(typeof(PushAttachmentGitHubSnippet), "github_snippet")] [JsonDerivedType(typeof(PushAttachmentBlob), "blob")] [JsonDerivedType(typeof(PushAttachmentExtensionContext), "extension_context")] public partial class PushAttachment @@ -7017,6 +7109,284 @@ public partial class PushAttachmentGitHubReference : PushAttachment public required string Url { get; set; } } +/// Pointer to a GitHub repository. +[Experimental(Diagnostics.Experimental)] +public sealed class PushGitHubRepoRef +{ + /// Numeric GitHub repository id. + [JsonPropertyName("id")] + public long? Id { get; set; } + + /// Repository name (without owner). + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// Repository owner login (user or organization). + [JsonPropertyName("owner")] + public string Owner { get; set; } = string.Empty; +} + +/// Pointer to a GitHub commit. +/// The github_commit variant of . +[Experimental(Diagnostics.Experimental)] +public partial class PushAttachmentGitHubCommit : PushAttachment +{ + /// + [JsonIgnore] + public override string Type => "github_commit"; + + /// First line of the commit message. + [JsonPropertyName("message")] + public required string Message { get; set; } + + /// Full commit SHA. + [JsonPropertyName("oid")] + public required string Oid { get; set; } + + /// Repository the commit belongs to. + [JsonPropertyName("repo")] + public required PushGitHubRepoRef Repo { get; set; } + + /// URL to the commit on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Pointer to a GitHub release. +/// The github_release variant of . +[Experimental(Diagnostics.Experimental)] +public partial class PushAttachmentGitHubRelease : PushAttachment +{ + /// + [JsonIgnore] + public override string Type => "github_release"; + + /// Human-readable release name. + [JsonPropertyName("name")] + public required string Name { get; set; } + + /// Repository the release belongs to. + [JsonPropertyName("repo")] + public required PushGitHubRepoRef Repo { get; set; } + + /// Git tag the release is anchored to. + [JsonPropertyName("tagName")] + public required string TagName { get; set; } + + /// URL to the release on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Pointer to a GitHub Actions job. +/// The github_actions_job variant of . +[Experimental(Diagnostics.Experimental)] +public partial class PushAttachmentGitHubActionsJob : PushAttachment +{ + /// + [JsonIgnore] + public override string Type => "github_actions_job"; + + /// Terminal conclusion of the job when finished (e.g., success, failure, cancelled). Absent for in-progress jobs. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("conclusion")] + public string? Conclusion { get; set; } + + /// Job id within the workflow run. + [JsonPropertyName("jobId")] + public required long JobId { get; set; } + + /// Display name of the job. + [JsonPropertyName("jobName")] + public required string JobName { get; set; } + + /// Repository the workflow run belongs to. + [JsonPropertyName("repo")] + public required PushGitHubRepoRef Repo { get; set; } + + /// URL to the job on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } + + /// Display name of the workflow the job ran in. + [JsonPropertyName("workflowName")] + public required string WorkflowName { get; set; } +} + +/// Pointer to a GitHub repository. +/// The github_repository variant of . +[Experimental(Diagnostics.Experimental)] +public partial class PushAttachmentGitHubRepository : PushAttachment +{ + /// + [JsonIgnore] + public override string Type => "github_repository"; + + /// Short description of the repository. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("description")] + public string? Description { get; set; } + + /// Git ref this attachment is anchored at (branch, tag, or commit). When absent the default branch is implied. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("ref")] + public string? Ref { get; set; } + + /// Repository pointer. + [JsonPropertyName("repo")] + public required PushGitHubRepoRef Repo { get; set; } + + /// URL to the repository on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// One side of a file diff (head or base). +[Experimental(Diagnostics.Experimental)] +public sealed class PushAttachmentGitHubFileDiffSide +{ + /// Repository-relative path to the file. + [JsonPropertyName("path")] + public string Path { get; set; } = string.Empty; + + /// Git ref (branch, tag, or commit SHA) the file is read at. + [JsonPropertyName("ref")] + public string Ref { get; set; } = string.Empty; + + /// Repository the file lives in. + [JsonPropertyName("repo")] + public PushGitHubRepoRef Repo { get => field ??= new(); set; } +} + +/// Pointer to a single-file diff. At least one of `head` and `base` must be present. +/// The github_file_diff variant of . +[Experimental(Diagnostics.Experimental)] +public partial class PushAttachmentGitHubFileDiff : PushAttachment +{ + /// + [JsonIgnore] + public override string Type => "github_file_diff"; + + /// File location on the base side of the diff. Absent for additions. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("base")] + public PushAttachmentGitHubFileDiffSide? Base { get; set; } + + /// File location on the head side of the diff. Absent for deletions. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("head")] + public PushAttachmentGitHubFileDiffSide? Head { get; set; } + + /// URL to the diff on GitHub (e.g., a commit, compare, or PR-file URL). + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// One side of a tree comparison (head or base). +[Experimental(Diagnostics.Experimental)] +public sealed class PushAttachmentGitHubTreeComparisonSide +{ + /// Repository the revision belongs to. + [JsonPropertyName("repo")] + public PushGitHubRepoRef Repo { get => field ??= new(); set; } + + /// Git revision (branch, tag, or commit SHA). + [JsonPropertyName("revision")] + public string Revision { get; set; } = string.Empty; +} + +/// Pointer to a comparison between two git revisions. +/// The github_tree_comparison variant of . +[Experimental(Diagnostics.Experimental)] +public partial class PushAttachmentGitHubTreeComparison : PushAttachment +{ + /// + [JsonIgnore] + public override string Type => "github_tree_comparison"; + + /// Base side of the comparison. + [JsonPropertyName("base")] + public required PushAttachmentGitHubTreeComparisonSide Base { get; set; } + + /// Head side of the comparison. + [JsonPropertyName("head")] + public required PushAttachmentGitHubTreeComparisonSide Head { get; set; } + + /// URL to the comparison on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Generic GitHub URL reference. +/// The github_url variant of . +[Experimental(Diagnostics.Experimental)] +public partial class PushAttachmentGitHubUrl : PushAttachment +{ + /// + [JsonIgnore] + public override string Type => "github_url"; + + /// URL to the GitHub resource. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Pointer to a file in a GitHub repository at a specific ref. +/// The github_file variant of . +[Experimental(Diagnostics.Experimental)] +public partial class PushAttachmentGitHubFile : PushAttachment +{ + /// + [JsonIgnore] + public override string Type => "github_file"; + + /// Repository-relative path to the file. + [JsonPropertyName("path")] + public required string Path { get; set; } + + /// Git ref the file is read at (branch, tag, or commit SHA). + [JsonPropertyName("ref")] + public required string Ref { get; set; } + + /// Repository the file lives in. + [JsonPropertyName("repo")] + public required PushGitHubRepoRef Repo { get; set; } + + /// URL to the file on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Pointer to a line range inside a file in a GitHub repository. +/// The github_snippet variant of . +[Experimental(Diagnostics.Experimental)] +public partial class PushAttachmentGitHubSnippet : PushAttachment +{ + /// + [JsonIgnore] + public override string Type => "github_snippet"; + + /// Line range the snippet covers. + [JsonPropertyName("lineRange")] + public required PushAttachmentFileLineRange LineRange { get; set; } + + /// Repository-relative path to the file. + [JsonPropertyName("path")] + public required string Path { get; set; } + + /// Git ref the file is read at (branch, tag, or commit SHA). + [JsonPropertyName("ref")] + public required string Ref { get; set; } + + /// Repository the file lives in. + [JsonPropertyName("repo")] + public required PushGitHubRepoRef Repo { get; set; } + + /// URL to the snippet on GitHub (with line anchor). + [JsonPropertyName("url")] + public required string Url { get; set; } +} + /// Blob attachment with inline base64-encoded data. /// The blob variant of . [Experimental(Diagnostics.Experimental)] @@ -7207,6 +7577,14 @@ public sealed class UpdateSubagentSettingsRequestSubagents /// Names of subagents the user has turned off; they cannot be dispatched. [JsonPropertyName("disabledSubagents")] public IList? DisabledSubagents { get; set; } + + /// Maximum number of subagents that can run concurrently; applies to usage-based billing users only. + [JsonPropertyName("maxConcurrency")] + public int? MaxConcurrency { get; set; } + + /// Maximum subagent nesting depth; applies to usage-based billing users only. + [JsonPropertyName("maxDepth")] + public int? MaxDepth { get; set; } } /// Subagent settings to apply to the current session. @@ -7327,7 +7705,7 @@ internal sealed class CommandsListRequestWithSession public string SessionId { get; set; } = string.Empty; } -/// Result of invoking the slash command (text output, prompt to send to the agent, or completion). +/// Result of invoking the slash command (text output, prompt to send to the agent, completion, or subcommand selection). /// Polymorphic base type discriminated by kind. [Experimental(Diagnostics.Experimental)] [JsonPolymorphic( @@ -17043,12 +17421,13 @@ public async Task InstallAsync(string source, string? worki /// Uninstalls an installed plugin. /// Plugin name or "plugin@marketplace" spec to uninstall. When ambiguous, prefer the fully-qualified spec. + /// Stable source identity for a direct (non-marketplace) install. Disambiguates uninstall when multiple installed plugins share the same name. /// The to monitor for cancellation requests. The default is . - public async Task UninstallAsync(string name, CancellationToken cancellationToken = default) + public async Task UninstallAsync(string name, string? directSourceId = null, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(name); - var request = new PluginsUninstallRequest { Name = name }; + var request = new PluginsUninstallRequest { Name = name, DirectSourceId = directSourceId }; await CopilotClient.InvokeRpcAsync(_rpc, "plugins.uninstall", [request], cancellationToken); } @@ -17827,8 +18206,8 @@ internal SessionRpc(CopilotSession session) internal CopilotSession Session => _session; - /// Auth APIs. - public AuthApi Auth => + /// GitHubAuth APIs. + public GitHubAuthApi GitHubAuth => field ?? Interlocked.CompareExchange(ref field, new(_session), null) ?? field; @@ -18096,13 +18475,13 @@ public async Task LogAsync(string message, SessionLogLevel? level = n } } -/// Provides session-scoped Auth APIs. +/// Provides session-scoped GitHubAuth APIs. [Experimental(Diagnostics.Experimental)] -public sealed class AuthApi +public sealed class GitHubAuthApi { private readonly CopilotSession _session; - internal AuthApi(CopilotSession session) + internal GitHubAuthApi(CopilotSession session) { _session = session; } @@ -18114,12 +18493,12 @@ public async Task GetStatusAsync(CancellationToken cancellati { _session.ThrowIfDisposed(); - var request = new SessionAuthGetStatusRequest { SessionId = _session.SessionId }; - return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.auth.getStatus", [request], cancellationToken); + var request = new SessionGitHubAuthGetStatusRequest { SessionId = _session.SessionId }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.gitHubAuth.getStatus", [request], cancellationToken); } /// Updates the session's auth credentials used for outbound model and API requests. - /// The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime stores the value verbatim and uses it for outbound model/API requests; it does NOT re-validate or re-fetch the associated Copilot user response. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. + /// The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime installs the supplied value immediately for outbound model/API requests. When the credential carries a raw token (`token`, `env`, or `gh-cli`) but no `copilotUser`, the runtime additionally re-resolves `copilotUser` server-side (best-effort, asynchronously, after the synchronous install) so plan/quota/billing metadata regains fidelity; on resolution failure the verbatim credential remains installed. It does NOT otherwise validate the credential. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. /// The to monitor for cancellation requests. The default is . /// Indicates whether the credential update succeeded. public async Task SetCredentialsAsync(AuthInfo? credentials = null, CancellationToken cancellationToken = default) @@ -18127,7 +18506,7 @@ public async Task SetCredentialsAsync(AuthInfo? cre _session.ThrowIfDisposed(); var request = new SessionSetCredentialsParams { SessionId = _session.SessionId, Credentials = credentials }; - return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.auth.setCredentials", [request], cancellationToken); + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.gitHubAuth.setCredentials", [request], cancellationToken); } } @@ -19139,6 +19518,12 @@ public async Task IsServerRunningAsync(string serverNa Interlocked.CompareExchange(ref field, new(_session), null) ?? field; + /// Headers APIs. + public McpHeadersApi Headers => + field ?? + Interlocked.CompareExchange(ref field, new(_session), null) ?? + field; + /// Apps APIs. public McpAppsApi Apps => field ?? @@ -19207,6 +19592,33 @@ public async Task LoginAsync(string serverName, bool? force } } +/// Provides session-scoped McpHeaders APIs. +[Experimental(Diagnostics.Experimental)] +public sealed class McpHeadersApi +{ + private readonly CopilotSession _session; + + internal McpHeadersApi(CopilotSession session) + { + _session = session; + } + + /// Responds to a pending MCP dynamic headers refresh request. Hosts that subscribe to `mcp.headers_refresh_required` use this to provide short-lived per-server headers or to indicate that no dynamic headers are available for this refresh. + /// Headers refresh request identifier from mcp.headers_refresh_required. + /// Host response: supply dynamic headers or decline this refresh. + /// The to monitor for cancellation requests. The default is . + /// Indicates whether the pending MCP headers refresh response was accepted. + public async Task HandlePendingHeadersRefreshRequestAsync(string requestId, McpHeadersHandlePendingHeadersRefreshRequest result, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(requestId); + ArgumentNullException.ThrowIfNull(result); + _session.ThrowIfDisposed(); + + var request = new McpHeadersHandlePendingHeadersRefreshRequestRequest { SessionId = _session.SessionId, RequestId = requestId, Result = result }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.mcp.headers.handlePendingHeadersRefreshRequest", [request], cancellationToken); + } +} + /// Provides session-scoped McpApps APIs. [Experimental(Diagnostics.Experimental)] public sealed class McpAppsApi @@ -19407,6 +19819,7 @@ internal OptionsApi(CopilotSession session) /// Resolved sandbox configuration. /// Whether interactive shell sessions are logged. /// How env values are passed to MCP servers (`direct` inlines literal values; `indirect` resolves at launch). + /// Whether to include instructions from every MCP server in the system prompt instead of only allowlisted servers. /// Additional directories to search for skills. /// Skill IDs that should be excluded from this session. /// Whether to discover custom instructions on demand after successful file views (AGENTS.md / CLAUDE.md / .github/copilot-instructions.md surfacing). Combined with `skipCustomInstructions` and the runtime-side `ON_DEMAND_INSTRUCTIONS` feature flag. @@ -19436,13 +19849,14 @@ internal OptionsApi(CopilotSession session) /// Whether to enable cross-session store writes and reads. /// Whether to enable skill directory scanning and loading. Falls back to enableConfigDiscovery when unset. /// Context tier for models with tiered pricing. The session uses this to derive effective `modelCapabilitiesOverrides` so compaction, truncation, token display, and request limits honor the selected tier. + /// Optional response budget limits. Pass null to clear the response budget. /// 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, ModelCapabilitiesOverride? modelCapabilitiesOverrides = null, string? reasoningEffort = null, OptionsUpdateReasoningSummary? reasoningSummary = null, string? clientName = null, string? lspClientName = null, string? integrationId = null, IDictionary? featureFlags = null, bool? isExperimentalMode = null, ProviderConfig? provider = null, CapiSessionOptions? capi = null, string? workingDirectory = null, IList? availableTools = null, IList? excludedTools = null, OptionsUpdateToolFilterPrecedence? toolFilterPrecedence = null, bool? enableScriptSafety = null, string? shellInitProfile = null, IList? shellProcessFlags = null, SandboxConfig? sandboxConfig = null, bool? logInteractiveShells = null, OptionsUpdateEnvValueMode? envValueMode = null, IList? skillDirectories = null, IList? disabledSkills = null, bool? enableOnDemandInstructionDiscovery = null, long? maxInlineBinaryBytes = null, IList? installedPlugins = null, bool? customAgentsLocalOnly = null, bool? suppressCustomAgentPrompt = 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, IList? sessionCapabilities = null, bool? skipEmbeddingRetrieval = null, string? organizationCustomInstructions = null, bool? enableFileHooks = null, bool? enableHostGitOperations = null, bool? enableSessionStore = null, bool? enableSkills = null, OptionsUpdateContextTier? contextTier = null, CancellationToken cancellationToken = default) + public async Task UpdateAsync(string? model = null, ModelCapabilitiesOverride? modelCapabilitiesOverrides = null, string? reasoningEffort = null, OptionsUpdateReasoningSummary? reasoningSummary = null, string? clientName = null, string? lspClientName = null, string? integrationId = null, IDictionary? featureFlags = null, bool? isExperimentalMode = null, ProviderConfig? provider = null, CapiSessionOptions? capi = null, string? workingDirectory = null, IList? availableTools = null, IList? excludedTools = null, OptionsUpdateToolFilterPrecedence? toolFilterPrecedence = null, bool? enableScriptSafety = null, string? shellInitProfile = null, IList? shellProcessFlags = null, SandboxConfig? sandboxConfig = null, bool? logInteractiveShells = null, OptionsUpdateEnvValueMode? envValueMode = null, bool? allowAllMcpServerInstructions = null, IList? skillDirectories = null, IList? disabledSkills = null, bool? enableOnDemandInstructionDiscovery = null, long? maxInlineBinaryBytes = null, IList? installedPlugins = null, bool? customAgentsLocalOnly = null, bool? suppressCustomAgentPrompt = 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, IList? sessionCapabilities = null, bool? skipEmbeddingRetrieval = null, string? organizationCustomInstructions = null, bool? enableFileHooks = null, bool? enableHostGitOperations = null, bool? enableSessionStore = null, bool? enableSkills = null, OptionsUpdateContextTier? contextTier = null, ResponseBudgetConfig? responseBudget = null, CancellationToken cancellationToken = default) { _session.ThrowIfDisposed(); - var request = new SessionUpdateOptionsParams { SessionId = _session.SessionId, Model = model, ModelCapabilitiesOverrides = modelCapabilitiesOverrides, ReasoningEffort = reasoningEffort, ReasoningSummary = reasoningSummary, ClientName = clientName, LspClientName = lspClientName, IntegrationId = integrationId, FeatureFlags = featureFlags, IsExperimentalMode = isExperimentalMode, Provider = provider, Capi = capi, WorkingDirectory = workingDirectory, AvailableTools = availableTools, ExcludedTools = excludedTools, ToolFilterPrecedence = toolFilterPrecedence, EnableScriptSafety = enableScriptSafety, ShellInitProfile = shellInitProfile, ShellProcessFlags = shellProcessFlags, SandboxConfig = sandboxConfig, LogInteractiveShells = logInteractiveShells, EnvValueMode = envValueMode, SkillDirectories = skillDirectories, DisabledSkills = disabledSkills, EnableOnDemandInstructionDiscovery = enableOnDemandInstructionDiscovery, MaxInlineBinaryBytes = maxInlineBinaryBytes, InstalledPlugins = installedPlugins, CustomAgentsLocalOnly = customAgentsLocalOnly, SuppressCustomAgentPrompt = suppressCustomAgentPrompt, 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, ManageScheduleEnabled = manageScheduleEnabled, SessionCapabilities = sessionCapabilities, SkipEmbeddingRetrieval = skipEmbeddingRetrieval, OrganizationCustomInstructions = organizationCustomInstructions, EnableFileHooks = enableFileHooks, EnableHostGitOperations = enableHostGitOperations, EnableSessionStore = enableSessionStore, EnableSkills = enableSkills, ContextTier = contextTier }; + var request = new SessionUpdateOptionsParams { SessionId = _session.SessionId, Model = model, ModelCapabilitiesOverrides = modelCapabilitiesOverrides, ReasoningEffort = reasoningEffort, ReasoningSummary = reasoningSummary, ClientName = clientName, LspClientName = lspClientName, IntegrationId = integrationId, FeatureFlags = featureFlags, IsExperimentalMode = isExperimentalMode, Provider = provider, Capi = capi, WorkingDirectory = workingDirectory, AvailableTools = availableTools, ExcludedTools = excludedTools, ToolFilterPrecedence = toolFilterPrecedence, EnableScriptSafety = enableScriptSafety, ShellInitProfile = shellInitProfile, ShellProcessFlags = shellProcessFlags, SandboxConfig = sandboxConfig, LogInteractiveShells = logInteractiveShells, EnvValueMode = envValueMode, AllowAllMcpServerInstructions = allowAllMcpServerInstructions, SkillDirectories = skillDirectories, DisabledSkills = disabledSkills, EnableOnDemandInstructionDiscovery = enableOnDemandInstructionDiscovery, MaxInlineBinaryBytes = maxInlineBinaryBytes, InstalledPlugins = installedPlugins, CustomAgentsLocalOnly = customAgentsLocalOnly, SuppressCustomAgentPrompt = suppressCustomAgentPrompt, 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, ManageScheduleEnabled = manageScheduleEnabled, SessionCapabilities = sessionCapabilities, SkipEmbeddingRetrieval = skipEmbeddingRetrieval, OrganizationCustomInstructions = organizationCustomInstructions, EnableFileHooks = enableFileHooks, EnableHostGitOperations = enableHostGitOperations, EnableSessionStore = enableSessionStore, EnableSkills = enableSkills, ContextTier = contextTier, ResponseBudget = responseBudget }; return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.options.update", [request], cancellationToken); } } @@ -19630,7 +20044,7 @@ public async Task ListAsync(CommandsListRequest? request = null, Ca /// Command name. Leading slashes are stripped and the name is matched case-insensitively. /// Raw input after the command name. /// The to monitor for cancellation requests. The default is . - /// Result of invoking the slash command (text output, prompt to send to the agent, or completion). + /// Result of invoking the slash command (text output, prompt to send to the agent, completion, or subcommand selection). public async Task InvokeAsync(string name, string? input = null, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(name); @@ -20957,6 +21371,8 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.AbortData), TypeInfoPropertyName = "SessionEventsAbortData")] [JsonSerializable(typeof(GitHub.Copilot.AbortEvent), TypeInfoPropertyName = "SessionEventsAbortEvent")] [JsonSerializable(typeof(GitHub.Copilot.AbortReason), TypeInfoPropertyName = "SessionEventsAbortReason")] +[JsonSerializable(typeof(GitHub.Copilot.AssistantIdleData), TypeInfoPropertyName = "SessionEventsAssistantIdleData")] +[JsonSerializable(typeof(GitHub.Copilot.AssistantIdleEvent), TypeInfoPropertyName = "SessionEventsAssistantIdleEvent")] [JsonSerializable(typeof(GitHub.Copilot.AssistantIntentData), TypeInfoPropertyName = "SessionEventsAssistantIntentData")] [JsonSerializable(typeof(GitHub.Copilot.AssistantIntentEvent), TypeInfoPropertyName = "SessionEventsAssistantIntentEvent")] [JsonSerializable(typeof(GitHub.Copilot.AssistantMessageData), TypeInfoPropertyName = "SessionEventsAssistantMessageData")] @@ -20989,8 +21405,19 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.AttachmentExtensionContext), TypeInfoPropertyName = "SessionEventsAttachmentExtensionContext")] [JsonSerializable(typeof(GitHub.Copilot.AttachmentFile), TypeInfoPropertyName = "SessionEventsAttachmentFile")] [JsonSerializable(typeof(GitHub.Copilot.AttachmentFileLineRange), TypeInfoPropertyName = "SessionEventsAttachmentFileLineRange")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubActionsJob), TypeInfoPropertyName = "SessionEventsAttachmentGitHubActionsJob")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubCommit), TypeInfoPropertyName = "SessionEventsAttachmentGitHubCommit")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubFile), TypeInfoPropertyName = "SessionEventsAttachmentGitHubFile")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubFileDiff), TypeInfoPropertyName = "SessionEventsAttachmentGitHubFileDiff")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubFileDiffSide), TypeInfoPropertyName = "SessionEventsAttachmentGitHubFileDiffSide")] [JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubReference), TypeInfoPropertyName = "SessionEventsAttachmentGitHubReference")] [JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubReferenceType), TypeInfoPropertyName = "SessionEventsAttachmentGitHubReferenceType")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubRelease), TypeInfoPropertyName = "SessionEventsAttachmentGitHubRelease")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubRepository), TypeInfoPropertyName = "SessionEventsAttachmentGitHubRepository")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubSnippet), TypeInfoPropertyName = "SessionEventsAttachmentGitHubSnippet")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubTreeComparison), TypeInfoPropertyName = "SessionEventsAttachmentGitHubTreeComparison")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubTreeComparisonSide), TypeInfoPropertyName = "SessionEventsAttachmentGitHubTreeComparisonSide")] +[JsonSerializable(typeof(GitHub.Copilot.AttachmentGitHubUrl), TypeInfoPropertyName = "SessionEventsAttachmentGitHubUrl")] [JsonSerializable(typeof(GitHub.Copilot.AttachmentSelection), TypeInfoPropertyName = "SessionEventsAttachmentSelection")] [JsonSerializable(typeof(GitHub.Copilot.AttachmentSelectionDetails), TypeInfoPropertyName = "SessionEventsAttachmentSelectionDetails")] [JsonSerializable(typeof(GitHub.Copilot.AttachmentSelectionDetailsEnd), TypeInfoPropertyName = "SessionEventsAttachmentSelectionDetailsEnd")] @@ -21054,6 +21481,7 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.ExternalToolCompletedEvent), TypeInfoPropertyName = "SessionEventsExternalToolCompletedEvent")] [JsonSerializable(typeof(GitHub.Copilot.ExternalToolRequestedData), TypeInfoPropertyName = "SessionEventsExternalToolRequestedData")] [JsonSerializable(typeof(GitHub.Copilot.ExternalToolRequestedEvent), TypeInfoPropertyName = "SessionEventsExternalToolRequestedEvent")] +[JsonSerializable(typeof(GitHub.Copilot.GitHubRepoRef), TypeInfoPropertyName = "SessionEventsGitHubRepoRef")] [JsonSerializable(typeof(GitHub.Copilot.HandoffRepository), TypeInfoPropertyName = "SessionEventsHandoffRepository")] [JsonSerializable(typeof(GitHub.Copilot.HandoffSourceType), TypeInfoPropertyName = "SessionEventsHandoffSourceType")] [JsonSerializable(typeof(GitHub.Copilot.HookEndData), TypeInfoPropertyName = "SessionEventsHookEndData")] @@ -21068,9 +21496,16 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.McpAppToolCallCompleteEvent), TypeInfoPropertyName = "SessionEventsMcpAppToolCallCompleteEvent")] [JsonSerializable(typeof(GitHub.Copilot.McpAppToolCallCompleteToolMeta), TypeInfoPropertyName = "SessionEventsMcpAppToolCallCompleteToolMeta")] [JsonSerializable(typeof(GitHub.Copilot.McpAppToolCallCompleteToolMetaUI), TypeInfoPropertyName = "SessionEventsMcpAppToolCallCompleteToolMetaUI")] +[JsonSerializable(typeof(GitHub.Copilot.McpHeadersRefreshCompletedData), TypeInfoPropertyName = "SessionEventsMcpHeadersRefreshCompletedData")] +[JsonSerializable(typeof(GitHub.Copilot.McpHeadersRefreshCompletedEvent), TypeInfoPropertyName = "SessionEventsMcpHeadersRefreshCompletedEvent")] +[JsonSerializable(typeof(GitHub.Copilot.McpHeadersRefreshCompletedOutcome), TypeInfoPropertyName = "SessionEventsMcpHeadersRefreshCompletedOutcome")] +[JsonSerializable(typeof(GitHub.Copilot.McpHeadersRefreshRequiredData), TypeInfoPropertyName = "SessionEventsMcpHeadersRefreshRequiredData")] +[JsonSerializable(typeof(GitHub.Copilot.McpHeadersRefreshRequiredEvent), TypeInfoPropertyName = "SessionEventsMcpHeadersRefreshRequiredEvent")] +[JsonSerializable(typeof(GitHub.Copilot.McpHeadersRefreshRequiredReason), TypeInfoPropertyName = "SessionEventsMcpHeadersRefreshRequiredReason")] [JsonSerializable(typeof(GitHub.Copilot.McpOauthCompletedData), TypeInfoPropertyName = "SessionEventsMcpOauthCompletedData")] [JsonSerializable(typeof(GitHub.Copilot.McpOauthCompletedEvent), TypeInfoPropertyName = "SessionEventsMcpOauthCompletedEvent")] [JsonSerializable(typeof(GitHub.Copilot.McpOauthCompletionOutcome), TypeInfoPropertyName = "SessionEventsMcpOauthCompletionOutcome")] +[JsonSerializable(typeof(GitHub.Copilot.McpOauthRequestReason), TypeInfoPropertyName = "SessionEventsMcpOauthRequestReason")] [JsonSerializable(typeof(GitHub.Copilot.McpOauthRequiredData), TypeInfoPropertyName = "SessionEventsMcpOauthRequiredData")] [JsonSerializable(typeof(GitHub.Copilot.McpOauthRequiredEvent), TypeInfoPropertyName = "SessionEventsMcpOauthRequiredEvent")] [JsonSerializable(typeof(GitHub.Copilot.McpOauthRequiredStaticClientConfig), TypeInfoPropertyName = "SessionEventsMcpOauthRequiredStaticClientConfig")] @@ -21128,6 +21563,7 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.PersistedBinaryResult), TypeInfoPropertyName = "SessionEventsPersistedBinaryResult")] [JsonSerializable(typeof(GitHub.Copilot.PlanChangedOperation), TypeInfoPropertyName = "SessionEventsPlanChangedOperation")] [JsonSerializable(typeof(GitHub.Copilot.ReasoningSummary), TypeInfoPropertyName = "SessionEventsReasoningSummary")] +[JsonSerializable(typeof(GitHub.Copilot.ResponseBudgetConfig), TypeInfoPropertyName = "SessionEventsResponseBudgetConfig")] [JsonSerializable(typeof(GitHub.Copilot.SamplingCompletedData), TypeInfoPropertyName = "SessionEventsSamplingCompletedData")] [JsonSerializable(typeof(GitHub.Copilot.SamplingCompletedEvent), TypeInfoPropertyName = "SessionEventsSamplingCompletedEvent")] [JsonSerializable(typeof(GitHub.Copilot.SamplingRequestedData), TypeInfoPropertyName = "SessionEventsSamplingRequestedData")] @@ -21202,6 +21638,7 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.ToolExecutionProgressEvent), TypeInfoPropertyName = "SessionEventsToolExecutionProgressEvent")] [JsonSerializable(typeof(GitHub.Copilot.ToolExecutionStartData), TypeInfoPropertyName = "SessionEventsToolExecutionStartData")] [JsonSerializable(typeof(GitHub.Copilot.ToolExecutionStartEvent), TypeInfoPropertyName = "SessionEventsToolExecutionStartEvent")] +[JsonSerializable(typeof(GitHub.Copilot.ToolExecutionStartShellToolInfo), TypeInfoPropertyName = "SessionEventsToolExecutionStartShellToolInfo")] [JsonSerializable(typeof(GitHub.Copilot.ToolExecutionStartToolDescription), TypeInfoPropertyName = "SessionEventsToolExecutionStartToolDescription")] [JsonSerializable(typeof(GitHub.Copilot.ToolExecutionStartToolDescriptionMeta), TypeInfoPropertyName = "SessionEventsToolExecutionStartToolDescriptionMeta")] [JsonSerializable(typeof(GitHub.Copilot.ToolExecutionStartToolDescriptionMetaUI), TypeInfoPropertyName = "SessionEventsToolExecutionStartToolDescriptionMetaUI")] @@ -21214,6 +21651,7 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(GitHub.Copilot.UserInputRequestedEvent), TypeInfoPropertyName = "SessionEventsUserInputRequestedEvent")] [JsonSerializable(typeof(GitHub.Copilot.UserMessageAgentMode), TypeInfoPropertyName = "SessionEventsUserMessageAgentMode")] [JsonSerializable(typeof(GitHub.Copilot.UserMessageData), TypeInfoPropertyName = "SessionEventsUserMessageData")] +[JsonSerializable(typeof(GitHub.Copilot.UserMessageDelivery), TypeInfoPropertyName = "SessionEventsUserMessageDelivery")] [JsonSerializable(typeof(GitHub.Copilot.UserMessageEvent), TypeInfoPropertyName = "SessionEventsUserMessageEvent")] [JsonSerializable(typeof(GitHub.Copilot.UserToolSessionApproval), TypeInfoPropertyName = "SessionEventsUserToolSessionApproval")] [JsonSerializable(typeof(GitHub.Copilot.UserToolSessionApprovalCommands), TypeInfoPropertyName = "SessionEventsUserToolSessionApprovalCommands")] @@ -21387,6 +21825,9 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(McpExecuteSamplingRequest))] [JsonSerializable(typeof(McpExecuteSamplingResult))] [JsonSerializable(typeof(McpFilteredServer))] +[JsonSerializable(typeof(McpHeadersHandlePendingHeadersRefreshRequest))] +[JsonSerializable(typeof(McpHeadersHandlePendingHeadersRefreshRequestRequest))] +[JsonSerializable(typeof(McpHeadersHandlePendingHeadersRefreshRequestResult))] [JsonSerializable(typeof(McpHostState))] [JsonSerializable(typeof(McpIsServerRunningRequest))] [JsonSerializable(typeof(McpIsServerRunningResult))] @@ -21546,9 +21987,12 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(ProviderTokenAcquireResult))] [JsonSerializable(typeof(PushAttachment))] [JsonSerializable(typeof(PushAttachmentFileLineRange))] +[JsonSerializable(typeof(PushAttachmentGitHubFileDiffSide))] +[JsonSerializable(typeof(PushAttachmentGitHubTreeComparisonSide))] [JsonSerializable(typeof(PushAttachmentSelectionDetails))] [JsonSerializable(typeof(PushAttachmentSelectionDetailsEnd))] [JsonSerializable(typeof(PushAttachmentSelectionDetailsStart))] +[JsonSerializable(typeof(PushGitHubRepoRef))] [JsonSerializable(typeof(QueuePendingItems))] [JsonSerializable(typeof(QueuePendingItemsResult))] [JsonSerializable(typeof(QueueRemoveMostRecentResult))] @@ -21596,7 +22040,6 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(SessionAgentGetCurrentRequest))] [JsonSerializable(typeof(SessionAgentListRequest))] [JsonSerializable(typeof(SessionAgentReloadRequest))] -[JsonSerializable(typeof(SessionAuthGetStatusRequest))] [JsonSerializable(typeof(SessionAuthStatus))] [JsonSerializable(typeof(SessionBulkDeleteResult))] [JsonSerializable(typeof(SessionCanvasListOpenRequest))] @@ -21630,6 +22073,7 @@ public static void RegisterClientGlobalApiHandlers(JsonRpc rpc, ClientGlobalApiH [JsonSerializable(typeof(SessionFsStatRequest))] [JsonSerializable(typeof(SessionFsStatResult))] [JsonSerializable(typeof(SessionFsWriteFileRequest))] +[JsonSerializable(typeof(SessionGitHubAuthGetStatusRequest))] [JsonSerializable(typeof(SessionHistoryAbortManualCompactionRequest))] [JsonSerializable(typeof(SessionHistoryCancelBackgroundCompactionRequest))] [JsonSerializable(typeof(SessionHistorySummarizeForHandoffRequest))] diff --git a/dotnet/src/Generated/SessionEvents.cs b/dotnet/src/Generated/SessionEvents.cs index f1765e5c44..a2333f52d0 100644 --- a/dotnet/src/Generated/SessionEvents.cs +++ b/dotnet/src/Generated/SessionEvents.cs @@ -25,6 +25,7 @@ namespace GitHub.Copilot; TypeDiscriminatorPropertyName = "type", IgnoreUnrecognizedTypeDiscriminators = true)] [JsonDerivedType(typeof(AbortEvent), "abort")] +[JsonDerivedType(typeof(AssistantIdleEvent), "assistant.idle")] [JsonDerivedType(typeof(AssistantIntentEvent), "assistant.intent")] [JsonDerivedType(typeof(AssistantMessageEvent), "assistant.message")] [JsonDerivedType(typeof(AssistantMessageDeltaEvent), "assistant.message_delta")] @@ -52,6 +53,8 @@ namespace GitHub.Copilot; [JsonDerivedType(typeof(HookProgressEvent), "hook.progress")] [JsonDerivedType(typeof(HookStartEvent), "hook.start")] [JsonDerivedType(typeof(McpAppToolCallCompleteEvent), "mcp_app.tool_call_complete")] +[JsonDerivedType(typeof(McpHeadersRefreshCompletedEvent), "mcp.headers_refresh_completed")] +[JsonDerivedType(typeof(McpHeadersRefreshRequiredEvent), "mcp.headers_refresh_required")] [JsonDerivedType(typeof(McpOauthCompletedEvent), "mcp.oauth_completed")] [JsonDerivedType(typeof(McpOauthRequiredEvent), "mcp.oauth_required")] [JsonDerivedType(typeof(ModelCallFailureEvent), "model.call_failure")] @@ -655,6 +658,19 @@ public sealed partial class AssistantTurnEndEvent : SessionEvent public required AssistantTurnEndData Data { get; set; } } +/// Payload emitted whenever the main agent's processing loop goes idle, including while related background work (running agents or in-flight attached shell commands) is still pending and the session-level idle event is therefore deferred. +/// Represents the assistant.idle event. +public sealed partial class AssistantIdleEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "assistant.idle"; + + /// The assistant.idle event payload. + [JsonPropertyName("data")] + public required AssistantIdleData Data { get; set; } +} + /// LLM API call usage metrics including tokens, costs, quotas, and billing information. /// Represents the assistant.usage event. public sealed partial class AssistantUsageEvent : SessionEvent @@ -1046,6 +1062,32 @@ public sealed partial class McpOauthCompletedEvent : SessionEvent public required McpOauthCompletedData Data { get; set; } } +/// Dynamic headers refresh request for a remote MCP server. +/// Represents the mcp.headers_refresh_required event. +public sealed partial class McpHeadersRefreshRequiredEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "mcp.headers_refresh_required"; + + /// The mcp.headers_refresh_required event payload. + [JsonPropertyName("data")] + public required McpHeadersRefreshRequiredData Data { get; set; } +} + +/// MCP headers refresh request completion notification. +/// Represents the mcp.headers_refresh_completed event. +public sealed partial class McpHeadersRefreshCompletedEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "mcp.headers_refresh_completed"; + + /// The mcp.headers_refresh_completed event payload. + [JsonPropertyName("data")] + public required McpHeadersRefreshCompletedData Data { get; set; } +} + /// Opaque custom notification data. Consumers may branch on source and name, but payload semantics are source-defined. /// Represents the session.custom_notification event. public sealed partial class SessionCustomNotificationEvent : SessionEvent @@ -1449,6 +1491,11 @@ public sealed partial class SessionStartData [JsonPropertyName("remoteSteerable")] public bool? RemoteSteerable { get; set; } + /// Response budget limits configured at session creation time, if any. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("responseBudget")] + public ResponseBudgetConfig? ResponseBudget { get; set; } + /// Model selected at session creation time, if any. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("selectedModel")] @@ -1514,6 +1561,11 @@ public sealed partial class SessionResumeData [JsonPropertyName("remoteSteerable")] public bool? RemoteSteerable { get; set; } + /// Response budget limits currently configured at resume time; null when no budget is active. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("responseBudget")] + public ResponseBudgetConfig? ResponseBudget { get; set; } + /// ISO 8601 timestamp when the session was resumed. [JsonPropertyName("resumeTime")] public required DateTimeOffset ResumeTime { get; set; } @@ -2202,6 +2254,11 @@ public sealed partial class UserMessageData [JsonPropertyName("content")] public required string Content { get; set; } + /// How this message was delivered to the agentic loop relative to loop state (idle-start vs. steering/queued while busy). The timing axis; combine with `source` (origin) for the full picture. Used for telemetry attribution. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("delivery")] + public UserMessageDelivery? Delivery { get; set; } + /// CAPI interaction ID for correlating this user message with its turn. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("interactionId")] @@ -2426,6 +2483,15 @@ public sealed partial class AssistantTurnEndData public required string TurnId { get; set; } } +/// Payload emitted whenever the main agent's processing loop goes idle, including while related background work (running agents or in-flight attached shell commands) is still pending and the session-level idle event is therefore deferred. +public sealed partial class AssistantIdleData +{ + /// True when the preceding agentic loop was cancelled via abort signal. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("aborted")] + public bool? Aborted { get; set; } +} + /// LLM API call usage metrics including tokens, costs, quotas, and billing information. public sealed partial class AssistantUsageData { @@ -2676,6 +2742,11 @@ public sealed partial class ToolExecutionStartData [JsonPropertyName("parentToolCallId")] public string? ParentToolCallId { get; set; } + /// Shell-tool path hints derived from the command at start time for shell tools (bash/powershell/local_shell). Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. Absent for non-shell tools. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("shellToolInfo")] + public ToolExecutionStartShellToolInfo? ShellToolInfo { get; set; } + /// Unique identifier for this tool call. [JsonPropertyName("toolCallId")] public required string ToolCallId { get; set; } @@ -3244,6 +3315,10 @@ public sealed partial class SamplingCompletedData /// OAuth authentication request for an MCP server. public sealed partial class McpOauthRequiredData { + /// Why the runtime is requesting host-provided OAuth credentials. + [JsonPropertyName("reason")] + public required McpOauthRequestReason Reason { get; set; } + /// Unique identifier for this OAuth request; used to respond via session.mcp.oauth.handlePendingRequest. [JsonPropertyName("requestId")] public required string RequestId { get; set; } @@ -3284,6 +3359,38 @@ public sealed partial class McpOauthCompletedData public required string RequestId { get; set; } } +/// Dynamic headers refresh request for a remote MCP server. +public sealed partial class McpHeadersRefreshRequiredData +{ + /// Why dynamic headers are being requested. + [JsonPropertyName("reason")] + public required McpHeadersRefreshRequiredReason Reason { get; set; } + + /// Unique identifier for this headers refresh request; used to respond via session.mcp.headers.handlePendingHeadersRefreshRequest(). + [JsonPropertyName("requestId")] + public required string RequestId { get; set; } + + /// Display name of the remote MCP server requesting headers. + [JsonPropertyName("serverName")] + public required string ServerName { get; set; } + + /// URL of the remote MCP server requesting headers. + [JsonPropertyName("serverUrl")] + public required string ServerUrl { get; set; } +} + +/// MCP headers refresh request completion notification. +public sealed partial class McpHeadersRefreshCompletedData +{ + /// How the pending MCP headers refresh request resolved. + [JsonPropertyName("outcome")] + public required McpHeadersRefreshCompletedOutcome Outcome { get; set; } + + /// Request ID of the resolved headers refresh request. + [JsonPropertyName("requestId")] + public required string RequestId { get; set; } +} + /// Opaque custom notification data. Consumers may branch on source and name, but payload semantics are source-defined. public sealed partial class SessionCustomNotificationData { @@ -3800,6 +3907,21 @@ public sealed partial class WorkingDirectoryContext public string? RepositoryHost { get; set; } } +/// Optional response budget limits. +/// Nested data type for ResponseBudgetConfig. +public sealed partial class ResponseBudgetConfig +{ + /// Maximum AI Credits allowed while responding to one top-level user message. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("maxAiCredits")] + public double? MaxAiCredits { get; set; } + + /// Maximum model-call iterations allowed while responding to one top-level user message. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("maxModelIterations")] + public long? MaxModelIterations { get; set; } +} + /// Repository context for the handed-off session. /// Nested data type for HandoffRepository. public sealed partial class HandoffRepository @@ -4173,6 +4295,276 @@ public sealed partial class AttachmentGitHubReference : Attachment public required string Url { get; set; } } +/// Pointer to a GitHub repository. +/// Nested data type for GitHubRepoRef. +public sealed partial class GitHubRepoRef +{ + /// Numeric GitHub repository id. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("id")] + public long? Id { get; set; } + + /// Repository name (without owner). + [JsonPropertyName("name")] + public required string Name { get; set; } + + /// Repository owner login (user or organization). + [JsonPropertyName("owner")] + public required string Owner { get; set; } +} + +/// Pointer to a GitHub commit. +/// The github_commit variant of . +public sealed partial class AttachmentGitHubCommit : Attachment +{ + /// + [JsonIgnore] + public override string Type => "github_commit"; + + /// First line of the commit message. + [JsonPropertyName("message")] + public required string Message { get; set; } + + /// Full commit SHA. + [JsonPropertyName("oid")] + public required string Oid { get; set; } + + /// Repository the commit belongs to. + [JsonPropertyName("repo")] + public required GitHubRepoRef Repo { get; set; } + + /// URL to the commit on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Pointer to a GitHub release. +/// The github_release variant of . +public sealed partial class AttachmentGitHubRelease : Attachment +{ + /// + [JsonIgnore] + public override string Type => "github_release"; + + /// Human-readable release name. + [JsonPropertyName("name")] + public required string Name { get; set; } + + /// Repository the release belongs to. + [JsonPropertyName("repo")] + public required GitHubRepoRef Repo { get; set; } + + /// Git tag the release is anchored to. + [JsonPropertyName("tagName")] + public required string TagName { get; set; } + + /// URL to the release on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Pointer to a GitHub Actions job. +/// The github_actions_job variant of . +public sealed partial class AttachmentGitHubActionsJob : Attachment +{ + /// + [JsonIgnore] + public override string Type => "github_actions_job"; + + /// Terminal conclusion of the job when finished (e.g., success, failure, cancelled). Absent for in-progress jobs. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("conclusion")] + public string? Conclusion { get; set; } + + /// Job id within the workflow run. + [JsonPropertyName("jobId")] + public required long JobId { get; set; } + + /// Display name of the job. + [JsonPropertyName("jobName")] + public required string JobName { get; set; } + + /// Repository the workflow run belongs to. + [JsonPropertyName("repo")] + public required GitHubRepoRef Repo { get; set; } + + /// URL to the job on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } + + /// Display name of the workflow the job ran in. + [JsonPropertyName("workflowName")] + public required string WorkflowName { get; set; } +} + +/// Pointer to a GitHub repository. +/// The github_repository variant of . +public sealed partial class AttachmentGitHubRepository : Attachment +{ + /// + [JsonIgnore] + public override string Type => "github_repository"; + + /// Short description of the repository. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("description")] + public string? Description { get; set; } + + /// Git ref this attachment is anchored at (branch, tag, or commit). When absent the default branch is implied. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("ref")] + public string? Ref { get; set; } + + /// Repository pointer. + [JsonPropertyName("repo")] + public required GitHubRepoRef Repo { get; set; } + + /// URL to the repository on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// One side of a file diff (head or base). +/// Nested data type for AttachmentGitHubFileDiffSide. +public sealed partial class AttachmentGitHubFileDiffSide +{ + /// Repository-relative path to the file. + [JsonPropertyName("path")] + public required string Path { get; set; } + + /// Git ref (branch, tag, or commit SHA) the file is read at. + [JsonPropertyName("ref")] + public required string Ref { get; set; } + + /// Repository the file lives in. + [JsonPropertyName("repo")] + public required GitHubRepoRef Repo { get; set; } +} + +/// Pointer to a single-file diff. At least one of `head` and `base` must be present. +/// The github_file_diff variant of . +public sealed partial class AttachmentGitHubFileDiff : Attachment +{ + /// + [JsonIgnore] + public override string Type => "github_file_diff"; + + /// File location on the base side of the diff. Absent for additions. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("base")] + public AttachmentGitHubFileDiffSide? Base { get; set; } + + /// File location on the head side of the diff. Absent for deletions. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("head")] + public AttachmentGitHubFileDiffSide? Head { get; set; } + + /// URL to the diff on GitHub (e.g., a commit, compare, or PR-file URL). + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// One side of a tree comparison (head or base). +/// Nested data type for AttachmentGitHubTreeComparisonSide. +public sealed partial class AttachmentGitHubTreeComparisonSide +{ + /// Repository the revision belongs to. + [JsonPropertyName("repo")] + public required GitHubRepoRef Repo { get; set; } + + /// Git revision (branch, tag, or commit SHA). + [JsonPropertyName("revision")] + public required string Revision { get; set; } +} + +/// Pointer to a comparison between two git revisions. +/// The github_tree_comparison variant of . +public sealed partial class AttachmentGitHubTreeComparison : Attachment +{ + /// + [JsonIgnore] + public override string Type => "github_tree_comparison"; + + /// Base side of the comparison. + [JsonPropertyName("base")] + public required AttachmentGitHubTreeComparisonSide Base { get; set; } + + /// Head side of the comparison. + [JsonPropertyName("head")] + public required AttachmentGitHubTreeComparisonSide Head { get; set; } + + /// URL to the comparison on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Generic GitHub URL reference. +/// The github_url variant of . +public sealed partial class AttachmentGitHubUrl : Attachment +{ + /// + [JsonIgnore] + public override string Type => "github_url"; + + /// URL to the GitHub resource. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Pointer to a file in a GitHub repository at a specific ref. +/// The github_file variant of . +public sealed partial class AttachmentGitHubFile : Attachment +{ + /// + [JsonIgnore] + public override string Type => "github_file"; + + /// Repository-relative path to the file. + [JsonPropertyName("path")] + public required string Path { get; set; } + + /// Git ref the file is read at (branch, tag, or commit SHA). + [JsonPropertyName("ref")] + public required string Ref { get; set; } + + /// Repository the file lives in. + [JsonPropertyName("repo")] + public required GitHubRepoRef Repo { get; set; } + + /// URL to the file on GitHub. + [JsonPropertyName("url")] + public required string Url { get; set; } +} + +/// Pointer to a line range inside a file in a GitHub repository. +/// The github_snippet variant of . +public sealed partial class AttachmentGitHubSnippet : Attachment +{ + /// + [JsonIgnore] + public override string Type => "github_snippet"; + + /// Line range the snippet covers. + [JsonPropertyName("lineRange")] + public required AttachmentFileLineRange LineRange { get; set; } + + /// Repository-relative path to the file. + [JsonPropertyName("path")] + public required string Path { get; set; } + + /// Git ref the file is read at (branch, tag, or commit SHA). + [JsonPropertyName("ref")] + public required string Ref { get; set; } + + /// Repository the file lives in. + [JsonPropertyName("repo")] + public required GitHubRepoRef Repo { get; set; } + + /// URL to the snippet on GitHub (with line anchor). + [JsonPropertyName("url")] + public required string Url { get; set; } +} + /// Blob attachment with inline base64-encoded data. /// The blob variant of . public sealed partial class AttachmentBlob : Attachment @@ -4250,7 +4642,7 @@ public sealed partial class AttachmentExtensionContext : Attachment public required string Title { get; set; } } -/// A user message attachment — a file, directory, code selection, blob, GitHub reference, or extension-supplied context payload. +/// A user message attachment — a file, directory, code selection, blob, GitHub reference, GitHub-anchored pointer, or extension-supplied context payload. /// Polymorphic base type discriminated by type. [JsonPolymorphic( TypeDiscriminatorPropertyName = "type", @@ -4259,6 +4651,15 @@ public sealed partial class AttachmentExtensionContext : Attachment [JsonDerivedType(typeof(AttachmentDirectory), "directory")] [JsonDerivedType(typeof(AttachmentSelection), "selection")] [JsonDerivedType(typeof(AttachmentGitHubReference), "github_reference")] +[JsonDerivedType(typeof(AttachmentGitHubCommit), "github_commit")] +[JsonDerivedType(typeof(AttachmentGitHubRelease), "github_release")] +[JsonDerivedType(typeof(AttachmentGitHubActionsJob), "github_actions_job")] +[JsonDerivedType(typeof(AttachmentGitHubRepository), "github_repository")] +[JsonDerivedType(typeof(AttachmentGitHubFileDiff), "github_file_diff")] +[JsonDerivedType(typeof(AttachmentGitHubTreeComparison), "github_tree_comparison")] +[JsonDerivedType(typeof(AttachmentGitHubUrl), "github_url")] +[JsonDerivedType(typeof(AttachmentGitHubFile), "github_file")] +[JsonDerivedType(typeof(AttachmentGitHubSnippet), "github_snippet")] [JsonDerivedType(typeof(AttachmentBlob), "blob")] [JsonDerivedType(typeof(AttachmentExtensionContext), "extension_context")] public partial class Attachment @@ -4633,6 +5034,19 @@ public sealed partial class ModelCallFailureRequestFingerprint public required long ToolResultMessageCount { get; set; } } +/// Shell-aware path hints for a shell tool's command, captured at start time so consumers can snapshot a file's pre-image before the tool runs. +/// Nested data type for ToolExecutionStartShellToolInfo. +public sealed partial class ToolExecutionStartShellToolInfo +{ + /// Whether the command includes a file write redirection (e.g., > or >>). + [JsonPropertyName("hasWriteFileRedirection")] + public required bool HasWriteFileRedirection { get; set; } + + /// File paths the command may read or write, derived from the command at start time. Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. + [JsonPropertyName("possiblePaths")] + public required string[] PossiblePaths { get; set; } +} + /// Schema for the `ToolExecutionStartToolDescriptionMetaUI` type. /// Nested data type for ToolExecutionStartToolDescriptionMetaUI. public sealed partial class ToolExecutionStartToolDescriptionMetaUI @@ -6620,6 +7034,11 @@ public sealed partial class McpOauthRequiredStaticClientConfig [JsonPropertyName("clientId")] public required string ClientId { get; set; } + /// Optional OAuth client secret for confidential static clients, when the runtime can resolve one. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("clientSecret")] + public string? ClientSecret { get; set; } + /// Optional non-default OAuth grant type. When set to 'client_credentials', the OAuth flow runs headlessly using the client_id + keychain-stored secret (no browser, no callback server). [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("grantType")] @@ -6640,9 +7059,10 @@ public sealed partial class McpOauthWWWAuthenticateParams [JsonPropertyName("error")] public string? Error { get; set; } - /// Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter. + /// Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter, if present. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("resourceMetadataUrl")] - public required string ResourceMetadataUrl { get; set; } + public string? ResourceMetadataUrl { get; set; } /// Requested OAuth scopes from the WWW-Authenticate scope parameter, if present. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -7729,6 +8149,70 @@ public override void Write(Utf8JsonWriter writer, AttachmentGitHubReferenceType } } +/// How this user message was delivered to the agentic loop, relative to whether the loop was already running. This is the timing axis only; the message's origin (human vs. system/command/schedule/skill/etc.) is carried separately by `source`. A system-injected message has a delivery too — e.g. a background-task notification waking an idle agent is `idle`, the same mechanism as a human starting a fresh turn. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct UserMessageDelivery : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public UserMessageDelivery(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Delivered while the loop was idle; starts its own run immediately (a human's fresh turn, or a system notification waking an idle agent). + public static UserMessageDelivery Idle { get; } = new("idle"); + + /// Injected into the current in-flight run while the agent was busy (immediate mode). + public static UserMessageDelivery Steering { get; } = new("steering"); + + /// Enqueued while the agent was busy; processed as its own run afterward. + public static UserMessageDelivery Queued { get; } = new("queued"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(UserMessageDelivery left, UserMessageDelivery right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(UserMessageDelivery left, UserMessageDelivery right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is UserMessageDelivery other && Equals(other); + + /// + public bool Equals(UserMessageDelivery 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 UserMessageDelivery Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, UserMessageDelivery value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(UserMessageDelivery)); + } + } +} + /// The system that produced a citation. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] @@ -9035,6 +9519,73 @@ public override void Write(Utf8JsonWriter writer, ElicitationCompletedAction val } } +/// Reason the runtime is requesting host-provided MCP OAuth credentials. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct McpOauthRequestReason : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public McpOauthRequestReason(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Initial credentials are required before connecting to the MCP server. + public static McpOauthRequestReason Initial { get; } = new("initial"); + + /// The current host-provided credential was rejected and a replacement is requested. + public static McpOauthRequestReason Refresh { get; } = new("refresh"); + + /// The server requires a new host authorization flow before continuing. + public static McpOauthRequestReason Reauth { get; } = new("reauth"); + + /// The server requires a credential with additional scope or audience. + public static McpOauthRequestReason Upscope { get; } = new("upscope"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(McpOauthRequestReason left, McpOauthRequestReason right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(McpOauthRequestReason left, McpOauthRequestReason right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is McpOauthRequestReason other && Equals(other); + + /// + public bool Equals(McpOauthRequestReason 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 McpOauthRequestReason Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, McpOauthRequestReason value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(McpOauthRequestReason)); + } + } +} + /// How the pending MCP OAuth request was completed. [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] @@ -9096,6 +9647,134 @@ public override void Write(Utf8JsonWriter writer, McpOauthCompletionOutcome valu } } +/// Why dynamic headers are being requested. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct McpHeadersRefreshRequiredReason : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public McpHeadersRefreshRequiredReason(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// The transport is making its first dynamic header request for this server. + public static McpHeadersRefreshRequiredReason Startup { get; } = new("startup"); + + /// The previously cached dynamic headers expired. + public static McpHeadersRefreshRequiredReason TtlExpired { get; } = new("ttl-expired"); + + /// The server returned 401 and stale dynamic headers were invalidated. + public static McpHeadersRefreshRequiredReason AuthFailed { get; } = new("auth-failed"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(McpHeadersRefreshRequiredReason left, McpHeadersRefreshRequiredReason right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(McpHeadersRefreshRequiredReason left, McpHeadersRefreshRequiredReason right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is McpHeadersRefreshRequiredReason other && Equals(other); + + /// + public bool Equals(McpHeadersRefreshRequiredReason 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 McpHeadersRefreshRequiredReason Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, McpHeadersRefreshRequiredReason value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(McpHeadersRefreshRequiredReason)); + } + } +} + +/// How the pending MCP headers refresh request resolved. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct McpHeadersRefreshCompletedOutcome : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public McpHeadersRefreshCompletedOutcome(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// The host supplied dynamic headers. + public static McpHeadersRefreshCompletedOutcome Headers { get; } = new("headers"); + + /// The host responded with no dynamic headers. + public static McpHeadersRefreshCompletedOutcome None { get; } = new("none"); + + /// No response arrived within the bounded window. + public static McpHeadersRefreshCompletedOutcome Timeout { get; } = new("timeout"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(McpHeadersRefreshCompletedOutcome left, McpHeadersRefreshCompletedOutcome right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(McpHeadersRefreshCompletedOutcome left, McpHeadersRefreshCompletedOutcome right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is McpHeadersRefreshCompletedOutcome other && Equals(other); + + /// + public bool Equals(McpHeadersRefreshCompletedOutcome 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 McpHeadersRefreshCompletedOutcome Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, McpHeadersRefreshCompletedOutcome value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(McpHeadersRefreshCompletedOutcome)); + } + } +} + /// The user's auto-mode-switch choice. [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] @@ -9651,6 +10330,8 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] [JsonSerializable(typeof(AbortData))] [JsonSerializable(typeof(AbortEvent))] +[JsonSerializable(typeof(AssistantIdleData))] +[JsonSerializable(typeof(AssistantIdleEvent))] [JsonSerializable(typeof(AssistantIntentData))] [JsonSerializable(typeof(AssistantIntentEvent))] [JsonSerializable(typeof(AssistantMessageData))] @@ -9682,7 +10363,18 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu [JsonSerializable(typeof(AttachmentExtensionContext))] [JsonSerializable(typeof(AttachmentFile))] [JsonSerializable(typeof(AttachmentFileLineRange))] +[JsonSerializable(typeof(AttachmentGitHubActionsJob))] +[JsonSerializable(typeof(AttachmentGitHubCommit))] +[JsonSerializable(typeof(AttachmentGitHubFile))] +[JsonSerializable(typeof(AttachmentGitHubFileDiff))] +[JsonSerializable(typeof(AttachmentGitHubFileDiffSide))] [JsonSerializable(typeof(AttachmentGitHubReference))] +[JsonSerializable(typeof(AttachmentGitHubRelease))] +[JsonSerializable(typeof(AttachmentGitHubRepository))] +[JsonSerializable(typeof(AttachmentGitHubSnippet))] +[JsonSerializable(typeof(AttachmentGitHubTreeComparison))] +[JsonSerializable(typeof(AttachmentGitHubTreeComparisonSide))] +[JsonSerializable(typeof(AttachmentGitHubUrl))] [JsonSerializable(typeof(AttachmentSelection))] [JsonSerializable(typeof(AttachmentSelectionDetails))] [JsonSerializable(typeof(AttachmentSelectionDetailsEnd))] @@ -9735,6 +10427,7 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu [JsonSerializable(typeof(ExternalToolCompletedEvent))] [JsonSerializable(typeof(ExternalToolRequestedData))] [JsonSerializable(typeof(ExternalToolRequestedEvent))] +[JsonSerializable(typeof(GitHubRepoRef))] [JsonSerializable(typeof(HandoffRepository))] [JsonSerializable(typeof(HookEndData))] [JsonSerializable(typeof(HookEndError))] @@ -9748,6 +10441,10 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu [JsonSerializable(typeof(McpAppToolCallCompleteEvent))] [JsonSerializable(typeof(McpAppToolCallCompleteToolMeta))] [JsonSerializable(typeof(McpAppToolCallCompleteToolMetaUI))] +[JsonSerializable(typeof(McpHeadersRefreshCompletedData))] +[JsonSerializable(typeof(McpHeadersRefreshCompletedEvent))] +[JsonSerializable(typeof(McpHeadersRefreshRequiredData))] +[JsonSerializable(typeof(McpHeadersRefreshRequiredEvent))] [JsonSerializable(typeof(McpOauthCompletedData))] [JsonSerializable(typeof(McpOauthCompletedEvent))] [JsonSerializable(typeof(McpOauthRequiredData))] @@ -9803,6 +10500,7 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu [JsonSerializable(typeof(PermissionRule))] [JsonSerializable(typeof(PersistedBinaryImage))] [JsonSerializable(typeof(PersistedBinaryResult))] +[JsonSerializable(typeof(ResponseBudgetConfig))] [JsonSerializable(typeof(SamplingCompletedData))] [JsonSerializable(typeof(SamplingCompletedEvent))] [JsonSerializable(typeof(SamplingRequestedData))] @@ -9956,6 +10654,7 @@ public override void Write(Utf8JsonWriter writer, ExtensionsLoadedExtensionStatu [JsonSerializable(typeof(ToolExecutionProgressEvent))] [JsonSerializable(typeof(ToolExecutionStartData))] [JsonSerializable(typeof(ToolExecutionStartEvent))] +[JsonSerializable(typeof(ToolExecutionStartShellToolInfo))] [JsonSerializable(typeof(ToolExecutionStartToolDescription))] [JsonSerializable(typeof(ToolExecutionStartToolDescriptionMeta))] [JsonSerializable(typeof(ToolExecutionStartToolDescriptionMetaUI))] diff --git a/dotnet/test/E2E/PerSessionAuthE2ETests.cs b/dotnet/test/E2E/PerSessionAuthE2ETests.cs index 6bc92f08d2..7e104b33de 100644 --- a/dotnet/test/E2E/PerSessionAuthE2ETests.cs +++ b/dotnet/test/E2E/PerSessionAuthE2ETests.cs @@ -81,7 +81,7 @@ public async Task ShouldAuthenticateWithGitHubToken() OnPermissionRequest = PermissionHandler.ApproveAll, }); - var status = await session.Rpc.Auth.GetStatusAsync(); + var status = await session.Rpc.GitHubAuth.GetStatusAsync(); Assert.True(status.IsAuthenticated); Assert.Equal("alice", status.Login); } @@ -103,11 +103,11 @@ public async Task ShouldIsolateAuthBetweenSessions() OnPermissionRequest = PermissionHandler.ApproveAll, }); - var statusA = await sessionA.Rpc.Auth.GetStatusAsync(); + var statusA = await sessionA.Rpc.GitHubAuth.GetStatusAsync(); Assert.True(statusA.IsAuthenticated); Assert.Equal("alice", statusA.Login); - var statusB = await sessionB.Rpc.Auth.GetStatusAsync(); + var statusB = await sessionB.Rpc.GitHubAuth.GetStatusAsync(); Assert.True(statusB.IsAuthenticated); Assert.Equal("bob", statusB.Login); } @@ -122,7 +122,7 @@ public async Task ShouldBeUnauthenticatedWithoutToken() OnPermissionRequest = PermissionHandler.ApproveAll, }); - var status = await session.Rpc.Auth.GetStatusAsync(); + var status = await session.Rpc.GitHubAuth.GetStatusAsync(); // Without a per-session GitHub token, there is no per-session identity. Assert.True(string.IsNullOrEmpty(status.Login), $"Expected no per-session login without token, got {status.Login}"); } diff --git a/dotnet/test/E2E/RpcServerPluginsE2ETests.cs b/dotnet/test/E2E/RpcServerPluginsE2ETests.cs index 58d2cb5258..eea4095931 100644 --- a/dotnet/test/E2E/RpcServerPluginsE2ETests.cs +++ b/dotnet/test/E2E/RpcServerPluginsE2ETests.cs @@ -29,7 +29,7 @@ public class RpcServerPluginsE2ETests(E2ETestFixture fixture, ITestOutputHelper private const string DirectPluginName = "csharp-e2e-direct"; [Fact] - public async Task Should_Install_List_And_Uninstall_Plugin_From_Local_Marketplace() + public async Task Should_Install_And_List_Plugin_From_Local_Marketplace() { var marketplaceDir = CreateLocalMarketplaceFixture(); var (client, home) = await CreateIsolatedClientAsync(); @@ -53,10 +53,6 @@ public async Task Should_Install_List_And_Uninstall_Plugin_From_Local_Marketplac p => p.Name == PluginName && p.Marketplace == MarketplaceName); Assert.True(listed.Enabled); - await client.Rpc.Plugins.UninstallAsync(spec); - - var afterUninstall = await client.Rpc.Plugins.ListAsync(); - Assert.DoesNotContain(afterUninstall.Plugins, p => p.Name == PluginName && p.Marketplace == MarketplaceName); } finally { @@ -157,8 +153,9 @@ public async Task Should_Install_Direct_Local_Plugin_With_Deprecation_Warning() var afterInstall = await client.Rpc.Plugins.ListAsync(); Assert.Single(afterInstall.Plugins, p => p.Name == DirectPluginName); + Assert.False(string.IsNullOrEmpty(install.Plugin.DirectSourceId)); - await client.Rpc.Plugins.UninstallAsync(DirectPluginName); + await client.Rpc.Plugins.UninstallAsync(DirectPluginName, install.Plugin.DirectSourceId); var afterUninstall = await client.Rpc.Plugins.ListAsync(); Assert.DoesNotContain(afterUninstall.Plugins, p => p.Name == DirectPluginName); diff --git a/dotnet/test/E2E/RpcSessionStateE2ETests.cs b/dotnet/test/E2E/RpcSessionStateE2ETests.cs index 9701c5ea29..93af399203 100644 --- a/dotnet/test/E2E/RpcSessionStateE2ETests.cs +++ b/dotnet/test/E2E/RpcSessionStateE2ETests.cs @@ -449,7 +449,7 @@ public async Task Should_Set_Auth_Credentials() }); var login = $"sdk-rpc-{Guid.NewGuid():N}"; - var setCredentials = await session.Rpc.Auth.SetCredentialsAsync(new AuthInfoUser + var setCredentials = await session.Rpc.GitHubAuth.SetCredentialsAsync(new AuthInfoUser { CopilotUser = new CopilotUserResponse { @@ -468,7 +468,7 @@ public async Task Should_Set_Auth_Credentials() }); Assert.True(setCredentials.Success); - var status = await session.Rpc.Auth.GetStatusAsync(); + var status = await session.Rpc.GitHubAuth.GetStatusAsync(); Assert.True(status.IsAuthenticated); Assert.Equal(AuthInfoType.User, status.AuthType); Assert.Equal("https://github.com", status.Host); diff --git a/dotnet/test/E2E/SessionE2ETests.cs b/dotnet/test/E2E/SessionE2ETests.cs index 979144b6e9..202436c04f 100644 --- a/dotnet/test/E2E/SessionE2ETests.cs +++ b/dotnet/test/E2E/SessionE2ETests.cs @@ -34,7 +34,7 @@ public async Task ShouldCreateAndDisconnectSessions() [Fact] public async Task Should_Have_Stateful_Conversation() { - var session = await CreateSessionAsync(); + await using var session = await CreateSessionAsync(); var assistantMessage = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 1+1?" }); Assert.NotNull(assistantMessage); @@ -689,17 +689,19 @@ public async Task DisposeAsync_From_Handler_Does_Not_Deadlock() session.On(evt => { - if (evt is UserMessageEvent) + if (evt is SessionInfoEvent) { // Call DisposeAsync from within a handler — must not deadlock. session.DisposeAsync().AsTask().ContinueWith(_ => disposed.TrySetResult()); } }); - await session.SendAsync(new MessageOptions { Prompt = "What is 1+1?" }); + await session.LogAsync("Dispose from handler trigger"); // If this times out, we deadlocked. await disposed.Task.WaitAsync(TimeSpan.FromSeconds(10)); + + await Client.ForceStopAsync(); } [Fact] diff --git a/dotnet/test/Unit/SessionEventSerializationTests.cs b/dotnet/test/Unit/SessionEventSerializationTests.cs index 47b4ac3f73..f537f500f3 100644 --- a/dotnet/test/Unit/SessionEventSerializationTests.cs +++ b/dotnet/test/Unit/SessionEventSerializationTests.cs @@ -150,6 +150,7 @@ public class SessionEventSerializationTests Data = new McpOauthRequiredData { RequestId = "oauth-request", + Reason = McpOauthRequestReason.Initial, ServerName = "oauth-server", ServerUrl = "https://example.com/mcp", StaticClientConfig = new McpOauthRequiredStaticClientConfig diff --git a/go/internal/e2e/per_session_auth_e2e_test.go b/go/internal/e2e/per_session_auth_e2e_test.go index eed11bcfa2..e004fa6b5a 100644 --- a/go/internal/e2e/per_session_auth_e2e_test.go +++ b/go/internal/e2e/per_session_auth_e2e_test.go @@ -47,7 +47,7 @@ func TestPerSessionAuthE2E(t *testing.T) { t.Fatalf("Failed to create session: %v", err) } - authStatus, err := session.RPC.Auth.GetStatus(t.Context()) + authStatus, err := session.RPC.GitHubAuth.GetStatus(t.Context()) if err != nil { t.Fatalf("Failed to get auth status: %v", err) } @@ -79,12 +79,12 @@ func TestPerSessionAuthE2E(t *testing.T) { t.Fatalf("Failed to create session B: %v", err) } - statusA, err := sessionA.RPC.Auth.GetStatus(t.Context()) + statusA, err := sessionA.RPC.GitHubAuth.GetStatus(t.Context()) if err != nil { t.Fatalf("Failed to get auth status for session A: %v", err) } - statusB, err := sessionB.RPC.Auth.GetStatus(t.Context()) + statusB, err := sessionB.RPC.GitHubAuth.GetStatus(t.Context()) if err != nil { t.Fatalf("Failed to get auth status for session B: %v", err) } @@ -115,7 +115,7 @@ func TestPerSessionAuthE2E(t *testing.T) { t.Fatalf("Failed to create session: %v", err) } - authStatus, err := session.RPC.Auth.GetStatus(t.Context()) + authStatus, err := session.RPC.GitHubAuth.GetStatus(t.Context()) if err != nil { t.Fatalf("Failed to get auth status: %v", err) } diff --git a/go/internal/e2e/rpc_server_plugins_e2e_test.go b/go/internal/e2e/rpc_server_plugins_e2e_test.go index e79760e4a7..9dbd17a672 100644 --- a/go/internal/e2e/rpc_server_plugins_e2e_test.go +++ b/go/internal/e2e/rpc_server_plugins_e2e_test.go @@ -20,7 +20,7 @@ const ( func TestRpcServerPlugins(t *testing.T) { ctx := testharness.NewTestContext(t) - t.Run("should_install_list_and_uninstall_plugin_from_local_marketplace", func(t *testing.T) { + t.Run("should_install_and_list_plugin_from_local_marketplace", func(t *testing.T) { ctx.ConfigureForTest(t) marketplaceDir := createPortedLocalMarketplaceFixture(t) client := newStartedIsolatedPortedClient(t, ctx) @@ -63,17 +63,6 @@ func TestRpcServerPlugins(t *testing.T) { t.Fatal("Expected listed marketplace plugin to be enabled") } - if _, err := client.RPC.Plugins.Uninstall(t.Context(), &rpc.PluginsUninstallRequest{Name: spec}); err != nil { - t.Fatalf("Plugins.Uninstall failed: %v", err) - } - - afterUninstall, err := client.RPC.Plugins.List(t.Context()) - if err != nil { - t.Fatalf("Plugins.List after uninstall failed: %v", err) - } - if findPortedInstalledPlugin(afterUninstall.Plugins, portedPluginName, portedMarketplaceName) != nil { - t.Fatalf("Expected plugin %q to be removed", spec) - } }) t.Run("should_enable_and_disable_marketplace_plugin", func(t *testing.T) { @@ -200,8 +189,14 @@ func TestRpcServerPlugins(t *testing.T) { if countPortedInstalledPluginByName(afterInstall.Plugins, portedDirectPluginName) != 1 { t.Fatalf("Expected exactly one direct plugin named %q, got %+v", portedDirectPluginName, afterInstall.Plugins) } + if install.Plugin.DirectSourceID == nil { + t.Fatal("Expected direct plugin install to include directSourceId") + } - if _, err := client.RPC.Plugins.Uninstall(t.Context(), &rpc.PluginsUninstallRequest{Name: portedDirectPluginName}); err != nil { + if _, err := client.RPC.Plugins.Uninstall(t.Context(), &rpc.PluginsUninstallRequest{ + DirectSourceID: install.Plugin.DirectSourceID, + Name: portedDirectPluginName, + }); err != nil { t.Fatalf("Plugins.Uninstall direct failed: %v", err) } afterUninstall, err := client.RPC.Plugins.List(t.Context()) diff --git a/go/internal/e2e/rpc_session_state_e2e_test.go b/go/internal/e2e/rpc_session_state_e2e_test.go index 9b28471ba3..07ec4138d6 100644 --- a/go/internal/e2e/rpc_session_state_e2e_test.go +++ b/go/internal/e2e/rpc_session_state_e2e_test.go @@ -704,7 +704,7 @@ func TestRPCSessionStateE2E(t *testing.T) { api := ctx.ProxyURL telemetry := "https://localhost:1/telemetry" - setCredentials, err := session.RPC.Auth.SetCredentials(t.Context(), &rpc.SessionSetCredentialsParams{ + setCredentials, err := session.RPC.GitHubAuth.SetCredentials(t.Context(), &rpc.SessionSetCredentialsParams{ Credentials: &rpc.UserAuthInfo{ CopilotUser: &rpc.CopilotUserResponse{ AnalyticsTrackingID: rpcPtr("rpc-session-state-tracking-id"), @@ -727,7 +727,7 @@ func TestRPCSessionStateE2E(t *testing.T) { t.Fatalf("Expected Auth.SetCredentials Success=true, got %+v", setCredentials) } - status, err := session.RPC.Auth.GetStatus(t.Context()) + status, err := session.RPC.GitHubAuth.GetStatus(t.Context()) if err != nil { t.Fatalf("Auth.GetStatus failed: %v", err) } diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go index 03ec16cea1..fa6de97204 100644 --- a/go/rpc/zrpc.go +++ b/go/rpc/zrpc.go @@ -424,8 +424,8 @@ type AllowAllPermissionState struct { Enabled bool `json:"enabled"` } -// A user message attachment — a file, directory, code selection, blob, GitHub reference, or -// extension-supplied context payload +// A user message attachment — a file, directory, code selection, blob, GitHub-anchored +// pointer, or extension-supplied context payload // Experimental: Attachment is part of an experimental API and may change or be removed. type Attachment interface { attachment() @@ -545,6 +545,85 @@ func (AttachmentFile) Type() AttachmentType { return AttachmentTypeFile } +// Pointer to a GitHub Actions job. +// Experimental: AttachmentGitHubActionsJob is part of an experimental API and may change or +// be removed. +type AttachmentGitHubActionsJob struct { + // Terminal conclusion of the job when finished (e.g., success, failure, cancelled). Absent + // for in-progress jobs. + Conclusion *string `json:"conclusion,omitempty"` + // Job id within the workflow run + JobID int64 `json:"jobId"` + // Display name of the job + JobName string `json:"jobName"` + // Repository the workflow run belongs to + Repo GitHubRepoRef `json:"repo"` + // URL to the job on GitHub + URL string `json:"url"` + // Display name of the workflow the job ran in + WorkflowName string `json:"workflowName"` +} + +func (AttachmentGitHubActionsJob) attachment() {} +func (AttachmentGitHubActionsJob) Type() AttachmentType { + return AttachmentTypeGitHubActionsJob +} + +// Pointer to a GitHub commit. +// Experimental: AttachmentGitHubCommit is part of an experimental API and may change or be +// removed. +type AttachmentGitHubCommit struct { + // First line of the commit message + Message string `json:"message"` + // Full commit SHA + Oid string `json:"oid"` + // Repository the commit belongs to + Repo GitHubRepoRef `json:"repo"` + // URL to the commit on GitHub + URL string `json:"url"` +} + +func (AttachmentGitHubCommit) attachment() {} +func (AttachmentGitHubCommit) Type() AttachmentType { + return AttachmentTypeGitHubCommit +} + +// Pointer to a file in a GitHub repository at a specific ref. +// Experimental: AttachmentGitHubFile is part of an experimental API and may change or be +// removed. +type AttachmentGitHubFile struct { + // Repository-relative path to the file + Path string `json:"path"` + // Git ref the file is read at (branch, tag, or commit SHA) + Ref string `json:"ref"` + // Repository the file lives in + Repo GitHubRepoRef `json:"repo"` + // URL to the file on GitHub + URL string `json:"url"` +} + +func (AttachmentGitHubFile) attachment() {} +func (AttachmentGitHubFile) Type() AttachmentType { + return AttachmentTypeGitHubFile +} + +// Pointer to a single-file diff. At least one of `head` and `base` must be present. +// Experimental: AttachmentGitHubFileDiff is part of an experimental API and may change or +// be removed. +type AttachmentGitHubFileDiff struct { + // File location on the base side of the diff. Absent for additions. + Base *AttachmentGitHubFileDiffSide `json:"base,omitempty"` + // File location on the head side of the diff. Absent for deletions. + Head *AttachmentGitHubFileDiffSide `json:"head,omitempty"` + // URL to the diff on GitHub (e.g., a commit, compare, or PR-file URL) + URL string `json:"url"` +} + +func (AttachmentGitHubFileDiff) attachment() {} +func (AttachmentGitHubFileDiff) Type() AttachmentType { + return AttachmentTypeGitHubFileDiff +} + // GitHub issue, pull request, or discussion reference // Experimental: AttachmentGitHubReference is part of an experimental API and may change or // be removed. @@ -566,6 +645,96 @@ func (AttachmentGitHubReference) Type() AttachmentType { return AttachmentTypeGitHubReference } +// Pointer to a GitHub release. +// Experimental: AttachmentGitHubRelease is part of an experimental API and may change or be +// removed. +type AttachmentGitHubRelease struct { + // Human-readable release name + Name string `json:"name"` + // Repository the release belongs to + Repo GitHubRepoRef `json:"repo"` + // Git tag the release is anchored to + TagName string `json:"tagName"` + // URL to the release on GitHub + URL string `json:"url"` +} + +func (AttachmentGitHubRelease) attachment() {} +func (AttachmentGitHubRelease) Type() AttachmentType { + return AttachmentTypeGitHubRelease +} + +// Pointer to a GitHub repository. +// Experimental: AttachmentGitHubRepository is part of an experimental API and may change or +// be removed. +type AttachmentGitHubRepository struct { + // Short description of the repository + Description *string `json:"description,omitempty"` + // Git ref this attachment is anchored at (branch, tag, or commit). When absent the default + // branch is implied. + Ref *string `json:"ref,omitempty"` + // Repository pointer + Repo GitHubRepoRef `json:"repo"` + // URL to the repository on GitHub + URL string `json:"url"` +} + +func (AttachmentGitHubRepository) attachment() {} +func (AttachmentGitHubRepository) Type() AttachmentType { + return AttachmentTypeGitHubRepository +} + +// Pointer to a line range inside a file in a GitHub repository. +// Experimental: AttachmentGitHubSnippet is part of an experimental API and may change or be +// removed. +type AttachmentGitHubSnippet struct { + // Line range the snippet covers + LineRange AttachmentFileLineRange `json:"lineRange"` + // Repository-relative path to the file + Path string `json:"path"` + // Git ref the file is read at (branch, tag, or commit SHA) + Ref string `json:"ref"` + // Repository the file lives in + Repo GitHubRepoRef `json:"repo"` + // URL to the snippet on GitHub (with line anchor) + URL string `json:"url"` +} + +func (AttachmentGitHubSnippet) attachment() {} +func (AttachmentGitHubSnippet) Type() AttachmentType { + return AttachmentTypeGitHubSnippet +} + +// Pointer to a comparison between two git revisions. +// Experimental: AttachmentGitHubTreeComparison is part of an experimental API and may +// change or be removed. +type AttachmentGitHubTreeComparison struct { + // Base side of the comparison + Base AttachmentGitHubTreeComparisonSide `json:"base"` + // Head side of the comparison + Head AttachmentGitHubTreeComparisonSide `json:"head"` + // URL to the comparison on GitHub + URL string `json:"url"` +} + +func (AttachmentGitHubTreeComparison) attachment() {} +func (AttachmentGitHubTreeComparison) Type() AttachmentType { + return AttachmentTypeGitHubTreeComparison +} + +// Generic GitHub URL reference. +// Experimental: AttachmentGitHubURL is part of an experimental API and may change or be +// removed. +type AttachmentGitHubURL struct { + // URL to the GitHub resource + URL string `json:"url"` +} + +func (AttachmentGitHubURL) attachment() {} +func (AttachmentGitHubURL) Type() AttachmentType { + return AttachmentTypeGitHubURL +} + // Code selection attachment from an editor // Experimental: AttachmentSelection is part of an experimental API and may change or be // removed. @@ -595,6 +764,28 @@ type AttachmentFileLineRange struct { Start int64 `json:"start"` } +// One side of a file diff (head or base) +// Experimental: AttachmentGitHubFileDiffSide is part of an experimental API and may change +// or be removed. +type AttachmentGitHubFileDiffSide struct { + // Repository-relative path to the file + Path string `json:"path"` + // Git ref (branch, tag, or commit SHA) the file is read at + Ref string `json:"ref"` + // Repository the file lives in + Repo GitHubRepoRef `json:"repo"` +} + +// One side of a tree comparison (head or base) +// Experimental: AttachmentGitHubTreeComparisonSide is part of an experimental API and may +// change or be removed. +type AttachmentGitHubTreeComparisonSide struct { + // Repository the revision belongs to + Repo GitHubRepoRef `json:"repo"` + // Git revision (branch, tag, or commit SHA) + Revision string `json:"revision"` +} + // Position range of the selection within the file // Experimental: AttachmentSelectionDetails is part of an experimental API and may change or // be removed. @@ -1713,6 +1904,17 @@ type FolderTrustCheckResult struct { Trusted bool `json:"trusted"` } +// Pointer to a GitHub repository. +// Experimental: GitHubRepoRef is part of an experimental API and may change or be removed. +type GitHubRepoRef struct { + // Numeric GitHub repository id + ID *int64 `json:"id,omitempty"` + // Repository name (without owner) + Name string `json:"name"` + // Repository owner login (user or organization) + Owner string `json:"owner"` +} + // Pending external tool call request ID, with the tool result or an error describing why it // failed. // Experimental: HandlePendingToolCallRequest is part of an experimental API and may change @@ -1844,6 +2046,10 @@ type InstalledPlugin struct { // Experimental: InstalledPluginInfo is part of an experimental API and may change or be // removed. type InstalledPluginInfo struct { + // Opaque, stable hash identifying a direct (non-marketplace) install source. Present only + // for direct repo / URL / local installs; absent for marketplace plugins. Same source + // yields the same id; distinct sources never collide. + DirectSourceID *string `json:"directSourceId,omitempty"` // Whether the plugin is currently enabled for new sessions Enabled bool `json:"enabled"` // Marketplace the plugin came from. Empty string ("") for direct repo / URL / local @@ -2617,6 +2823,65 @@ type MCPFilteredServer struct { RedactedReason *string `json:"redactedReason,omitempty"` } +// Host response: supply dynamic headers or decline this refresh. +// Experimental: MCPHeadersHandlePendingHeadersRefreshRequest is part of an experimental API +// and may change or be removed. +type MCPHeadersHandlePendingHeadersRefreshRequest interface { + mcpHeadersHandlePendingHeadersRefreshRequest() + Kind() MCPHeadersHandlePendingHeadersRefreshRequestKind +} + +type RawMCPHeadersHandlePendingHeadersRefreshRequestData struct { + Discriminator MCPHeadersHandlePendingHeadersRefreshRequestKind + Raw json.RawMessage +} + +func (RawMCPHeadersHandlePendingHeadersRefreshRequestData) mcpHeadersHandlePendingHeadersRefreshRequest() { +} +func (r RawMCPHeadersHandlePendingHeadersRefreshRequestData) Kind() MCPHeadersHandlePendingHeadersRefreshRequestKind { + return r.Discriminator +} + +type MCPHeadersHandlePendingHeadersRefreshRequestHeaders struct { + // Headers to overlay onto the MCP request. Dynamic headers override static config headers + // but do not replace SDK-managed request headers. + Headers map[string]string `json:"headers"` +} + +func (MCPHeadersHandlePendingHeadersRefreshRequestHeaders) mcpHeadersHandlePendingHeadersRefreshRequest() { +} +func (MCPHeadersHandlePendingHeadersRefreshRequestHeaders) Kind() MCPHeadersHandlePendingHeadersRefreshRequestKind { + return MCPHeadersHandlePendingHeadersRefreshRequestKindHeaders +} + +type MCPHeadersHandlePendingHeadersRefreshRequestNone struct { +} + +func (MCPHeadersHandlePendingHeadersRefreshRequestNone) mcpHeadersHandlePendingHeadersRefreshRequest() { +} +func (MCPHeadersHandlePendingHeadersRefreshRequestNone) Kind() MCPHeadersHandlePendingHeadersRefreshRequestKind { + return MCPHeadersHandlePendingHeadersRefreshRequestKindNone +} + +// MCP headers refresh request id and the host response. +// Experimental: MCPHeadersHandlePendingHeadersRefreshRequestRequest is part of an +// experimental API and may change or be removed. +type MCPHeadersHandlePendingHeadersRefreshRequestRequest struct { + // Headers refresh request identifier from mcp.headers_refresh_required + RequestID string `json:"requestId"` + // Host response: supply dynamic headers or decline this refresh. + Result MCPHeadersHandlePendingHeadersRefreshRequest `json:"result"` +} + +// Indicates whether the pending MCP headers refresh response was accepted. +// Experimental: MCPHeadersHandlePendingHeadersRefreshRequestResult is part of an +// experimental API and may change or be removed. +type MCPHeadersHandlePendingHeadersRefreshRequestResult struct { + // Whether the response was accepted. False if the request was unknown, timed out, or + // already resolved. + Success bool `json:"success"` +} + // Host-level state, omitted when no MCP host is initialized. // Experimental: MCPHostState is part of an experimental API and may change or be removed. type MCPHostState struct { @@ -2768,8 +3033,6 @@ type MCPOauthPendingRequestResponseToken struct { AccessToken string `json:"accessToken"` // Token lifetime in seconds, if known. ExpiresIn *int64 `json:"expiresIn,omitempty"` - // Refresh token supplied by the host, if available. - RefreshToken *string `json:"refreshToken,omitempty"` // OAuth token type. Defaults to Bearer when omitted. TokenType *string `json:"tokenType,omitempty"` } @@ -3236,6 +3499,10 @@ type Model struct { // Billing information type ModelBilling struct { + // Whole-number percentage discount (0-100) applied to usage billed through this model. + // Populated for the synthetic `auto` model, where requests routed by auto-mode are billed + // at a reduced rate; absent for concrete models. + DiscountPercent *int32 `json:"discountPercent,omitempty"` // Billing cost multiplier relative to the base rate Multiplier *float64 `json:"multiplier,omitempty"` // Token-level pricing information for this model @@ -4891,6 +5158,9 @@ type PluginsReloadRequest struct { // Experimental: PluginsUninstallRequest is part of an experimental API and may change or be // removed. type PluginsUninstallRequest struct { + // Stable source identity for a direct (non-marketplace) install. Disambiguates uninstall + // when multiple installed plugins share the same name. + DirectSourceID *string `json:"directSourceId,omitempty"` // Plugin name or "plugin@marketplace" spec to uninstall. When ambiguous, prefer the // fully-qualified spec. Name string `json:"name"` @@ -5214,6 +5484,85 @@ func (PushAttachmentFile) Type() PushAttachmentType { return PushAttachmentTypeFile } +// Pointer to a GitHub Actions job. +// Experimental: PushAttachmentGitHubActionsJob is part of an experimental API and may +// change or be removed. +type PushAttachmentGitHubActionsJob struct { + // Terminal conclusion of the job when finished (e.g., success, failure, cancelled). Absent + // for in-progress jobs. + Conclusion *string `json:"conclusion,omitempty"` + // Job id within the workflow run + JobID int64 `json:"jobId"` + // Display name of the job + JobName string `json:"jobName"` + // Repository the workflow run belongs to + Repo PushGitHubRepoRef `json:"repo"` + // URL to the job on GitHub + URL string `json:"url"` + // Display name of the workflow the job ran in + WorkflowName string `json:"workflowName"` +} + +func (PushAttachmentGitHubActionsJob) pushAttachment() {} +func (PushAttachmentGitHubActionsJob) Type() PushAttachmentType { + return PushAttachmentTypeGitHubActionsJob +} + +// Pointer to a GitHub commit. +// Experimental: PushAttachmentGitHubCommit is part of an experimental API and may change or +// be removed. +type PushAttachmentGitHubCommit struct { + // First line of the commit message + Message string `json:"message"` + // Full commit SHA + Oid string `json:"oid"` + // Repository the commit belongs to + Repo PushGitHubRepoRef `json:"repo"` + // URL to the commit on GitHub + URL string `json:"url"` +} + +func (PushAttachmentGitHubCommit) pushAttachment() {} +func (PushAttachmentGitHubCommit) Type() PushAttachmentType { + return PushAttachmentTypeGitHubCommit +} + +// Pointer to a file in a GitHub repository at a specific ref. +// Experimental: PushAttachmentGitHubFile is part of an experimental API and may change or +// be removed. +type PushAttachmentGitHubFile struct { + // Repository-relative path to the file + Path string `json:"path"` + // Git ref the file is read at (branch, tag, or commit SHA) + Ref string `json:"ref"` + // Repository the file lives in + Repo PushGitHubRepoRef `json:"repo"` + // URL to the file on GitHub + URL string `json:"url"` +} + +func (PushAttachmentGitHubFile) pushAttachment() {} +func (PushAttachmentGitHubFile) Type() PushAttachmentType { + return PushAttachmentTypeGitHubFile +} + +// Pointer to a single-file diff. At least one of `head` and `base` must be present. +// Experimental: PushAttachmentGitHubFileDiff is part of an experimental API and may change +// or be removed. +type PushAttachmentGitHubFileDiff struct { + // File location on the base side of the diff. Absent for additions. + Base *PushAttachmentGitHubFileDiffSide `json:"base,omitempty"` + // File location on the head side of the diff. Absent for deletions. + Head *PushAttachmentGitHubFileDiffSide `json:"head,omitempty"` + // URL to the diff on GitHub (e.g., a commit, compare, or PR-file URL) + URL string `json:"url"` +} + +func (PushAttachmentGitHubFileDiff) pushAttachment() {} +func (PushAttachmentGitHubFileDiff) Type() PushAttachmentType { + return PushAttachmentTypeGitHubFileDiff +} + // GitHub issue, pull request, or discussion reference // Experimental: PushAttachmentGitHubReference is part of an experimental API and may change // or be removed. @@ -5235,6 +5584,96 @@ func (PushAttachmentGitHubReference) Type() PushAttachmentType { return PushAttachmentTypeGitHubReference } +// Pointer to a GitHub release. +// Experimental: PushAttachmentGitHubRelease is part of an experimental API and may change +// or be removed. +type PushAttachmentGitHubRelease struct { + // Human-readable release name + Name string `json:"name"` + // Repository the release belongs to + Repo PushGitHubRepoRef `json:"repo"` + // Git tag the release is anchored to + TagName string `json:"tagName"` + // URL to the release on GitHub + URL string `json:"url"` +} + +func (PushAttachmentGitHubRelease) pushAttachment() {} +func (PushAttachmentGitHubRelease) Type() PushAttachmentType { + return PushAttachmentTypeGitHubRelease +} + +// Pointer to a GitHub repository. +// Experimental: PushAttachmentGitHubRepository is part of an experimental API and may +// change or be removed. +type PushAttachmentGitHubRepository struct { + // Short description of the repository + Description *string `json:"description,omitempty"` + // Git ref this attachment is anchored at (branch, tag, or commit). When absent the default + // branch is implied. + Ref *string `json:"ref,omitempty"` + // Repository pointer + Repo PushGitHubRepoRef `json:"repo"` + // URL to the repository on GitHub + URL string `json:"url"` +} + +func (PushAttachmentGitHubRepository) pushAttachment() {} +func (PushAttachmentGitHubRepository) Type() PushAttachmentType { + return PushAttachmentTypeGitHubRepository +} + +// Pointer to a line range inside a file in a GitHub repository. +// Experimental: PushAttachmentGitHubSnippet is part of an experimental API and may change +// or be removed. +type PushAttachmentGitHubSnippet struct { + // Line range the snippet covers + LineRange PushAttachmentFileLineRange `json:"lineRange"` + // Repository-relative path to the file + Path string `json:"path"` + // Git ref the file is read at (branch, tag, or commit SHA) + Ref string `json:"ref"` + // Repository the file lives in + Repo PushGitHubRepoRef `json:"repo"` + // URL to the snippet on GitHub (with line anchor) + URL string `json:"url"` +} + +func (PushAttachmentGitHubSnippet) pushAttachment() {} +func (PushAttachmentGitHubSnippet) Type() PushAttachmentType { + return PushAttachmentTypeGitHubSnippet +} + +// Pointer to a comparison between two git revisions. +// Experimental: PushAttachmentGitHubTreeComparison is part of an experimental API and may +// change or be removed. +type PushAttachmentGitHubTreeComparison struct { + // Base side of the comparison + Base PushAttachmentGitHubTreeComparisonSide `json:"base"` + // Head side of the comparison + Head PushAttachmentGitHubTreeComparisonSide `json:"head"` + // URL to the comparison on GitHub + URL string `json:"url"` +} + +func (PushAttachmentGitHubTreeComparison) pushAttachment() {} +func (PushAttachmentGitHubTreeComparison) Type() PushAttachmentType { + return PushAttachmentTypeGitHubTreeComparison +} + +// Generic GitHub URL reference. +// Experimental: PushAttachmentGitHubURL is part of an experimental API and may change or be +// removed. +type PushAttachmentGitHubURL struct { + // URL to the GitHub resource + URL string `json:"url"` +} + +func (PushAttachmentGitHubURL) pushAttachment() {} +func (PushAttachmentGitHubURL) Type() PushAttachmentType { + return PushAttachmentTypeGitHubURL +} + // Code selection attachment from an editor // Experimental: PushAttachmentSelection is part of an experimental API and may change or be // removed. @@ -5264,6 +5703,28 @@ type PushAttachmentFileLineRange struct { Start int64 `json:"start"` } +// One side of a file diff (head or base) +// Experimental: PushAttachmentGitHubFileDiffSide is part of an experimental API and may +// change or be removed. +type PushAttachmentGitHubFileDiffSide struct { + // Repository-relative path to the file + Path string `json:"path"` + // Git ref (branch, tag, or commit SHA) the file is read at + Ref string `json:"ref"` + // Repository the file lives in + Repo PushGitHubRepoRef `json:"repo"` +} + +// One side of a tree comparison (head or base) +// Experimental: PushAttachmentGitHubTreeComparisonSide is part of an experimental API and +// may change or be removed. +type PushAttachmentGitHubTreeComparisonSide struct { + // Repository the revision belongs to + Repo PushGitHubRepoRef `json:"repo"` + // Git revision (branch, tag, or commit SHA) + Revision string `json:"revision"` +} + // Position range of the selection within the file // Experimental: PushAttachmentSelectionDetails is part of an experimental API and may // change or be removed. @@ -5294,6 +5755,18 @@ type PushAttachmentSelectionDetailsStart struct { Line int64 `json:"line"` } +// Pointer to a GitHub repository. +// Experimental: PushGitHubRepoRef is part of an experimental API and may change or be +// removed. +type PushGitHubRepoRef struct { + // Numeric GitHub repository id + ID *int64 `json:"id,omitempty"` + // Repository name (without owner) + Name string `json:"name"` + // Repository owner login (user or organization) + Owner string `json:"owner"` +} + // Result of the queued command execution. // Experimental: QueuedCommandResult is part of an experimental API and may change or be // removed. @@ -5641,6 +6114,16 @@ type RemoteSessionRepository struct { Owner string `json:"owner"` } +// Optional response budget limits. +// Experimental: ResponseBudgetConfig is part of an experimental API and may change or be +// removed. +type ResponseBudgetConfig struct { + // Maximum AI Credits allowed while responding to one top-level user message. + MaxAiCredits *float64 `json:"maxAiCredits,omitempty"` + // Maximum model-call iterations allowed while responding to one top-level user message. + MaxModelIterations *int64 `json:"maxModelIterations,omitempty"` +} + type RuntimeShutdownResult struct { } @@ -6565,6 +7048,9 @@ type SessionOpenOptions struct { AdditionalContentExclusionPolicies []SessionOpenOptionsAdditionalContentExclusionPolicy `json:"additionalContentExclusionPolicies,omitzero"` // Runtime context discriminator for agent filtering. AgentContext *string `json:"agentContext,omitempty"` + // Whether to include instructions from every MCP server in the system prompt instead of + // only allowlisted servers. + AllowAllMCPServerInstructions *bool `json:"allowAllMcpServerInstructions,omitempty"` // Whether ask_user is explicitly disabled. AskUserDisabled *bool `json:"askUserDisabled,omitempty"` // Initial authentication info for the session. @@ -6662,6 +7148,8 @@ type SessionOpenOptions struct { RemoteExporting *bool `json:"remoteExporting,omitempty"` // Whether this session supports remote steering. RemoteSteerable *bool `json:"remoteSteerable,omitempty"` + // Initial response budget limits for the session. + ResponseBudget *ResponseBudgetConfig `json:"responseBudget,omitempty"` // Whether the host is an interactive UI. RunningInInteractiveMode *bool `json:"runningInInteractiveMode,omitempty"` // Resolved sandbox configuration. @@ -6996,10 +7484,14 @@ type SessionsEnrichMetadataRequest struct { // or be removed. type SessionSetCredentialsParams struct { // The new auth credentials to install on the session. When omitted or `undefined`, the call - // is a no-op and the session's existing credentials are preserved. The runtime stores the - // value verbatim and uses it for outbound model/API requests; it does NOT re-validate or - // re-fetch the associated Copilot user response. Several variants carry secret material; - // treat this method's params as containing secrets at rest and in transit. + // is a no-op and the session's existing credentials are preserved. The runtime installs the + // supplied value immediately for outbound model/API requests. When the credential carries a + // raw token (`token`, `env`, or `gh-cli`) but no `copilotUser`, the runtime additionally + // re-resolves `copilotUser` server-side (best-effort, asynchronously, after the synchronous + // install) so plan/quota/billing metadata regains fidelity; on resolution failure the + // verbatim credential remains installed. It does NOT otherwise validate the credential. + // Several variants carry secret material; treat this method's params as containing secrets + // at rest and in transit. Credentials AuthInfo `json:"credentials,omitempty"` } @@ -7007,6 +7499,15 @@ type SessionSetCredentialsParams struct { // Experimental: SessionSetCredentialsResult is part of an experimental API and may change // or be removed. type SessionSetCredentialsResult struct { + // Whether the session ended up with a populated `copilotUser` for the installed + // credentials. `true` when the supplied credential already carried `copilotUser` or it was + // successfully re-resolved server-side. `false` when the credential is installed without + // `copilotUser` — either re-resolution failed, or the variant cannot be re-resolved from + // the credential alone (only the raw-token variants `token`, `env`, and `gh-cli` can). In + // both `false` cases the token swap still applied, but plan/quota/billing metadata is + // degraded. Present whenever a credential was supplied; omitted only when no credential was + // supplied (no-op call). + CopilotUserResolved *bool `json:"copilotUserResolved,omitempty"` // Whether the operation succeeded Success bool `json:"success"` } @@ -7384,6 +7885,9 @@ type SessionUpdateOptionsParams struct { AdditionalContentExclusionPolicies []OptionsUpdateAdditionalContentExclusionPolicy `json:"additionalContentExclusionPolicies,omitzero"` // Runtime context discriminator (e.g., `cli`, `actions`). AgentContext *string `json:"agentContext,omitempty"` + // Whether to include instructions from every MCP server in the system prompt instead of + // only allowlisted servers. + AllowAllMCPServerInstructions *bool `json:"allowAllMcpServerInstructions,omitempty"` // Whether to disable the `ask_user` tool (encourages autonomous behavior). AskUserDisabled *bool `json:"askUserDisabled,omitempty"` // Allowlist of tool names available to this session. @@ -7471,6 +7975,8 @@ type SessionUpdateOptionsParams struct { ReasoningEffort *string `json:"reasoningEffort,omitempty"` // Reasoning summary mode for supported model clients. ReasoningSummary *OptionsUpdateReasoningSummary `json:"reasoningSummary,omitempty"` + // Optional response budget limits. Pass null to clear the response budget. + ResponseBudget *ResponseBudgetConfig `json:"responseBudget,omitempty"` // Whether the session is running in an interactive UI. RunningInInteractiveMode *bool `json:"runningInInteractiveMode,omitempty"` // Resolved sandbox configuration. @@ -7781,8 +8287,8 @@ type SlashCommandInput struct { Required *bool `json:"required,omitempty"` } -// Result of invoking the slash command (text output, prompt to send to the agent, or -// completion). +// Result of invoking the slash command (text output, prompt to send to the agent, +// completion, or subcommand selection). // Experimental: SlashCommandInvocationResult is part of an experimental API and may change // or be removed. type SlashCommandInvocationResult interface { @@ -7896,6 +8402,11 @@ type SubagentSettings struct { Agents map[string]SubagentSettingsEntry `json:"agents,omitzero"` // Names of subagents the user has turned off; they cannot be dispatched DisabledSubagents []string `json:"disabledSubagents,omitzero"` + // Maximum number of subagents that can run concurrently; applies to usage-based billing + // users only + MaxConcurrency *int32 `json:"maxConcurrency,omitempty"` + // Maximum subagent nesting depth; applies to usage-based billing users only + MaxDepth *int32 `json:"maxDepth,omitempty"` } // Subagent model, reasoning effort, and context tier settings @@ -9356,12 +9867,21 @@ const ( type AttachmentType string const ( - AttachmentTypeBlob AttachmentType = "blob" - AttachmentTypeDirectory AttachmentType = "directory" - AttachmentTypeExtensionContext AttachmentType = "extension_context" - AttachmentTypeFile AttachmentType = "file" - AttachmentTypeGitHubReference AttachmentType = "github_reference" - AttachmentTypeSelection AttachmentType = "selection" + AttachmentTypeBlob AttachmentType = "blob" + AttachmentTypeDirectory AttachmentType = "directory" + AttachmentTypeExtensionContext AttachmentType = "extension_context" + AttachmentTypeFile AttachmentType = "file" + AttachmentTypeGitHubActionsJob AttachmentType = "github_actions_job" + AttachmentTypeGitHubCommit AttachmentType = "github_commit" + AttachmentTypeGitHubFile AttachmentType = "github_file" + AttachmentTypeGitHubFileDiff AttachmentType = "github_file_diff" + AttachmentTypeGitHubReference AttachmentType = "github_reference" + AttachmentTypeGitHubRelease AttachmentType = "github_release" + AttachmentTypeGitHubRepository AttachmentType = "github_repository" + AttachmentTypeGitHubSnippet AttachmentType = "github_snippet" + AttachmentTypeGitHubTreeComparison AttachmentType = "github_tree_comparison" + AttachmentTypeGitHubURL AttachmentType = "github_url" + AttachmentTypeSelection AttachmentType = "selection" ) // Type discriminator for AuthInfo. @@ -9760,6 +10280,14 @@ const ( MCPAppsSetHostContextDetailsThemeLight MCPAppsSetHostContextDetailsTheme = "light" ) +// Kind discriminator for MCPHeadersHandlePendingHeadersRefreshRequest. +type MCPHeadersHandlePendingHeadersRefreshRequestKind string + +const ( + MCPHeadersHandlePendingHeadersRefreshRequestKindHeaders MCPHeadersHandlePendingHeadersRefreshRequestKind = "headers" + MCPHeadersHandlePendingHeadersRefreshRequestKindNone MCPHeadersHandlePendingHeadersRefreshRequestKind = "none" +) + // OAuth grant type override for this login. // Experimental: MCPOauthLoginGrantType is part of an experimental API and may change or be // removed. @@ -10255,12 +10783,21 @@ const ( type PushAttachmentType string const ( - PushAttachmentTypeBlob PushAttachmentType = "blob" - PushAttachmentTypeDirectory PushAttachmentType = "directory" - PushAttachmentTypeExtensionContext PushAttachmentType = "extension_context" - PushAttachmentTypeFile PushAttachmentType = "file" - PushAttachmentTypeGitHubReference PushAttachmentType = "github_reference" - PushAttachmentTypeSelection PushAttachmentType = "selection" + PushAttachmentTypeBlob PushAttachmentType = "blob" + PushAttachmentTypeDirectory PushAttachmentType = "directory" + PushAttachmentTypeExtensionContext PushAttachmentType = "extension_context" + PushAttachmentTypeFile PushAttachmentType = "file" + PushAttachmentTypeGitHubActionsJob PushAttachmentType = "github_actions_job" + PushAttachmentTypeGitHubCommit PushAttachmentType = "github_commit" + PushAttachmentTypeGitHubFile PushAttachmentType = "github_file" + PushAttachmentTypeGitHubFileDiff PushAttachmentType = "github_file_diff" + PushAttachmentTypeGitHubReference PushAttachmentType = "github_reference" + PushAttachmentTypeGitHubRelease PushAttachmentType = "github_release" + PushAttachmentTypeGitHubRepository PushAttachmentType = "github_repository" + PushAttachmentTypeGitHubSnippet PushAttachmentType = "github_snippet" + PushAttachmentTypeGitHubTreeComparison PushAttachmentType = "github_tree_comparison" + PushAttachmentTypeGitHubURL PushAttachmentType = "github_url" + PushAttachmentTypeSelection PushAttachmentType = "selection" ) // Whether this item is a queued user message or a queued slash command / model change @@ -12677,54 +13214,6 @@ func (a *AgentAPI) Select(ctx context.Context, params *AgentSelectRequest) (*Age return &result, nil } -// Experimental: AuthAPI contains experimental APIs that may change or be removed. -type AuthAPI sessionAPI - -// GetStatus gets authentication status and account metadata for the session. -// -// RPC method: session.auth.getStatus. -// -// Returns: Authentication status and account metadata for the session. -func (a *AuthAPI) GetStatus(ctx context.Context) (*SessionAuthStatus, error) { - req := map[string]any{"sessionId": a.sessionID} - raw, err := a.client.Request(ctx, "session.auth.getStatus", req) - if err != nil { - return nil, err - } - var result SessionAuthStatus - if err := json.Unmarshal(raw, &result); err != nil { - return nil, err - } - return &result, nil -} - -// SetCredentials updates the session's auth credentials used for outbound model and API -// requests. -// -// RPC method: session.auth.setCredentials. -// -// Parameters: New auth credentials to install on the session. Omit to leave credentials -// unchanged. -// -// Returns: Indicates whether the credential update succeeded. -func (a *AuthAPI) SetCredentials(ctx context.Context, params *SessionSetCredentialsParams) (*SessionSetCredentialsResult, error) { - req := map[string]any{"sessionId": a.sessionID} - if params != nil { - if params.Credentials != nil { - req["credentials"] = params.Credentials - } - } - raw, err := a.client.Request(ctx, "session.auth.setCredentials", req) - if err != nil { - return nil, err - } - var result SessionSetCredentialsResult - if err := json.Unmarshal(raw, &result); err != nil { - return nil, err - } - return &result, nil -} - // Experimental: CanvasAPI contains experimental APIs that may change or be removed. type CanvasAPI sessionAPI @@ -12933,7 +13422,7 @@ func (a *CommandsAPI) HandlePendingCommand(ctx context.Context, params *Commands // Parameters: Slash command name and optional raw input string to invoke. // // Returns: Result of invoking the slash command (text output, prompt to send to the agent, -// or completion). +// completion, or subcommand selection). func (a *CommandsAPI) Invoke(ctx context.Context, params *CommandsInvokeRequest) (SlashCommandInvocationResult, error) { req := map[string]any{"sessionId": a.sessionID} if params != nil { @@ -13257,6 +13746,54 @@ func (a *FleetAPI) Start(ctx context.Context, params *FleetStartRequest) (*Fleet return &result, nil } +// Experimental: GitHubAuthAPI contains experimental APIs that may change or be removed. +type GitHubAuthAPI sessionAPI + +// GetStatus gets authentication status and account metadata for the session. +// +// RPC method: session.gitHubAuth.getStatus. +// +// Returns: Authentication status and account metadata for the session. +func (a *GitHubAuthAPI) GetStatus(ctx context.Context) (*SessionAuthStatus, error) { + req := map[string]any{"sessionId": a.sessionID} + raw, err := a.client.Request(ctx, "session.gitHubAuth.getStatus", req) + if err != nil { + return nil, err + } + var result SessionAuthStatus + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// SetCredentials updates the session's auth credentials used for outbound model and API +// requests. +// +// RPC method: session.gitHubAuth.setCredentials. +// +// Parameters: New auth credentials to install on the session. Omit to leave credentials +// unchanged. +// +// Returns: Indicates whether the credential update succeeded. +func (a *GitHubAuthAPI) SetCredentials(ctx context.Context, params *SessionSetCredentialsParams) (*SessionSetCredentialsResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + if params.Credentials != nil { + req["credentials"] = params.Credentials + } + } + raw, err := a.client.Request(ctx, "session.gitHubAuth.setCredentials", req) + if err != nil { + return nil, err + } + var result SessionSetCredentialsResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + // Experimental: HistoryAPI contains experimental APIs that may change or be removed. type HistoryAPI sessionAPI @@ -13824,6 +14361,41 @@ func (s *MCPAPI) Apps() *MCPAppsAPI { return (*MCPAppsAPI)(s) } +// Experimental: MCPHeadersAPI contains experimental APIs that may change or be removed. +type MCPHeadersAPI sessionAPI + +// HandlePendingHeadersRefreshRequest responds to a pending MCP dynamic headers refresh +// request. Hosts that subscribe to `mcp.headers_refresh_required` use this to provide +// short-lived per-server headers or to indicate that no dynamic headers are available for +// this refresh. +// +// RPC method: session.mcp.headers.handlePendingHeadersRefreshRequest. +// +// Parameters: MCP headers refresh request id and the host response. +// +// Returns: Indicates whether the pending MCP headers refresh response was accepted. +func (a *MCPHeadersAPI) HandlePendingHeadersRefreshRequest(ctx context.Context, params *MCPHeadersHandlePendingHeadersRefreshRequestRequest) (*MCPHeadersHandlePendingHeadersRefreshRequestResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["requestId"] = params.RequestID + req["result"] = params.Result + } + raw, err := a.client.Request(ctx, "session.mcp.headers.handlePendingHeadersRefreshRequest", req) + if err != nil { + return nil, err + } + var result MCPHeadersHandlePendingHeadersRefreshRequestResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Experimental: Headers returns experimental APIs that may change or be removed. +func (s *MCPAPI) Headers() *MCPHeadersAPI { + return (*MCPHeadersAPI)(s) +} + // Experimental: MCPOauthAPI contains experimental APIs that may change or be removed. type MCPOauthAPI sessionAPI @@ -14317,6 +14889,9 @@ func (a *OptionsAPI) Update(ctx context.Context, params *SessionUpdateOptionsPar if params.AgentContext != nil { req["agentContext"] = *params.AgentContext } + if params.AllowAllMCPServerInstructions != nil { + req["allowAllMcpServerInstructions"] = *params.AllowAllMCPServerInstructions + } if params.AskUserDisabled != nil { req["askUserDisabled"] = *params.AskUserDisabled } @@ -14425,6 +15000,9 @@ func (a *OptionsAPI) Update(ctx context.Context, params *SessionUpdateOptionsPar if params.ReasoningSummary != nil { req["reasoningSummary"] = *params.ReasoningSummary } + if params.ResponseBudget != nil { + req["responseBudget"] = *params.ResponseBudget + } if params.RunningInInteractiveMode != nil { req["runningInInteractiveMode"] = *params.RunningInInteractiveMode } @@ -16503,12 +17081,12 @@ type SessionRPC struct { common sessionAPI Agent *AgentAPI - Auth *AuthAPI Canvas *CanvasAPI Commands *CommandsAPI EventLog *EventLogAPI Extensions *ExtensionsAPI Fleet *FleetAPI + GitHubAuth *GitHubAuthAPI History *HistoryAPI Instructions *InstructionsAPI Lsp *LspAPI @@ -16714,12 +17292,12 @@ func NewSessionRPC(client *jsonrpc2.Client, sessionID string) *SessionRPC { r := &SessionRPC{} r.common = sessionAPI{client: client, sessionID: sessionID} r.Agent = (*AgentAPI)(&r.common) - r.Auth = (*AuthAPI)(&r.common) r.Canvas = (*CanvasAPI)(&r.common) r.Commands = (*CommandsAPI)(&r.common) r.EventLog = (*EventLogAPI)(&r.common) r.Extensions = (*ExtensionsAPI)(&r.common) r.Fleet = (*FleetAPI)(&r.common) + r.GitHubAuth = (*GitHubAuthAPI)(&r.common) r.History = (*HistoryAPI)(&r.common) r.Instructions = (*InstructionsAPI)(&r.common) r.Lsp = (*LspAPI)(&r.common) diff --git a/go/rpc/zrpc_encoding.go b/go/rpc/zrpc_encoding.go index b4942942b5..8b9e492702 100644 --- a/go/rpc/zrpc_encoding.go +++ b/go/rpc/zrpc_encoding.go @@ -348,12 +348,66 @@ func unmarshalAttachment(data []byte) (Attachment, error) { return nil, err } return &d, nil + case AttachmentTypeGitHubActionsJob: + var d AttachmentGitHubActionsJob + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AttachmentTypeGitHubCommit: + var d AttachmentGitHubCommit + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AttachmentTypeGitHubFile: + var d AttachmentGitHubFile + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AttachmentTypeGitHubFileDiff: + var d AttachmentGitHubFileDiff + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil case AttachmentTypeGitHubReference: var d AttachmentGitHubReference if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil + case AttachmentTypeGitHubRelease: + var d AttachmentGitHubRelease + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AttachmentTypeGitHubRepository: + var d AttachmentGitHubRepository + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AttachmentTypeGitHubSnippet: + var d AttachmentGitHubSnippet + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AttachmentTypeGitHubTreeComparison: + var d AttachmentGitHubTreeComparison + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AttachmentTypeGitHubURL: + var d AttachmentGitHubURL + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil case AttachmentTypeSelection: var d AttachmentSelection if err := json.Unmarshal(data, &d); err != nil { @@ -420,6 +474,50 @@ func (r AttachmentFile) MarshalJSON() ([]byte, error) { }) } +func (r AttachmentGitHubActionsJob) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubActionsJob + return json.Marshal(struct { + Type AttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r AttachmentGitHubCommit) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubCommit + return json.Marshal(struct { + Type AttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r AttachmentGitHubFile) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubFile + return json.Marshal(struct { + Type AttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r AttachmentGitHubFileDiff) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubFileDiff + return json.Marshal(struct { + Type AttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + func (r AttachmentGitHubReference) MarshalJSON() ([]byte, error) { type alias AttachmentGitHubReference return json.Marshal(struct { @@ -431,6 +529,61 @@ func (r AttachmentGitHubReference) MarshalJSON() ([]byte, error) { }) } +func (r AttachmentGitHubRelease) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubRelease + return json.Marshal(struct { + Type AttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r AttachmentGitHubRepository) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubRepository + return json.Marshal(struct { + Type AttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r AttachmentGitHubSnippet) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubSnippet + return json.Marshal(struct { + Type AttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r AttachmentGitHubTreeComparison) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubTreeComparison + return json.Marshal(struct { + Type AttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r AttachmentGitHubURL) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubURL + return json.Marshal(struct { + Type AttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + func (r AttachmentSelection) MarshalJSON() ([]byte, error) { type alias AttachmentSelection return json.Marshal(struct { @@ -1138,6 +1291,89 @@ func (r *MCPConfigUpdateRequest) UnmarshalJSON(data []byte) error { return nil } +func unmarshalMCPHeadersHandlePendingHeadersRefreshRequest(data []byte) (MCPHeadersHandlePendingHeadersRefreshRequest, error) { + if string(data) == "null" { + return nil, nil + } + type rawUnion struct { + Kind MCPHeadersHandlePendingHeadersRefreshRequestKind `json:"kind"` + } + var raw rawUnion + if err := json.Unmarshal(data, &raw); err != nil { + return nil, err + } + + switch raw.Kind { + case MCPHeadersHandlePendingHeadersRefreshRequestKindHeaders: + var d MCPHeadersHandlePendingHeadersRefreshRequestHeaders + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case MCPHeadersHandlePendingHeadersRefreshRequestKindNone: + var d MCPHeadersHandlePendingHeadersRefreshRequestNone + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + default: + return &RawMCPHeadersHandlePendingHeadersRefreshRequestData{Discriminator: raw.Kind, Raw: data}, nil + } +} + +func (r RawMCPHeadersHandlePendingHeadersRefreshRequestData) MarshalJSON() ([]byte, error) { + if r.Raw != nil { + return r.Raw, nil + } + return json.Marshal(struct { + Kind MCPHeadersHandlePendingHeadersRefreshRequestKind `json:"kind"` + }{ + Kind: r.Discriminator, + }) +} + +func (r MCPHeadersHandlePendingHeadersRefreshRequestHeaders) MarshalJSON() ([]byte, error) { + type alias MCPHeadersHandlePendingHeadersRefreshRequestHeaders + return json.Marshal(struct { + Kind MCPHeadersHandlePendingHeadersRefreshRequestKind `json:"kind"` + alias + }{ + Kind: r.Kind(), + alias: alias(r), + }) +} + +func (r MCPHeadersHandlePendingHeadersRefreshRequestNone) MarshalJSON() ([]byte, error) { + type alias MCPHeadersHandlePendingHeadersRefreshRequestNone + return json.Marshal(struct { + Kind MCPHeadersHandlePendingHeadersRefreshRequestKind `json:"kind"` + alias + }{ + Kind: r.Kind(), + alias: alias(r), + }) +} + +func (r *MCPHeadersHandlePendingHeadersRefreshRequestRequest) UnmarshalJSON(data []byte) error { + type rawMCPHeadersHandlePendingHeadersRefreshRequestRequest struct { + RequestID string `json:"requestId"` + Result json.RawMessage `json:"result"` + } + var raw rawMCPHeadersHandlePendingHeadersRefreshRequestRequest + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + r.RequestID = raw.RequestID + if raw.Result != nil { + value, err := unmarshalMCPHeadersHandlePendingHeadersRefreshRequest(raw.Result) + if err != nil { + return err + } + r.Result = value + } + return nil +} + func unmarshalMCPOauthPendingRequestResponse(data []byte) (MCPOauthPendingRequestResponse, error) { if string(data) == "null" { return nil, nil @@ -2371,12 +2607,66 @@ func unmarshalPushAttachment(data []byte) (PushAttachment, error) { return nil, err } return &d, nil + case PushAttachmentTypeGitHubActionsJob: + var d PushAttachmentGitHubActionsJob + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case PushAttachmentTypeGitHubCommit: + var d PushAttachmentGitHubCommit + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case PushAttachmentTypeGitHubFile: + var d PushAttachmentGitHubFile + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case PushAttachmentTypeGitHubFileDiff: + var d PushAttachmentGitHubFileDiff + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil case PushAttachmentTypeGitHubReference: var d PushAttachmentGitHubReference if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil + case PushAttachmentTypeGitHubRelease: + var d PushAttachmentGitHubRelease + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case PushAttachmentTypeGitHubRepository: + var d PushAttachmentGitHubRepository + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case PushAttachmentTypeGitHubSnippet: + var d PushAttachmentGitHubSnippet + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case PushAttachmentTypeGitHubTreeComparison: + var d PushAttachmentGitHubTreeComparison + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case PushAttachmentTypeGitHubURL: + var d PushAttachmentGitHubURL + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil case PushAttachmentTypeSelection: var d PushAttachmentSelection if err := json.Unmarshal(data, &d); err != nil { @@ -2443,6 +2733,50 @@ func (r PushAttachmentFile) MarshalJSON() ([]byte, error) { }) } +func (r PushAttachmentGitHubActionsJob) MarshalJSON() ([]byte, error) { + type alias PushAttachmentGitHubActionsJob + return json.Marshal(struct { + Type PushAttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r PushAttachmentGitHubCommit) MarshalJSON() ([]byte, error) { + type alias PushAttachmentGitHubCommit + return json.Marshal(struct { + Type PushAttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r PushAttachmentGitHubFile) MarshalJSON() ([]byte, error) { + type alias PushAttachmentGitHubFile + return json.Marshal(struct { + Type PushAttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r PushAttachmentGitHubFileDiff) MarshalJSON() ([]byte, error) { + type alias PushAttachmentGitHubFileDiff + return json.Marshal(struct { + Type PushAttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + func (r PushAttachmentGitHubReference) MarshalJSON() ([]byte, error) { type alias PushAttachmentGitHubReference return json.Marshal(struct { @@ -2454,6 +2788,61 @@ func (r PushAttachmentGitHubReference) MarshalJSON() ([]byte, error) { }) } +func (r PushAttachmentGitHubRelease) MarshalJSON() ([]byte, error) { + type alias PushAttachmentGitHubRelease + return json.Marshal(struct { + Type PushAttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r PushAttachmentGitHubRepository) MarshalJSON() ([]byte, error) { + type alias PushAttachmentGitHubRepository + return json.Marshal(struct { + Type PushAttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r PushAttachmentGitHubSnippet) MarshalJSON() ([]byte, error) { + type alias PushAttachmentGitHubSnippet + return json.Marshal(struct { + Type PushAttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r PushAttachmentGitHubTreeComparison) MarshalJSON() ([]byte, error) { + type alias PushAttachmentGitHubTreeComparison + return json.Marshal(struct { + Type PushAttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r PushAttachmentGitHubURL) MarshalJSON() ([]byte, error) { + type alias PushAttachmentGitHubURL + return json.Marshal(struct { + Type PushAttachmentType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + func (r PushAttachmentSelection) MarshalJSON() ([]byte, error) { type alias PushAttachmentSelection return json.Marshal(struct { @@ -2819,6 +3208,7 @@ func (r *SessionOpenOptions) UnmarshalJSON(data []byte) error { type rawSessionOpenOptions struct { AdditionalContentExclusionPolicies []SessionOpenOptionsAdditionalContentExclusionPolicy `json:"additionalContentExclusionPolicies,omitzero"` AgentContext *string `json:"agentContext,omitempty"` + AllowAllMCPServerInstructions *bool `json:"allowAllMcpServerInstructions,omitempty"` AskUserDisabled *bool `json:"askUserDisabled,omitempty"` AuthInfo json.RawMessage `json:"authInfo,omitempty"` AvailableTools []string `json:"availableTools,omitzero"` @@ -2861,6 +3251,7 @@ func (r *SessionOpenOptions) UnmarshalJSON(data []byte) error { RemoteDefaultedOn *bool `json:"remoteDefaultedOn,omitempty"` RemoteExporting *bool `json:"remoteExporting,omitempty"` RemoteSteerable *bool `json:"remoteSteerable,omitempty"` + ResponseBudget *ResponseBudgetConfig `json:"responseBudget,omitempty"` RunningInInteractiveMode *bool `json:"runningInInteractiveMode,omitempty"` SandboxConfig *SandboxConfig `json:"sandboxConfig,omitempty"` SessionCapabilities []SessionCapability `json:"sessionCapabilities,omitzero"` @@ -2879,6 +3270,7 @@ func (r *SessionOpenOptions) UnmarshalJSON(data []byte) error { } r.AdditionalContentExclusionPolicies = raw.AdditionalContentExclusionPolicies r.AgentContext = raw.AgentContext + r.AllowAllMCPServerInstructions = raw.AllowAllMCPServerInstructions r.AskUserDisabled = raw.AskUserDisabled if raw.AuthInfo != nil { value, err := unmarshalAuthInfo(raw.AuthInfo) @@ -2927,6 +3319,7 @@ func (r *SessionOpenOptions) UnmarshalJSON(data []byte) error { r.RemoteDefaultedOn = raw.RemoteDefaultedOn r.RemoteExporting = raw.RemoteExporting r.RemoteSteerable = raw.RemoteSteerable + r.ResponseBudget = raw.ResponseBudget r.RunningInInteractiveMode = raw.RunningInInteractiveMode r.SandboxConfig = raw.SandboxConfig r.SessionCapabilities = raw.SessionCapabilities diff --git a/go/rpc/zsession_encoding.go b/go/rpc/zsession_encoding.go index 89e9cc26d3..f26dabc269 100644 --- a/go/rpc/zsession_encoding.go +++ b/go/rpc/zsession_encoding.go @@ -41,6 +41,12 @@ func (e *SessionEvent) UnmarshalJSON(data []byte) error { return err } e.Data = &d + case SessionEventTypeAssistantIdle: + var d AssistantIdleData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d case SessionEventTypeAssistantIntent: var d AssistantIntentData if err := json.Unmarshal(raw.Data, &d); err != nil { @@ -203,6 +209,18 @@ func (e *SessionEvent) UnmarshalJSON(data []byte) error { return err } e.Data = &d + case SessionEventTypeMCPHeadersRefreshCompleted: + var d MCPHeadersRefreshCompletedData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d + case SessionEventTypeMCPHeadersRefreshRequired: + var d MCPHeadersRefreshRequiredData + if err := json.Unmarshal(raw.Data, &d); err != nil { + return err + } + e.Data = &d case SessionEventTypeMCPOauthCompleted: var d MCPOauthCompletedData if err := json.Unmarshal(raw.Data, &d); err != nil { @@ -645,6 +663,7 @@ func (r *UserMessageData) UnmarshalJSON(data []byte) error { AgentMode *UserMessageAgentMode `json:"agentMode,omitempty"` Attachments []json.RawMessage `json:"attachments,omitzero"` Content string `json:"content"` + Delivery *UserMessageDelivery `json:"delivery,omitempty"` InteractionID *string `json:"interactionId,omitempty"` IsAutopilotContinuation *bool `json:"isAutopilotContinuation,omitempty"` NativeDocumentPathFallbackPaths []string `json:"nativeDocumentPathFallbackPaths,omitzero"` @@ -669,6 +688,7 @@ func (r *UserMessageData) UnmarshalJSON(data []byte) error { } } r.Content = raw.Content + r.Delivery = raw.Delivery r.InteractionID = raw.InteractionID r.IsAutopilotContinuation = raw.IsAutopilotContinuation r.NativeDocumentPathFallbackPaths = raw.NativeDocumentPathFallbackPaths diff --git a/go/rpc/zsession_events.go b/go/rpc/zsession_events.go index 7964da76bc..df0aa5beea 100644 --- a/go/rpc/zsession_events.go +++ b/go/rpc/zsession_events.go @@ -54,6 +54,7 @@ type SessionEventType string const ( SessionEventTypeAbort SessionEventType = "abort" + SessionEventTypeAssistantIdle SessionEventType = "assistant.idle" SessionEventTypeAssistantIntent SessionEventType = "assistant.intent" SessionEventTypeAssistantMessage SessionEventType = "assistant.message" SessionEventTypeAssistantMessageDelta SessionEventType = "assistant.message_delta" @@ -81,6 +82,8 @@ const ( SessionEventTypeHookProgress SessionEventType = "hook.progress" SessionEventTypeHookStart SessionEventType = "hook.start" SessionEventTypeMCPAppToolCallComplete SessionEventType = "mcp_app.tool_call_complete" + SessionEventTypeMCPHeadersRefreshCompleted SessionEventType = "mcp.headers_refresh_completed" + SessionEventTypeMCPHeadersRefreshRequired SessionEventType = "mcp.headers_refresh_required" SessionEventTypeMCPOauthCompleted SessionEventType = "mcp.oauth_completed" SessionEventTypeMCPOauthRequired SessionEventType = "mcp.oauth_required" SessionEventTypeModelCallFailure SessionEventType = "model.call_failure" @@ -453,6 +456,23 @@ type SessionCanvasRemovedData struct { func (*SessionCanvasRemovedData) sessionEventData() {} func (*SessionCanvasRemovedData) Type() SessionEventType { return SessionEventTypeSessionCanvasRemoved } +// Dynamic headers refresh request for a remote MCP server +type MCPHeadersRefreshRequiredData struct { + // Why dynamic headers are being requested. + Reason MCPHeadersRefreshRequiredReason `json:"reason"` + // Unique identifier for this headers refresh request; used to respond via session.mcp.headers.handlePendingHeadersRefreshRequest() + RequestID string `json:"requestId"` + // Display name of the remote MCP server requesting headers + ServerName string `json:"serverName"` + // URL of the remote MCP server requesting headers + ServerURL string `json:"serverUrl"` +} + +func (*MCPHeadersRefreshRequiredData) sessionEventData() {} +func (*MCPHeadersRefreshRequiredData) Type() SessionEventType { + return SessionEventTypeMCPHeadersRefreshRequired +} + // Elicitation request completion with the user's response type ElicitationCompletedData struct { // The user action: "accept" (submitted form), "decline" (explicitly refused), or "cancel" (dismissed) @@ -744,6 +764,19 @@ type MCPOauthCompletedData struct { func (*MCPOauthCompletedData) sessionEventData() {} func (*MCPOauthCompletedData) Type() SessionEventType { return SessionEventTypeMCPOauthCompleted } +// MCP headers refresh request completion notification +type MCPHeadersRefreshCompletedData struct { + // How the pending MCP headers refresh request resolved. + Outcome MCPHeadersRefreshCompletedOutcome `json:"outcome"` + // Request ID of the resolved headers refresh request + RequestID string `json:"requestId"` +} + +func (*MCPHeadersRefreshCompletedData) sessionEventData() {} +func (*MCPHeadersRefreshCompletedData) Type() SessionEventType { + return SessionEventTypeMCPHeadersRefreshCompleted +} + // Model change details including previous and new model identifiers type SessionModelChangeData struct { // Reason the change happened, when not user-initiated. Currently `"rate_limit_auto_switch"` for changes triggered by the auto-mode-switch rate-limit recovery path. UI clients can use this to render contextual copy. @@ -780,6 +813,8 @@ func (*SessionRemoteSteerableChangedData) Type() SessionEventType { // OAuth authentication request for an MCP server type MCPOauthRequiredData struct { + // Why the runtime is requesting host-provided OAuth credentials. + Reason MCPOauthRequestReason `json:"reason"` // Unique identifier for this OAuth request; used to respond via session.mcp.oauth.handlePendingRequest RequestID string `json:"requestId"` // Raw OAuth protected-resource metadata document fetched for the MCP server, if available @@ -816,6 +851,15 @@ func (*SessionCustomNotificationData) Type() SessionEventType { return SessionEventTypeSessionCustomNotification } +// Payload emitted whenever the main agent's processing loop goes idle, including while related background work (running agents or in-flight attached shell commands) is still pending and the session-level idle event is therefore deferred +type AssistantIdleData struct { + // True when the preceding agentic loop was cancelled via abort signal + Aborted *bool `json:"aborted,omitempty"` +} + +func (*AssistantIdleData) sessionEventData() {} +func (*AssistantIdleData) Type() SessionEventType { return SessionEventTypeAssistantIdle } + // Payload indicating the session is idle with no background agents or attached shell commands in flight type SessionIdleData struct { // True when the preceding agentic loop was cancelled via abort signal @@ -1165,6 +1209,8 @@ type UserMessageData struct { Attachments []Attachment `json:"attachments,omitzero"` // The user's message text as displayed in the timeline Content string `json:"content"` + // How this message was delivered to the agentic loop relative to loop state (idle-start vs. steering/queued while busy). The timing axis; combine with `source` (origin) for the full picture. Used for telemetry attribution. + Delivery *UserMessageDelivery `json:"delivery,omitempty"` // CAPI interaction ID for correlating this user message with its turn InteractionID *string `json:"interactionId,omitempty"` // True when this user message was auto-injected by autopilot's continuation loop rather than typed by the user; used to distinguish autopilot-driven turns in telemetry. @@ -1247,6 +1293,8 @@ type SessionStartData struct { ReasoningSummary *ReasoningSummary `json:"reasoningSummary,omitempty"` // Whether this session supports remote steering via GitHub RemoteSteerable *bool `json:"remoteSteerable,omitempty"` + // Response budget limits configured at session creation time, if any + ResponseBudget *ResponseBudgetConfig `json:"responseBudget,omitempty"` // Model selected at session creation time, if any SelectedModel *string `json:"selectedModel,omitempty"` // Unique identifier for the session @@ -1280,6 +1328,8 @@ type SessionResumeData struct { ReasoningSummary *ReasoningSummary `json:"reasoningSummary,omitempty"` // Whether this session supports remote steering via GitHub RemoteSteerable *bool `json:"remoteSteerable,omitempty"` + // Response budget limits currently configured at resume time; null when no budget is active + ResponseBudget *ResponseBudgetConfig `json:"responseBudget,omitempty"` // ISO 8601 timestamp when the session was resumed ResumeTime time.Time `json:"resumeTime"` // Model currently selected at resume time @@ -1610,6 +1660,8 @@ type ToolExecutionStartData struct { // Tool call ID of the parent tool invocation when this event originates from a sub-agent // Deprecated: ParentToolCallID is deprecated. ParentToolCallID *string `json:"parentToolCallId,omitempty"` + // Shell-tool path hints derived from the command at start time for shell tools (bash/powershell/local_shell). Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. Absent for non-shell tools. + ShellToolInfo *ToolExecutionStartShellToolInfo `json:"shellToolInfo,omitempty"` // Unique identifier for this tool call ToolCallID string `json:"toolCallId"` // Tool definition metadata, present for MCP tools with MCP Apps support @@ -2145,6 +2197,8 @@ type MCPAppToolCallCompleteToolMetaUI struct { type MCPOauthRequiredStaticClientConfig struct { // OAuth client ID for the server ClientID string `json:"clientId"` + // Optional OAuth client secret for confidential static clients, when the runtime can resolve one + ClientSecret *string `json:"clientSecret,omitempty"` // Optional non-default OAuth grant type. When set to 'client_credentials', the OAuth flow runs headlessly using the client_id + keychain-stored secret (no browser, no callback server). GrantType *MCPOauthRequiredStaticClientConfigGrantType `json:"grantType,omitempty"` // Whether this is a public OAuth client @@ -2155,8 +2209,8 @@ type MCPOauthRequiredStaticClientConfig struct { type MCPOauthWwwAuthenticateParams struct { // OAuth error from the WWW-Authenticate error parameter, if present Error *string `json:"error,omitempty"` - // Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter - ResourceMetadataURL string `json:"resourceMetadataUrl"` + // Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter, if present + ResourceMetadataURL *string `json:"resourceMetadataUrl,omitempty"` // Requested OAuth scopes from the WWW-Authenticate scope parameter, if present Scope *string `json:"scope,omitempty"` } @@ -3264,6 +3318,14 @@ type ToolExecutionCompleteUIResourceMetaUIPermissionsGeolocation struct { type ToolExecutionCompleteUIResourceMetaUIPermissionsMicrophone struct { } +// Shell-aware path hints for a shell tool's command, captured at start time so consumers can snapshot a file's pre-image before the tool runs. +type ToolExecutionStartShellToolInfo struct { + // Whether the command includes a file write redirection (e.g., > or >>). + HasWriteFileRedirection bool `json:"hasWriteFileRedirection"` + // File paths the command may read or write, derived from the command at start time. Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. + PossiblePaths []string `json:"possiblePaths"` +} + // Tool definition metadata, present for MCP tools with MCP Apps support type ToolExecutionStartToolDescription struct { // Tool description @@ -3494,6 +3556,30 @@ const ( HandoffSourceTypeRemote HandoffSourceType = "remote" ) +// How the pending MCP headers refresh request resolved. +type MCPHeadersRefreshCompletedOutcome string + +const ( + // The host supplied dynamic headers. + MCPHeadersRefreshCompletedOutcomeHeaders MCPHeadersRefreshCompletedOutcome = "headers" + // The host responded with no dynamic headers. + MCPHeadersRefreshCompletedOutcomeNone MCPHeadersRefreshCompletedOutcome = "none" + // No response arrived within the bounded window. + MCPHeadersRefreshCompletedOutcomeTimeout MCPHeadersRefreshCompletedOutcome = "timeout" +) + +// Why dynamic headers are being requested. +type MCPHeadersRefreshRequiredReason string + +const ( + // The server returned 401 and stale dynamic headers were invalidated. + MCPHeadersRefreshRequiredReasonAuthFailed MCPHeadersRefreshRequiredReason = "auth-failed" + // The transport is making its first dynamic header request for this server. + MCPHeadersRefreshRequiredReasonStartup MCPHeadersRefreshRequiredReason = "startup" + // The previously cached dynamic headers expired. + MCPHeadersRefreshRequiredReasonTtlExpired MCPHeadersRefreshRequiredReason = "ttl-expired" +) + // How the pending MCP OAuth request was completed type MCPOauthCompletionOutcome string @@ -3504,6 +3590,20 @@ const ( MCPOauthCompletionOutcomeToken MCPOauthCompletionOutcome = "token" ) +// Reason the runtime is requesting host-provided MCP OAuth credentials +type MCPOauthRequestReason string + +const ( + // Initial credentials are required before connecting to the MCP server. + MCPOauthRequestReasonInitial MCPOauthRequestReason = "initial" + // The server requires a new host authorization flow before continuing. + MCPOauthRequestReasonReauth MCPOauthRequestReason = "reauth" + // The current host-provided credential was rejected and a replacement is requested. + MCPOauthRequestReasonRefresh MCPOauthRequestReason = "refresh" + // The server requires a credential with additional scope or audience. + MCPOauthRequestReasonUpscope MCPOauthRequestReason = "upscope" +) + // Optional non-default OAuth grant type. When set to 'client_credentials', the OAuth flow runs headlessly using the client_id + keychain-stored secret (no browser, no callback server). type MCPOauthRequiredStaticClientConfigGrantType string @@ -3768,6 +3868,18 @@ const ( UserMessageAgentModeShell UserMessageAgentMode = "shell" ) +// How this user message was delivered to the agentic loop, relative to whether the loop was already running. This is the timing axis only; the message's origin (human vs. system/command/schedule/skill/etc.) is carried separately by `source`. A system-injected message has a delivery too — e.g. a background-task notification waking an idle agent is `idle`, the same mechanism as a human starting a fresh turn. +type UserMessageDelivery string + +const ( + // Delivered while the loop was idle; starts its own run immediately (a human's fresh turn, or a system notification waking an idle agent). + UserMessageDeliveryIdle UserMessageDelivery = "idle" + // Enqueued while the agent was busy; processed as its own run afterward. + UserMessageDeliveryQueued UserMessageDelivery = "queued" + // Injected into the current in-flight run while the agent was busy (immediate mode). + UserMessageDeliverySteering UserMessageDelivery = "steering" +) + // Hosting platform type of the repository (github or ado) type WorkingDirectoryContextHostType string diff --git a/go/zsession_events.go b/go/zsession_events.go index 75a22cc997..6b9f17aa63 100644 --- a/go/zsession_events.go +++ b/go/zsession_events.go @@ -9,6 +9,7 @@ import "github.com/github/copilot-sdk/go/rpc" type ( AbortData = rpc.AbortData AbortReason = rpc.AbortReason + AssistantIdleData = rpc.AssistantIdleData AssistantIntentData = rpc.AssistantIntentData AssistantMessageData = rpc.AssistantMessageData AssistantMessageDeltaData = rpc.AssistantMessageDeltaData @@ -31,8 +32,19 @@ type ( AttachmentExtensionContext = rpc.AttachmentExtensionContext AttachmentFile = rpc.AttachmentFile AttachmentFileLineRange = rpc.AttachmentFileLineRange + AttachmentGitHubActionsJob = rpc.AttachmentGitHubActionsJob + AttachmentGitHubCommit = rpc.AttachmentGitHubCommit + AttachmentGitHubFile = rpc.AttachmentGitHubFile + AttachmentGitHubFileDiff = rpc.AttachmentGitHubFileDiff + AttachmentGitHubFileDiffSide = rpc.AttachmentGitHubFileDiffSide AttachmentGitHubReference = rpc.AttachmentGitHubReference AttachmentGitHubReferenceType = rpc.AttachmentGitHubReferenceType + AttachmentGitHubRelease = rpc.AttachmentGitHubRelease + AttachmentGitHubRepository = rpc.AttachmentGitHubRepository + AttachmentGitHubSnippet = rpc.AttachmentGitHubSnippet + AttachmentGitHubTreeComparison = rpc.AttachmentGitHubTreeComparison + AttachmentGitHubTreeComparisonSide = rpc.AttachmentGitHubTreeComparisonSide + AttachmentGitHubURL = rpc.AttachmentGitHubURL AttachmentSelection = rpc.AttachmentSelection AttachmentSelectionDetails = rpc.AttachmentSelectionDetails AttachmentSelectionDetailsEnd = rpc.AttachmentSelectionDetailsEnd @@ -86,6 +98,7 @@ type ( ExtensionsLoadedExtensionStatus = rpc.ExtensionsLoadedExtensionStatus ExternalToolCompletedData = rpc.ExternalToolCompletedData ExternalToolRequestedData = rpc.ExternalToolRequestedData + GitHubRepoRef = rpc.GitHubRepoRef HandoffRepository = rpc.HandoffRepository HandoffSourceType = rpc.HandoffSourceType HookEndData = rpc.HookEndData @@ -96,8 +109,13 @@ type ( MCPAppToolCallCompleteError = rpc.MCPAppToolCallCompleteError MCPAppToolCallCompleteToolMeta = rpc.MCPAppToolCallCompleteToolMeta MCPAppToolCallCompleteToolMetaUI = rpc.MCPAppToolCallCompleteToolMetaUI + MCPHeadersRefreshCompletedData = rpc.MCPHeadersRefreshCompletedData + MCPHeadersRefreshCompletedOutcome = rpc.MCPHeadersRefreshCompletedOutcome + MCPHeadersRefreshRequiredData = rpc.MCPHeadersRefreshRequiredData + MCPHeadersRefreshRequiredReason = rpc.MCPHeadersRefreshRequiredReason MCPOauthCompletedData = rpc.MCPOauthCompletedData MCPOauthCompletionOutcome = rpc.MCPOauthCompletionOutcome + MCPOauthRequestReason = rpc.MCPOauthRequestReason MCPOauthRequiredData = rpc.MCPOauthRequiredData MCPOauthRequiredStaticClientConfig = rpc.MCPOauthRequiredStaticClientConfig MCPOauthRequiredStaticClientConfigGrantType = rpc.MCPOauthRequiredStaticClientConfigGrantType @@ -174,6 +192,7 @@ type ( RawSystemNotification = rpc.RawSystemNotification RawToolExecutionCompleteContent = rpc.RawToolExecutionCompleteContent ReasoningSummary = rpc.ReasoningSummary + ResponseBudgetConfig = rpc.ResponseBudgetConfig SamplingCompletedData = rpc.SamplingCompletedData SamplingRequestedData = rpc.SamplingRequestedData SessionAutopilotObjectiveChangedData = rpc.SessionAutopilotObjectiveChangedData @@ -282,6 +301,7 @@ type ( ToolExecutionPartialResultData = rpc.ToolExecutionPartialResultData ToolExecutionProgressData = rpc.ToolExecutionProgressData ToolExecutionStartData = rpc.ToolExecutionStartData + ToolExecutionStartShellToolInfo = rpc.ToolExecutionStartShellToolInfo ToolExecutionStartToolDescription = rpc.ToolExecutionStartToolDescription ToolExecutionStartToolDescriptionMeta = rpc.ToolExecutionStartToolDescriptionMeta ToolExecutionStartToolDescriptionMetaUI = rpc.ToolExecutionStartToolDescriptionMetaUI @@ -291,6 +311,7 @@ type ( UserInputRequestedData = rpc.UserInputRequestedData UserMessageAgentMode = rpc.UserMessageAgentMode UserMessageData = rpc.UserMessageData + UserMessageDelivery = rpc.UserMessageDelivery UserToolSessionApproval = rpc.UserToolSessionApproval UserToolSessionApprovalCommands = rpc.UserToolSessionApprovalCommands UserToolSessionApprovalCustomTool = rpc.UserToolSessionApprovalCustomTool @@ -324,7 +345,16 @@ const ( AttachmentTypeDirectory = rpc.AttachmentTypeDirectory AttachmentTypeExtensionContext = rpc.AttachmentTypeExtensionContext AttachmentTypeFile = rpc.AttachmentTypeFile + AttachmentTypeGitHubActionsJob = rpc.AttachmentTypeGitHubActionsJob + AttachmentTypeGitHubCommit = rpc.AttachmentTypeGitHubCommit + AttachmentTypeGitHubFile = rpc.AttachmentTypeGitHubFile + AttachmentTypeGitHubFileDiff = rpc.AttachmentTypeGitHubFileDiff AttachmentTypeGitHubReference = rpc.AttachmentTypeGitHubReference + AttachmentTypeGitHubRelease = rpc.AttachmentTypeGitHubRelease + AttachmentTypeGitHubRepository = rpc.AttachmentTypeGitHubRepository + AttachmentTypeGitHubSnippet = rpc.AttachmentTypeGitHubSnippet + AttachmentTypeGitHubTreeComparison = rpc.AttachmentTypeGitHubTreeComparison + AttachmentTypeGitHubURL = rpc.AttachmentTypeGitHubURL AttachmentTypeSelection = rpc.AttachmentTypeSelection AutoModeSwitchResponseNo = rpc.AutoModeSwitchResponseNo AutoModeSwitchResponseYes = rpc.AutoModeSwitchResponseYes @@ -368,8 +398,18 @@ const ( ExtensionsLoadedExtensionStatusStarting = rpc.ExtensionsLoadedExtensionStatusStarting HandoffSourceTypeLocal = rpc.HandoffSourceTypeLocal HandoffSourceTypeRemote = rpc.HandoffSourceTypeRemote + MCPHeadersRefreshCompletedOutcomeHeaders = rpc.MCPHeadersRefreshCompletedOutcomeHeaders + MCPHeadersRefreshCompletedOutcomeNone = rpc.MCPHeadersRefreshCompletedOutcomeNone + MCPHeadersRefreshCompletedOutcomeTimeout = rpc.MCPHeadersRefreshCompletedOutcomeTimeout + MCPHeadersRefreshRequiredReasonAuthFailed = rpc.MCPHeadersRefreshRequiredReasonAuthFailed + MCPHeadersRefreshRequiredReasonStartup = rpc.MCPHeadersRefreshRequiredReasonStartup + MCPHeadersRefreshRequiredReasonTtlExpired = rpc.MCPHeadersRefreshRequiredReasonTtlExpired MCPOauthCompletionOutcomeCancelled = rpc.MCPOauthCompletionOutcomeCancelled MCPOauthCompletionOutcomeToken = rpc.MCPOauthCompletionOutcomeToken + MCPOauthRequestReasonInitial = rpc.MCPOauthRequestReasonInitial + MCPOauthRequestReasonReauth = rpc.MCPOauthRequestReasonReauth + MCPOauthRequestReasonRefresh = rpc.MCPOauthRequestReasonRefresh + MCPOauthRequestReasonUpscope = rpc.MCPOauthRequestReasonUpscope MCPOauthRequiredStaticClientConfigGrantTypeClientCredentials = rpc.MCPOauthRequiredStaticClientConfigGrantTypeClientCredentials MCPServerSourceBuiltin = rpc.MCPServerSourceBuiltin MCPServerSourcePlugin = rpc.MCPServerSourcePlugin @@ -442,6 +482,7 @@ const ( ReasoningSummaryDetailed = rpc.ReasoningSummaryDetailed ReasoningSummaryNone = rpc.ReasoningSummaryNone SessionEventTypeAbort = rpc.SessionEventTypeAbort + SessionEventTypeAssistantIdle = rpc.SessionEventTypeAssistantIdle SessionEventTypeAssistantIntent = rpc.SessionEventTypeAssistantIntent SessionEventTypeAssistantMessage = rpc.SessionEventTypeAssistantMessage SessionEventTypeAssistantMessageDelta = rpc.SessionEventTypeAssistantMessageDelta @@ -469,6 +510,8 @@ const ( SessionEventTypeHookProgress = rpc.SessionEventTypeHookProgress SessionEventTypeHookStart = rpc.SessionEventTypeHookStart SessionEventTypeMCPAppToolCallComplete = rpc.SessionEventTypeMCPAppToolCallComplete + SessionEventTypeMCPHeadersRefreshCompleted = rpc.SessionEventTypeMCPHeadersRefreshCompleted + SessionEventTypeMCPHeadersRefreshRequired = rpc.SessionEventTypeMCPHeadersRefreshRequired SessionEventTypeMCPOauthCompleted = rpc.SessionEventTypeMCPOauthCompleted SessionEventTypeMCPOauthRequired = rpc.SessionEventTypeMCPOauthRequired SessionEventTypeModelCallFailure = rpc.SessionEventTypeModelCallFailure @@ -577,6 +620,9 @@ const ( UserMessageAgentModeInteractive = rpc.UserMessageAgentModeInteractive UserMessageAgentModePlan = rpc.UserMessageAgentModePlan UserMessageAgentModeShell = rpc.UserMessageAgentModeShell + UserMessageDeliveryIdle = rpc.UserMessageDeliveryIdle + UserMessageDeliveryQueued = rpc.UserMessageDeliveryQueued + UserMessageDeliverySteering = rpc.UserMessageDeliverySteering UserToolSessionApprovalKindCommands = rpc.UserToolSessionApprovalKindCommands UserToolSessionApprovalKindCustomTool = rpc.UserToolSessionApprovalKindCustomTool UserToolSessionApprovalKindExtensionManagement = rpc.UserToolSessionApprovalKindExtensionManagement diff --git a/java/pom.xml b/java/pom.xml index 9cba6df463..dfb779acf3 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -86,7 +86,7 @@ DO NOT EDIT MANUALLY. Updated by the update-copilot-dependency workflow. --> - ^1.0.65 + ^1.0.66-1 diff --git a/java/scripts/codegen/package-lock.json b/java/scripts/codegen/package-lock.json index 510d094976..3befb50acf 100644 --- a/java/scripts/codegen/package-lock.json +++ b/java/scripts/codegen/package-lock.json @@ -6,7 +6,7 @@ "": { "name": "copilot-sdk-java-codegen", "dependencies": { - "@github/copilot": "^1.0.65", + "@github/copilot": "^1.0.66-1", "json-schema": "^0.4.0", "tsx": "^4.22.4" } @@ -428,9 +428,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.65.tgz", - "integrity": "sha512-J1XvLuOiVpiAi/E1MBICBymszCgdGLnZxokosXzGcmcjEVZd+QSDoW/kPRHq6oEyBT9SDASPcjCEZ9Q0rLJllg==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.66-1.tgz", + "integrity": "sha512-Cf0rTsG1wfdRzGmD9PC0TPYxQojItwo6Hv/Jp6GwakrBswLn4PlxW/pCQA7n3o2DahTQDX2y6Z9olAdx0dHFQA==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "detect-libc": "^2.1.2" @@ -439,20 +439,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.65", - "@github/copilot-darwin-x64": "1.0.65", - "@github/copilot-linux-arm64": "1.0.65", - "@github/copilot-linux-x64": "1.0.65", - "@github/copilot-linuxmusl-arm64": "1.0.65", - "@github/copilot-linuxmusl-x64": "1.0.65", - "@github/copilot-win32-arm64": "1.0.65", - "@github/copilot-win32-x64": "1.0.65" + "@github/copilot-darwin-arm64": "1.0.66-1", + "@github/copilot-darwin-x64": "1.0.66-1", + "@github/copilot-linux-arm64": "1.0.66-1", + "@github/copilot-linux-x64": "1.0.66-1", + "@github/copilot-linuxmusl-arm64": "1.0.66-1", + "@github/copilot-linuxmusl-x64": "1.0.66-1", + "@github/copilot-win32-arm64": "1.0.66-1", + "@github/copilot-win32-x64": "1.0.66-1" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.65.tgz", - "integrity": "sha512-NFc4xIstZNiIuAYkurQT5DVtbZjBoZ/z6yt/Ffcom7Y5QGjfpN4BFuekv9k+OADRioxxR99NgmhjbuNPWtQhNQ==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.66-1.tgz", + "integrity": "sha512-HTum+52pVBlrUrUjn/r/Q6kd2c0pvGsi6NyfuaGLRKStSQj00Iz5urYlo0hcq5JKF9eGB7ow+aeYc7BDIUVnhw==", "cpu": [ "arm64" ], @@ -466,9 +466,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.65.tgz", - "integrity": "sha512-0wtV22KmTa12VbqWRRkgvJcBz/oIbszfcIpyDWGc4MzbCVksajQ3TWVQ6c7Sdzj5RifCaYdkHAX2zuIYXYlLoQ==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.66-1.tgz", + "integrity": "sha512-gniq5/n2nX8cBQncjwvU7nAGYj21ALSknNUqhPWIQYwx+IM6KnGeBgSpldubJCMDjkZkbPYqskVcxTGvw0GGHA==", "cpu": [ "x64" ], @@ -482,9 +482,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.65.tgz", - "integrity": "sha512-dOwdy/YbTXQN/+x2v4ZgiDycdRtWElyHxPuA6ail3yJDt0nagwn8OYAA/diBLPMAJuuBXiOZGvvb9fGRuh7Xgg==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.66-1.tgz", + "integrity": "sha512-PG/xIIndXo0NpKYXR8GYPXAA3p/kuf4lsA898Pq+9UH5wU9ybqo5P/n5HBLXNOQnpP8+u9pjL9rPbvtwxMkzaQ==", "cpu": [ "arm64" ], @@ -498,9 +498,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.65.tgz", - "integrity": "sha512-al/1a/l/GrpHtygTxt7PZspmv0eHBPdAZ5B31J7Hv/GRdVZM4STCC9dCIOSUFsOX2fhaKD8yLfz4HureSYs23g==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.66-1.tgz", + "integrity": "sha512-Tb11uVan2f8YjFLiTvPUC8yLSYdmoMru9J8axZRuiSgOtRfmaJGxHoM/axPYW+874YAn4gSygs7OPUt1C+67Xw==", "cpu": [ "x64" ], @@ -514,9 +514,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.65.tgz", - "integrity": "sha512-xccQeJSR45xyoaL7J5mZjtU++dmte+ZCDQkIlrpTn2yuMl2LWriBvorQ1P2MwVnXmIiW/GHi93B+lNtsybA9yw==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.66-1.tgz", + "integrity": "sha512-GJEVj60B5MeJ8kfnf/dRmyX4EwU4HWL7yUZkrAG6xznSyHHPoTWtZ/tudQX/mf69emXtO7Nt9cLOcNIEdYRPMg==", "cpu": [ "arm64" ], @@ -530,9 +530,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.65.tgz", - "integrity": "sha512-RHPVUaqjSrhKHQ2EpfGKWErnV+R5elGIZaHXPKO10zpSaQD9b/C9u6nLigZnBuT/8sCaJpVrazPMwOYvYA62aw==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.66-1.tgz", + "integrity": "sha512-I5k9mMRuIO+pmPGDiblFXd+HOBJo92XEIBwbZMaAW3qRuyF5UcEFuWlczOCYzcTreXfBqNkG1P9qsBeDDNXfnQ==", "cpu": [ "x64" ], @@ -546,9 +546,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.65.tgz", - "integrity": "sha512-/vSE/t9Wm3eFSWpxlKyn/oL8OAVOB0yFO7ECxhgbtiqNrBd1tgpYh1k7IXBIWa/saxlV1+de6DEmPuQfx3Z0bg==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.66-1.tgz", + "integrity": "sha512-tUkNUkx5F2TIefY3KDORon3THo256hr/ZVUMEph5fr6xSib4d8gGgNjzok/4kEfIR3a7L/45g0Qi+CzQNtjSdA==", "cpu": [ "arm64" ], @@ -562,9 +562,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.65.tgz", - "integrity": "sha512-wjVWXepET+SpFg8z8V43ZiTy6X1OerCb7yu3QZKNNJ3zY9z20goihPXQCDWkiJpGzszNSgfrsiqUzpUsC9qS0A==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.66-1.tgz", + "integrity": "sha512-ktTbksWav2WSVi8BbTYxD4CJ+OrPximk5zPWff3stsU1MrG0XjZtlML1KUY3d/rrq2lpfZqh0ooF+A4bt8IFsQ==", "cpu": [ "x64" ], diff --git a/java/scripts/codegen/package.json b/java/scripts/codegen/package.json index 53d5b3ebab..91442b63c6 100644 --- a/java/scripts/codegen/package.json +++ b/java/scripts/codegen/package.json @@ -7,7 +7,7 @@ "generate:java": "tsx java.ts" }, "dependencies": { - "@github/copilot": "^1.0.65", + "@github/copilot": "^1.0.66-1", "json-schema": "^0.4.0", "tsx": "^4.22.4" } diff --git a/java/src/generated/java/com/github/copilot/generated/AssistantIdleEvent.java b/java/src/generated/java/com/github/copilot/generated/AssistantIdleEvent.java new file mode 100644 index 0000000000..3b79b8d50e --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/AssistantIdleEvent.java @@ -0,0 +1,41 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Session event "assistant.idle". Payload emitted whenever the main agent's processing loop goes idle, including while related background work (running agents or in-flight attached shell commands) is still pending and the session-level idle event is therefore deferred + * @since 1.0.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class AssistantIdleEvent extends SessionEvent { + + @Override + public String getType() { return "assistant.idle"; } + + @JsonProperty("data") + private AssistantIdleEventData data; + + public AssistantIdleEventData getData() { return data; } + public void setData(AssistantIdleEventData data) { this.data = data; } + + /** Data payload for {@link AssistantIdleEvent}. */ + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + public record AssistantIdleEventData( + /** True when the preceding agentic loop was cancelled via abort signal */ + @JsonProperty("aborted") Boolean aborted + ) { + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshCompletedEvent.java b/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshCompletedEvent.java new file mode 100644 index 0000000000..a3ba903aea --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshCompletedEvent.java @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Session event "mcp.headers_refresh_completed". MCP headers refresh request completion notification + * @since 1.0.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class McpHeadersRefreshCompletedEvent extends SessionEvent { + + @Override + public String getType() { return "mcp.headers_refresh_completed"; } + + @JsonProperty("data") + private McpHeadersRefreshCompletedEventData data; + + public McpHeadersRefreshCompletedEventData getData() { return data; } + public void setData(McpHeadersRefreshCompletedEventData data) { this.data = data; } + + /** Data payload for {@link McpHeadersRefreshCompletedEvent}. */ + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + public record McpHeadersRefreshCompletedEventData( + /** Request ID of the resolved headers refresh request */ + @JsonProperty("requestId") String requestId, + /** How the pending MCP headers refresh request resolved. */ + @JsonProperty("outcome") McpHeadersRefreshCompletedOutcome outcome + ) { + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshCompletedOutcome.java b/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshCompletedOutcome.java new file mode 100644 index 0000000000..7980dd0a67 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshCompletedOutcome.java @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import javax.annotation.processing.Generated; + +/** + * How the pending MCP headers refresh request resolved. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum McpHeadersRefreshCompletedOutcome { + /** The {@code headers} variant. */ + HEADERS("headers"), + /** The {@code none} variant. */ + NONE("none"), + /** The {@code timeout} variant. */ + TIMEOUT("timeout"); + + private final String value; + McpHeadersRefreshCompletedOutcome(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static McpHeadersRefreshCompletedOutcome fromValue(String value) { + for (McpHeadersRefreshCompletedOutcome v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown McpHeadersRefreshCompletedOutcome value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshRequiredEvent.java b/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshRequiredEvent.java new file mode 100644 index 0000000000..d8774bb326 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshRequiredEvent.java @@ -0,0 +1,47 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Session event "mcp.headers_refresh_required". Dynamic headers refresh request for a remote MCP server + * @since 1.0.0 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class McpHeadersRefreshRequiredEvent extends SessionEvent { + + @Override + public String getType() { return "mcp.headers_refresh_required"; } + + @JsonProperty("data") + private McpHeadersRefreshRequiredEventData data; + + public McpHeadersRefreshRequiredEventData getData() { return data; } + public void setData(McpHeadersRefreshRequiredEventData data) { this.data = data; } + + /** Data payload for {@link McpHeadersRefreshRequiredEvent}. */ + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonInclude(JsonInclude.Include.NON_NULL) + public record McpHeadersRefreshRequiredEventData( + /** Unique identifier for this headers refresh request; used to respond via session.mcp.headers.handlePendingHeadersRefreshRequest() */ + @JsonProperty("requestId") String requestId, + /** Display name of the remote MCP server requesting headers */ + @JsonProperty("serverName") String serverName, + /** URL of the remote MCP server requesting headers */ + @JsonProperty("serverUrl") String serverUrl, + /** Why dynamic headers are being requested. */ + @JsonProperty("reason") McpHeadersRefreshRequiredReason reason + ) { + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshRequiredReason.java b/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshRequiredReason.java new file mode 100644 index 0000000000..86c8f8b2d6 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/McpHeadersRefreshRequiredReason.java @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import javax.annotation.processing.Generated; + +/** + * Why dynamic headers are being requested. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum McpHeadersRefreshRequiredReason { + /** The {@code startup} variant. */ + STARTUP("startup"), + /** The {@code ttl-expired} variant. */ + TTL_EXPIRED("ttl-expired"), + /** The {@code auth-failed} variant. */ + AUTH_FAILED("auth-failed"); + + private final String value; + McpHeadersRefreshRequiredReason(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static McpHeadersRefreshRequiredReason fromValue(String value) { + for (McpHeadersRefreshRequiredReason v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown McpHeadersRefreshRequiredReason value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/McpOauthRequestReason.java b/java/src/generated/java/com/github/copilot/generated/McpOauthRequestReason.java new file mode 100644 index 0000000000..2a6eec7063 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/McpOauthRequestReason.java @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import javax.annotation.processing.Generated; + +/** + * Reason the runtime is requesting host-provided MCP OAuth credentials + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum McpOauthRequestReason { + /** The {@code initial} variant. */ + INITIAL("initial"), + /** The {@code refresh} variant. */ + REFRESH("refresh"), + /** The {@code reauth} variant. */ + REAUTH("reauth"), + /** The {@code upscope} variant. */ + UPSCOPE("upscope"); + + private final String value; + McpOauthRequestReason(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static McpOauthRequestReason fromValue(String value) { + for (McpOauthRequestReason v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown McpOauthRequestReason value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/McpOauthRequiredEvent.java b/java/src/generated/java/com/github/copilot/generated/McpOauthRequiredEvent.java index 3f6ef8ef60..67413d382f 100644 --- a/java/src/generated/java/com/github/copilot/generated/McpOauthRequiredEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/McpOauthRequiredEvent.java @@ -45,7 +45,9 @@ public record McpOauthRequiredEventData( /** OAuth WWW-Authenticate parameters parsed from the auth challenge, if available */ @JsonProperty("wwwAuthenticateParams") McpOauthWWWAuthenticateParams wwwAuthenticateParams, /** Raw OAuth protected-resource metadata document fetched for the MCP server, if available */ - @JsonProperty("resourceMetadata") String resourceMetadata + @JsonProperty("resourceMetadata") String resourceMetadata, + /** Why the runtime is requesting host-provided OAuth credentials. */ + @JsonProperty("reason") McpOauthRequestReason reason ) { } } diff --git a/java/src/generated/java/com/github/copilot/generated/McpOauthRequiredStaticClientConfig.java b/java/src/generated/java/com/github/copilot/generated/McpOauthRequiredStaticClientConfig.java index 764f8b7fc8..5f42ec90c4 100644 --- a/java/src/generated/java/com/github/copilot/generated/McpOauthRequiredStaticClientConfig.java +++ b/java/src/generated/java/com/github/copilot/generated/McpOauthRequiredStaticClientConfig.java @@ -23,6 +23,8 @@ public record McpOauthRequiredStaticClientConfig( /** OAuth client ID for the server */ @JsonProperty("clientId") String clientId, + /** Optional OAuth client secret for confidential static clients, when the runtime can resolve one */ + @JsonProperty("clientSecret") String clientSecret, /** Whether this is a public OAuth client */ @JsonProperty("publicClient") Boolean publicClient, /** Optional non-default OAuth grant type. When set to 'client_credentials', the OAuth flow runs headlessly using the client_id + keychain-stored secret (no browser, no callback server). */ diff --git a/java/src/generated/java/com/github/copilot/generated/McpOauthWWWAuthenticateParams.java b/java/src/generated/java/com/github/copilot/generated/McpOauthWWWAuthenticateParams.java index faa08e1e89..3e1fdb0d10 100644 --- a/java/src/generated/java/com/github/copilot/generated/McpOauthWWWAuthenticateParams.java +++ b/java/src/generated/java/com/github/copilot/generated/McpOauthWWWAuthenticateParams.java @@ -21,7 +21,7 @@ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public record McpOauthWWWAuthenticateParams( - /** Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter */ + /** Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter, if present */ @JsonProperty("resourceMetadataUrl") String resourceMetadataUrl, /** Requested OAuth scopes from the WWW-Authenticate scope parameter, if present */ @JsonProperty("scope") String scope, diff --git a/java/src/generated/java/com/github/copilot/generated/ResponseBudgetConfig.java b/java/src/generated/java/com/github/copilot/generated/ResponseBudgetConfig.java new file mode 100644 index 0000000000..0acfdbdb3d --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/ResponseBudgetConfig.java @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Optional response budget limits. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record ResponseBudgetConfig( + /** Maximum model-call iterations allowed while responding to one top-level user message. */ + @JsonProperty("maxModelIterations") Long maxModelIterations, + /** Maximum AI Credits allowed while responding to one top-level user message. */ + @JsonProperty("maxAiCredits") Double maxAiCredits +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/SessionEvent.java b/java/src/generated/java/com/github/copilot/generated/SessionEvent.java index f92dbf2fae..bcbb09831c 100644 --- a/java/src/generated/java/com/github/copilot/generated/SessionEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/SessionEvent.java @@ -63,6 +63,7 @@ @JsonSubTypes.Type(value = AssistantMessageStartEvent.class, name = "assistant.message_start"), @JsonSubTypes.Type(value = AssistantMessageDeltaEvent.class, name = "assistant.message_delta"), @JsonSubTypes.Type(value = AssistantTurnEndEvent.class, name = "assistant.turn_end"), + @JsonSubTypes.Type(value = AssistantIdleEvent.class, name = "assistant.idle"), @JsonSubTypes.Type(value = AssistantUsageEvent.class, name = "assistant.usage"), @JsonSubTypes.Type(value = ModelCallFailureEvent.class, name = "model.call_failure"), @JsonSubTypes.Type(value = AbortEvent.class, name = "abort"), @@ -93,6 +94,8 @@ @JsonSubTypes.Type(value = SamplingCompletedEvent.class, name = "sampling.completed"), @JsonSubTypes.Type(value = McpOauthRequiredEvent.class, name = "mcp.oauth_required"), @JsonSubTypes.Type(value = McpOauthCompletedEvent.class, name = "mcp.oauth_completed"), + @JsonSubTypes.Type(value = McpHeadersRefreshRequiredEvent.class, name = "mcp.headers_refresh_required"), + @JsonSubTypes.Type(value = McpHeadersRefreshCompletedEvent.class, name = "mcp.headers_refresh_completed"), @JsonSubTypes.Type(value = SessionCustomNotificationEvent.class, name = "session.custom_notification"), @JsonSubTypes.Type(value = ExternalToolRequestedEvent.class, name = "external_tool.requested"), @JsonSubTypes.Type(value = ExternalToolCompletedEvent.class, name = "external_tool.completed"), @@ -161,6 +164,7 @@ public abstract sealed class SessionEvent permits AssistantMessageStartEvent, AssistantMessageDeltaEvent, AssistantTurnEndEvent, + AssistantIdleEvent, AssistantUsageEvent, ModelCallFailureEvent, AbortEvent, @@ -191,6 +195,8 @@ public abstract sealed class SessionEvent permits SamplingCompletedEvent, McpOauthRequiredEvent, McpOauthCompletedEvent, + McpHeadersRefreshRequiredEvent, + McpHeadersRefreshCompletedEvent, SessionCustomNotificationEvent, ExternalToolRequestedEvent, ExternalToolCompletedEvent, diff --git a/java/src/generated/java/com/github/copilot/generated/SessionResumeEvent.java b/java/src/generated/java/com/github/copilot/generated/SessionResumeEvent.java index b1cfda9338..47e8b3a997 100644 --- a/java/src/generated/java/com/github/copilot/generated/SessionResumeEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/SessionResumeEvent.java @@ -49,6 +49,8 @@ public record SessionResumeEventData( @JsonProperty("reasoningSummary") ReasoningSummary reasoningSummary, /** Context tier currently selected at resume time; null when no tier is active */ @JsonProperty("contextTier") ContextTier contextTier, + /** Response budget limits currently configured at resume time; null when no budget is active */ + @JsonProperty("responseBudget") ResponseBudgetConfig responseBudget, /** Updated working directory and git context at resume time */ @JsonProperty("context") WorkingDirectoryContext context, /** Whether the session was already in use by another client at resume time */ diff --git a/java/src/generated/java/com/github/copilot/generated/SessionStartEvent.java b/java/src/generated/java/com/github/copilot/generated/SessionStartEvent.java index 2b36fa3e7b..3cd6fb9664 100644 --- a/java/src/generated/java/com/github/copilot/generated/SessionStartEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/SessionStartEvent.java @@ -53,6 +53,8 @@ public record SessionStartEventData( @JsonProperty("reasoningSummary") ReasoningSummary reasoningSummary, /** Context tier selected at session creation time for models with tiered context pricing; null when no tier is selected (e.g., non-tiered model) */ @JsonProperty("contextTier") ContextTier contextTier, + /** Response budget limits configured at session creation time, if any */ + @JsonProperty("responseBudget") ResponseBudgetConfig responseBudget, /** Working directory and git context at session start */ @JsonProperty("context") WorkingDirectoryContext context, /** Whether the session was already in use by another client at start time */ diff --git a/java/src/generated/java/com/github/copilot/generated/ToolExecutionStartEvent.java b/java/src/generated/java/com/github/copilot/generated/ToolExecutionStartEvent.java index cd4e5a137d..b119a3eb0e 100644 --- a/java/src/generated/java/com/github/copilot/generated/ToolExecutionStartEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/ToolExecutionStartEvent.java @@ -40,6 +40,8 @@ public record ToolExecutionStartEventData( @JsonProperty("toolName") String toolName, /** Arguments passed to the tool */ @JsonProperty("arguments") Object arguments, + /** Shell-tool path hints derived from the command at start time for shell tools (bash/powershell/local_shell). Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. Absent for non-shell tools. */ + @JsonProperty("shellToolInfo") ToolExecutionStartShellToolInfo shellToolInfo, /** Model identifier that generated this tool call */ @JsonProperty("model") String model, /** Name of the MCP server hosting this tool, when the tool is an MCP tool */ diff --git a/java/src/generated/java/com/github/copilot/generated/ToolExecutionStartShellToolInfo.java b/java/src/generated/java/com/github/copilot/generated/ToolExecutionStartShellToolInfo.java new file mode 100644 index 0000000000..88ac787fca --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/ToolExecutionStartShellToolInfo.java @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; +import javax.annotation.processing.Generated; + +/** + * Shell-aware path hints for a shell tool's command, captured at start time so consumers can snapshot a file's pre-image before the tool runs. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record ToolExecutionStartShellToolInfo( + /** File paths the command may read or write, derived from the command at start time. Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. */ + @JsonProperty("possiblePaths") List possiblePaths, + /** Whether the command includes a file write redirection (e.g., > or >>). */ + @JsonProperty("hasWriteFileRedirection") Boolean hasWriteFileRedirection +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/UserMessageDelivery.java b/java/src/generated/java/com/github/copilot/generated/UserMessageDelivery.java new file mode 100644 index 0000000000..ab64a88592 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/UserMessageDelivery.java @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: session-events.schema.json + +package com.github.copilot.generated; + +import javax.annotation.processing.Generated; + +/** + * How this user message was delivered to the agentic loop, relative to whether the loop was already running. This is the timing axis only; the message's origin (human vs. system/command/schedule/skill/etc.) is carried separately by `source`. A system-injected message has a delivery too — e.g. a background-task notification waking an idle agent is `idle`, the same mechanism as a human starting a fresh turn. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum UserMessageDelivery { + /** The {@code idle} variant. */ + IDLE("idle"), + /** The {@code steering} variant. */ + STEERING("steering"), + /** The {@code queued} variant. */ + QUEUED("queued"); + + private final String value; + UserMessageDelivery(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static UserMessageDelivery fromValue(String value) { + for (UserMessageDelivery v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown UserMessageDelivery value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/UserMessageEvent.java b/java/src/generated/java/com/github/copilot/generated/UserMessageEvent.java index 69f959ab65..57f64b6527 100644 --- a/java/src/generated/java/com/github/copilot/generated/UserMessageEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/UserMessageEvent.java @@ -47,6 +47,8 @@ public record UserMessageEventData( @JsonProperty("nativeDocumentPathFallbackPaths") List nativeDocumentPathFallbackPaths, /** Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected messages that should be hidden from the user) */ @JsonProperty("source") String source, + /** How this message was delivered to the agentic loop relative to loop state (idle-start vs. steering/queued while busy). The timing axis; combine with `source` (origin) for the full picture. Used for telemetry attribution. */ + @JsonProperty("delivery") UserMessageDelivery delivery, /** The agent mode that was active when this message was sent */ @JsonProperty("agentMode") UserMessageAgentMode agentMode, /** True when this user message was auto-injected by autopilot's continuation loop rather than typed by the user; used to distinguish autopilot-driven turns in telemetry. */ diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/InstalledPluginInfo.java b/java/src/generated/java/com/github/copilot/generated/rpc/InstalledPluginInfo.java index 898c5438ed..2f4895690f 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/InstalledPluginInfo.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/InstalledPluginInfo.java @@ -25,6 +25,8 @@ public record InstalledPluginInfo( @JsonProperty("name") String name, /** Marketplace the plugin came from. Empty string ("") for direct repo / URL / local installs. */ @JsonProperty("marketplace") String marketplace, + /** Opaque, stable hash identifying a direct (non-marketplace) install source. Present only for direct repo / URL / local installs; absent for marketplace plugins. Same source yields the same id; distinct sources never collide. */ + @JsonProperty("directSourceId") String directSourceId, /** Installed version (when reported by the plugin manifest) */ @JsonProperty("version") String version, /** Whether the plugin is currently enabled for new sessions */ diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ModelBilling.java b/java/src/generated/java/com/github/copilot/generated/rpc/ModelBilling.java index 94a8188f16..53ed64f4bf 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/ModelBilling.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ModelBilling.java @@ -24,6 +24,8 @@ public record ModelBilling( /** Billing cost multiplier relative to the base rate */ @JsonProperty("multiplier") Double multiplier, /** Token-level pricing information for this model */ - @JsonProperty("tokenPrices") ModelBillingTokenPrices tokenPrices + @JsonProperty("tokenPrices") ModelBillingTokenPrices tokenPrices, + /** Whole-number percentage discount (0-100) applied to usage billed through this model. Populated for the synthetic `auto` model, where requests routed by auto-mode are billed at a reduced rate; absent for concrete models. */ + @JsonProperty("discountPercent") Long discountPercent ) { } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/PluginsUninstallParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/PluginsUninstallParams.java index 630bbd19e7..fb1fbeb8cf 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/PluginsUninstallParams.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/PluginsUninstallParams.java @@ -25,6 +25,8 @@ @JsonIgnoreProperties(ignoreUnknown = true) public record PluginsUninstallParams( /** Plugin name or "plugin@marketplace" spec to uninstall. When ambiguous, prefer the fully-qualified spec. */ - @JsonProperty("name") String name + @JsonProperty("name") String name, + /** Stable source identity for a direct (non-marketplace) install. Disambiguates uninstall when multiple installed plugins share the same name. */ + @JsonProperty("directSourceId") String directSourceId ) { } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ResponseBudgetConfig.java b/java/src/generated/java/com/github/copilot/generated/rpc/ResponseBudgetConfig.java new file mode 100644 index 0000000000..b83639c09a --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ResponseBudgetConfig.java @@ -0,0 +1,29 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Optional response budget limits. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record ResponseBudgetConfig( + /** Maximum model-call iterations allowed while responding to one top-level user message. */ + @JsonProperty("maxModelIterations") Long maxModelIterations, + /** Maximum AI Credits allowed while responding to one top-level user message. */ + @JsonProperty("maxAiCredits") Double maxAiCredits +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthApi.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthApi.java similarity index 72% rename from java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthApi.java rename to java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthApi.java index 253ee86931..93fb871501 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthApi.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthApi.java @@ -12,12 +12,12 @@ import javax.annotation.processing.Generated; /** - * API methods for the {@code auth} namespace. + * API methods for the {@code gitHubAuth} namespace. * * @since 1.0.0 */ @javax.annotation.processing.Generated("copilot-sdk-codegen") -public final class SessionAuthApi { +public final class SessionGitHubAuthApi { private static final com.fasterxml.jackson.databind.ObjectMapper MAPPER = RpcMapper.INSTANCE; @@ -25,7 +25,7 @@ public final class SessionAuthApi { private final String sessionId; /** @param caller the RPC transport function */ - SessionAuthApi(RpcCaller caller, String sessionId) { + SessionGitHubAuthApi(RpcCaller caller, String sessionId) { this.caller = caller; this.sessionId = sessionId; } @@ -37,8 +37,8 @@ public final class SessionAuthApi { * @since 1.0.0 */ @CopilotExperimental - public CompletableFuture getStatus() { - return caller.invoke("session.auth.getStatus", java.util.Map.of("sessionId", this.sessionId), SessionAuthGetStatusResult.class); + public CompletableFuture getStatus() { + return caller.invoke("session.gitHubAuth.getStatus", java.util.Map.of("sessionId", this.sessionId), SessionGitHubAuthGetStatusResult.class); } /** @@ -51,10 +51,10 @@ public CompletableFuture getStatus() { * @since 1.0.0 */ @CopilotExperimental - public CompletableFuture setCredentials(SessionAuthSetCredentialsParams params) { + public CompletableFuture setCredentials(SessionGitHubAuthSetCredentialsParams params) { com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); _p.put("sessionId", this.sessionId); - return caller.invoke("session.auth.setCredentials", _p, SessionAuthSetCredentialsResult.class); + return caller.invoke("session.gitHubAuth.setCredentials", _p, SessionGitHubAuthSetCredentialsResult.class); } } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthGetStatusParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthGetStatusParams.java similarity index 95% rename from java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthGetStatusParams.java rename to java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthGetStatusParams.java index 8875f6f241..f959105c90 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthGetStatusParams.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthGetStatusParams.java @@ -23,7 +23,7 @@ @javax.annotation.processing.Generated("copilot-sdk-codegen") @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public record SessionAuthGetStatusParams( +public record SessionGitHubAuthGetStatusParams( /** Target session identifier */ @JsonProperty("sessionId") String sessionId ) { diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthGetStatusResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthGetStatusResult.java similarity index 97% rename from java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthGetStatusResult.java rename to java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthGetStatusResult.java index c1bbbc4185..9357f00791 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthGetStatusResult.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthGetStatusResult.java @@ -23,7 +23,7 @@ @javax.annotation.processing.Generated("copilot-sdk-codegen") @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public record SessionAuthGetStatusResult( +public record SessionGitHubAuthGetStatusResult( /** Whether the session has resolved authentication */ @JsonProperty("isAuthenticated") Boolean isAuthenticated, /** Authentication type */ diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthSetCredentialsParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthSetCredentialsParams.java similarity index 65% rename from java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthSetCredentialsParams.java rename to java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthSetCredentialsParams.java index 145b241aaf..1d41404d45 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthSetCredentialsParams.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthSetCredentialsParams.java @@ -23,10 +23,10 @@ @javax.annotation.processing.Generated("copilot-sdk-codegen") @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public record SessionAuthSetCredentialsParams( +public record SessionGitHubAuthSetCredentialsParams( /** Target session identifier */ @JsonProperty("sessionId") String sessionId, - /** The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime stores the value verbatim and uses it for outbound model/API requests; it does NOT re-validate or re-fetch the associated Copilot user response. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. */ + /** The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime installs the supplied value immediately for outbound model/API requests. When the credential carries a raw token (`token`, `env`, or `gh-cli`) but no `copilotUser`, the runtime additionally re-resolves `copilotUser` server-side (best-effort, asynchronously, after the synchronous install) so plan/quota/billing metadata regains fidelity; on resolution failure the verbatim credential remains installed. It does NOT otherwise validate the credential. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. */ @JsonProperty("credentials") Object credentials ) { } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthSetCredentialsResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthSetCredentialsResult.java new file mode 100644 index 0000000000..50715193a8 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionGitHubAuthSetCredentialsResult.java @@ -0,0 +1,32 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * Indicates whether the credential update succeeded. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionGitHubAuthSetCredentialsResult( + /** Whether the operation succeeded */ + @JsonProperty("success") Boolean success, + /** Whether the session ended up with a populated `copilotUser` for the installed credentials. `true` when the supplied credential already carried `copilotUser` or it was successfully re-resolved server-side. `false` when the credential is installed without `copilotUser` — either re-resolution failed, or the variant cannot be re-resolved from the credential alone (only the raw-token variants `token`, `env`, and `gh-cli` can). In both `false` cases the token swap still applied, but plan/quota/billing metadata is degraded. Present whenever a credential was supplied; omitted only when no credential was supplied (no-op call). */ + @JsonProperty("copilotUserResolved") Boolean copilotUserResolved +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpApi.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpApi.java index 4246b11f82..f4603c249f 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpApi.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpApi.java @@ -26,6 +26,8 @@ public final class SessionMcpApi { /** API methods for the {@code mcp.oauth} sub-namespace. */ public final SessionMcpOauthApi oauth; + /** API methods for the {@code mcp.headers} sub-namespace. */ + public final SessionMcpHeadersApi headers; /** API methods for the {@code mcp.apps} sub-namespace. */ public final SessionMcpAppsApi apps; @@ -34,6 +36,7 @@ public final class SessionMcpApi { this.caller = caller; this.sessionId = sessionId; this.oauth = new SessionMcpOauthApi(caller, sessionId); + this.headers = new SessionMcpHeadersApi(caller, sessionId); this.apps = new SessionMcpAppsApi(caller, sessionId); } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpHeadersApi.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpHeadersApi.java new file mode 100644 index 0000000000..45679f83a4 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpHeadersApi.java @@ -0,0 +1,49 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.github.copilot.CopilotExperimental; +import java.util.concurrent.CompletableFuture; +import javax.annotation.processing.Generated; + +/** + * API methods for the {@code mcp.headers} namespace. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class SessionMcpHeadersApi { + + private static final com.fasterxml.jackson.databind.ObjectMapper MAPPER = RpcMapper.INSTANCE; + + private final RpcCaller caller; + private final String sessionId; + + /** @param caller the RPC transport function */ + SessionMcpHeadersApi(RpcCaller caller, String sessionId) { + this.caller = caller; + this.sessionId = sessionId; + } + + /** + * MCP headers refresh request id and the host response. + *

+ * Note: the {@code sessionId} field in the params record is overridden + * by the session-scoped wrapper; any value provided is ignored. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture handlePendingHeadersRefreshRequest(SessionMcpHeadersHandlePendingHeadersRefreshRequestParams params) { + com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); + _p.put("sessionId", this.sessionId); + return caller.invoke("session.mcp.headers.handlePendingHeadersRefreshRequest", _p, SessionMcpHeadersHandlePendingHeadersRefreshRequestResult.class); + } + +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpHeadersHandlePendingHeadersRefreshRequestParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpHeadersHandlePendingHeadersRefreshRequestParams.java new file mode 100644 index 0000000000..77ce6f7329 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpHeadersHandlePendingHeadersRefreshRequestParams.java @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.copilot.CopilotExperimental; +import javax.annotation.processing.Generated; + +/** + * MCP headers refresh request id and the host response. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ +@CopilotExperimental +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record SessionMcpHeadersHandlePendingHeadersRefreshRequestParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Headers refresh request identifier from mcp.headers_refresh_required */ + @JsonProperty("requestId") String requestId, + /** Host response: supply dynamic headers or decline this refresh. */ + @JsonProperty("result") Object result +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthSetCredentialsResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpHeadersHandlePendingHeadersRefreshRequestResult.java similarity index 78% rename from java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthSetCredentialsResult.java rename to java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpHeadersHandlePendingHeadersRefreshRequestResult.java index 41fbf68305..a890713060 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionAuthSetCredentialsResult.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionMcpHeadersHandlePendingHeadersRefreshRequestResult.java @@ -14,7 +14,7 @@ import javax.annotation.processing.Generated; /** - * Indicates whether the credential update succeeded. + * Indicates whether the pending MCP headers refresh response was accepted. * * @apiNote This method is experimental and may change in a future version. * @since 1.0.0 @@ -23,8 +23,8 @@ @javax.annotation.processing.Generated("copilot-sdk-codegen") @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public record SessionAuthSetCredentialsResult( - /** Whether the operation succeeded */ +public record SessionMcpHeadersHandlePendingHeadersRefreshRequestResult( + /** Whether the response was accepted. False if the request was unknown, timed out, or already resolved. */ @JsonProperty("success") Boolean success ) { } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionOptionsUpdateParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionOptionsUpdateParams.java index 4479a3175a..0ac8db564d 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionOptionsUpdateParams.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionOptionsUpdateParams.java @@ -70,6 +70,8 @@ public record SessionOptionsUpdateParams( @JsonProperty("logInteractiveShells") Boolean logInteractiveShells, /** How env values are passed to MCP servers (`direct` inlines literal values; `indirect` resolves at launch). */ @JsonProperty("envValueMode") OptionsUpdateEnvValueMode envValueMode, + /** Whether to include instructions from every MCP server in the system prompt instead of only allowlisted servers. */ + @JsonProperty("allowAllMcpServerInstructions") Boolean allowAllMcpServerInstructions, /** Additional directories to search for skills. */ @JsonProperty("skillDirectories") List skillDirectories, /** Skill IDs that should be excluded from this session. */ @@ -127,6 +129,8 @@ public record SessionOptionsUpdateParams( /** Whether to enable skill directory scanning and loading. Falls back to enableConfigDiscovery when unset. */ @JsonProperty("enableSkills") Boolean enableSkills, /** Context tier for models with tiered pricing. The session uses this to derive effective `modelCapabilitiesOverrides` so compaction, truncation, token display, and request limits honor the selected tier. */ - @JsonProperty("contextTier") OptionsUpdateContextTier contextTier + @JsonProperty("contextTier") OptionsUpdateContextTier contextTier, + /** Optional response budget limits. Pass null to clear the response budget. */ + @JsonProperty("responseBudget") ResponseBudgetConfig responseBudget ) { } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionRpc.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionRpc.java index 4f36674d58..57ca767129 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionRpc.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionRpc.java @@ -29,8 +29,8 @@ public final class SessionRpc { private final RpcCaller caller; private final String sessionId; - /** API methods for the {@code auth} namespace. */ - public final SessionAuthApi auth; + /** API methods for the {@code gitHubAuth} namespace. */ + public final SessionGitHubAuthApi gitHubAuth; /** API methods for the {@code canvas} namespace. */ public final SessionCanvasApi canvas; /** API methods for the {@code model} namespace. */ @@ -101,7 +101,7 @@ public final class SessionRpc { public SessionRpc(RpcCaller caller, String sessionId) { this.caller = caller; this.sessionId = sessionId; - this.auth = new SessionAuthApi(caller, sessionId); + this.gitHubAuth = new SessionGitHubAuthApi(caller, sessionId); this.canvas = new SessionCanvasApi(caller, sessionId); this.model = new SessionModelApi(caller, sessionId); this.mode = new SessionModeApi(caller, sessionId); diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionToolsUpdateSubagentSettingsParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionToolsUpdateSubagentSettingsParams.java index 44758350bd..d8c0c64fd0 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionToolsUpdateSubagentSettingsParams.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionToolsUpdateSubagentSettingsParams.java @@ -39,7 +39,11 @@ public record SessionToolsUpdateSubagentSettingsParamsSubagents( /** Per-agent settings keyed by subagent agent_type */ @JsonProperty("agents") Map agents, /** Names of subagents the user has turned off; they cannot be dispatched */ - @JsonProperty("disabledSubagents") List disabledSubagents + @JsonProperty("disabledSubagents") List disabledSubagents, + /** Maximum number of subagents that can run concurrently; applies to usage-based billing users only */ + @JsonProperty("maxConcurrency") Long maxConcurrency, + /** Maximum subagent nesting depth; applies to usage-based billing users only */ + @JsonProperty("maxDepth") Long maxDepth ) { } } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SlashCommandInvocationResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SlashCommandInvocationResult.java index 265f24e669..336c0eda84 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SlashCommandInvocationResult.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SlashCommandInvocationResult.java @@ -13,7 +13,7 @@ import javax.annotation.processing.Generated; /** - * Result of invoking the slash command (text output, prompt to send to the agent, or completion). + * Result of invoking the slash command (text output, prompt to send to the agent, completion, or subcommand selection). * * @since 1.0.0 */ diff --git a/java/src/main/java/com/github/copilot/CopilotClient.java b/java/src/main/java/com/github/copilot/CopilotClient.java index 1a49941895..8473b3bb45 100644 --- a/java/src/main/java/com/github/copilot/CopilotClient.java +++ b/java/src/main/java/com/github/copilot/CopilotClient.java @@ -864,7 +864,7 @@ CompletableFuture updateSessionOptionsForMode(CopilotSession session, Bool return CompletableFuture.completedFuture(null); } - var params = new SessionOptionsUpdateParams(null, // sessionId — set by SessionOptionsApi + var params = new SessionOptionsUpdateParams(null, // sessionId - set by SessionOptionsApi null, // model null, // modelCapabilitiesOverrides null, // reasoningEffort @@ -886,6 +886,7 @@ CompletableFuture updateSessionOptionsForMode(CopilotSession session, Bool null, // sandboxConfig null, // logInteractiveShells null, // envValueMode + null, // allowAllMcpServerInstructions null, // skillDirectories null, // disabledSkills null, // enableOnDemandInstructionDiscovery @@ -914,7 +915,8 @@ CompletableFuture updateSessionOptionsForMode(CopilotSession session, Bool null, // enableHostGitOperations null, // enableSessionStore null, // enableSkills - null // contextTier + null, // contextTier + null // responseBudget ); return session.getRpc().options.update(params).thenCompose(result -> { diff --git a/java/src/test/java/com/github/copilot/PerSessionAuthTest.java b/java/src/test/java/com/github/copilot/PerSessionAuthTest.java index 1b0c419c30..9e5cd1b324 100644 --- a/java/src/test/java/com/github/copilot/PerSessionAuthTest.java +++ b/java/src/test/java/com/github/copilot/PerSessionAuthTest.java @@ -13,7 +13,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import com.github.copilot.generated.rpc.SessionAuthGetStatusResult; +import com.github.copilot.generated.rpc.SessionGitHubAuthGetStatusResult; import com.github.copilot.rpc.CopilotClientOptions; import com.github.copilot.rpc.PermissionHandler; import com.github.copilot.rpc.SessionConfig; @@ -73,7 +73,7 @@ void shouldAuthenticateWithGitHubToken() throws Exception { .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)).get(); try { - SessionAuthGetStatusResult authStatus = session.getRpc().auth.getStatus().get(); + SessionGitHubAuthGetStatusResult authStatus = session.getRpc().gitHubAuth.getStatus().get(); assertTrue(authStatus.isAuthenticated(), "Expected session to be authenticated"); assertEquals("alice", authStatus.login()); @@ -94,8 +94,8 @@ void shouldIsolateAuthBetweenSessions() throws Exception { .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)).get(); try { - SessionAuthGetStatusResult statusA = sessionA.getRpc().auth.getStatus().get(); - SessionAuthGetStatusResult statusB = sessionB.getRpc().auth.getStatus().get(); + SessionGitHubAuthGetStatusResult statusA = sessionA.getRpc().gitHubAuth.getStatus().get(); + SessionGitHubAuthGetStatusResult statusB = sessionB.getRpc().gitHubAuth.getStatus().get(); assertTrue(statusA.isAuthenticated(), "Expected session A to be authenticated"); assertEquals("alice", statusA.login()); @@ -131,7 +131,7 @@ void shouldBeUnauthenticatedWithoutToken() throws Exception { .createSession(new SessionConfig().setOnPermissionRequest(PermissionHandler.APPROVE_ALL)).get(); try { - SessionAuthGetStatusResult authStatus = session.getRpc().auth.getStatus().get(); + SessionGitHubAuthGetStatusResult authStatus = session.getRpc().gitHubAuth.getStatus().get(); // With no global or per-session token, there is no identity at all. assertNull(authStatus.login(), "Expected no login without per-session token"); diff --git a/java/src/test/java/com/github/copilot/SessionEventHandlingTest.java b/java/src/test/java/com/github/copilot/SessionEventHandlingTest.java index 3ca56b817d..6e80b7593c 100644 --- a/java/src/test/java/com/github/copilot/SessionEventHandlingTest.java +++ b/java/src/test/java/com/github/copilot/SessionEventHandlingTest.java @@ -180,7 +180,7 @@ void testHandlerReceivesCorrectEventData() { SessionStartEvent startEvent = createSessionStartEvent(); startEvent.setData(new SessionStartEvent.SessionStartEventData("my-session-123", null, null, null, null, null, - null, null, null, null, null, null, null)); + null, null, null, null, null, null, null, null)); dispatchEvent(startEvent); AssistantMessageEvent msgEvent = createAssistantMessageEvent("Test content"); @@ -857,7 +857,7 @@ private SessionStartEvent createSessionStartEvent() { private SessionStartEvent createSessionStartEvent(String sessionId) { var event = new SessionStartEvent(); var data = new SessionStartEvent.SessionStartEventData(sessionId, null, null, null, null, null, null, null, - null, null, null, null, null); + null, null, null, null, null, null); event.setData(data); return event; } diff --git a/java/src/test/java/com/github/copilot/generated/rpc/GeneratedRpcRecordsCoverageTest.java b/java/src/test/java/com/github/copilot/generated/rpc/GeneratedRpcRecordsCoverageTest.java index b5e83f17dc..7df3562e32 100644 --- a/java/src/test/java/com/github/copilot/generated/rpc/GeneratedRpcRecordsCoverageTest.java +++ b/java/src/test/java/com/github/copilot/generated/rpc/GeneratedRpcRecordsCoverageTest.java @@ -803,7 +803,7 @@ void modelsListResult_nested() { var limits = new ModelCapabilitiesLimits(100000L, 8192L, 128000L, null); var capabilities = new ModelCapabilities(supports, limits); var policy = new ModelPolicy(ModelPolicyState.ENABLED, null); - var billing = new ModelBilling(1.0, null); + var billing = new ModelBilling(1.0, null, null); var modelItem = new Model("gpt-5", "GPT-5", capabilities, policy, billing, null, null, null, null); var result = new ModelsListResult(List.of(modelItem)); diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json index 6cf1463a38..bfdf31c99e 100644 --- a/nodejs/package-lock.json +++ b/nodejs/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0-dev", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.65", + "@github/copilot": "^1.0.66-1", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, @@ -699,9 +699,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.65.tgz", - "integrity": "sha512-J1XvLuOiVpiAi/E1MBICBymszCgdGLnZxokosXzGcmcjEVZd+QSDoW/kPRHq6oEyBT9SDASPcjCEZ9Q0rLJllg==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.66-1.tgz", + "integrity": "sha512-Cf0rTsG1wfdRzGmD9PC0TPYxQojItwo6Hv/Jp6GwakrBswLn4PlxW/pCQA7n3o2DahTQDX2y6Z9olAdx0dHFQA==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "detect-libc": "^2.1.2" @@ -710,20 +710,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.65", - "@github/copilot-darwin-x64": "1.0.65", - "@github/copilot-linux-arm64": "1.0.65", - "@github/copilot-linux-x64": "1.0.65", - "@github/copilot-linuxmusl-arm64": "1.0.65", - "@github/copilot-linuxmusl-x64": "1.0.65", - "@github/copilot-win32-arm64": "1.0.65", - "@github/copilot-win32-x64": "1.0.65" + "@github/copilot-darwin-arm64": "1.0.66-1", + "@github/copilot-darwin-x64": "1.0.66-1", + "@github/copilot-linux-arm64": "1.0.66-1", + "@github/copilot-linux-x64": "1.0.66-1", + "@github/copilot-linuxmusl-arm64": "1.0.66-1", + "@github/copilot-linuxmusl-x64": "1.0.66-1", + "@github/copilot-win32-arm64": "1.0.66-1", + "@github/copilot-win32-x64": "1.0.66-1" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.65.tgz", - "integrity": "sha512-NFc4xIstZNiIuAYkurQT5DVtbZjBoZ/z6yt/Ffcom7Y5QGjfpN4BFuekv9k+OADRioxxR99NgmhjbuNPWtQhNQ==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.66-1.tgz", + "integrity": "sha512-HTum+52pVBlrUrUjn/r/Q6kd2c0pvGsi6NyfuaGLRKStSQj00Iz5urYlo0hcq5JKF9eGB7ow+aeYc7BDIUVnhw==", "cpu": [ "arm64" ], @@ -737,9 +737,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.65.tgz", - "integrity": "sha512-0wtV22KmTa12VbqWRRkgvJcBz/oIbszfcIpyDWGc4MzbCVksajQ3TWVQ6c7Sdzj5RifCaYdkHAX2zuIYXYlLoQ==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.66-1.tgz", + "integrity": "sha512-gniq5/n2nX8cBQncjwvU7nAGYj21ALSknNUqhPWIQYwx+IM6KnGeBgSpldubJCMDjkZkbPYqskVcxTGvw0GGHA==", "cpu": [ "x64" ], @@ -753,9 +753,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.65.tgz", - "integrity": "sha512-dOwdy/YbTXQN/+x2v4ZgiDycdRtWElyHxPuA6ail3yJDt0nagwn8OYAA/diBLPMAJuuBXiOZGvvb9fGRuh7Xgg==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.66-1.tgz", + "integrity": "sha512-PG/xIIndXo0NpKYXR8GYPXAA3p/kuf4lsA898Pq+9UH5wU9ybqo5P/n5HBLXNOQnpP8+u9pjL9rPbvtwxMkzaQ==", "cpu": [ "arm64" ], @@ -769,9 +769,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.65.tgz", - "integrity": "sha512-al/1a/l/GrpHtygTxt7PZspmv0eHBPdAZ5B31J7Hv/GRdVZM4STCC9dCIOSUFsOX2fhaKD8yLfz4HureSYs23g==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.66-1.tgz", + "integrity": "sha512-Tb11uVan2f8YjFLiTvPUC8yLSYdmoMru9J8axZRuiSgOtRfmaJGxHoM/axPYW+874YAn4gSygs7OPUt1C+67Xw==", "cpu": [ "x64" ], @@ -785,9 +785,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.65.tgz", - "integrity": "sha512-xccQeJSR45xyoaL7J5mZjtU++dmte+ZCDQkIlrpTn2yuMl2LWriBvorQ1P2MwVnXmIiW/GHi93B+lNtsybA9yw==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.66-1.tgz", + "integrity": "sha512-GJEVj60B5MeJ8kfnf/dRmyX4EwU4HWL7yUZkrAG6xznSyHHPoTWtZ/tudQX/mf69emXtO7Nt9cLOcNIEdYRPMg==", "cpu": [ "arm64" ], @@ -801,9 +801,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.65.tgz", - "integrity": "sha512-RHPVUaqjSrhKHQ2EpfGKWErnV+R5elGIZaHXPKO10zpSaQD9b/C9u6nLigZnBuT/8sCaJpVrazPMwOYvYA62aw==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.66-1.tgz", + "integrity": "sha512-I5k9mMRuIO+pmPGDiblFXd+HOBJo92XEIBwbZMaAW3qRuyF5UcEFuWlczOCYzcTreXfBqNkG1P9qsBeDDNXfnQ==", "cpu": [ "x64" ], @@ -817,9 +817,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.65.tgz", - "integrity": "sha512-/vSE/t9Wm3eFSWpxlKyn/oL8OAVOB0yFO7ECxhgbtiqNrBd1tgpYh1k7IXBIWa/saxlV1+de6DEmPuQfx3Z0bg==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.66-1.tgz", + "integrity": "sha512-tUkNUkx5F2TIefY3KDORon3THo256hr/ZVUMEph5fr6xSib4d8gGgNjzok/4kEfIR3a7L/45g0Qi+CzQNtjSdA==", "cpu": [ "arm64" ], @@ -833,9 +833,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.65.tgz", - "integrity": "sha512-wjVWXepET+SpFg8z8V43ZiTy6X1OerCb7yu3QZKNNJ3zY9z20goihPXQCDWkiJpGzszNSgfrsiqUzpUsC9qS0A==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.66-1.tgz", + "integrity": "sha512-ktTbksWav2WSVi8BbTYxD4CJ+OrPximk5zPWff3stsU1MrG0XjZtlML1KUY3d/rrq2lpfZqh0ooF+A4bt8IFsQ==", "cpu": [ "x64" ], diff --git a/nodejs/package.json b/nodejs/package.json index d037ceefae..6d45a75dcd 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -56,7 +56,7 @@ "author": "GitHub", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.65", + "@github/copilot": "^1.0.66-1", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/samples/package-lock.json b/nodejs/samples/package-lock.json index 34152796f4..2823d3db4a 100644 --- a/nodejs/samples/package-lock.json +++ b/nodejs/samples/package-lock.json @@ -18,7 +18,7 @@ "version": "0.0.0-dev", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.65", + "@github/copilot": "^1.0.66-1", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts index 38f77412d9..3ceadb45a0 100644 --- a/nodejs/src/generated/rpc.ts +++ b/nodejs/src/generated/rpc.ts @@ -5,7 +5,7 @@ import type { MessageConnection } from "vscode-jsonrpc/node.js"; -import type { AbortReason, Attachment, ContextTier, EmbeddedBlobResourceContents, EmbeddedTextResourceContents, McpServerSource, McpServerStatus, PermissionPromptRequest, PermissionRule, ReasoningSummary, SessionEvent, SessionMode, ShutdownType, SkillSource, UserToolSessionApproval } from "./session-events.js"; +import type { AbortReason, Attachment, ContextTier, EmbeddedBlobResourceContents, EmbeddedTextResourceContents, McpServerSource, McpServerStatus, PermissionPromptRequest, PermissionRule, ReasoningSummary, ResponseBudgetConfig, SessionEvent, SessionMode, ShutdownType, SkillSource, UserToolSessionApproval } from "./session-events.js"; /** * Initial authentication info for the session. @@ -681,6 +681,26 @@ export type McpServerConfigHttpOauthGrantType = | "authorization_code" /** Headless client credentials flow using the configured OAuth client. */ | "client_credentials"; +/** + * Host response: supply dynamic headers or decline this refresh. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "McpHeadersHandlePendingHeadersRefreshRequest". + */ +/** @experimental */ +export type McpHeadersHandlePendingHeadersRefreshRequest = + | { + /** + * Headers to overlay onto the MCP request. Dynamic headers override static config headers but do not replace SDK-managed request headers. + */ + headers: { + [k: string]: string | undefined; + }; + kind: "headers"; + } + | { + kind: "none"; + }; /** * Host response to the pending OAuth request. * @@ -698,10 +718,6 @@ export type McpOauthPendingRequestResponse = * OAuth token type. Defaults to Bearer when omitted. */ tokenType?: string; - /** - * Refresh token supplied by the host, if available. - */ - refreshToken?: string; /** * Token lifetime in seconds, if known. */ @@ -1169,6 +1185,15 @@ export type PushAttachment = | PushAttachmentDirectory | PushAttachmentSelection | PushAttachmentGitHubReference + | PushAttachmentGitHubCommit + | PushAttachmentGitHubRelease + | PushAttachmentGitHubActionsJob + | PushAttachmentGitHubRepository + | PushAttachmentGitHubFileDiff + | PushAttachmentGitHubTreeComparison + | PushAttachmentGitHubUrl + | PushAttachmentGitHubFile + | PushAttachmentGitHubSnippet | PushAttachmentBlob | ExtensionContextPushInput; /** @@ -1580,7 +1605,7 @@ export type SkillDiscoveryScope = /** A configured custom skill directory. */ | "custom"; /** - * Result of invoking the slash command (text output, prompt to send to the agent, or completion). + * Result of invoking the slash command (text output, prompt to send to the agent, completion, or subcommand selection). * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema * via the `definition` "SlashCommandInvocationResult". @@ -1609,6 +1634,14 @@ export type SubagentSettings = { * Names of subagents the user has turned off; they cannot be dispatched */ disabledSubagents?: string[]; + /** + * Maximum number of subagents that can run concurrently; applies to usage-based billing users only + */ + maxConcurrency?: number; + /** + * Maximum subagent nesting depth; applies to usage-based billing users only + */ + maxDepth?: number; } | null; /** * Context tier override for matching subagents @@ -4315,6 +4348,10 @@ export interface InstalledPluginInfo { * Marketplace the plugin came from. Empty string ("") for direct repo / URL / local installs. */ marketplace: string; + /** + * Opaque, stable hash identifying a direct (non-marketplace) install source. Present only for direct repo / URL / local installs; absent for marketplace plugins. Same source yields the same id; distinct sources never collide. + */ + directSourceId?: string; /** * Installed version (when reported by the plugin manifest) */ @@ -5539,6 +5576,33 @@ export interface McpFilteredServer { */ enterpriseName?: string; } +/** + * MCP headers refresh request id and the host response. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "McpHeadersHandlePendingHeadersRefreshRequestRequest". + */ +/** @experimental */ +export interface McpHeadersHandlePendingHeadersRefreshRequestRequest { + /** + * Headers refresh request identifier from mcp.headers_refresh_required + */ + requestId: string; + result: McpHeadersHandlePendingHeadersRefreshRequest; +} +/** + * Indicates whether the pending MCP headers refresh response was accepted. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "McpHeadersHandlePendingHeadersRefreshRequestResult". + */ +/** @experimental */ +export interface McpHeadersHandlePendingHeadersRefreshRequestResult { + /** + * Whether the response was accepted. False if the request was unknown, timed out, or already resolved. + */ + success: boolean; +} /** * Host-level state, omitted when no MCP host is initialized. * @@ -6357,6 +6421,10 @@ export interface ModelBilling { */ multiplier?: number; tokenPrices?: ModelBillingTokenPrices; + /** + * Whole-number percentage discount (0-100) applied to usage billed through this model. Populated for the synthetic `auto` model, where requests routed by auto-mode are billed at a reduced rate; absent for concrete models. + */ + discountPercent?: number; } /** * Token-level pricing information for this model @@ -8391,6 +8459,10 @@ export interface PluginsUninstallRequest { * Plugin name or "plugin@marketplace" spec to uninstall. When ambiguous, prefer the fully-qualified spec. */ name: string; + /** + * Stable source identity for a direct (non-marketplace) install. Disambiguates uninstall when multiple installed plugins share the same name. + */ + directSourceId?: string | null; } /** * Name (or spec) of the plugin to update. @@ -8889,6 +8961,279 @@ export interface PushAttachmentGitHubReference { */ url: string; } +/** + * Pointer to a GitHub commit. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubCommit". + */ +/** @experimental */ +export interface PushAttachmentGitHubCommit { + /** + * Attachment type discriminator + */ + type: "github_commit"; + repo: PushGitHubRepoRef; + /** + * Full commit SHA + */ + oid: string; + /** + * First line of the commit message + */ + message: string; + /** + * URL to the commit on GitHub + */ + url: string; +} +/** + * Pointer to a GitHub repository. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushGitHubRepoRef". + */ +/** @experimental */ +export interface PushGitHubRepoRef { + /** + * Numeric GitHub repository id + */ + id?: number; + /** + * Repository name (without owner) + */ + name: string; + /** + * Repository owner login (user or organization) + */ + owner: string; +} +/** + * Pointer to a GitHub release. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubRelease". + */ +/** @experimental */ +export interface PushAttachmentGitHubRelease { + /** + * Attachment type discriminator + */ + type: "github_release"; + repo: PushGitHubRepoRef; + /** + * Git tag the release is anchored to + */ + tagName: string; + /** + * Human-readable release name + */ + name: string; + /** + * URL to the release on GitHub + */ + url: string; +} +/** + * Pointer to a GitHub Actions job. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubActionsJob". + */ +/** @experimental */ +export interface PushAttachmentGitHubActionsJob { + /** + * Attachment type discriminator + */ + type: "github_actions_job"; + repo: PushGitHubRepoRef; + /** + * Job id within the workflow run + */ + jobId: number; + /** + * Display name of the job + */ + jobName: string; + /** + * Display name of the workflow the job ran in + */ + workflowName: string; + /** + * URL to the job on GitHub + */ + url: string; + /** + * Terminal conclusion of the job when finished (e.g., success, failure, cancelled). Absent for in-progress jobs. + */ + conclusion?: string; +} +/** + * Pointer to a GitHub repository. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubRepository". + */ +/** @experimental */ +export interface PushAttachmentGitHubRepository { + /** + * Attachment type discriminator + */ + type: "github_repository"; + repo: PushGitHubRepoRef; + /** + * URL to the repository on GitHub + */ + url: string; + /** + * Short description of the repository + */ + description?: string; + /** + * Git ref this attachment is anchored at (branch, tag, or commit). When absent the default branch is implied. + */ + ref?: string; +} +/** + * Pointer to a single-file diff. At least one of `head` and `base` must be present. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubFileDiff". + */ +/** @experimental */ +export interface PushAttachmentGitHubFileDiff { + /** + * Attachment type discriminator + */ + type: "github_file_diff"; + /** + * URL to the diff on GitHub (e.g., a commit, compare, or PR-file URL) + */ + url: string; + head?: PushAttachmentGitHubFileDiffSide; + base?: PushAttachmentGitHubFileDiffSide; +} +/** + * One side of a file diff (head or base) + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubFileDiffSide". + */ +/** @experimental */ +export interface PushAttachmentGitHubFileDiffSide { + repo: PushGitHubRepoRef; + /** + * Git ref (branch, tag, or commit SHA) the file is read at + */ + ref: string; + /** + * Repository-relative path to the file + */ + path: string; +} +/** + * Pointer to a comparison between two git revisions. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubTreeComparison". + */ +/** @experimental */ +export interface PushAttachmentGitHubTreeComparison { + /** + * Attachment type discriminator + */ + type: "github_tree_comparison"; + /** + * URL to the comparison on GitHub + */ + url: string; + base: PushAttachmentGitHubTreeComparisonSide; + head: PushAttachmentGitHubTreeComparisonSide; +} +/** + * One side of a tree comparison (head or base) + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubTreeComparisonSide". + */ +/** @experimental */ +export interface PushAttachmentGitHubTreeComparisonSide { + repo: PushGitHubRepoRef; + /** + * Git revision (branch, tag, or commit SHA) + */ + revision: string; +} +/** + * Generic GitHub URL reference. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubUrl". + */ +/** @experimental */ +export interface PushAttachmentGitHubUrl { + /** + * Attachment type discriminator + */ + type: "github_url"; + /** + * URL to the GitHub resource + */ + url: string; +} +/** + * Pointer to a file in a GitHub repository at a specific ref. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubFile". + */ +/** @experimental */ +export interface PushAttachmentGitHubFile { + /** + * Attachment type discriminator + */ + type: "github_file"; + repo: PushGitHubRepoRef; + /** + * Git ref the file is read at (branch, tag, or commit SHA) + */ + ref: string; + /** + * Repository-relative path to the file + */ + path: string; + /** + * URL to the file on GitHub + */ + url: string; +} +/** + * Pointer to a line range inside a file in a GitHub repository. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "PushAttachmentGitHubSnippet". + */ +/** @experimental */ +export interface PushAttachmentGitHubSnippet { + /** + * Attachment type discriminator + */ + type: "github_snippet"; + repo: PushGitHubRepoRef; + /** + * Git ref the file is read at (branch, tag, or commit SHA) + */ + ref: string; + /** + * Repository-relative path to the file + */ + path: string; + /** + * URL to the snippet on GitHub (with line anchor) + */ + url: string; + lineRange: PushAttachmentFileLineRange; +} /** * Blob attachment with inline base64-encoded data * @@ -10617,6 +10962,10 @@ export interface SessionOpenOptions { */ logInteractiveShells?: boolean; envValueMode?: SessionOpenOptionsEnvValueMode; + /** + * Whether to include instructions from every MCP server in the system prompt instead of only allowlisted servers. + */ + allowAllMcpServerInstructions?: boolean; /** * Additional directories to search for skills. */ @@ -10684,6 +11033,7 @@ export interface SessionOpenOptions { */ maxInlineBinaryBytes?: number; modelCapabilitiesOverrides?: ModelCapabilitiesOverride; + responseBudget?: ResponseBudgetConfig; /** * Runtime context discriminator for agent filtering. */ @@ -11070,6 +11420,10 @@ export interface SessionSetCredentialsResult { * Whether the operation succeeded */ success: boolean; + /** + * Whether the session ended up with a populated `copilotUser` for the installed credentials. `true` when the supplied credential already carried `copilotUser` or it was successfully re-resolved server-side. `false` when the credential is installed without `copilotUser` — either re-resolution failed, or the variant cannot be re-resolved from the credential alone (only the raw-token variants `token`, `env`, and `gh-cli` can). In both `false` cases the token swap still applied, but plan/quota/billing metadata is degraded. Present whenever a credential was supplied; omitted only when no credential was supplied (no-op call). + */ + copilotUserResolved?: boolean; } /** * UUID prefix to resolve to a unique session ID. @@ -11580,6 +11934,10 @@ export interface SessionUpdateOptionsParams { */ logInteractiveShells?: boolean; envValueMode?: OptionsUpdateEnvValueMode; + /** + * Whether to include instructions from every MCP server in the system prompt instead of only allowlisted servers. + */ + allowAllMcpServerInstructions?: boolean; /** * Additional directories to search for skills. */ @@ -11695,6 +12053,10 @@ export interface SessionUpdateOptionsParams { */ enableSkills?: boolean; contextTier?: OptionsUpdateContextTier; + /** + * Optional response budget limits. Pass null to clear the response budget. + */ + responseBudget?: ResponseBudgetConfig | null; } /** * Indicates whether the session options patch was applied successfully. @@ -14468,14 +14830,14 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin shutdown: async (params: ShutdownRequest): Promise => connection.sendRequest("session.shutdown", { sessionId, ...params }), /** @experimental */ - auth: { + gitHubAuth: { /** * Gets authentication status and account metadata for the session. * * @returns Authentication status and account metadata for the session. */ getStatus: async (): Promise => - connection.sendRequest("session.auth.getStatus", { sessionId }), + connection.sendRequest("session.gitHubAuth.getStatus", { sessionId }), /** * Updates the session's auth credentials used for outbound model and API requests. * @@ -14484,7 +14846,7 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin * @returns Indicates whether the credential update succeeded. */ setCredentials: async (params: SessionSetCredentialsParams): Promise => - connection.sendRequest("session.auth.setCredentials", { sessionId, ...params }), + connection.sendRequest("session.gitHubAuth.setCredentials", { sessionId, ...params }), }, /** @experimental */ canvas: { @@ -15018,6 +15380,18 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin connection.sendRequest("session.mcp.oauth.login", { sessionId, ...params }), }, /** @experimental */ + headers: { + /** + * Responds to a pending MCP dynamic headers refresh request. Hosts that subscribe to `mcp.headers_refresh_required` use this to provide short-lived per-server headers or to indicate that no dynamic headers are available for this refresh. + * + * @param params MCP headers refresh request id and the host response. + * + * @returns Indicates whether the pending MCP headers refresh response was accepted. + */ + handlePendingHeadersRefreshRequest: async (params: McpHeadersHandlePendingHeadersRefreshRequestRequest): Promise => + connection.sendRequest("session.mcp.headers.handlePendingHeadersRefreshRequest", { sessionId, ...params }), + }, + /** @experimental */ apps: { /** * Fetch an MCP resource (typically a `ui://` MCP App bundle, per SEP-1865) from a connected server. Requires the `mcp-apps` session capability. @@ -15218,7 +15592,7 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin * * @param params Slash command name and optional raw input string to invoke. * - * @returns Result of invoking the slash command (text output, prompt to send to the agent, or completion). + * @returns Result of invoking the slash command (text output, prompt to send to the agent, completion, or subcommand selection). */ invoke: async (params: CommandsInvokeRequest): Promise => connection.sendRequest("session.commands.invoke", { sessionId, ...params }), diff --git a/nodejs/src/generated/session-events.ts b/nodejs/src/generated/session-events.ts index 96a3bddac7..5ecc550de3 100644 --- a/nodejs/src/generated/session-events.ts +++ b/nodejs/src/generated/session-events.ts @@ -45,6 +45,7 @@ export type SessionEvent = | AssistantMessageStartEvent | AssistantMessageDeltaEvent | AssistantTurnEndEvent + | AssistantIdleEvent | AssistantUsageEvent | ModelCallFailureEvent | AbortEvent @@ -75,6 +76,8 @@ export type SessionEvent = | SamplingCompletedEvent | McpOauthRequiredEvent | McpOauthCompletedEvent + | McpHeadersRefreshRequiredEvent + | McpHeadersRefreshCompletedEvent | CustomNotificationEvent | ExternalToolRequestedEvent | ExternalToolCompletedEvent @@ -207,13 +210,22 @@ export type UserMessageAgentMode = /** The agent is in shell-focused UI mode. */ | "shell"; /** - * A user message attachment — a file, directory, code selection, blob, GitHub reference, or extension-supplied context payload + * A user message attachment — a file, directory, code selection, blob, GitHub reference, GitHub-anchored pointer, or extension-supplied context payload */ export type Attachment = | AttachmentFile | AttachmentDirectory | AttachmentSelection | AttachmentGitHubReference + | AttachmentGitHubCommit + | AttachmentGitHubRelease + | AttachmentGitHubActionsJob + | AttachmentGitHubRepository + | AttachmentGitHubFileDiff + | AttachmentGitHubTreeComparison + | AttachmentGitHubUrl + | AttachmentGitHubFile + | AttachmentGitHubSnippet | AttachmentBlob | AttachmentExtensionContext; /** @@ -234,6 +246,16 @@ export type AttachmentGitHubReferenceType = | "pr" /** GitHub discussion reference. */ | "discussion"; +/** + * How this user message was delivered to the agentic loop, relative to whether the loop was already running. This is the timing axis only; the message's origin (human vs. system/command/schedule/skill/etc.) is carried separately by `source`. A system-injected message has a delivery too — e.g. a background-task notification waking an idle agent is `idle`, the same mechanism as a human starting a fresh turn. + */ +export type UserMessageDelivery = + /** Delivered while the loop was idle; starts its own run immediately (a human's fresh turn, or a system notification waking an idle agent). */ + | "idle" + /** Injected into the current in-flight run while the agent was busy (immediate mode). */ + | "steering" + /** Enqueued while the agent was busy; processed as its own run afterward. */ + | "queued"; /** * The system that produced a citation. */ @@ -507,6 +529,18 @@ export type ElicitationCompletedAction = | "decline" /** The user dismissed the request. */ | "cancel"; +/** + * Reason the runtime is requesting host-provided MCP OAuth credentials + */ +export type McpOauthRequestReason = + /** Initial credentials are required before connecting to the MCP server. */ + | "initial" + /** The current host-provided credential was rejected and a replacement is requested. */ + | "refresh" + /** The server requires a new host authorization flow before continuing. */ + | "reauth" + /** The server requires a credential with additional scope or audience. */ + | "upscope"; /** * How the pending MCP OAuth request was completed */ @@ -515,6 +549,26 @@ export type McpOauthCompletionOutcome = | "token" /** The request completed without an OAuth provider. */ | "cancelled"; +/** + * Why dynamic headers are being requested. + */ +export type McpHeadersRefreshRequiredReason = + /** The transport is making its first dynamic header request for this server. */ + | "startup" + /** The previously cached dynamic headers expired. */ + | "ttl-expired" + /** The server returned 401 and stale dynamic headers were invalidated. */ + | "auth-failed"; +/** + * How the pending MCP headers refresh request resolved. + */ +export type McpHeadersRefreshCompletedOutcome = + /** The host supplied dynamic headers. */ + | "headers" + /** The host responded with no dynamic headers. */ + | "none" + /** No response arrived within the bounded window. */ + | "timeout"; /** * The user's auto-mode-switch choice */ @@ -684,6 +738,7 @@ export interface StartData { * Whether this session supports remote steering via GitHub */ remoteSteerable?: boolean; + responseBudget?: ResponseBudgetConfig; /** * Model selected at session creation time, if any */ @@ -735,6 +790,19 @@ export interface WorkingDirectoryContext { */ repositoryHost?: string; } +/** + * Optional response budget limits. + */ +export interface ResponseBudgetConfig { + /** + * Maximum AI Credits allowed while responding to one top-level user message. + */ + maxAiCredits?: number; + /** + * Maximum model-call iterations allowed while responding to one top-level user message. + */ + maxModelIterations?: number; +} /** * Session event "session.resume". Session resume metadata including current context and event count */ @@ -799,6 +867,10 @@ export interface ResumeData { * Whether this session supports remote steering via GitHub */ remoteSteerable?: boolean; + /** + * Response budget limits currently configured at resume time; null when no budget is active + */ + responseBudget?: ResponseBudgetConfig | null; /** * ISO 8601 timestamp when the session was resumed */ @@ -2322,6 +2394,7 @@ export interface UserMessageData { * The user's message text as displayed in the timeline */ content: string; + delivery?: UserMessageDelivery; /** * CAPI interaction ID for correlating this user message with its turn */ @@ -2501,6 +2574,231 @@ export interface AttachmentGitHubReference { */ url: string; } +/** + * Pointer to a GitHub commit. + */ +export interface AttachmentGitHubCommit { + /** + * First line of the commit message + */ + message: string; + /** + * Full commit SHA + */ + oid: string; + repo: GitHubRepoRef; + /** + * Attachment type discriminator + */ + type: "github_commit"; + /** + * URL to the commit on GitHub + */ + url: string; +} +/** + * Pointer to a GitHub repository. + */ +export interface GitHubRepoRef { + /** + * Numeric GitHub repository id + */ + id?: number; + /** + * Repository name (without owner) + */ + name: string; + /** + * Repository owner login (user or organization) + */ + owner: string; +} +/** + * Pointer to a GitHub release. + */ +export interface AttachmentGitHubRelease { + /** + * Human-readable release name + */ + name: string; + repo: GitHubRepoRef; + /** + * Git tag the release is anchored to + */ + tagName: string; + /** + * Attachment type discriminator + */ + type: "github_release"; + /** + * URL to the release on GitHub + */ + url: string; +} +/** + * Pointer to a GitHub Actions job. + */ +export interface AttachmentGitHubActionsJob { + /** + * Terminal conclusion of the job when finished (e.g., success, failure, cancelled). Absent for in-progress jobs. + */ + conclusion?: string; + /** + * Job id within the workflow run + */ + jobId: number; + /** + * Display name of the job + */ + jobName: string; + repo: GitHubRepoRef; + /** + * Attachment type discriminator + */ + type: "github_actions_job"; + /** + * URL to the job on GitHub + */ + url: string; + /** + * Display name of the workflow the job ran in + */ + workflowName: string; +} +/** + * Pointer to a GitHub repository. + */ +export interface AttachmentGitHubRepository { + /** + * Short description of the repository + */ + description?: string; + /** + * Git ref this attachment is anchored at (branch, tag, or commit). When absent the default branch is implied. + */ + ref?: string; + repo: GitHubRepoRef; + /** + * Attachment type discriminator + */ + type: "github_repository"; + /** + * URL to the repository on GitHub + */ + url: string; +} +/** + * Pointer to a single-file diff. At least one of `head` and `base` must be present. + */ +export interface AttachmentGitHubFileDiff { + base?: AttachmentGitHubFileDiffSide; + head?: AttachmentGitHubFileDiffSide; + /** + * Attachment type discriminator + */ + type: "github_file_diff"; + /** + * URL to the diff on GitHub (e.g., a commit, compare, or PR-file URL) + */ + url: string; +} +/** + * One side of a file diff (head or base) + */ +export interface AttachmentGitHubFileDiffSide { + /** + * Repository-relative path to the file + */ + path: string; + /** + * Git ref (branch, tag, or commit SHA) the file is read at + */ + ref: string; + repo: GitHubRepoRef; +} +/** + * Pointer to a comparison between two git revisions. + */ +export interface AttachmentGitHubTreeComparison { + base: AttachmentGitHubTreeComparisonSide; + head: AttachmentGitHubTreeComparisonSide; + /** + * Attachment type discriminator + */ + type: "github_tree_comparison"; + /** + * URL to the comparison on GitHub + */ + url: string; +} +/** + * One side of a tree comparison (head or base) + */ +export interface AttachmentGitHubTreeComparisonSide { + repo: GitHubRepoRef; + /** + * Git revision (branch, tag, or commit SHA) + */ + revision: string; +} +/** + * Generic GitHub URL reference. + */ +export interface AttachmentGitHubUrl { + /** + * Attachment type discriminator + */ + type: "github_url"; + /** + * URL to the GitHub resource + */ + url: string; +} +/** + * Pointer to a file in a GitHub repository at a specific ref. + */ +export interface AttachmentGitHubFile { + /** + * Repository-relative path to the file + */ + path: string; + /** + * Git ref the file is read at (branch, tag, or commit SHA) + */ + ref: string; + repo: GitHubRepoRef; + /** + * Attachment type discriminator + */ + type: "github_file"; + /** + * URL to the file on GitHub + */ + url: string; +} +/** + * Pointer to a line range inside a file in a GitHub repository. + */ +export interface AttachmentGitHubSnippet { + lineRange: AttachmentFileLineRange; + /** + * Repository-relative path to the file + */ + path: string; + /** + * Git ref the file is read at (branch, tag, or commit SHA) + */ + ref: string; + repo: GitHubRepoRef; + /** + * Attachment type discriminator + */ + type: "github_snippet"; + /** + * URL to the snippet on GitHub (with line anchor) + */ + url: string; +} /** * Blob attachment with inline base64-encoded data */ @@ -3219,6 +3517,45 @@ export interface AssistantTurnEndData { */ turnId: string; } +/** + * Session event "assistant.idle". Payload emitted whenever the main agent's processing loop goes idle, including while related background work (running agents or in-flight attached shell commands) is still pending and the session-level idle event is therefore deferred + */ +export interface AssistantIdleEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: AssistantIdleData; + /** + * Always true for events that are transient and not persisted to the session event log on disk. + */ + ephemeral: true; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "assistant.idle". + */ + type: "assistant.idle"; +} +/** + * Payload emitted whenever the main agent's processing loop goes idle, including while related background work (running agents or in-flight attached shell commands) is still pending and the session-level idle event is therefore deferred + */ +export interface AssistantIdleData { + /** + * True when the preceding agentic loop was cancelled via abort signal + */ + aborted?: boolean; +} /** * Session event "assistant.usage". LLM API call usage metrics including tokens, costs, quotas, and billing information */ @@ -3712,6 +4049,7 @@ export interface ToolExecutionStartData { * Tool call ID of the parent tool invocation when this event originates from a sub-agent */ parentToolCallId?: string; + shellToolInfo?: ToolExecutionStartShellToolInfo; /** * Unique identifier for this tool call */ @@ -3726,6 +4064,19 @@ export interface ToolExecutionStartData { */ turnId?: string; } +/** + * Shell-aware path hints for a shell tool's command, captured at start time so consumers can snapshot a file's pre-image before the tool runs. + */ +export interface ToolExecutionStartShellToolInfo { + /** + * Whether the command includes a file write redirection (e.g., > or >>). + */ + hasWriteFileRedirection: boolean; + /** + * File paths the command may read or write, derived from the command at start time. Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. + */ + possiblePaths: string[]; +} /** * Tool definition metadata, present for MCP tools with MCP Apps support */ @@ -6407,6 +6758,7 @@ export interface McpOauthRequiredEvent { * OAuth authentication request for an MCP server */ export interface McpOauthRequiredData { + reason: McpOauthRequestReason; /** * Unique identifier for this OAuth request; used to respond via session.mcp.oauth.handlePendingRequest */ @@ -6434,6 +6786,10 @@ export interface McpOauthRequiredStaticClientConfig { * OAuth client ID for the server */ clientId: string; + /** + * Optional OAuth client secret for confidential static clients, when the runtime can resolve one + */ + clientSecret?: string; /** * Optional non-default OAuth grant type. When set to 'client_credentials', the OAuth flow runs headlessly using the client_id + keychain-stored secret (no browser, no callback server). */ @@ -6452,9 +6808,9 @@ export interface McpOauthWWWAuthenticateParams { */ error?: string; /** - * Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter + * Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter, if present */ - resourceMetadataUrl: string; + resourceMetadataUrl?: string; /** * Requested OAuth scopes from the WWW-Authenticate scope parameter, if present */ @@ -6500,6 +6856,94 @@ export interface McpOauthCompletedData { */ requestId: string; } +/** + * Session event "mcp.headers_refresh_required". Dynamic headers refresh request for a remote MCP server + */ +export interface McpHeadersRefreshRequiredEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: McpHeadersRefreshRequiredData; + /** + * Always true for events that are transient and not persisted to the session event log on disk. + */ + ephemeral: true; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "mcp.headers_refresh_required". + */ + type: "mcp.headers_refresh_required"; +} +/** + * Dynamic headers refresh request for a remote MCP server + */ +export interface McpHeadersRefreshRequiredData { + reason: McpHeadersRefreshRequiredReason; + /** + * Unique identifier for this headers refresh request; used to respond via session.mcp.headers.handlePendingHeadersRefreshRequest() + */ + requestId: string; + /** + * Display name of the remote MCP server requesting headers + */ + serverName: string; + /** + * URL of the remote MCP server requesting headers + */ + serverUrl: string; +} +/** + * Session event "mcp.headers_refresh_completed". MCP headers refresh request completion notification + */ +export interface McpHeadersRefreshCompletedEvent { + /** + * Sub-agent instance identifier. Absent for events from the root/main agent and session-level events. + */ + agentId?: string; + data: McpHeadersRefreshCompletedData; + /** + * Always true for events that are transient and not persisted to the session event log on disk. + */ + ephemeral: true; + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * Type discriminator. Always "mcp.headers_refresh_completed". + */ + type: "mcp.headers_refresh_completed"; +} +/** + * MCP headers refresh request completion notification + */ +export interface McpHeadersRefreshCompletedData { + outcome: McpHeadersRefreshCompletedOutcome; + /** + * Request ID of the resolved headers refresh request + */ + requestId: string; +} /** * Session event "session.custom_notification". Opaque custom notification data. Consumers may branch on source and name, but payload semantics are source-defined. */ diff --git a/nodejs/test/e2e/per_session_auth.e2e.test.ts b/nodejs/test/e2e/per_session_auth.e2e.test.ts index 0bb1dbd4e9..5f55d397d8 100644 --- a/nodejs/test/e2e/per_session_auth.e2e.test.ts +++ b/nodejs/test/e2e/per_session_auth.e2e.test.ts @@ -42,7 +42,7 @@ describe("Per-session GitHub auth", async () => { gitHubToken: "token-alice", }); - const authStatus = await session.rpc.auth.getStatus(); + const authStatus = await session.rpc.gitHubAuth.getStatus(); expect(authStatus.isAuthenticated).toBe(true); expect(authStatus.login).toBe("alice"); expect(authStatus.copilotPlan).toBe("individual_pro"); @@ -60,8 +60,8 @@ describe("Per-session GitHub auth", async () => { gitHubToken: "token-bob", }); - const statusA = await sessionA.rpc.auth.getStatus(); - const statusB = await sessionB.rpc.auth.getStatus(); + const statusA = await sessionA.rpc.gitHubAuth.getStatus(); + const statusB = await sessionB.rpc.gitHubAuth.getStatus(); expect(statusA.isAuthenticated).toBe(true); expect(statusA.login).toBe("alice"); @@ -92,7 +92,7 @@ describe("Per-session GitHub auth", async () => { onPermissionRequest: approveAll, }); - const authStatus = await session.rpc.auth.getStatus(); + const authStatus = await session.rpc.gitHubAuth.getStatus(); // Without a per-session GitHub token, there is no per-session identity. // In CI the process-level fake token may still authenticate globally, // so we check login rather than isAuthenticated. diff --git a/nodejs/test/e2e/rpc_server_plugins.e2e.test.ts b/nodejs/test/e2e/rpc_server_plugins.e2e.test.ts index c678c05436..4bc3c63c96 100644 --- a/nodejs/test/e2e/rpc_server_plugins.e2e.test.ts +++ b/nodejs/test/e2e/rpc_server_plugins.e2e.test.ts @@ -127,46 +127,31 @@ This skill exists so the plugin reports at least one installed skill. writeFileSync(join(pluginDir, "SKILL.md"), skill); } - it( - "should install list and uninstall plugin from local marketplace", - { timeout: 120_000 }, - async () => { - const marketplaceDir = createLocalMarketplaceFixture(); - const { client, home } = await createIsolatedStartedClient(); - try { - await client.rpc.plugins.marketplaces.add({ source: marketplaceDir }); - - const spec = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`; - const install = await client.rpc.plugins.install({ source: spec }); - - expect(install.plugin.name).toBe(PLUGIN_NAME); - expect(install.plugin.marketplace).toBe(MARKETPLACE_NAME); - expect(install.plugin.enabled).toBe(true); - expect(install.skillsInstalled).toBeGreaterThanOrEqual(1); - expect(install.deprecationWarning ?? null).toBeNull(); + it("should install and list plugin from local marketplace", { timeout: 120_000 }, async () => { + const marketplaceDir = createLocalMarketplaceFixture(); + const { client, home } = await createIsolatedStartedClient(); + try { + await client.rpc.plugins.marketplaces.add({ source: marketplaceDir }); - const afterInstall = await client.rpc.plugins.list(); - const listed = afterInstall.plugins.filter( - (plugin) => - plugin.name === PLUGIN_NAME && plugin.marketplace === MARKETPLACE_NAME - ); - expect(listed).toHaveLength(1); - expect(listed[0].enabled).toBe(true); + const spec = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`; + const install = await client.rpc.plugins.install({ source: spec }); - await client.rpc.plugins.uninstall({ name: spec }); + expect(install.plugin.name).toBe(PLUGIN_NAME); + expect(install.plugin.marketplace).toBe(MARKETPLACE_NAME); + expect(install.plugin.enabled).toBe(true); + expect(install.skillsInstalled).toBeGreaterThanOrEqual(1); + expect(install.deprecationWarning ?? null).toBeNull(); - const afterUninstall = await client.rpc.plugins.list(); - expect( - afterUninstall.plugins.some( - (plugin) => - plugin.name === PLUGIN_NAME && plugin.marketplace === MARKETPLACE_NAME - ) - ).toBe(false); - } finally { - await disposeIsolated(client, home, marketplaceDir); - } + const afterInstall = await client.rpc.plugins.list(); + const listed = afterInstall.plugins.filter( + (plugin) => plugin.name === PLUGIN_NAME && plugin.marketplace === MARKETPLACE_NAME + ); + expect(listed).toHaveLength(1); + expect(listed[0].enabled).toBe(true); + } finally { + await disposeIsolated(client, home, marketplaceDir); } - ); + }); it("should enable and disable marketplace plugin", { timeout: 120_000 }, async () => { const marketplaceDir = createLocalMarketplaceFixture(); @@ -244,8 +229,12 @@ This skill exists so the plugin reports at least one installed skill. expect( afterInstall.plugins.filter((plugin) => plugin.name === DIRECT_PLUGIN_NAME) ).toHaveLength(1); + expect(install.plugin.directSourceId).toBeTruthy(); - await client.rpc.plugins.uninstall({ name: DIRECT_PLUGIN_NAME }); + await client.rpc.plugins.uninstall({ + name: DIRECT_PLUGIN_NAME, + directSourceId: install.plugin.directSourceId, + }); const afterUninstall = await client.rpc.plugins.list(); expect( diff --git a/nodejs/test/e2e/rpc_session_state.e2e.test.ts b/nodejs/test/e2e/rpc_session_state.e2e.test.ts index d1a628a0df..7c33d55d68 100644 --- a/nodejs/test/e2e/rpc_session_state.e2e.test.ts +++ b/nodejs/test/e2e/rpc_session_state.e2e.test.ts @@ -492,7 +492,7 @@ describe("Session-scoped RPC", async () => { const session = await client.createSession({ onPermissionRequest: approveAll }); try { const login = `sdk-rpc-${randomUUID()}`; - const setCredentials = await session.rpc.auth.setCredentials({ + const setCredentials = await session.rpc.gitHubAuth.setCredentials({ credentials: { type: "user", host: "https://github.com", @@ -511,7 +511,7 @@ describe("Session-scoped RPC", async () => { }); expect(setCredentials.success).toBe(true); - const status = await session.rpc.auth.getStatus(); + const status = await session.rpc.gitHubAuth.getStatus(); expect(status.isAuthenticated).toBe(true); expect(status.authType).toBe("user"); expect(status.host).toBe("https://github.com"); diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py index b38c12ff39..212865e17e 100644 --- a/python/copilot/generated/rpc.py +++ b/python/copilot/generated/rpc.py @@ -6,7 +6,7 @@ from typing import ClassVar, TYPE_CHECKING -from .session_events import AbortReason, Attachment, ContextTier, EmbeddedBlobResourceContents, EmbeddedTextResourceContents, McpServerSource, McpServerStatus, PermissionPromptRequest, PermissionRule, ReasoningSummary, SessionEvent, SessionMode, ShutdownType, SkillSource, UserToolSessionApproval +from .session_events import AbortReason, Attachment, ContextTier, EmbeddedBlobResourceContents, EmbeddedTextResourceContents, McpServerSource, McpServerStatus, PermissionPromptRequest, PermissionRule, ReasoningSummary, ResponseBudgetConfig, SessionEvent, SessionMode, ShutdownType, SkillSource, UserToolSessionApproval if TYPE_CHECKING: from .._jsonrpc import JsonRpcClient @@ -2982,6 +2982,31 @@ def to_dict(self) -> dict: result["redactedReason"] = from_union([from_str, from_none], self.redacted_reason) return result +class MCPHeadersHandlePendingHeadersRefreshRequestKind(Enum): + HEADERS = "headers" + NONE = "none" + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class MCPHeadersHandlePendingHeadersRefreshRequestResult: + """Indicates whether the pending MCP headers refresh response was accepted.""" + + success: bool + """Whether the response was accepted. False if the request was unknown, timed out, or + already resolved. + """ + + @staticmethod + def from_dict(obj: Any) -> 'MCPHeadersHandlePendingHeadersRefreshRequestResult': + assert isinstance(obj, dict) + success = from_bool(obj.get("success")) + return MCPHeadersHandlePendingHeadersRefreshRequestResult(success) + + def to_dict(self) -> dict: + result: dict = {} + result["success"] = from_bool(self.success) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class MCPServerFailureInfo: @@ -5216,11 +5241,55 @@ def to_dict(self) -> dict: result["token"] = from_str(self.token) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushGitHubRepoRef: + """Repository the commit belongs to + + Pointer to a GitHub repository. + + Repository the release belongs to + + Repository the workflow run belongs to + + Repository pointer + + Repository the file lives in + + Repository the revision belongs to + """ + name: str + """Repository name (without owner)""" + + owner: str + """Repository owner login (user or organization)""" + + id: int | None = None + """Numeric GitHub repository id""" + + @staticmethod + def from_dict(obj: Any) -> 'PushGitHubRepoRef': + assert isinstance(obj, dict) + name = from_str(obj.get("name")) + owner = from_str(obj.get("owner")) + id = from_union([from_int, from_none], obj.get("id")) + return PushGitHubRepoRef(name, owner, id) + + def to_dict(self) -> dict: + result: dict = {} + result["name"] = from_str(self.name) + result["owner"] = from_str(self.owner) + if self.id is not None: + result["id"] = from_union([from_int, from_none], self.id) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class PushAttachmentFileLineRange: - """Optional line range to scope the attachment to a specific section of the file""" + """Optional line range to scope the attachment to a specific section of the file + Line range the snippet covers + """ end: int """End line number (1-based, inclusive)""" @@ -5300,7 +5369,16 @@ class PushAttachmentType(Enum): DIRECTORY = "directory" EXTENSION_CONTEXT = "extension_context" FILE = "file" + GITHUB_ACTIONS_JOB = "github_actions_job" + GITHUB_COMMIT = "github_commit" + GITHUB_FILE = "github_file" + GITHUB_FILE_DIFF = "github_file_diff" GITHUB_REFERENCE = "github_reference" + GITHUB_RELEASE = "github_release" + GITHUB_REPOSITORY = "github_repository" + GITHUB_SNIPPET = "github_snippet" + GITHUB_TREE_COMPARISON = "github_tree_comparison" + GITHUB_URL = "github_url" SELECTION = "selection" class PushAttachmentBlobType(Enum): @@ -5309,10 +5387,37 @@ class PushAttachmentBlobType(Enum): class PushAttachmentFileType(Enum): FILE = "file" +class PushAttachmentGitHubActionsJobType(Enum): + GITHUB_ACTIONS_JOB = "github_actions_job" + +class PushAttachmentGitHubCommitType(Enum): + GITHUB_COMMIT = "github_commit" + +class PushAttachmentGitHubFileType(Enum): + GITHUB_FILE = "github_file" + +class PushAttachmentGitHubFileDiffType(Enum): + GITHUB_FILE_DIFF = "github_file_diff" + # Experimental: this type is part of an experimental API and may change or be removed. class PushAttachmentGitHubReferenceType(Enum): GITHUB_REFERENCE = "github_reference" +class PushAttachmentGitHubReleaseType(Enum): + GITHUB_RELEASE = "github_release" + +class PushAttachmentGitHubRepositoryType(Enum): + GITHUB_REPOSITORY = "github_repository" + +class PushAttachmentGitHubSnippetType(Enum): + GITHUB_SNIPPET = "github_snippet" + +class PushAttachmentGitHubTreeComparisonType(Enum): + GITHUB_TREE_COMPARISON = "github_tree_comparison" + +class PushAttachmentGitHubURLType(Enum): + GITHUB_URL = "github_url" + class PushAttachmentSelectionType(Enum): SELECTION = "selection" @@ -6796,10 +6901,14 @@ class SessionSetCredentialsParams: credentials: AuthInfo | None = None """The new auth credentials to install on the session. When omitted or `undefined`, the call - is a no-op and the session's existing credentials are preserved. The runtime stores the - value verbatim and uses it for outbound model/API requests; it does NOT re-validate or - re-fetch the associated Copilot user response. Several variants carry secret material; - treat this method's params as containing secrets at rest and in transit. + is a no-op and the session's existing credentials are preserved. The runtime installs the + supplied value immediately for outbound model/API requests. When the credential carries a + raw token (`token`, `env`, or `gh-cli`) but no `copilotUser`, the runtime additionally + re-resolves `copilotUser` server-side (best-effort, asynchronously, after the synchronous + install) so plan/quota/billing metadata regains fidelity; on resolution failure the + verbatim credential remains installed. It does NOT otherwise validate the credential. + Several variants carry secret material; treat this method's params as containing secrets + at rest and in transit. """ @staticmethod @@ -6822,15 +6931,29 @@ class SessionSetCredentialsResult: success: bool """Whether the operation succeeded""" + copilot_user_resolved: bool | None = None + """Whether the session ended up with a populated `copilotUser` for the installed + credentials. `true` when the supplied credential already carried `copilotUser` or it was + successfully re-resolved server-side. `false` when the credential is installed without + `copilotUser` — either re-resolution failed, or the variant cannot be re-resolved from + the credential alone (only the raw-token variants `token`, `env`, and `gh-cli` can). In + both `false` cases the token swap still applied, but plan/quota/billing metadata is + degraded. Present whenever a credential was supplied; omitted only when no credential was + supplied (no-op call). + """ + @staticmethod def from_dict(obj: Any) -> 'SessionSetCredentialsResult': assert isinstance(obj, dict) success = from_bool(obj.get("success")) - return SessionSetCredentialsResult(success) + copilot_user_resolved = from_union([from_bool, from_none], obj.get("copilotUserResolved")) + return SessionSetCredentialsResult(success, copilot_user_resolved) def to_dict(self) -> dict: result: dict = {} result["success"] = from_bool(self.success) + if self.copilot_user_resolved is not None: + result["copilotUserResolved"] = from_union([from_bool, from_none], self.copilot_user_resolved) return result # Experimental: this type is part of an experimental API and may change or be removed. @@ -11402,6 +11525,31 @@ def to_dict(self) -> dict: result["allowedServers"] = from_union([lambda x: from_list(lambda x: to_class(MCPAllowedServer, x), x), from_none], self.allowed_servers) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class MCPHeadersHandlePendingHeadersRefreshRequest: + """Host response: supply dynamic headers or decline this refresh.""" + + kind: MCPHeadersHandlePendingHeadersRefreshRequestKind + headers: dict[str, str] | None = None + """Headers to overlay onto the MCP request. Dynamic headers override static config headers + but do not replace SDK-managed request headers. + """ + + @staticmethod + def from_dict(obj: Any) -> 'MCPHeadersHandlePendingHeadersRefreshRequest': + assert isinstance(obj, dict) + kind = MCPHeadersHandlePendingHeadersRefreshRequestKind(obj.get("kind")) + headers = from_union([lambda x: from_dict(from_str, x), from_none], obj.get("headers")) + return MCPHeadersHandlePendingHeadersRefreshRequest(kind, headers) + + def to_dict(self) -> dict: + result: dict = {} + result["kind"] = to_enum(MCPHeadersHandlePendingHeadersRefreshRequestKind, self.kind) + if self.headers is not None: + result["headers"] = from_union([lambda x: from_dict(from_str, x), from_none], self.headers) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class MCPHostState: @@ -11463,9 +11611,6 @@ class MCPOauthPendingRequestResponse: expires_in: int | None = None """Token lifetime in seconds, if known.""" - refresh_token: str | None = None - """Refresh token supplied by the host, if available.""" - token_type: str | None = None """OAuth token type. Defaults to Bearer when omitted.""" @@ -11475,9 +11620,8 @@ def from_dict(obj: Any) -> 'MCPOauthPendingRequestResponse': kind = MCPOauthPendingRequestResponseKind(obj.get("kind")) access_token = from_union([from_str, from_none], obj.get("accessToken")) expires_in = from_union([from_int, from_none], obj.get("expiresIn")) - refresh_token = from_union([from_str, from_none], obj.get("refreshToken")) token_type = from_union([from_str, from_none], obj.get("tokenType")) - return MCPOauthPendingRequestResponse(kind, access_token, expires_in, refresh_token, token_type) + return MCPOauthPendingRequestResponse(kind, access_token, expires_in, token_type) def to_dict(self) -> dict: result: dict = {} @@ -11486,8 +11630,6 @@ def to_dict(self) -> dict: result["accessToken"] = from_union([from_str, from_none], self.access_token) if self.expires_in is not None: result["expiresIn"] = from_union([from_int, from_none], self.expires_in) - if self.refresh_token is not None: - result["refreshToken"] = from_union([from_str, from_none], self.refresh_token) if self.token_type is not None: result["tokenType"] = from_union([from_str, from_none], self.token_type) return result @@ -13192,6 +13334,11 @@ class InstalledPluginInfo: name: str """Plugin name""" + direct_source_id: str | None = None + """Opaque, stable hash identifying a direct (non-marketplace) install source. Present only + for direct repo / URL / local installs; absent for marketplace plugins. Same source + yields the same id; distinct sources never collide. + """ version: str | None = None """Installed version (when reported by the plugin manifest)""" @@ -13201,14 +13348,17 @@ def from_dict(obj: Any) -> 'InstalledPluginInfo': enabled = from_bool(obj.get("enabled")) marketplace = from_str(obj.get("marketplace")) name = from_str(obj.get("name")) + direct_source_id = from_union([from_str, from_none], obj.get("directSourceId")) version = from_union([from_str, from_none], obj.get("version")) - return InstalledPluginInfo(enabled, marketplace, name, version) + return InstalledPluginInfo(enabled, marketplace, name, direct_source_id, version) def to_dict(self) -> dict: result: dict = {} result["enabled"] = from_bool(self.enabled) result["marketplace"] = from_str(self.marketplace) result["name"] = from_str(self.name) + if self.direct_source_id is not None: + result["directSourceId"] = from_union([from_str, from_none], self.direct_source_id) if self.version is not None: result["version"] = from_union([from_str, from_none], self.version) return result @@ -13441,16 +13591,23 @@ class PluginsUninstallRequest: """Plugin name or "plugin@marketplace" spec to uninstall. When ambiguous, prefer the fully-qualified spec. """ + direct_source_id: str | None = None + """Stable source identity for a direct (non-marketplace) install. Disambiguates uninstall + when multiple installed plugins share the same name. + """ @staticmethod def from_dict(obj: Any) -> 'PluginsUninstallRequest': assert isinstance(obj, dict) name = from_str(obj.get("name")) - return PluginsUninstallRequest(name) + direct_source_id = from_union([from_none, from_str], obj.get("directSourceId")) + return PluginsUninstallRequest(name, direct_source_id) def to_dict(self) -> dict: result: dict = {} result["name"] = from_str(self.name) + if self.direct_source_id is not None: + result["directSourceId"] = from_union([from_none, from_str], self.direct_source_id) return result # Experimental: this type is part of an experimental API and may change or be removed. @@ -13551,6 +13708,115 @@ def to_dict(self) -> dict: result["wireApi"] = from_union([lambda x: to_enum(ProviderWireAPI, x), from_none], self.wire_api) return result +@dataclass +class PushAttachmentGitHubSide: + """File location on the base side of the diff. Absent for additions. + + One side of a file diff (head or base) + + File location on the head side of the diff. Absent for deletions. + + Base side of the comparison + + One side of a tree comparison (head or base) + + Head side of the comparison + """ + repo: PushGitHubRepoRef + """Repository the file lives in + + Repository the revision belongs to + """ + path: str | None = None + """Repository-relative path to the file""" + + ref: str | None = None + """Git ref (branch, tag, or commit SHA) the file is read at""" + + revision: str | None = None + """Git revision (branch, tag, or commit SHA)""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubSide': + assert isinstance(obj, dict) + repo = PushGitHubRepoRef.from_dict(obj.get("repo")) + path = from_union([from_str, from_none], obj.get("path")) + ref = from_union([from_str, from_none], obj.get("ref")) + revision = from_union([from_str, from_none], obj.get("revision")) + return PushAttachmentGitHubSide(repo, path, ref, revision) + + def to_dict(self) -> dict: + result: dict = {} + result["repo"] = to_class(PushGitHubRepoRef, self.repo) + if self.path is not None: + result["path"] = from_union([from_str, from_none], self.path) + if self.ref is not None: + result["ref"] = from_union([from_str, from_none], self.ref) + if self.revision is not None: + result["revision"] = from_union([from_str, from_none], self.revision) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubFileDiffSide: + """File location on the base side of the diff. Absent for additions. + + One side of a file diff (head or base) + + File location on the head side of the diff. Absent for deletions. + """ + path: str + """Repository-relative path to the file""" + + ref: str + """Git ref (branch, tag, or commit SHA) the file is read at""" + + repo: PushGitHubRepoRef + """Repository the file lives in""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubFileDiffSide': + assert isinstance(obj, dict) + path = from_str(obj.get("path")) + ref = from_str(obj.get("ref")) + repo = PushGitHubRepoRef.from_dict(obj.get("repo")) + return PushAttachmentGitHubFileDiffSide(path, ref, repo) + + def to_dict(self) -> dict: + result: dict = {} + result["path"] = from_str(self.path) + result["ref"] = from_str(self.ref) + result["repo"] = to_class(PushGitHubRepoRef, self.repo) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubTreeComparisonSide: + """Base side of the comparison + + One side of a tree comparison (head or base) + + Head side of the comparison + """ + repo: PushGitHubRepoRef + """Repository the revision belongs to""" + + revision: str + """Git revision (branch, tag, or commit SHA)""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubTreeComparisonSide': + assert isinstance(obj, dict) + repo = PushGitHubRepoRef.from_dict(obj.get("repo")) + revision = from_str(obj.get("revision")) + return PushAttachmentGitHubTreeComparisonSide(repo, revision) + + def to_dict(self) -> dict: + result: dict = {} + result["repo"] = to_class(PushGitHubRepoRef, self.repo) + result["revision"] = from_str(self.revision) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class PushAttachmentSelectionDetails: @@ -13643,6 +13909,133 @@ def to_dict(self) -> dict: result["lineRange"] = from_union([lambda x: to_class(PushAttachmentFileLineRange, x), from_none], self.line_range) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubActionsJob: + """Pointer to a GitHub Actions job.""" + + job_id: int + """Job id within the workflow run""" + + job_name: str + """Display name of the job""" + + repo: PushGitHubRepoRef + """Repository the workflow run belongs to""" + + type: ClassVar[str] = "github_actions_job" + """Attachment type discriminator""" + + url: str + """URL to the job on GitHub""" + + workflow_name: str + """Display name of the workflow the job ran in""" + + conclusion: str | None = None + """Terminal conclusion of the job when finished (e.g., success, failure, cancelled). Absent + for in-progress jobs. + """ + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubActionsJob': + assert isinstance(obj, dict) + job_id = from_int(obj.get("jobId")) + job_name = from_str(obj.get("jobName")) + repo = PushGitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + workflow_name = from_str(obj.get("workflowName")) + conclusion = from_union([from_str, from_none], obj.get("conclusion")) + return PushAttachmentGitHubActionsJob(job_id, job_name, repo, url, workflow_name, conclusion) + + def to_dict(self) -> dict: + result: dict = {} + result["jobId"] = from_int(self.job_id) + result["jobName"] = from_str(self.job_name) + result["repo"] = to_class(PushGitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + result["workflowName"] = from_str(self.workflow_name) + if self.conclusion is not None: + result["conclusion"] = from_union([from_str, from_none], self.conclusion) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubCommit: + """Pointer to a GitHub commit.""" + + message: str + """First line of the commit message""" + + oid: str + """Full commit SHA""" + + repo: PushGitHubRepoRef + """Repository the commit belongs to""" + + type: ClassVar[str] = "github_commit" + """Attachment type discriminator""" + + url: str + """URL to the commit on GitHub""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubCommit': + assert isinstance(obj, dict) + message = from_str(obj.get("message")) + oid = from_str(obj.get("oid")) + repo = PushGitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + return PushAttachmentGitHubCommit(message, oid, repo, url) + + def to_dict(self) -> dict: + result: dict = {} + result["message"] = from_str(self.message) + result["oid"] = from_str(self.oid) + result["repo"] = to_class(PushGitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubFile: + """Pointer to a file in a GitHub repository at a specific ref.""" + + path: str + """Repository-relative path to the file""" + + ref: str + """Git ref the file is read at (branch, tag, or commit SHA)""" + + repo: PushGitHubRepoRef + """Repository the file lives in""" + + type: ClassVar[str] = "github_file" + """Attachment type discriminator""" + + url: str + """URL to the file on GitHub""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubFile': + assert isinstance(obj, dict) + path = from_str(obj.get("path")) + ref = from_str(obj.get("ref")) + repo = PushGitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + return PushAttachmentGitHubFile(path, ref, repo, url) + + def to_dict(self) -> dict: + result: dict = {} + result["path"] = from_str(self.path) + result["ref"] = from_str(self.ref) + result["repo"] = to_class(PushGitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class PushAttachmentGitHubReference: @@ -13686,6 +14079,152 @@ def to_dict(self) -> dict: result["url"] = from_str(self.url) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubRelease: + """Pointer to a GitHub release.""" + + name: str + """Human-readable release name""" + + repo: PushGitHubRepoRef + """Repository the release belongs to""" + + tag_name: str + """Git tag the release is anchored to""" + + type: ClassVar[str] = "github_release" + """Attachment type discriminator""" + + url: str + """URL to the release on GitHub""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubRelease': + assert isinstance(obj, dict) + name = from_str(obj.get("name")) + repo = PushGitHubRepoRef.from_dict(obj.get("repo")) + tag_name = from_str(obj.get("tagName")) + url = from_str(obj.get("url")) + return PushAttachmentGitHubRelease(name, repo, tag_name, url) + + def to_dict(self) -> dict: + result: dict = {} + result["name"] = from_str(self.name) + result["repo"] = to_class(PushGitHubRepoRef, self.repo) + result["tagName"] = from_str(self.tag_name) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubRepository: + """Pointer to a GitHub repository.""" + + repo: PushGitHubRepoRef + """Repository pointer""" + + type: ClassVar[str] = "github_repository" + """Attachment type discriminator""" + + url: str + """URL to the repository on GitHub""" + + description: str | None = None + """Short description of the repository""" + + ref: str | None = None + """Git ref this attachment is anchored at (branch, tag, or commit). When absent the default + branch is implied. + """ + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubRepository': + assert isinstance(obj, dict) + repo = PushGitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + description = from_union([from_str, from_none], obj.get("description")) + ref = from_union([from_str, from_none], obj.get("ref")) + return PushAttachmentGitHubRepository(repo, url, description, ref) + + def to_dict(self) -> dict: + result: dict = {} + result["repo"] = to_class(PushGitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + if self.description is not None: + result["description"] = from_union([from_str, from_none], self.description) + if self.ref is not None: + result["ref"] = from_union([from_str, from_none], self.ref) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubSnippet: + """Pointer to a line range inside a file in a GitHub repository.""" + + line_range: PushAttachmentFileLineRange + """Line range the snippet covers""" + + path: str + """Repository-relative path to the file""" + + ref: str + """Git ref the file is read at (branch, tag, or commit SHA)""" + + repo: PushGitHubRepoRef + """Repository the file lives in""" + + type: ClassVar[str] = "github_snippet" + """Attachment type discriminator""" + + url: str + """URL to the snippet on GitHub (with line anchor)""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubSnippet': + assert isinstance(obj, dict) + line_range = PushAttachmentFileLineRange.from_dict(obj.get("lineRange")) + path = from_str(obj.get("path")) + ref = from_str(obj.get("ref")) + repo = PushGitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + return PushAttachmentGitHubSnippet(line_range, path, ref, repo, url) + + def to_dict(self) -> dict: + result: dict = {} + result["lineRange"] = to_class(PushAttachmentFileLineRange, self.line_range) + result["path"] = from_str(self.path) + result["ref"] = from_str(self.ref) + result["repo"] = to_class(PushGitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubURL: + """Generic GitHub URL reference.""" + + type: ClassVar[str] = "github_url" + """Attachment type discriminator""" + + url: str + """URL to the GitHub resource""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubURL': + assert isinstance(obj, dict) + url = from_str(obj.get("url")) + return PushAttachmentGitHubURL(url) + + def to_dict(self) -> dict: + result: dict = {} + result["type"] = self.type + result["url"] = from_str(self.url) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class QueuePendingItems: @@ -16791,6 +17330,30 @@ def to_dict(self) -> dict: result["serverName"] = from_str(self.server_name) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class MCPHeadersHandlePendingHeadersRefreshRequestRequest: + """MCP headers refresh request id and the host response.""" + + request_id: str + """Headers refresh request identifier from mcp.headers_refresh_required""" + + result: MCPHeadersHandlePendingHeadersRefreshRequest + """Host response: supply dynamic headers or decline this refresh.""" + + @staticmethod + def from_dict(obj: Any) -> 'MCPHeadersHandlePendingHeadersRefreshRequestRequest': + assert isinstance(obj, dict) + request_id = from_str(obj.get("requestId")) + result = MCPHeadersHandlePendingHeadersRefreshRequest.from_dict(obj.get("result")) + return MCPHeadersHandlePendingHeadersRefreshRequestRequest(request_id, result) + + def to_dict(self) -> dict: + result: dict = {} + result["requestId"] = from_str(self.request_id) + result["result"] = to_class(MCPHeadersHandlePendingHeadersRefreshRequest, self.result) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class MCPOauthHandlePendingRequest: @@ -16819,6 +17382,11 @@ def to_dict(self) -> dict: class ModelBilling: """Billing information""" + discount_percent: int | None = None + """Whole-number percentage discount (0-100) applied to usage billed through this model. + Populated for the synthetic `auto` model, where requests routed by auto-mode are billed + at a reduced rate; absent for concrete models. + """ multiplier: float | None = None """Billing cost multiplier relative to the base rate""" @@ -16828,12 +17396,15 @@ class ModelBilling: @staticmethod def from_dict(obj: Any) -> 'ModelBilling': assert isinstance(obj, dict) + discount_percent = from_union([from_int, from_none], obj.get("discountPercent")) multiplier = from_union([from_float, from_none], obj.get("multiplier")) token_prices = from_union([ModelBillingTokenPrices.from_dict, from_none], obj.get("tokenPrices")) - return ModelBilling(multiplier, token_prices) + return ModelBilling(discount_percent, multiplier, token_prices) def to_dict(self) -> dict: result: dict = {} + if self.discount_percent is not None: + result["discountPercent"] = from_union([from_int, from_none], self.discount_percent) if self.multiplier is not None: result["multiplier"] = from_union([to_float, from_none], self.multiplier) if self.token_prices is not None: @@ -17088,6 +17659,74 @@ def to_dict(self) -> dict: result["results"] = from_list(lambda x: to_class(PluginUpdateAllEntry, x), self.results) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubFileDiff: + """Pointer to a single-file diff. At least one of `head` and `base` must be present.""" + + type: ClassVar[str] = "github_file_diff" + """Attachment type discriminator""" + + url: str + """URL to the diff on GitHub (e.g., a commit, compare, or PR-file URL)""" + + base: PushAttachmentGitHubFileDiffSide | None = None + """File location on the base side of the diff. Absent for additions.""" + + head: PushAttachmentGitHubFileDiffSide | None = None + """File location on the head side of the diff. Absent for deletions.""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubFileDiff': + assert isinstance(obj, dict) + url = from_str(obj.get("url")) + base = from_union([PushAttachmentGitHubFileDiffSide.from_dict, from_none], obj.get("base")) + head = from_union([PushAttachmentGitHubFileDiffSide.from_dict, from_none], obj.get("head")) + return PushAttachmentGitHubFileDiff(url, base, head) + + def to_dict(self) -> dict: + result: dict = {} + result["type"] = self.type + result["url"] = from_str(self.url) + if self.base is not None: + result["base"] = from_union([lambda x: to_class(PushAttachmentGitHubFileDiffSide, x), from_none], self.base) + if self.head is not None: + result["head"] = from_union([lambda x: to_class(PushAttachmentGitHubFileDiffSide, x), from_none], self.head) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class PushAttachmentGitHubTreeComparison: + """Pointer to a comparison between two git revisions.""" + + base: PushAttachmentGitHubTreeComparisonSide + """Base side of the comparison""" + + head: PushAttachmentGitHubTreeComparisonSide + """Head side of the comparison""" + + type: ClassVar[str] = "github_tree_comparison" + """Attachment type discriminator""" + + url: str + """URL to the comparison on GitHub""" + + @staticmethod + def from_dict(obj: Any) -> 'PushAttachmentGitHubTreeComparison': + assert isinstance(obj, dict) + base = PushAttachmentGitHubTreeComparisonSide.from_dict(obj.get("base")) + head = PushAttachmentGitHubTreeComparisonSide.from_dict(obj.get("head")) + url = from_str(obj.get("url")) + return PushAttachmentGitHubTreeComparison(base, head, url) + + def to_dict(self) -> dict: + result: dict = {} + result["base"] = to_class(PushAttachmentGitHubTreeComparisonSide, self.base) + result["head"] = to_class(PushAttachmentGitHubTreeComparisonSide, self.head) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class PushAttachmentSelection: @@ -19165,6 +19804,10 @@ class SessionOpenOptions: agent_context: str | None = None """Runtime context discriminator for agent filtering.""" + allow_all_mcp_server_instructions: bool | None = None + """Whether to include instructions from every MCP server in the system prompt instead of + only allowlisted servers. + """ ask_user_disabled: bool | None = None """Whether ask_user is explicitly disabled.""" @@ -19300,6 +19943,9 @@ class SessionOpenOptions: remote_steerable: bool | None = None """Whether this session supports remote steering.""" + response_budget: ResponseBudgetConfig | None = None + """Initial response budget limits for the session.""" + running_in_interactive_mode: bool | None = None """Whether the host is an interactive UI.""" @@ -19338,6 +19984,7 @@ def from_dict(obj: Any) -> 'SessionOpenOptions': assert isinstance(obj, dict) additional_content_exclusion_policies = from_union([lambda x: from_list(SessionOpenOptionsAdditionalContentExclusionPolicy.from_dict, x), from_none], obj.get("additionalContentExclusionPolicies")) agent_context = from_union([from_str, from_none], obj.get("agentContext")) + allow_all_mcp_server_instructions = from_union([from_bool, from_none], obj.get("allowAllMcpServerInstructions")) ask_user_disabled = from_union([from_bool, from_none], obj.get("askUserDisabled")) auth_info = from_union([_load_AuthInfo, from_none], obj.get("authInfo")) available_tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("availableTools")) @@ -19380,6 +20027,7 @@ def from_dict(obj: Any) -> 'SessionOpenOptions': remote_defaulted_on = from_union([from_bool, from_none], obj.get("remoteDefaultedOn")) remote_exporting = from_union([from_bool, from_none], obj.get("remoteExporting")) remote_steerable = from_union([from_bool, from_none], obj.get("remoteSteerable")) + response_budget = from_union([ResponseBudgetConfig.from_dict, from_none], obj.get("responseBudget")) running_in_interactive_mode = from_union([from_bool, from_none], obj.get("runningInInteractiveMode")) sandbox_config = from_union([SandboxConfig.from_dict, from_none], obj.get("sandboxConfig")) session_capabilities = from_union([lambda x: from_list(SessionCapability, x), from_none], obj.get("sessionCapabilities")) @@ -19391,7 +20039,7 @@ def from_dict(obj: Any) -> 'SessionOpenOptions': trajectory_file = from_union([from_str, from_none], obj.get("trajectoryFile")) working_directory = from_union([from_str, from_none], obj.get("workingDirectory")) working_directory_context = from_union([SessionContext.from_dict, from_none], obj.get("workingDirectoryContext")) - return SessionOpenOptions(additional_content_exclusion_policies, agent_context, ask_user_disabled, auth_info, available_tools, capi, client_kind, client_name, coauthor_enabled, config_dir, continue_on_auto_mode, copilot_url, custom_agents_local_only, detached_from_spawning_parent_engagement_id, detached_from_spawning_parent_session_id, disabled_instruction_sources, disabled_skills, enable_citations, enable_on_demand_instruction_discovery, enable_script_safety, enable_streaming, env_value_mode, events_log_directory, excluded_tools, exp_assignments, feature_flags, installed_plugins, integration_id, is_experimental_mode, log_interactive_shells, lsp_client_name, max_inline_binary_bytes, memory, model, model_capabilities_overrides, models, name, provider, providers, reasoning_effort, reasoning_summary, remote_defaulted_on, remote_exporting, remote_steerable, running_in_interactive_mode, sandbox_config, session_capabilities, session_id, shell_init_profile, shell_process_flags, skill_directories, skip_custom_instructions, trajectory_file, working_directory, working_directory_context) + return SessionOpenOptions(additional_content_exclusion_policies, agent_context, allow_all_mcp_server_instructions, ask_user_disabled, auth_info, available_tools, capi, client_kind, client_name, coauthor_enabled, config_dir, continue_on_auto_mode, copilot_url, custom_agents_local_only, detached_from_spawning_parent_engagement_id, detached_from_spawning_parent_session_id, disabled_instruction_sources, disabled_skills, enable_citations, enable_on_demand_instruction_discovery, enable_script_safety, enable_streaming, env_value_mode, events_log_directory, excluded_tools, exp_assignments, feature_flags, installed_plugins, integration_id, is_experimental_mode, log_interactive_shells, lsp_client_name, max_inline_binary_bytes, memory, model, model_capabilities_overrides, models, name, provider, providers, reasoning_effort, reasoning_summary, remote_defaulted_on, remote_exporting, remote_steerable, response_budget, running_in_interactive_mode, sandbox_config, session_capabilities, session_id, shell_init_profile, shell_process_flags, skill_directories, skip_custom_instructions, trajectory_file, working_directory, working_directory_context) def to_dict(self) -> dict: result: dict = {} @@ -19399,6 +20047,8 @@ def to_dict(self) -> dict: result["additionalContentExclusionPolicies"] = from_union([lambda x: from_list(lambda x: to_class(SessionOpenOptionsAdditionalContentExclusionPolicy, x), x), from_none], self.additional_content_exclusion_policies) if self.agent_context is not None: result["agentContext"] = from_union([from_str, from_none], self.agent_context) + if self.allow_all_mcp_server_instructions is not None: + result["allowAllMcpServerInstructions"] = from_union([from_bool, from_none], self.allow_all_mcp_server_instructions) if self.ask_user_disabled is not None: result["askUserDisabled"] = from_union([from_bool, from_none], self.ask_user_disabled) if self.auth_info is not None: @@ -19483,6 +20133,8 @@ def to_dict(self) -> dict: result["remoteExporting"] = from_union([from_bool, from_none], self.remote_exporting) if self.remote_steerable is not None: result["remoteSteerable"] = from_union([from_bool, from_none], self.remote_steerable) + if self.response_budget is not None: + result["responseBudget"] = from_union([lambda x: to_class(ResponseBudgetConfig, x), from_none], self.response_budget) if self.running_in_interactive_mode is not None: result["runningInInteractiveMode"] = from_union([from_bool, from_none], self.running_in_interactive_mode) if self.sandbox_config is not None: @@ -19518,6 +20170,10 @@ class SessionUpdateOptionsParams: agent_context: str | None = None """Runtime context discriminator (e.g., `cli`, `actions`).""" + allow_all_mcp_server_instructions: bool | None = None + """Whether to include instructions from every MCP server in the system prompt instead of + only allowlisted servers. + """ ask_user_disabled: bool | None = None """Whether to disable the `ask_user` tool (encourages autonomous behavior).""" @@ -19641,6 +20297,9 @@ class SessionUpdateOptionsParams: reasoning_summary: ReasoningSummary | None = None """Reasoning summary mode for supported model clients.""" + response_budget: ResponseBudgetConfig | None = None + """Optional response budget limits. Pass null to clear the response budget.""" + running_in_interactive_mode: bool | None = None """Whether the session is running in an interactive UI.""" @@ -19687,6 +20346,7 @@ def from_dict(obj: Any) -> 'SessionUpdateOptionsParams': assert isinstance(obj, dict) additional_content_exclusion_policies = from_union([lambda x: from_list(OptionsUpdateAdditionalContentExclusionPolicy.from_dict, x), from_none], obj.get("additionalContentExclusionPolicies")) agent_context = from_union([from_str, from_none], obj.get("agentContext")) + allow_all_mcp_server_instructions = from_union([from_bool, from_none], obj.get("allowAllMcpServerInstructions")) ask_user_disabled = from_union([from_bool, from_none], obj.get("askUserDisabled")) available_tools = from_union([lambda x: from_list(from_str, x), from_none], obj.get("availableTools")) capi = from_union([CapiSessionOptions.from_dict, from_none], obj.get("capi")) @@ -19723,6 +20383,7 @@ def from_dict(obj: Any) -> 'SessionUpdateOptionsParams': provider = from_union([ProviderConfig.from_dict, from_none], obj.get("provider")) reasoning_effort = from_union([from_str, from_none], obj.get("reasoningEffort")) reasoning_summary = from_union([ReasoningSummary, from_none], obj.get("reasoningSummary")) + response_budget = from_union([ResponseBudgetConfig.from_dict, from_none], obj.get("responseBudget")) running_in_interactive_mode = from_union([from_bool, from_none], obj.get("runningInInteractiveMode")) sandbox_config = from_union([SandboxConfig.from_dict, from_none], obj.get("sandboxConfig")) session_capabilities = from_union([lambda x: from_list(SessionCapability, x), from_none], obj.get("sessionCapabilities")) @@ -19735,7 +20396,7 @@ def from_dict(obj: Any) -> 'SessionUpdateOptionsParams': 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, capi, client_name, coauthor_enabled, context_tier, continue_on_auto_mode, copilot_url, custom_agents_local_only, disabled_instruction_sources, disabled_skills, enable_file_hooks, enable_host_git_operations, enable_on_demand_instruction_discovery, enable_reasoning_summaries, enable_script_safety, enable_session_store, enable_skills, 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, max_inline_binary_bytes, model, model_capabilities_overrides, organization_custom_instructions, provider, reasoning_effort, reasoning_summary, running_in_interactive_mode, sandbox_config, session_capabilities, shell_init_profile, shell_process_flags, skill_directories, skip_custom_instructions, skip_embedding_retrieval, suppress_custom_agent_prompt, tool_filter_precedence, trajectory_file, working_directory) + return SessionUpdateOptionsParams(additional_content_exclusion_policies, agent_context, allow_all_mcp_server_instructions, ask_user_disabled, available_tools, capi, client_name, coauthor_enabled, context_tier, continue_on_auto_mode, copilot_url, custom_agents_local_only, disabled_instruction_sources, disabled_skills, enable_file_hooks, enable_host_git_operations, enable_on_demand_instruction_discovery, enable_reasoning_summaries, enable_script_safety, enable_session_store, enable_skills, 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, max_inline_binary_bytes, model, model_capabilities_overrides, organization_custom_instructions, provider, reasoning_effort, reasoning_summary, response_budget, running_in_interactive_mode, sandbox_config, session_capabilities, shell_init_profile, shell_process_flags, skill_directories, skip_custom_instructions, skip_embedding_retrieval, suppress_custom_agent_prompt, tool_filter_precedence, trajectory_file, working_directory) def to_dict(self) -> dict: result: dict = {} @@ -19743,6 +20404,8 @@ def to_dict(self) -> dict: result["additionalContentExclusionPolicies"] = from_union([lambda x: from_list(lambda x: to_class(OptionsUpdateAdditionalContentExclusionPolicy, x), x), from_none], self.additional_content_exclusion_policies) if self.agent_context is not None: result["agentContext"] = from_union([from_str, from_none], self.agent_context) + if self.allow_all_mcp_server_instructions is not None: + result["allowAllMcpServerInstructions"] = from_union([from_bool, from_none], self.allow_all_mcp_server_instructions) if self.ask_user_disabled is not None: result["askUserDisabled"] = from_union([from_bool, from_none], self.ask_user_disabled) if self.available_tools is not None: @@ -19815,6 +20478,8 @@ def to_dict(self) -> dict: result["reasoningEffort"] = from_union([from_str, from_none], self.reasoning_effort) if self.reasoning_summary is not None: result["reasoningSummary"] = from_union([lambda x: to_enum(ReasoningSummary, x), from_none], self.reasoning_summary) + if self.response_budget is not None: + result["responseBudget"] = from_union([lambda x: to_class(ResponseBudgetConfig, x), from_none], self.response_budget) if self.running_in_interactive_mode is not None: result["runningInInteractiveMode"] = from_union([from_bool, from_none], self.running_in_interactive_mode) if self.sandbox_config is not None: @@ -20847,12 +21512,21 @@ class SubagentSettings: disabled_subagents: list[str] | None = None """Names of subagents the user has turned off; they cannot be dispatched""" + max_concurrency: int | None = None + """Maximum number of subagents that can run concurrently; applies to usage-based billing + users only + """ + max_depth: int | None = None + """Maximum subagent nesting depth; applies to usage-based billing users only""" + @staticmethod def from_dict(obj: Any) -> 'SubagentSettings': assert isinstance(obj, dict) agents = from_union([lambda x: from_dict(SubagentSettingsEntry.from_dict, x), from_none], obj.get("agents")) disabled_subagents = from_union([lambda x: from_list(from_str, x), from_none], obj.get("disabledSubagents")) - return SubagentSettings(agents, disabled_subagents) + max_concurrency = from_union([from_int, from_none], obj.get("maxConcurrency")) + max_depth = from_union([from_int, from_none], obj.get("maxDepth")) + return SubagentSettings(agents, disabled_subagents, max_concurrency, max_depth) def to_dict(self) -> dict: result: dict = {} @@ -20860,6 +21534,10 @@ def to_dict(self) -> dict: result["agents"] = from_union([lambda x: from_dict(lambda x: to_class(SubagentSettingsEntry, x), x), from_none], self.agents) if self.disabled_subagents is not None: result["disabledSubagents"] = from_union([lambda x: from_list(from_str, x), from_none], self.disabled_subagents) + if self.max_concurrency is not None: + result["maxConcurrency"] = from_union([from_int, from_none], self.max_concurrency) + if self.max_depth is not None: + result["maxDepth"] = from_union([from_int, from_none], self.max_depth) return result # Experimental: this type is part of an experimental API and may change or be removed. @@ -21162,6 +21840,9 @@ class RPC: mcp_execute_sampling_request: dict[str, Any] mcp_execute_sampling_result: dict[str, Any] mcp_filtered_server: MCPFilteredServer + mcp_headers_handle_pending_headers_refresh_request: MCPHeadersHandlePendingHeadersRefreshRequest + mcp_headers_handle_pending_headers_refresh_request_request: MCPHeadersHandlePendingHeadersRefreshRequestRequest + mcp_headers_handle_pending_headers_refresh_request_result: MCPHeadersHandlePendingHeadersRefreshRequestResult mcp_host_state: MCPHostState mcp_is_server_running_request: MCPIsServerRunningRequest mcp_is_server_running_result: MCPIsServerRunningResult @@ -21395,12 +22076,24 @@ class RPC: push_attachment_directory: PushAttachmentDirectory push_attachment_file: PushAttachmentFile push_attachment_file_line_range: PushAttachmentFileLineRange + push_attachment_git_hub_actions_job: PushAttachmentGitHubActionsJob + push_attachment_git_hub_commit: PushAttachmentGitHubCommit + push_attachment_git_hub_file: PushAttachmentGitHubFile + push_attachment_git_hub_file_diff: PushAttachmentGitHubFileDiff + push_attachment_git_hub_file_diff_side: PushAttachmentGitHubFileDiffSide push_attachment_git_hub_reference: PushAttachmentGitHubReference push_attachment_git_hub_reference_type: PushAttachmentGitHubReferenceTypeEnum + push_attachment_git_hub_release: PushAttachmentGitHubRelease + push_attachment_git_hub_repository: PushAttachmentGitHubRepository + push_attachment_git_hub_snippet: PushAttachmentGitHubSnippet + push_attachment_git_hub_tree_comparison: PushAttachmentGitHubTreeComparison + push_attachment_git_hub_tree_comparison_side: PushAttachmentGitHubTreeComparisonSide + push_attachment_git_hub_url: PushAttachmentGitHubURL push_attachment_selection: PushAttachmentSelection push_attachment_selection_details: PushAttachmentSelectionDetails push_attachment_selection_details_end: PushAttachmentSelectionDetailsEnd push_attachment_selection_details_start: PushAttachmentSelectionDetailsStart + push_git_hub_repo_ref: PushGitHubRepoRef queued_command_handled: QueuedCommandHandled queued_command_not_handled: QueuedCommandNotHandled queued_command_result: QueuedCommandResult @@ -21934,6 +22627,9 @@ def from_dict(obj: Any) -> 'RPC': mcp_execute_sampling_request = from_dict(lambda x: x, obj.get("McpExecuteSamplingRequest")) mcp_execute_sampling_result = from_dict(lambda x: x, obj.get("McpExecuteSamplingResult")) mcp_filtered_server = MCPFilteredServer.from_dict(obj.get("McpFilteredServer")) + mcp_headers_handle_pending_headers_refresh_request = MCPHeadersHandlePendingHeadersRefreshRequest.from_dict(obj.get("McpHeadersHandlePendingHeadersRefreshRequest")) + mcp_headers_handle_pending_headers_refresh_request_request = MCPHeadersHandlePendingHeadersRefreshRequestRequest.from_dict(obj.get("McpHeadersHandlePendingHeadersRefreshRequestRequest")) + mcp_headers_handle_pending_headers_refresh_request_result = MCPHeadersHandlePendingHeadersRefreshRequestResult.from_dict(obj.get("McpHeadersHandlePendingHeadersRefreshRequestResult")) mcp_host_state = MCPHostState.from_dict(obj.get("McpHostState")) mcp_is_server_running_request = MCPIsServerRunningRequest.from_dict(obj.get("McpIsServerRunningRequest")) mcp_is_server_running_result = MCPIsServerRunningResult.from_dict(obj.get("McpIsServerRunningResult")) @@ -22167,12 +22863,24 @@ def from_dict(obj: Any) -> 'RPC': push_attachment_directory = PushAttachmentDirectory.from_dict(obj.get("PushAttachmentDirectory")) push_attachment_file = PushAttachmentFile.from_dict(obj.get("PushAttachmentFile")) push_attachment_file_line_range = PushAttachmentFileLineRange.from_dict(obj.get("PushAttachmentFileLineRange")) + push_attachment_git_hub_actions_job = PushAttachmentGitHubActionsJob.from_dict(obj.get("PushAttachmentGitHubActionsJob")) + push_attachment_git_hub_commit = PushAttachmentGitHubCommit.from_dict(obj.get("PushAttachmentGitHubCommit")) + push_attachment_git_hub_file = PushAttachmentGitHubFile.from_dict(obj.get("PushAttachmentGitHubFile")) + push_attachment_git_hub_file_diff = PushAttachmentGitHubFileDiff.from_dict(obj.get("PushAttachmentGitHubFileDiff")) + push_attachment_git_hub_file_diff_side = PushAttachmentGitHubFileDiffSide.from_dict(obj.get("PushAttachmentGitHubFileDiffSide")) push_attachment_git_hub_reference = PushAttachmentGitHubReference.from_dict(obj.get("PushAttachmentGitHubReference")) push_attachment_git_hub_reference_type = PushAttachmentGitHubReferenceTypeEnum(obj.get("PushAttachmentGitHubReferenceType")) + push_attachment_git_hub_release = PushAttachmentGitHubRelease.from_dict(obj.get("PushAttachmentGitHubRelease")) + push_attachment_git_hub_repository = PushAttachmentGitHubRepository.from_dict(obj.get("PushAttachmentGitHubRepository")) + push_attachment_git_hub_snippet = PushAttachmentGitHubSnippet.from_dict(obj.get("PushAttachmentGitHubSnippet")) + push_attachment_git_hub_tree_comparison = PushAttachmentGitHubTreeComparison.from_dict(obj.get("PushAttachmentGitHubTreeComparison")) + push_attachment_git_hub_tree_comparison_side = PushAttachmentGitHubTreeComparisonSide.from_dict(obj.get("PushAttachmentGitHubTreeComparisonSide")) + push_attachment_git_hub_url = PushAttachmentGitHubURL.from_dict(obj.get("PushAttachmentGitHubUrl")) push_attachment_selection = PushAttachmentSelection.from_dict(obj.get("PushAttachmentSelection")) push_attachment_selection_details = PushAttachmentSelectionDetails.from_dict(obj.get("PushAttachmentSelectionDetails")) push_attachment_selection_details_end = PushAttachmentSelectionDetailsEnd.from_dict(obj.get("PushAttachmentSelectionDetailsEnd")) push_attachment_selection_details_start = PushAttachmentSelectionDetailsStart.from_dict(obj.get("PushAttachmentSelectionDetailsStart")) + push_git_hub_repo_ref = PushGitHubRepoRef.from_dict(obj.get("PushGitHubRepoRef")) queued_command_handled = QueuedCommandHandled.from_dict(obj.get("QueuedCommandHandled")) queued_command_not_handled = QueuedCommandNotHandled.from_dict(obj.get("QueuedCommandNotHandled")) queued_command_result = _load_QueuedCommandResult(obj.get("QueuedCommandResult")) @@ -22481,7 +23189,7 @@ def from_dict(obj: Any) -> 'RPC': subagent_settings = from_union([SubagentSettings.from_dict, from_none], obj.get("SubagentSettings")) 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_all_users, account_get_all_users_result, account_get_current_auth_result, account_get_quota_request, account_get_quota_result, account_login_request, account_login_result, account_logout_request, account_logout_result, account_quota_snapshot, agent_discovery_path, agent_discovery_path_list, agent_discovery_path_scope, 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, agents_discover_request, agent_select_request, agent_select_result, agents_get_discovery_paths_request, allow_all_permission_set_result, allow_all_permission_state, api_key_auth_info, auth_info, auth_info_type, cancel_user_requested_shell_command_result, canvas_action, canvas_action_invoke_request, canvas_action_invoke_result, canvas_close_request, canvas_host_context, canvas_host_context_capabilities, 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, capi_session_options, 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, configure_session_extensions_params, 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, current_tool_metadata, 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_context_push_input, 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_info, installed_plugin_source, installed_plugin_source_git_hub, installed_plugin_source_local, installed_plugin_source_url, instruction_discovery_path, instruction_discovery_path_kind, instruction_discovery_path_list, instruction_discovery_path_location, instructions_discover_request, instructions_get_discovery_paths_request, instructions_get_sources_result, instruction_source, instruction_source_location, instruction_source_type, llm_inference_headers, llm_inference_http_request_chunk_request, llm_inference_http_request_chunk_result, llm_inference_http_request_start_request, llm_inference_http_request_start_result, llm_inference_http_request_start_transport, llm_inference_http_response_chunk_error, llm_inference_http_response_chunk_request, llm_inference_http_response_chunk_result, llm_inference_http_response_start_request, llm_inference_http_response_start_result, llm_inference_set_provider_result, local_session_metadata_value, log_request, log_result, lsp_initialize_request, marketplace_add_result, marketplace_browse_result, marketplace_info, marketplace_list_result, marketplace_plugin_info, marketplace_refresh_entry, marketplace_refresh_result, marketplace_remove_result, mcp_allowed_server, 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_configure_git_hub_request, mcp_configure_git_hub_result, 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_filtered_server, mcp_host_state, mcp_is_server_running_request, mcp_is_server_running_result, mcp_list_tools_request, mcp_list_tools_result, mcp_oauth_handle_pending_request, mcp_oauth_handle_pending_result, mcp_oauth_login_grant_type, mcp_oauth_login_request, mcp_oauth_login_result, mcp_oauth_pending_request_response, mcp_oauth_respond_request, mcp_oauth_respond_result, mcp_register_external_client_request, mcp_reload_with_config_request, mcp_remove_git_hub_result, mcp_restart_server_request, 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_defer_tools, mcp_server_config_http, mcp_server_config_http_oauth_grant_type, mcp_server_config_http_type, mcp_server_config_stdio, mcp_server_failure_info, mcp_server_list, mcp_server_needs_auth_info, mcp_set_env_value_mode_details, mcp_set_env_value_mode_params, mcp_set_env_value_mode_result, mcp_start_server_request, mcp_start_servers_result, mcp_stop_server_request, mcp_tools, mcp_unregister_external_client_request, memory_configuration, 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_list_request, 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, named_provider_config, name_get_result, name_set_auto_request, name_set_auto_result, name_set_request, open_canvas_instance, options_update_additional_content_exclusion_policy, options_update_additional_content_exclusion_policy_rule, options_update_additional_content_exclusion_policy_rule_source, options_update_additional_content_exclusion_policy_scope, options_update_context_tier, options_update_env_value_mode, options_update_reasoning_summary, 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_allow_all_source, 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_read_sql_todos_result, plan_read_sql_todos_with_dependencies_result, plan_sql_todo_dependency, plan_sql_todos_row, plan_update_request, plugin, plugin_install_result, plugin_list, plugin_list_result, plugins_disable_request, plugins_enable_request, plugins_install_request, plugins_marketplaces_add_request, plugins_marketplaces_browse_request, plugins_marketplaces_refresh_request, plugins_marketplaces_remove_request, plugins_reload_request, plugins_uninstall_request, plugins_update_request, plugin_update_all_entry, plugin_update_all_result, plugin_update_result, poll_spawned_sessions_result, provider_add_request, provider_add_result, provider_config, provider_config_azure, provider_config_transport, provider_config_type, provider_config_wire_api, provider_endpoint, provider_endpoint_transport, provider_endpoint_type, provider_endpoint_wire_api, provider_get_endpoint_request, provider_model_config, provider_session_token, provider_token_acquire_request, provider_token_acquire_result, push_attachment, push_attachment_blob, push_attachment_directory, push_attachment_file, push_attachment_file_line_range, push_attachment_git_hub_reference, push_attachment_git_hub_reference_type, push_attachment_selection, push_attachment_selection_details, push_attachment_selection_details_end, push_attachment_selection_details_start, 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, register_extension_tools_params, register_extension_tools_result, release_event_interest_params, remote_control_config, remote_control_config_existing_mc_session, remote_control_status, remote_control_status_active, remote_control_status_connecting, remote_control_status_error, remote_control_status_off, remote_control_status_result, remote_control_stop_result, remote_control_transfer_result, remote_enable_request, remote_enable_result, remote_notify_steerable_changed_request, remote_notify_steerable_changed_result, remote_session_connection_result, remote_session_metadata_repository, remote_session_metadata_task_type, remote_session_metadata_value, remote_session_mode, remote_session_repository, sandbox_config, sandbox_config_user_policy, sandbox_config_user_policy_experimental, sandbox_config_user_policy_experimental_seatbelt, sandbox_config_user_policy_filesystem, sandbox_config_user_policy_network, sandbox_config_user_policy_seatbelt, schedule_entry, schedule_list, schedule_stop_request, schedule_stop_result, secrets_add_filter_values_request, secrets_add_filter_values_result, send_agent_mode, send_attachments_to_message_params, send_mode, send_request, send_result, server_agent_list, server_instruction_source_list, server_skill, server_skill_list, session_activity, session_auth_status, session_bulk_delete_result, session_capability, 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_git_hub, session_installed_plugin_source_local, session_installed_plugin_source_url, session_list, session_list_entry, session_list_filter, session_load_deferred_repo_hooks_result, session_log_level, session_mcp_apps_call_tool_result, session_metadata_snapshot, session_mode, session_model_list, session_open_options, session_open_options_additional_content_exclusion_policy, session_open_options_additional_content_exclusion_policy_rule, session_open_options_additional_content_exclusion_policy_rule_source, session_open_options_additional_content_exclusion_policy_scope, session_open_options_env_value_mode, session_open_options_reasoning_summary, session_open_params, session_open_result, 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_board_entry_count_request, sessions_get_board_entry_count_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_open_attach, sessions_open_cloud, sessions_open_create, sessions_open_handoff, sessions_open_handoff_task_type, sessions_open_progress, sessions_open_progress_status, sessions_open_progress_step, sessions_open_remote, sessions_open_resume, sessions_open_resume_last, sessions_open_status, session_source, sessions_poll_spawned_sessions_event, sessions_poll_spawned_sessions_request, sessions_prune_old_request, sessions_register_extension_tools_on_session_options, 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, sessions_set_remote_control_steering_request, sessions_start_remote_control_request, sessions_stop_remote_control_request, sessions_transfer_remote_control_request, session_telemetry_engagement, session_update_options_params, session_update_options_result, session_working_directory_context, session_working_directory_context_host_type, shell_cancel_user_requested_request, shell_exec_request, shell_exec_result, shell_execute_user_requested_request, shell_kill_request, shell_kill_result, shell_kill_signal, shutdown_request, skill, skill_discovery_path, skill_discovery_path_list, skill_discovery_scope, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_discovery_paths_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, subagent_settings_entry, subagent_settings_entry_context_tier, 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_get_current_metadata_result, tools_initialize_and_validate_result, tools_list_request, tools_update_subagent_settings_result, 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_ephemeral_query_request, ui_ephemeral_query_result, 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, update_subagent_settings_request, 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, user_requested_shell_command_result, 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, subagent_settings, task_progress, workspace_summary) + return RPC(abort_request, abort_result, account_all_users, account_get_all_users_result, account_get_current_auth_result, account_get_quota_request, account_get_quota_result, account_login_request, account_login_result, account_logout_request, account_logout_result, account_quota_snapshot, agent_discovery_path, agent_discovery_path_list, agent_discovery_path_scope, 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, agents_discover_request, agent_select_request, agent_select_result, agents_get_discovery_paths_request, allow_all_permission_set_result, allow_all_permission_state, api_key_auth_info, auth_info, auth_info_type, cancel_user_requested_shell_command_result, canvas_action, canvas_action_invoke_request, canvas_action_invoke_result, canvas_close_request, canvas_host_context, canvas_host_context_capabilities, 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, capi_session_options, 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, configure_session_extensions_params, 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, current_tool_metadata, 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_context_push_input, 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_info, installed_plugin_source, installed_plugin_source_git_hub, installed_plugin_source_local, installed_plugin_source_url, instruction_discovery_path, instruction_discovery_path_kind, instruction_discovery_path_list, instruction_discovery_path_location, instructions_discover_request, instructions_get_discovery_paths_request, instructions_get_sources_result, instruction_source, instruction_source_location, instruction_source_type, llm_inference_headers, llm_inference_http_request_chunk_request, llm_inference_http_request_chunk_result, llm_inference_http_request_start_request, llm_inference_http_request_start_result, llm_inference_http_request_start_transport, llm_inference_http_response_chunk_error, llm_inference_http_response_chunk_request, llm_inference_http_response_chunk_result, llm_inference_http_response_start_request, llm_inference_http_response_start_result, llm_inference_set_provider_result, local_session_metadata_value, log_request, log_result, lsp_initialize_request, marketplace_add_result, marketplace_browse_result, marketplace_info, marketplace_list_result, marketplace_plugin_info, marketplace_refresh_entry, marketplace_refresh_result, marketplace_remove_result, mcp_allowed_server, 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_configure_git_hub_request, mcp_configure_git_hub_result, 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_filtered_server, mcp_headers_handle_pending_headers_refresh_request, mcp_headers_handle_pending_headers_refresh_request_request, mcp_headers_handle_pending_headers_refresh_request_result, mcp_host_state, mcp_is_server_running_request, mcp_is_server_running_result, mcp_list_tools_request, mcp_list_tools_result, mcp_oauth_handle_pending_request, mcp_oauth_handle_pending_result, mcp_oauth_login_grant_type, mcp_oauth_login_request, mcp_oauth_login_result, mcp_oauth_pending_request_response, mcp_oauth_respond_request, mcp_oauth_respond_result, mcp_register_external_client_request, mcp_reload_with_config_request, mcp_remove_git_hub_result, mcp_restart_server_request, 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_defer_tools, mcp_server_config_http, mcp_server_config_http_oauth_grant_type, mcp_server_config_http_type, mcp_server_config_stdio, mcp_server_failure_info, mcp_server_list, mcp_server_needs_auth_info, mcp_set_env_value_mode_details, mcp_set_env_value_mode_params, mcp_set_env_value_mode_result, mcp_start_server_request, mcp_start_servers_result, mcp_stop_server_request, mcp_tools, mcp_unregister_external_client_request, memory_configuration, 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_list_request, 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, named_provider_config, name_get_result, name_set_auto_request, name_set_auto_result, name_set_request, open_canvas_instance, options_update_additional_content_exclusion_policy, options_update_additional_content_exclusion_policy_rule, options_update_additional_content_exclusion_policy_rule_source, options_update_additional_content_exclusion_policy_scope, options_update_context_tier, options_update_env_value_mode, options_update_reasoning_summary, 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_allow_all_source, 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_read_sql_todos_result, plan_read_sql_todos_with_dependencies_result, plan_sql_todo_dependency, plan_sql_todos_row, plan_update_request, plugin, plugin_install_result, plugin_list, plugin_list_result, plugins_disable_request, plugins_enable_request, plugins_install_request, plugins_marketplaces_add_request, plugins_marketplaces_browse_request, plugins_marketplaces_refresh_request, plugins_marketplaces_remove_request, plugins_reload_request, plugins_uninstall_request, plugins_update_request, plugin_update_all_entry, plugin_update_all_result, plugin_update_result, poll_spawned_sessions_result, provider_add_request, provider_add_result, provider_config, provider_config_azure, provider_config_transport, provider_config_type, provider_config_wire_api, provider_endpoint, provider_endpoint_transport, provider_endpoint_type, provider_endpoint_wire_api, provider_get_endpoint_request, provider_model_config, provider_session_token, provider_token_acquire_request, provider_token_acquire_result, push_attachment, push_attachment_blob, push_attachment_directory, push_attachment_file, push_attachment_file_line_range, push_attachment_git_hub_actions_job, push_attachment_git_hub_commit, push_attachment_git_hub_file, push_attachment_git_hub_file_diff, push_attachment_git_hub_file_diff_side, push_attachment_git_hub_reference, push_attachment_git_hub_reference_type, push_attachment_git_hub_release, push_attachment_git_hub_repository, push_attachment_git_hub_snippet, push_attachment_git_hub_tree_comparison, push_attachment_git_hub_tree_comparison_side, push_attachment_git_hub_url, push_attachment_selection, push_attachment_selection_details, push_attachment_selection_details_end, push_attachment_selection_details_start, push_git_hub_repo_ref, 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, register_extension_tools_params, register_extension_tools_result, release_event_interest_params, remote_control_config, remote_control_config_existing_mc_session, remote_control_status, remote_control_status_active, remote_control_status_connecting, remote_control_status_error, remote_control_status_off, remote_control_status_result, remote_control_stop_result, remote_control_transfer_result, remote_enable_request, remote_enable_result, remote_notify_steerable_changed_request, remote_notify_steerable_changed_result, remote_session_connection_result, remote_session_metadata_repository, remote_session_metadata_task_type, remote_session_metadata_value, remote_session_mode, remote_session_repository, sandbox_config, sandbox_config_user_policy, sandbox_config_user_policy_experimental, sandbox_config_user_policy_experimental_seatbelt, sandbox_config_user_policy_filesystem, sandbox_config_user_policy_network, sandbox_config_user_policy_seatbelt, schedule_entry, schedule_list, schedule_stop_request, schedule_stop_result, secrets_add_filter_values_request, secrets_add_filter_values_result, send_agent_mode, send_attachments_to_message_params, send_mode, send_request, send_result, server_agent_list, server_instruction_source_list, server_skill, server_skill_list, session_activity, session_auth_status, session_bulk_delete_result, session_capability, 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_git_hub, session_installed_plugin_source_local, session_installed_plugin_source_url, session_list, session_list_entry, session_list_filter, session_load_deferred_repo_hooks_result, session_log_level, session_mcp_apps_call_tool_result, session_metadata_snapshot, session_mode, session_model_list, session_open_options, session_open_options_additional_content_exclusion_policy, session_open_options_additional_content_exclusion_policy_rule, session_open_options_additional_content_exclusion_policy_rule_source, session_open_options_additional_content_exclusion_policy_scope, session_open_options_env_value_mode, session_open_options_reasoning_summary, session_open_params, session_open_result, 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_board_entry_count_request, sessions_get_board_entry_count_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_open_attach, sessions_open_cloud, sessions_open_create, sessions_open_handoff, sessions_open_handoff_task_type, sessions_open_progress, sessions_open_progress_status, sessions_open_progress_step, sessions_open_remote, sessions_open_resume, sessions_open_resume_last, sessions_open_status, session_source, sessions_poll_spawned_sessions_event, sessions_poll_spawned_sessions_request, sessions_prune_old_request, sessions_register_extension_tools_on_session_options, 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, sessions_set_remote_control_steering_request, sessions_start_remote_control_request, sessions_stop_remote_control_request, sessions_transfer_remote_control_request, session_telemetry_engagement, session_update_options_params, session_update_options_result, session_working_directory_context, session_working_directory_context_host_type, shell_cancel_user_requested_request, shell_exec_request, shell_exec_result, shell_execute_user_requested_request, shell_kill_request, shell_kill_result, shell_kill_signal, shutdown_request, skill, skill_discovery_path, skill_discovery_path_list, skill_discovery_scope, skill_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_discovery_paths_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, subagent_settings_entry, subagent_settings_entry_context_tier, 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_get_current_metadata_result, tools_initialize_and_validate_result, tools_list_request, tools_update_subagent_settings_result, 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_ephemeral_query_request, ui_ephemeral_query_result, 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, update_subagent_settings_request, 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, user_requested_shell_command_result, 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, subagent_settings, task_progress, workspace_summary) def to_dict(self) -> dict: result: dict = {} @@ -22706,6 +23414,9 @@ def to_dict(self) -> dict: result["McpExecuteSamplingRequest"] = from_dict(lambda x: x, self.mcp_execute_sampling_request) result["McpExecuteSamplingResult"] = from_dict(lambda x: x, self.mcp_execute_sampling_result) result["McpFilteredServer"] = to_class(MCPFilteredServer, self.mcp_filtered_server) + result["McpHeadersHandlePendingHeadersRefreshRequest"] = to_class(MCPHeadersHandlePendingHeadersRefreshRequest, self.mcp_headers_handle_pending_headers_refresh_request) + result["McpHeadersHandlePendingHeadersRefreshRequestRequest"] = to_class(MCPHeadersHandlePendingHeadersRefreshRequestRequest, self.mcp_headers_handle_pending_headers_refresh_request_request) + result["McpHeadersHandlePendingHeadersRefreshRequestResult"] = to_class(MCPHeadersHandlePendingHeadersRefreshRequestResult, self.mcp_headers_handle_pending_headers_refresh_request_result) result["McpHostState"] = to_class(MCPHostState, self.mcp_host_state) result["McpIsServerRunningRequest"] = to_class(MCPIsServerRunningRequest, self.mcp_is_server_running_request) result["McpIsServerRunningResult"] = to_class(MCPIsServerRunningResult, self.mcp_is_server_running_result) @@ -22939,12 +23650,24 @@ def to_dict(self) -> dict: result["PushAttachmentDirectory"] = to_class(PushAttachmentDirectory, self.push_attachment_directory) result["PushAttachmentFile"] = to_class(PushAttachmentFile, self.push_attachment_file) result["PushAttachmentFileLineRange"] = to_class(PushAttachmentFileLineRange, self.push_attachment_file_line_range) + result["PushAttachmentGitHubActionsJob"] = to_class(PushAttachmentGitHubActionsJob, self.push_attachment_git_hub_actions_job) + result["PushAttachmentGitHubCommit"] = to_class(PushAttachmentGitHubCommit, self.push_attachment_git_hub_commit) + result["PushAttachmentGitHubFile"] = to_class(PushAttachmentGitHubFile, self.push_attachment_git_hub_file) + result["PushAttachmentGitHubFileDiff"] = to_class(PushAttachmentGitHubFileDiff, self.push_attachment_git_hub_file_diff) + result["PushAttachmentGitHubFileDiffSide"] = to_class(PushAttachmentGitHubFileDiffSide, self.push_attachment_git_hub_file_diff_side) result["PushAttachmentGitHubReference"] = to_class(PushAttachmentGitHubReference, self.push_attachment_git_hub_reference) result["PushAttachmentGitHubReferenceType"] = to_enum(PushAttachmentGitHubReferenceTypeEnum, self.push_attachment_git_hub_reference_type) + result["PushAttachmentGitHubRelease"] = to_class(PushAttachmentGitHubRelease, self.push_attachment_git_hub_release) + result["PushAttachmentGitHubRepository"] = to_class(PushAttachmentGitHubRepository, self.push_attachment_git_hub_repository) + result["PushAttachmentGitHubSnippet"] = to_class(PushAttachmentGitHubSnippet, self.push_attachment_git_hub_snippet) + result["PushAttachmentGitHubTreeComparison"] = to_class(PushAttachmentGitHubTreeComparison, self.push_attachment_git_hub_tree_comparison) + result["PushAttachmentGitHubTreeComparisonSide"] = to_class(PushAttachmentGitHubTreeComparisonSide, self.push_attachment_git_hub_tree_comparison_side) + result["PushAttachmentGitHubUrl"] = to_class(PushAttachmentGitHubURL, self.push_attachment_git_hub_url) result["PushAttachmentSelection"] = to_class(PushAttachmentSelection, self.push_attachment_selection) result["PushAttachmentSelectionDetails"] = to_class(PushAttachmentSelectionDetails, self.push_attachment_selection_details) result["PushAttachmentSelectionDetailsEnd"] = to_class(PushAttachmentSelectionDetailsEnd, self.push_attachment_selection_details_end) result["PushAttachmentSelectionDetailsStart"] = to_class(PushAttachmentSelectionDetailsStart, self.push_attachment_selection_details_start) + result["PushGitHubRepoRef"] = to_class(PushGitHubRepoRef, self.push_git_hub_repo_ref) result["QueuedCommandHandled"] = to_class(QueuedCommandHandled, self.queued_command_handled) result["QueuedCommandNotHandled"] = to_class(QueuedCommandNotHandled, self.queued_command_not_handled) result["QueuedCommandResult"] = (self.queued_command_result).to_dict() @@ -23384,7 +24107,7 @@ def _load_PermissionsLocationsAddToolApprovalDetails(obj: Any) -> "PermissionsLo case _: raise ValueError(f"Unknown PermissionsLocationsAddToolApprovalDetails kind: {kind!r}") # Schema for the `PushAttachment` type. -PushAttachment = PushAttachmentFile | PushAttachmentDirectory | PushAttachmentSelection | PushAttachmentGitHubReference | PushAttachmentBlob | ExtensionContextPushInput +PushAttachment = PushAttachmentFile | PushAttachmentDirectory | PushAttachmentSelection | PushAttachmentGitHubReference | PushAttachmentGitHubCommit | PushAttachmentGitHubRelease | PushAttachmentGitHubActionsJob | PushAttachmentGitHubRepository | PushAttachmentGitHubFileDiff | PushAttachmentGitHubTreeComparison | PushAttachmentGitHubURL | PushAttachmentGitHubFile | PushAttachmentGitHubSnippet | PushAttachmentBlob | ExtensionContextPushInput def _load_PushAttachment(obj: Any) -> "PushAttachment": assert isinstance(obj, dict) @@ -23394,6 +24117,15 @@ def _load_PushAttachment(obj: Any) -> "PushAttachment": case "directory": return PushAttachmentDirectory.from_dict(obj) case "selection": return PushAttachmentSelection.from_dict(obj) case "github_reference": return PushAttachmentGitHubReference.from_dict(obj) + case "github_commit": return PushAttachmentGitHubCommit.from_dict(obj) + case "github_release": return PushAttachmentGitHubRelease.from_dict(obj) + case "github_actions_job": return PushAttachmentGitHubActionsJob.from_dict(obj) + case "github_repository": return PushAttachmentGitHubRepository.from_dict(obj) + case "github_file_diff": return PushAttachmentGitHubFileDiff.from_dict(obj) + case "github_tree_comparison": return PushAttachmentGitHubTreeComparison.from_dict(obj) + case "github_url": return PushAttachmentGitHubURL.from_dict(obj) + case "github_file": return PushAttachmentGitHubFile.from_dict(obj) + case "github_snippet": return PushAttachmentGitHubSnippet.from_dict(obj) case "blob": return PushAttachmentBlob.from_dict(obj) case "extension_context": return ExtensionContextPushInput.from_dict(obj) case _: raise ValueError(f"Unknown PushAttachment type: {kind!r}") @@ -23449,7 +24181,7 @@ def _load_SessionOpenParams(obj: Any) -> "SessionOpenParams": case "handoff": return SessionsOpenHandoff.from_dict(obj) case _: raise ValueError(f"Unknown SessionOpenParams kind: {kind!r}") -# Result of invoking the slash command (text output, prompt to send to the agent, or completion). +# Result of invoking the slash command (text output, prompt to send to the agent, completion, or subcommand selection). SlashCommandInvocationResult = SlashCommandTextResult | SlashCommandAgentPromptResult | SlashCommandCompletedResult | SlashCommandSelectSubcommandResult def _load_SlashCommandInvocationResult(obj: Any) -> "SlashCommandInvocationResult": @@ -24044,20 +24776,20 @@ async def _connect(self, params: _ConnectRequest, *, timeout: float | None = Non # Experimental: this API group is experimental and may change or be removed. -class AuthApi: +class GitHubAuthApi: def __init__(self, client: "JsonRpcClient", session_id: str): self._client = client self._session_id = session_id async def get_status(self, *, timeout: float | None = None) -> SessionAuthStatus: "Gets authentication status and account metadata for the session.\n\nReturns:\n Authentication status and account metadata for the session." - return SessionAuthStatus.from_dict(await self._client.request("session.auth.getStatus", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + return SessionAuthStatus.from_dict(await self._client.request("session.gitHubAuth.getStatus", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) async def set_credentials(self, params: SessionSetCredentialsParams, *, timeout: float | None = None) -> SessionSetCredentialsResult: "Updates the session's auth credentials used for outbound model and API requests.\n\nArgs:\n params: New auth credentials to install on the session. Omit to leave credentials unchanged.\n\nReturns:\n Indicates whether the credential update succeeded." params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} params_dict["sessionId"] = self._session_id - return SessionSetCredentialsResult.from_dict(await self._client.request("session.auth.setCredentials", params_dict, **_timeout_kwargs(timeout))) + return SessionSetCredentialsResult.from_dict(await self._client.request("session.gitHubAuth.setCredentials", params_dict, **_timeout_kwargs(timeout))) # Experimental: this API group is experimental and may change or be removed. @@ -24418,6 +25150,19 @@ async def login(self, params: MCPOauthLoginRequest, *, timeout: float | None = N return MCPOauthLoginResult.from_dict(await self._client.request("session.mcp.oauth.login", params_dict, **_timeout_kwargs(timeout))) +# Experimental: this API group is experimental and may change or be removed. +class McpHeadersApi: + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + + async def handle_pending_headers_refresh_request(self, params: MCPHeadersHandlePendingHeadersRefreshRequestRequest, *, timeout: float | None = None) -> MCPHeadersHandlePendingHeadersRefreshRequestResult: + "Responds to a pending MCP dynamic headers refresh request. Hosts that subscribe to `mcp.headers_refresh_required` use this to provide short-lived per-server headers or to indicate that no dynamic headers are available for this refresh.\n\nArgs:\n params: MCP headers refresh request id and the host response.\n\nReturns:\n Indicates whether the pending MCP headers refresh response was accepted." + params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return MCPHeadersHandlePendingHeadersRefreshRequestResult.from_dict(await self._client.request("session.mcp.headers.handlePendingHeadersRefreshRequest", params_dict, **_timeout_kwargs(timeout))) + + # Experimental: this API group is experimental and may change or be removed. class McpAppsApi: def __init__(self, client: "JsonRpcClient", session_id: str): @@ -24465,6 +25210,7 @@ def __init__(self, client: "JsonRpcClient", session_id: str): self._client = client self._session_id = session_id self.oauth = McpOauthApi(client, session_id) + self.headers = McpHeadersApi(client, session_id) self.apps = McpAppsApi(client, session_id) async def list(self, *, timeout: float | None = None) -> MCPServerList: @@ -24663,7 +25409,7 @@ async def list(self, params: CommandsListRequest | None = None, *, timeout: floa return CommandList.from_dict(await self._client.request("session.commands.list", params_dict, **_timeout_kwargs(timeout))) async def invoke(self, params: CommandsInvokeRequest, *, timeout: float | None = None) -> SlashCommandInvocationResult: - "Invokes a slash command in the session.\n\nArgs:\n params: Slash command name and optional raw input string to invoke.\n\nReturns:\n Result of invoking the slash command (text output, prompt to send to the agent, or completion)." + "Invokes a slash command in the session.\n\nArgs:\n params: Slash command name and optional raw input string to invoke.\n\nReturns:\n Result of invoking the slash command (text output, prompt to send to the agent, completion, or subcommand selection)." params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} params_dict["sessionId"] = self._session_id return _load_SlashCommandInvocationResult(await self._client.request("session.commands.invoke", params_dict, **_timeout_kwargs(timeout))) @@ -25135,7 +25881,7 @@ class SessionRpc: def __init__(self, client: "JsonRpcClient", session_id: str): self._client = client self._session_id = session_id - self.auth = AuthApi(client, session_id) + self.git_hub_auth = GitHubAuthApi(client, session_id) self.canvas = CanvasApi(client, session_id) self.model = ModelApi(client, session_id) self.mode = ModeApi(client, session_id) @@ -25533,7 +26279,6 @@ async def handle_llm_inference_http_request_chunk(params: dict) -> dict | None: "AllowAllPermissionSetResult", "AllowAllPermissionState", "ApprovalKind", - "AuthApi", "AuthInfo", "AuthInfoType", "CancelUserRequestedShellCommandResult", @@ -25637,6 +26382,7 @@ async def handle_llm_inference_http_request_chunk(params: dict) -> dict | None: "FolderTrustCheckResult", "GhCLIAuthInfo", "GhCLIAuthInfoType", + "GitHubAuthApi", "HMACAuthInfo", "HMACAuthInfoType", "HandlePendingToolCallRequest", @@ -25723,6 +26469,10 @@ async def handle_llm_inference_http_request_chunk(params: dict) -> dict | None: "MCPExecuteSamplingParams", "MCPFilteredServer", "MCPGrantType", + "MCPHeadersHandlePendingHeadersRefreshRequest", + "MCPHeadersHandlePendingHeadersRefreshRequestKind", + "MCPHeadersHandlePendingHeadersRefreshRequestRequest", + "MCPHeadersHandlePendingHeadersRefreshRequestResult", "MCPHostState", "MCPIsServerRunningRequest", "MCPIsServerRunningResult", @@ -25779,6 +26529,7 @@ async def handle_llm_inference_http_request_chunk(params: dict) -> dict | None: "McpAppsSetHostContextDetailsTheme", "McpExecuteSamplingRequest", "McpExecuteSamplingResult", + "McpHeadersApi", "McpOauthApi", "McpOauthLoginGrantType", "McpServerAuthConfig", @@ -26024,15 +26775,37 @@ async def handle_llm_inference_http_request_chunk(params: dict) -> dict | None: "PushAttachmentFile", "PushAttachmentFileLineRange", "PushAttachmentFileType", + "PushAttachmentGitHubActionsJob", + "PushAttachmentGitHubActionsJobType", + "PushAttachmentGitHubCommit", + "PushAttachmentGitHubCommitType", + "PushAttachmentGitHubFile", + "PushAttachmentGitHubFileDiff", + "PushAttachmentGitHubFileDiffSide", + "PushAttachmentGitHubFileDiffType", + "PushAttachmentGitHubFileType", "PushAttachmentGitHubReference", "PushAttachmentGitHubReferenceType", "PushAttachmentGitHubReferenceTypeEnum", + "PushAttachmentGitHubRelease", + "PushAttachmentGitHubReleaseType", + "PushAttachmentGitHubRepository", + "PushAttachmentGitHubRepositoryType", + "PushAttachmentGitHubSide", + "PushAttachmentGitHubSnippet", + "PushAttachmentGitHubSnippetType", + "PushAttachmentGitHubTreeComparison", + "PushAttachmentGitHubTreeComparisonSide", + "PushAttachmentGitHubTreeComparisonType", + "PushAttachmentGitHubURL", + "PushAttachmentGitHubURLType", "PushAttachmentSelection", "PushAttachmentSelectionDetails", "PushAttachmentSelectionDetailsEnd", "PushAttachmentSelectionDetailsStart", "PushAttachmentSelectionType", "PushAttachmentType", + "PushGitHubRepoRef", "QueueApi", "QueuePendingItems", "QueuePendingItemsKind", diff --git a/python/copilot/generated/session_events.py b/python/copilot/generated/session_events.py index 0a3666c094..00f6bb35cd 100644 --- a/python/copilot/generated/session_events.py +++ b/python/copilot/generated/session_events.py @@ -160,6 +160,7 @@ class SessionEventType(Enum): ASSISTANT_MESSAGE_START = "assistant.message_start" ASSISTANT_MESSAGE_DELTA = "assistant.message_delta" ASSISTANT_TURN_END = "assistant.turn_end" + ASSISTANT_IDLE = "assistant.idle" ASSISTANT_USAGE = "assistant.usage" MODEL_CALL_FAILURE = "model.call_failure" ABORT = "abort" @@ -191,6 +192,8 @@ class SessionEventType(Enum): SAMPLING_COMPLETED = "sampling.completed" MCP_OAUTH_REQUIRED = "mcp.oauth_required" MCP_OAUTH_COMPLETED = "mcp.oauth_completed" + MCP_HEADERS_REFRESH_REQUIRED = "mcp.headers_refresh_required" + MCP_HEADERS_REFRESH_COMPLETED = "mcp.headers_refresh_completed" SESSION_CUSTOM_NOTIFICATION = "session.custom_notification" EXTERNAL_TOOL_REQUESTED = "external_tool.requested" EXTERNAL_TOOL_COMPLETED = "external_tool.completed" @@ -957,6 +960,26 @@ def to_dict(self) -> dict: return result +@dataclass +class AssistantIdleData: + "Payload emitted whenever the main agent's processing loop goes idle, including while related background work (running agents or in-flight attached shell commands) is still pending and the session-level idle event is therefore deferred" + aborted: bool | None = None + + @staticmethod + def from_dict(obj: Any) -> "AssistantIdleData": + assert isinstance(obj, dict) + aborted = from_union([from_none, from_bool], obj.get("aborted")) + return AssistantIdleData( + aborted=aborted, + ) + + def to_dict(self) -> dict: + result: dict = {} + if self.aborted is not None: + result["aborted"] = from_union([from_none, from_bool], self.aborted) + return result + + @dataclass class AssistantIntentData: "Agent intent description for current activity or plan" @@ -1740,6 +1763,172 @@ def to_dict(self) -> dict: return result +@dataclass +class AttachmentGitHubActionsJob: + "Pointer to a GitHub Actions job." + job_id: int + job_name: str + repo: GitHubRepoRef + type: ClassVar[str] = "github_actions_job" + url: str + workflow_name: str + conclusion: str | None = None + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubActionsJob": + assert isinstance(obj, dict) + job_id = from_int(obj.get("jobId")) + job_name = from_str(obj.get("jobName")) + repo = GitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + workflow_name = from_str(obj.get("workflowName")) + conclusion = from_union([from_none, from_str], obj.get("conclusion")) + return AttachmentGitHubActionsJob( + job_id=job_id, + job_name=job_name, + repo=repo, + url=url, + workflow_name=workflow_name, + conclusion=conclusion, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["jobId"] = to_int(self.job_id) + result["jobName"] = from_str(self.job_name) + result["repo"] = to_class(GitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + result["workflowName"] = from_str(self.workflow_name) + if self.conclusion is not None: + result["conclusion"] = from_union([from_none, from_str], self.conclusion) + return result + + +@dataclass +class AttachmentGitHubCommit: + "Pointer to a GitHub commit." + message: str + oid: str + repo: GitHubRepoRef + type: ClassVar[str] = "github_commit" + url: str + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubCommit": + assert isinstance(obj, dict) + message = from_str(obj.get("message")) + oid = from_str(obj.get("oid")) + repo = GitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + return AttachmentGitHubCommit( + message=message, + oid=oid, + repo=repo, + url=url, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["message"] = from_str(self.message) + result["oid"] = from_str(self.oid) + result["repo"] = to_class(GitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + + +@dataclass +class AttachmentGitHubFile: + "Pointer to a file in a GitHub repository at a specific ref." + path: str + ref: str + repo: GitHubRepoRef + type: ClassVar[str] = "github_file" + url: str + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubFile": + assert isinstance(obj, dict) + path = from_str(obj.get("path")) + ref = from_str(obj.get("ref")) + repo = GitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + return AttachmentGitHubFile( + path=path, + ref=ref, + repo=repo, + url=url, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["path"] = from_str(self.path) + result["ref"] = from_str(self.ref) + result["repo"] = to_class(GitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + + +@dataclass +class AttachmentGitHubFileDiff: + "Pointer to a single-file diff. At least one of `head` and `base` must be present." + type: ClassVar[str] = "github_file_diff" + url: str + base: AttachmentGitHubFileDiffSide | None = None + head: AttachmentGitHubFileDiffSide | None = None + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubFileDiff": + assert isinstance(obj, dict) + url = from_str(obj.get("url")) + base = from_union([from_none, AttachmentGitHubFileDiffSide.from_dict], obj.get("base")) + head = from_union([from_none, AttachmentGitHubFileDiffSide.from_dict], obj.get("head")) + return AttachmentGitHubFileDiff( + url=url, + base=base, + head=head, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["type"] = self.type + result["url"] = from_str(self.url) + if self.base is not None: + result["base"] = from_union([from_none, lambda x: to_class(AttachmentGitHubFileDiffSide, x)], self.base) + if self.head is not None: + result["head"] = from_union([from_none, lambda x: to_class(AttachmentGitHubFileDiffSide, x)], self.head) + return result + + +@dataclass +class AttachmentGitHubFileDiffSide: + "One side of a file diff (head or base)" + path: str + ref: str + repo: GitHubRepoRef + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubFileDiffSide": + assert isinstance(obj, dict) + path = from_str(obj.get("path")) + ref = from_str(obj.get("ref")) + repo = GitHubRepoRef.from_dict(obj.get("repo")) + return AttachmentGitHubFileDiffSide( + path=path, + ref=ref, + repo=repo, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["path"] = from_str(self.path) + result["ref"] = from_str(self.ref) + result["repo"] = to_class(GitHubRepoRef, self.repo) + return result + + @dataclass class AttachmentGitHubReference: "GitHub issue, pull request, or discussion reference" @@ -1777,6 +1966,184 @@ def to_dict(self) -> dict: return result +@dataclass +class AttachmentGitHubRelease: + "Pointer to a GitHub release." + name: str + repo: GitHubRepoRef + tag_name: str + type: ClassVar[str] = "github_release" + url: str + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubRelease": + assert isinstance(obj, dict) + name = from_str(obj.get("name")) + repo = GitHubRepoRef.from_dict(obj.get("repo")) + tag_name = from_str(obj.get("tagName")) + url = from_str(obj.get("url")) + return AttachmentGitHubRelease( + name=name, + repo=repo, + tag_name=tag_name, + url=url, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["name"] = from_str(self.name) + result["repo"] = to_class(GitHubRepoRef, self.repo) + result["tagName"] = from_str(self.tag_name) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + + +@dataclass +class AttachmentGitHubRepository: + "Pointer to a GitHub repository." + repo: GitHubRepoRef + type: ClassVar[str] = "github_repository" + url: str + description: str | None = None + ref: str | None = None + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubRepository": + assert isinstance(obj, dict) + repo = GitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + description = from_union([from_none, from_str], obj.get("description")) + ref = from_union([from_none, from_str], obj.get("ref")) + return AttachmentGitHubRepository( + repo=repo, + url=url, + description=description, + ref=ref, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["repo"] = to_class(GitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + if self.description is not None: + result["description"] = from_union([from_none, from_str], self.description) + if self.ref is not None: + result["ref"] = from_union([from_none, from_str], self.ref) + return result + + +@dataclass +class AttachmentGitHubSnippet: + "Pointer to a line range inside a file in a GitHub repository." + line_range: AttachmentFileLineRange + path: str + ref: str + repo: GitHubRepoRef + type: ClassVar[str] = "github_snippet" + url: str + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubSnippet": + assert isinstance(obj, dict) + line_range = AttachmentFileLineRange.from_dict(obj.get("lineRange")) + path = from_str(obj.get("path")) + ref = from_str(obj.get("ref")) + repo = GitHubRepoRef.from_dict(obj.get("repo")) + url = from_str(obj.get("url")) + return AttachmentGitHubSnippet( + line_range=line_range, + path=path, + ref=ref, + repo=repo, + url=url, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["lineRange"] = to_class(AttachmentFileLineRange, self.line_range) + result["path"] = from_str(self.path) + result["ref"] = from_str(self.ref) + result["repo"] = to_class(GitHubRepoRef, self.repo) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + + +@dataclass +class AttachmentGitHubTreeComparison: + "Pointer to a comparison between two git revisions." + base: AttachmentGitHubTreeComparisonSide + head: AttachmentGitHubTreeComparisonSide + type: ClassVar[str] = "github_tree_comparison" + url: str + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubTreeComparison": + assert isinstance(obj, dict) + base = AttachmentGitHubTreeComparisonSide.from_dict(obj.get("base")) + head = AttachmentGitHubTreeComparisonSide.from_dict(obj.get("head")) + url = from_str(obj.get("url")) + return AttachmentGitHubTreeComparison( + base=base, + head=head, + url=url, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["base"] = to_class(AttachmentGitHubTreeComparisonSide, self.base) + result["head"] = to_class(AttachmentGitHubTreeComparisonSide, self.head) + result["type"] = self.type + result["url"] = from_str(self.url) + return result + + +@dataclass +class AttachmentGitHubTreeComparisonSide: + "One side of a tree comparison (head or base)" + repo: GitHubRepoRef + revision: str + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubTreeComparisonSide": + assert isinstance(obj, dict) + repo = GitHubRepoRef.from_dict(obj.get("repo")) + revision = from_str(obj.get("revision")) + return AttachmentGitHubTreeComparisonSide( + repo=repo, + revision=revision, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["repo"] = to_class(GitHubRepoRef, self.repo) + result["revision"] = from_str(self.revision) + return result + + +@dataclass +class AttachmentGitHubUrl: + "Generic GitHub URL reference." + type: ClassVar[str] = "github_url" + url: str + + @staticmethod + def from_dict(obj: Any) -> "AttachmentGitHubUrl": + assert isinstance(obj, dict) + url = from_str(obj.get("url")) + return AttachmentGitHubUrl( + url=url, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["type"] = self.type + result["url"] = from_str(self.url) + return result + + @dataclass class AttachmentSelection: "Code selection attachment from an editor" @@ -2588,6 +2955,34 @@ def to_dict(self) -> dict: return result +@dataclass +class GitHubRepoRef: + "Pointer to a GitHub repository." + name: str + owner: str + id: int | None = None + + @staticmethod + def from_dict(obj: Any) -> "GitHubRepoRef": + assert isinstance(obj, dict) + name = from_str(obj.get("name")) + owner = from_str(obj.get("owner")) + id = from_union([from_none, from_int], obj.get("id")) + return GitHubRepoRef( + name=name, + owner=owner, + id=id, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["name"] = from_str(self.name) + result["owner"] = from_str(self.owner) + if self.id is not None: + result["id"] = from_union([from_none, to_int], self.id) + return result + + @dataclass class HandoffRepository: "Repository context for the handed-off session" @@ -2849,6 +3244,60 @@ def to_dict(self) -> dict: return result +@dataclass +class McpHeadersRefreshCompletedData: + "MCP headers refresh request completion notification" + outcome: McpHeadersRefreshCompletedOutcome + request_id: str + + @staticmethod + def from_dict(obj: Any) -> "McpHeadersRefreshCompletedData": + assert isinstance(obj, dict) + outcome = parse_enum(McpHeadersRefreshCompletedOutcome, obj.get("outcome")) + request_id = from_str(obj.get("requestId")) + return McpHeadersRefreshCompletedData( + outcome=outcome, + request_id=request_id, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["outcome"] = to_enum(McpHeadersRefreshCompletedOutcome, self.outcome) + result["requestId"] = from_str(self.request_id) + return result + + +@dataclass +class McpHeadersRefreshRequiredData: + "Dynamic headers refresh request for a remote MCP server" + reason: McpHeadersRefreshRequiredReason + request_id: str + server_name: str + server_url: str + + @staticmethod + def from_dict(obj: Any) -> "McpHeadersRefreshRequiredData": + assert isinstance(obj, dict) + reason = parse_enum(McpHeadersRefreshRequiredReason, obj.get("reason")) + request_id = from_str(obj.get("requestId")) + server_name = from_str(obj.get("serverName")) + server_url = from_str(obj.get("serverUrl")) + return McpHeadersRefreshRequiredData( + reason=reason, + request_id=request_id, + server_name=server_name, + server_url=server_url, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["reason"] = to_enum(McpHeadersRefreshRequiredReason, self.reason) + result["requestId"] = from_str(self.request_id) + result["serverName"] = from_str(self.server_name) + result["serverUrl"] = from_str(self.server_url) + return result + + @dataclass class McpOauthCompletedData: "MCP OAuth request completion notification" @@ -2875,6 +3324,7 @@ def to_dict(self) -> dict: @dataclass class McpOauthRequiredData: "OAuth authentication request for an MCP server" + reason: McpOauthRequestReason request_id: str server_name: str server_url: str @@ -2885,6 +3335,7 @@ class McpOauthRequiredData: @staticmethod def from_dict(obj: Any) -> "McpOauthRequiredData": assert isinstance(obj, dict) + reason = parse_enum(McpOauthRequestReason, obj.get("reason")) request_id = from_str(obj.get("requestId")) server_name = from_str(obj.get("serverName")) server_url = from_str(obj.get("serverUrl")) @@ -2892,6 +3343,7 @@ def from_dict(obj: Any) -> "McpOauthRequiredData": static_client_config = from_union([from_none, McpOauthRequiredStaticClientConfig.from_dict], obj.get("staticClientConfig")) www_authenticate_params = from_union([from_none, McpOauthWWWAuthenticateParams.from_dict], obj.get("wwwAuthenticateParams")) return McpOauthRequiredData( + reason=reason, request_id=request_id, server_name=server_name, server_url=server_url, @@ -2902,6 +3354,7 @@ def from_dict(obj: Any) -> "McpOauthRequiredData": def to_dict(self) -> dict: result: dict = {} + result["reason"] = to_enum(McpOauthRequestReason, self.reason) result["requestId"] = from_str(self.request_id) result["serverName"] = from_str(self.server_name) result["serverUrl"] = from_str(self.server_url) @@ -2918,6 +3371,7 @@ def to_dict(self) -> dict: class McpOauthRequiredStaticClientConfig: "Static OAuth client configuration, if the server specifies one" client_id: str + client_secret: str | None = None grant_type: str | None = None public_client: bool | None = None @@ -2925,10 +3379,12 @@ class McpOauthRequiredStaticClientConfig: def from_dict(obj: Any) -> "McpOauthRequiredStaticClientConfig": assert isinstance(obj, dict) client_id = from_str(obj.get("clientId")) + client_secret = from_union([from_none, from_str], obj.get("clientSecret")) grant_type = from_union([from_none, from_str], obj.get("grantType")) public_client = from_union([from_none, from_bool], obj.get("publicClient")) return McpOauthRequiredStaticClientConfig( client_id=client_id, + client_secret=client_secret, grant_type=grant_type, public_client=public_client, ) @@ -2936,6 +3392,8 @@ def from_dict(obj: Any) -> "McpOauthRequiredStaticClientConfig": def to_dict(self) -> dict: result: dict = {} result["clientId"] = from_str(self.client_id) + if self.client_secret is not None: + result["clientSecret"] = from_union([from_none, from_str], self.client_secret) if self.grant_type is not None: result["grantType"] = from_union([from_none, from_str], self.grant_type) if self.public_client is not None: @@ -2946,27 +3404,28 @@ def to_dict(self) -> dict: @dataclass class McpOauthWWWAuthenticateParams: "OAuth WWW-Authenticate parameters parsed from an MCP auth challenge" - resource_metadata_url: str error: str | None = None + resource_metadata_url: str | None = None scope: str | None = None @staticmethod def from_dict(obj: Any) -> "McpOauthWWWAuthenticateParams": assert isinstance(obj, dict) - resource_metadata_url = from_str(obj.get("resourceMetadataUrl")) error = from_union([from_none, from_str], obj.get("error")) + resource_metadata_url = from_union([from_none, from_str], obj.get("resourceMetadataUrl")) scope = from_union([from_none, from_str], obj.get("scope")) return McpOauthWWWAuthenticateParams( - resource_metadata_url=resource_metadata_url, error=error, + resource_metadata_url=resource_metadata_url, scope=scope, ) def to_dict(self) -> dict: result: dict = {} - result["resourceMetadataUrl"] = from_str(self.resource_metadata_url) if self.error is not None: result["error"] = from_union([from_none, from_str], self.error) + if self.resource_metadata_url is not None: + result["resourceMetadataUrl"] = from_union([from_none, from_str], self.resource_metadata_url) if self.scope is not None: result["scope"] = from_union([from_none, from_str], self.scope) return result @@ -4318,6 +4777,31 @@ def to_dict(self) -> dict: return result +@dataclass +class ResponseBudgetConfig: + "Optional response budget limits." + max_ai_credits: float | None = None + max_model_iterations: int | None = None + + @staticmethod + def from_dict(obj: Any) -> "ResponseBudgetConfig": + assert isinstance(obj, dict) + max_ai_credits = from_union([from_none, from_float], obj.get("maxAiCredits")) + max_model_iterations = from_union([from_none, from_int], obj.get("maxModelIterations")) + return ResponseBudgetConfig( + max_ai_credits=max_ai_credits, + max_model_iterations=max_model_iterations, + ) + + def to_dict(self) -> dict: + result: dict = {} + if self.max_ai_credits is not None: + result["maxAiCredits"] = from_union([from_none, to_float], self.max_ai_credits) + if self.max_model_iterations is not None: + result["maxModelIterations"] = from_union([from_none, to_int], self.max_model_iterations) + return result + + @dataclass class SamplingCompletedData: "Sampling request completion notification signaling UI dismissal" @@ -5097,6 +5581,7 @@ class SessionResumeData: reasoning_effort: str | None = None reasoning_summary: ReasoningSummary | None = None remote_steerable: bool | None = None + response_budget: ResponseBudgetConfig | None = None selected_model: str | None = None session_was_active: bool | None = None @@ -5113,6 +5598,7 @@ def from_dict(obj: Any) -> "SessionResumeData": reasoning_effort = from_union([from_none, from_str], obj.get("reasoningEffort")) reasoning_summary = from_union([from_none, lambda x: parse_enum(ReasoningSummary, x)], obj.get("reasoningSummary")) remote_steerable = from_union([from_none, from_bool], obj.get("remoteSteerable")) + response_budget = from_union([from_none, ResponseBudgetConfig.from_dict], obj.get("responseBudget")) selected_model = from_union([from_none, from_str], obj.get("selectedModel")) session_was_active = from_union([from_none, from_bool], obj.get("sessionWasActive")) return SessionResumeData( @@ -5126,6 +5612,7 @@ def from_dict(obj: Any) -> "SessionResumeData": reasoning_effort=reasoning_effort, reasoning_summary=reasoning_summary, remote_steerable=remote_steerable, + response_budget=response_budget, selected_model=selected_model, session_was_active=session_was_active, ) @@ -5150,6 +5637,8 @@ def to_dict(self) -> dict: result["reasoningSummary"] = from_union([from_none, lambda x: to_enum(ReasoningSummary, x)], self.reasoning_summary) if self.remote_steerable is not None: result["remoteSteerable"] = from_union([from_none, from_bool], self.remote_steerable) + if self.response_budget is not None: + result["responseBudget"] = from_union([from_none, lambda x: to_class(ResponseBudgetConfig, x)], self.response_budget) if self.selected_model is not None: result["selectedModel"] = from_union([from_none, from_str], self.selected_model) if self.session_was_active is not None: @@ -5401,6 +5890,7 @@ class SessionStartData: reasoning_effort: str | None = None reasoning_summary: ReasoningSummary | None = None remote_steerable: bool | None = None + response_budget: ResponseBudgetConfig | None = None selected_model: str | None = None @staticmethod @@ -5418,6 +5908,7 @@ def from_dict(obj: Any) -> "SessionStartData": reasoning_effort = from_union([from_none, from_str], obj.get("reasoningEffort")) reasoning_summary = from_union([from_none, lambda x: parse_enum(ReasoningSummary, x)], obj.get("reasoningSummary")) remote_steerable = from_union([from_none, from_bool], obj.get("remoteSteerable")) + response_budget = from_union([from_none, ResponseBudgetConfig.from_dict], obj.get("responseBudget")) selected_model = from_union([from_none, from_str], obj.get("selectedModel")) return SessionStartData( copilot_version=copilot_version, @@ -5432,6 +5923,7 @@ def from_dict(obj: Any) -> "SessionStartData": reasoning_effort=reasoning_effort, reasoning_summary=reasoning_summary, remote_steerable=remote_steerable, + response_budget=response_budget, selected_model=selected_model, ) @@ -5456,6 +5948,8 @@ def to_dict(self) -> dict: result["reasoningSummary"] = from_union([from_none, lambda x: to_enum(ReasoningSummary, x)], self.reasoning_summary) if self.remote_steerable is not None: result["remoteSteerable"] = from_union([from_none, from_bool], self.remote_steerable) + if self.response_budget is not None: + result["responseBudget"] = from_union([from_none, lambda x: to_class(ResponseBudgetConfig, x)], self.response_budget) if self.selected_model is not None: result["selectedModel"] = from_union([from_none, from_str], self.selected_model) return result @@ -7091,6 +7585,7 @@ class ToolExecutionStartData: model: str | None = None # Deprecated: this field is deprecated. parent_tool_call_id: str | None = None + shell_tool_info: ToolExecutionStartShellToolInfo | None = None tool_description: ToolExecutionStartToolDescription | None = None turn_id: str | None = None @@ -7105,6 +7600,7 @@ def from_dict(obj: Any) -> "ToolExecutionStartData": mcp_tool_name = from_union([from_none, from_str], obj.get("mcpToolName")) model = from_union([from_none, from_str], obj.get("model")) parent_tool_call_id = from_union([from_none, from_str], obj.get("parentToolCallId")) + shell_tool_info = from_union([from_none, ToolExecutionStartShellToolInfo.from_dict], obj.get("shellToolInfo")) tool_description = from_union([from_none, ToolExecutionStartToolDescription.from_dict], obj.get("toolDescription")) turn_id = from_union([from_none, from_str], obj.get("turnId")) return ToolExecutionStartData( @@ -7116,6 +7612,7 @@ def from_dict(obj: Any) -> "ToolExecutionStartData": mcp_tool_name=mcp_tool_name, model=model, parent_tool_call_id=parent_tool_call_id, + shell_tool_info=shell_tool_info, tool_description=tool_description, turn_id=turn_id, ) @@ -7136,6 +7633,8 @@ def to_dict(self) -> dict: result["model"] = from_union([from_none, from_str], self.model) if self.parent_tool_call_id is not None: result["parentToolCallId"] = from_union([from_none, from_str], self.parent_tool_call_id) + if self.shell_tool_info is not None: + result["shellToolInfo"] = from_union([from_none, lambda x: to_class(ToolExecutionStartShellToolInfo, x)], self.shell_tool_info) if self.tool_description is not None: result["toolDescription"] = from_union([from_none, lambda x: to_class(ToolExecutionStartToolDescription, x)], self.tool_description) if self.turn_id is not None: @@ -7143,6 +7642,29 @@ def to_dict(self) -> dict: return result +@dataclass +class ToolExecutionStartShellToolInfo: + "Shell-aware path hints for a shell tool's command, captured at start time so consumers can snapshot a file's pre-image before the tool runs." + has_write_file_redirection: bool + possible_paths: list[str] + + @staticmethod + def from_dict(obj: Any) -> "ToolExecutionStartShellToolInfo": + assert isinstance(obj, dict) + has_write_file_redirection = from_bool(obj.get("hasWriteFileRedirection")) + possible_paths = from_list(from_str, obj.get("possiblePaths")) + return ToolExecutionStartShellToolInfo( + has_write_file_redirection=has_write_file_redirection, + possible_paths=possible_paths, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["hasWriteFileRedirection"] = from_bool(self.has_write_file_redirection) + result["possiblePaths"] = from_list(from_str, self.possible_paths) + return result + + @dataclass class ToolExecutionStartToolDescription: "Tool definition metadata, present for MCP tools with MCP Apps support" @@ -7318,6 +7840,7 @@ class UserMessageData: content: str agent_mode: UserMessageAgentMode | None = None attachments: list[Attachment] | None = None + delivery: UserMessageDelivery | None = None interaction_id: str | None = None is_autopilot_continuation: bool | None = None native_document_path_fallback_paths: list[str] | None = None @@ -7332,6 +7855,7 @@ def from_dict(obj: Any) -> "UserMessageData": content = from_str(obj.get("content")) agent_mode = from_union([from_none, lambda x: parse_enum(UserMessageAgentMode, x)], obj.get("agentMode")) attachments = from_union([from_none, lambda x: from_list(_load_Attachment, x)], obj.get("attachments")) + delivery = from_union([from_none, lambda x: parse_enum(UserMessageDelivery, x)], obj.get("delivery")) interaction_id = from_union([from_none, from_str], obj.get("interactionId")) is_autopilot_continuation = from_union([from_none, from_bool], obj.get("isAutopilotContinuation")) native_document_path_fallback_paths = from_union([from_none, lambda x: from_list(from_str, x)], obj.get("nativeDocumentPathFallbackPaths")) @@ -7343,6 +7867,7 @@ def from_dict(obj: Any) -> "UserMessageData": content=content, agent_mode=agent_mode, attachments=attachments, + delivery=delivery, interaction_id=interaction_id, is_autopilot_continuation=is_autopilot_continuation, native_document_path_fallback_paths=native_document_path_fallback_paths, @@ -7359,6 +7884,8 @@ def to_dict(self) -> dict: result["agentMode"] = from_union([from_none, lambda x: to_enum(UserMessageAgentMode, x)], self.agent_mode) if self.attachments is not None: result["attachments"] = from_union([from_none, lambda x: from_list(lambda x: x.to_dict(), x)], self.attachments) + if self.delivery is not None: + result["delivery"] = from_union([from_none, lambda x: to_enum(UserMessageDelivery, x)], self.delivery) if self.interaction_id is not None: result["interactionId"] = from_union([from_none, from_str], self.interaction_id) if self.is_autopilot_continuation is not None: @@ -7599,6 +8126,15 @@ def _load_Attachment(obj: Any) -> "Attachment": case "directory": return AttachmentDirectory.from_dict(obj) case "selection": return AttachmentSelection.from_dict(obj) case "github_reference": return AttachmentGitHubReference.from_dict(obj) + case "github_commit": return AttachmentGitHubCommit.from_dict(obj) + case "github_release": return AttachmentGitHubRelease.from_dict(obj) + case "github_actions_job": return AttachmentGitHubActionsJob.from_dict(obj) + case "github_repository": return AttachmentGitHubRepository.from_dict(obj) + case "github_file_diff": return AttachmentGitHubFileDiff.from_dict(obj) + case "github_tree_comparison": return AttachmentGitHubTreeComparison.from_dict(obj) + case "github_url": return AttachmentGitHubUrl.from_dict(obj) + case "github_file": return AttachmentGitHubFile.from_dict(obj) + case "github_snippet": return AttachmentGitHubSnippet.from_dict(obj) case "blob": return AttachmentBlob.from_dict(obj) case "extension_context": return AttachmentExtensionContext.from_dict(obj) case _: raise ValueError(f"Unknown Attachment type: {kind!r}") @@ -7714,8 +8250,8 @@ def _load_UserToolSessionApproval(obj: Any) -> "UserToolSessionApproval": PersistedBinaryResult = PersistedBinaryImage | OmittedBinaryResult | BinaryAssetReference -# A user message attachment — a file, directory, code selection, blob, GitHub reference, or extension-supplied context payload -Attachment = AttachmentFile | AttachmentDirectory | AttachmentSelection | AttachmentGitHubReference | AttachmentBlob | AttachmentExtensionContext +# A user message attachment — a file, directory, code selection, blob, GitHub reference, GitHub-anchored pointer, or extension-supplied context payload +Attachment = AttachmentFile | AttachmentDirectory | AttachmentSelection | AttachmentGitHubReference | AttachmentGitHubCommit | AttachmentGitHubRelease | AttachmentGitHubActionsJob | AttachmentGitHubRepository | AttachmentGitHubFileDiff | AttachmentGitHubTreeComparison | AttachmentGitHubUrl | AttachmentGitHubFile | AttachmentGitHubSnippet | AttachmentBlob | AttachmentExtensionContext # Derived user-facing permission prompt details for UI consumers @@ -7915,6 +8451,26 @@ class HandoffSourceType(Enum): LOCAL = "local" +class McpHeadersRefreshCompletedOutcome(Enum): + "How the pending MCP headers refresh request resolved." + # The host supplied dynamic headers. + HEADERS = "headers" + # The host responded with no dynamic headers. + NONE = "none" + # No response arrived within the bounded window. + TIMEOUT = "timeout" + + +class McpHeadersRefreshRequiredReason(Enum): + "Why dynamic headers are being requested." + # The transport is making its first dynamic header request for this server. + STARTUP = "startup" + # The previously cached dynamic headers expired. + TTL_EXPIRED = "ttl-expired" + # The server returned 401 and stale dynamic headers were invalidated. + AUTH_FAILED = "auth-failed" + + class McpOauthCompletionOutcome(Enum): "How the pending MCP OAuth request was completed" # The request completed with a token-backed OAuth provider. @@ -7923,6 +8479,18 @@ class McpOauthCompletionOutcome(Enum): CANCELLED = "cancelled" +class McpOauthRequestReason(Enum): + "Reason the runtime is requesting host-provided MCP OAuth credentials" + # Initial credentials are required before connecting to the MCP server. + INITIAL = "initial" + # The current host-provided credential was rejected and a replacement is requested. + REFRESH = "refresh" + # The server requires a new host authorization flow before continuing. + REAUTH = "reauth" + # The server requires a credential with additional scope or audience. + UPSCOPE = "upscope" + + class McpServerSource(Enum): "Configuration source: user, workspace, plugin, or builtin" # Server configured in the user's global MCP configuration. @@ -8149,6 +8717,16 @@ class UserMessageAgentMode(Enum): SHELL = "shell" +class UserMessageDelivery(Enum): + "How this user message was delivered to the agentic loop, relative to whether the loop was already running. This is the timing axis only; the message's origin (human vs. system/command/schedule/skill/etc.) is carried separately by `source`. A system-injected message has a delivery too — e.g. a background-task notification waking an idle agent is `idle`, the same mechanism as a human starting a fresh turn." + # Delivered while the loop was idle; starts its own run immediately (a human's fresh turn, or a system notification waking an idle agent). + IDLE = "idle" + # Injected into the current in-flight run while the agent was busy (immediate mode). + STEERING = "steering" + # Enqueued while the agent was busy; processed as its own run afterward. + QUEUED = "queued" + + class WorkingDirectoryContextHostType(Enum): "Hosting platform type of the repository (github or ado)" # Repository is hosted on GitHub. @@ -8165,7 +8743,7 @@ class WorkspaceFileChangedOperation(Enum): UPDATE = "update" -SessionEventData = SessionStartData | SessionResumeData | SessionRemoteSteerableChangedData | SessionErrorData | SessionIdleData | SessionTitleChangedData | SessionScheduleCreatedData | SessionScheduleCancelledData | SessionScheduleRearmedData | SessionAutopilotObjectiveChangedData | SessionInfoData | SessionWarningData | SessionModelChangeData | SessionModeChangedData | SessionPermissionsChangedData | SessionPlanChangedData | SessionTodosChangedData | SessionWorkspaceFileChangedData | SessionHandoffData | SessionTruncationData | SessionSnapshotRewindData | SessionShutdownData | SessionContextChangedData | SessionUsageInfoData | SessionCompactionStartData | SessionCompactionCompleteData | SessionTaskCompleteData | UserMessageData | PendingMessagesModifiedData | AssistantTurnStartData | AssistantIntentData | AssistantReasoningData | AssistantReasoningDeltaData | AssistantStreamingDeltaData | AssistantMessageData | AssistantMessageStartData | AssistantMessageDeltaData | AssistantTurnEndData | AssistantUsageData | ModelCallFailureData | AbortData | ToolUserRequestedData | ToolExecutionStartData | ToolExecutionPartialResultData | ToolExecutionProgressData | ToolExecutionCompleteData | SkillInvokedData | SubagentStartedData | SubagentCompletedData | SubagentFailedData | SubagentSelectedData | SubagentDeselectedData | HookStartData | HookEndData | HookProgressData | SessionBinaryAssetData | SystemMessageData | SystemNotificationData | PermissionRequestedData | PermissionCompletedData | UserInputRequestedData | UserInputCompletedData | ElicitationRequestedData | ElicitationCompletedData | SamplingRequestedData | SamplingCompletedData | McpOauthRequiredData | McpOauthCompletedData | SessionCustomNotificationData | ExternalToolRequestedData | ExternalToolCompletedData | CommandQueuedData | CommandExecuteData | CommandCompletedData | AutoModeSwitchRequestedData | AutoModeSwitchCompletedData | CommandsChangedData | CapabilitiesChangedData | ExitPlanModeRequestedData | ExitPlanModeCompletedData | SessionToolsUpdatedData | SessionBackgroundTasksChangedData | SessionSkillsLoadedData | SessionCustomAgentsUpdatedData | SessionMcpServersLoadedData | SessionMcpServerStatusChangedData | SessionExtensionsLoadedData | SessionCanvasOpenedData | SessionCanvasRegistryChangedData | SessionCanvasClosedData | SessionCanvasUnavailableData | SessionCanvasRecordedData | SessionCanvasRemovedData | SessionExtensionsAttachmentsPushedData | McpAppToolCallCompleteData | RawSessionEventData | Data +SessionEventData = SessionStartData | SessionResumeData | SessionRemoteSteerableChangedData | SessionErrorData | SessionIdleData | SessionTitleChangedData | SessionScheduleCreatedData | SessionScheduleCancelledData | SessionScheduleRearmedData | SessionAutopilotObjectiveChangedData | SessionInfoData | SessionWarningData | SessionModelChangeData | SessionModeChangedData | SessionPermissionsChangedData | SessionPlanChangedData | SessionTodosChangedData | SessionWorkspaceFileChangedData | SessionHandoffData | SessionTruncationData | SessionSnapshotRewindData | SessionShutdownData | SessionContextChangedData | SessionUsageInfoData | SessionCompactionStartData | SessionCompactionCompleteData | SessionTaskCompleteData | UserMessageData | PendingMessagesModifiedData | AssistantTurnStartData | AssistantIntentData | AssistantReasoningData | AssistantReasoningDeltaData | AssistantStreamingDeltaData | AssistantMessageData | AssistantMessageStartData | AssistantMessageDeltaData | AssistantTurnEndData | AssistantIdleData | AssistantUsageData | ModelCallFailureData | AbortData | ToolUserRequestedData | ToolExecutionStartData | ToolExecutionPartialResultData | ToolExecutionProgressData | ToolExecutionCompleteData | SkillInvokedData | SubagentStartedData | SubagentCompletedData | SubagentFailedData | SubagentSelectedData | SubagentDeselectedData | HookStartData | HookEndData | HookProgressData | SessionBinaryAssetData | SystemMessageData | SystemNotificationData | PermissionRequestedData | PermissionCompletedData | UserInputRequestedData | UserInputCompletedData | ElicitationRequestedData | ElicitationCompletedData | SamplingRequestedData | SamplingCompletedData | McpOauthRequiredData | McpOauthCompletedData | McpHeadersRefreshRequiredData | McpHeadersRefreshCompletedData | SessionCustomNotificationData | ExternalToolRequestedData | ExternalToolCompletedData | CommandQueuedData | CommandExecuteData | CommandCompletedData | AutoModeSwitchRequestedData | AutoModeSwitchCompletedData | CommandsChangedData | CapabilitiesChangedData | ExitPlanModeRequestedData | ExitPlanModeCompletedData | SessionToolsUpdatedData | SessionBackgroundTasksChangedData | SessionSkillsLoadedData | SessionCustomAgentsUpdatedData | SessionMcpServersLoadedData | SessionMcpServerStatusChangedData | SessionExtensionsLoadedData | SessionCanvasOpenedData | SessionCanvasRegistryChangedData | SessionCanvasClosedData | SessionCanvasUnavailableData | SessionCanvasRecordedData | SessionCanvasRemovedData | SessionExtensionsAttachmentsPushedData | McpAppToolCallCompleteData | RawSessionEventData | Data @dataclass @@ -8229,6 +8807,7 @@ def from_dict(obj: Any) -> "SessionEvent": case SessionEventType.ASSISTANT_MESSAGE_START: data = AssistantMessageStartData.from_dict(data_obj) case SessionEventType.ASSISTANT_MESSAGE_DELTA: data = AssistantMessageDeltaData.from_dict(data_obj) case SessionEventType.ASSISTANT_TURN_END: data = AssistantTurnEndData.from_dict(data_obj) + case SessionEventType.ASSISTANT_IDLE: data = AssistantIdleData.from_dict(data_obj) case SessionEventType.ASSISTANT_USAGE: data = AssistantUsageData.from_dict(data_obj) case SessionEventType.MODEL_CALL_FAILURE: data = ModelCallFailureData.from_dict(data_obj) case SessionEventType.ABORT: data = AbortData.from_dict(data_obj) @@ -8259,6 +8838,8 @@ def from_dict(obj: Any) -> "SessionEvent": case SessionEventType.SAMPLING_COMPLETED: data = SamplingCompletedData.from_dict(data_obj) case SessionEventType.MCP_OAUTH_REQUIRED: data = McpOauthRequiredData.from_dict(data_obj) case SessionEventType.MCP_OAUTH_COMPLETED: data = McpOauthCompletedData.from_dict(data_obj) + case SessionEventType.MCP_HEADERS_REFRESH_REQUIRED: data = McpHeadersRefreshRequiredData.from_dict(data_obj) + case SessionEventType.MCP_HEADERS_REFRESH_COMPLETED: data = McpHeadersRefreshCompletedData.from_dict(data_obj) case SessionEventType.SESSION_CUSTOM_NOTIFICATION: data = SessionCustomNotificationData.from_dict(data_obj) case SessionEventType.EXTERNAL_TOOL_REQUESTED: data = ExternalToolRequestedData.from_dict(data_obj) case SessionEventType.EXTERNAL_TOOL_COMPLETED: data = ExternalToolCompletedData.from_dict(data_obj) @@ -8322,6 +8903,7 @@ def session_event_to_dict(x: SessionEvent) -> Any: __all__ = [ "AbortData", "AbortReason", + "AssistantIdleData", "AssistantIntentData", "AssistantMessageData", "AssistantMessageDeltaData", @@ -8344,8 +8926,19 @@ def session_event_to_dict(x: SessionEvent) -> Any: "AttachmentExtensionContext", "AttachmentFile", "AttachmentFileLineRange", + "AttachmentGitHubActionsJob", + "AttachmentGitHubCommit", + "AttachmentGitHubFile", + "AttachmentGitHubFileDiff", + "AttachmentGitHubFileDiffSide", "AttachmentGitHubReference", "AttachmentGitHubReferenceType", + "AttachmentGitHubRelease", + "AttachmentGitHubRepository", + "AttachmentGitHubSnippet", + "AttachmentGitHubTreeComparison", + "AttachmentGitHubTreeComparisonSide", + "AttachmentGitHubUrl", "AttachmentSelection", "AttachmentSelectionDetails", "AttachmentSelectionDetailsEnd", @@ -8397,6 +8990,7 @@ def session_event_to_dict(x: SessionEvent) -> Any: "ExtensionsLoadedExtensionStatus", "ExternalToolCompletedData", "ExternalToolRequestedData", + "GitHubRepoRef", "HandoffRepository", "HandoffSourceType", "HookEndData", @@ -8407,8 +9001,13 @@ def session_event_to_dict(x: SessionEvent) -> Any: "McpAppToolCallCompleteError", "McpAppToolCallCompleteToolMeta", "McpAppToolCallCompleteToolMetaUI", + "McpHeadersRefreshCompletedData", + "McpHeadersRefreshCompletedOutcome", + "McpHeadersRefreshRequiredData", + "McpHeadersRefreshRequiredReason", "McpOauthCompletedData", "McpOauthCompletionOutcome", + "McpOauthRequestReason", "McpOauthRequiredData", "McpOauthRequiredStaticClientConfig", "McpOauthWWWAuthenticateParams", @@ -8471,6 +9070,7 @@ def session_event_to_dict(x: SessionEvent) -> Any: "PlanChangedOperation", "RawSessionEventData", "ReasoningSummary", + "ResponseBudgetConfig", "SamplingCompletedData", "SamplingRequestedData", "SessionAutopilotObjectiveChangedData", @@ -8577,6 +9177,7 @@ def session_event_to_dict(x: SessionEvent) -> Any: "ToolExecutionPartialResultData", "ToolExecutionProgressData", "ToolExecutionStartData", + "ToolExecutionStartShellToolInfo", "ToolExecutionStartToolDescription", "ToolExecutionStartToolDescriptionMeta", "ToolExecutionStartToolDescriptionMetaUI", @@ -8586,6 +9187,7 @@ def session_event_to_dict(x: SessionEvent) -> Any: "UserInputRequestedData", "UserMessageAgentMode", "UserMessageData", + "UserMessageDelivery", "UserToolSessionApproval", "UserToolSessionApprovalCommands", "UserToolSessionApprovalCustomTool", diff --git a/python/e2e/test_per_session_auth_e2e.py b/python/e2e/test_per_session_auth_e2e.py index 0aa42cdaa3..776408a799 100644 --- a/python/e2e/test_per_session_auth_e2e.py +++ b/python/e2e/test_per_session_auth_e2e.py @@ -58,7 +58,7 @@ async def test_should_create_session_with_github_token_and_check_auth_status( github_token="token-alice", ) - auth_status = await session.rpc.auth.get_status() + auth_status = await session.rpc.git_hub_auth.get_status() assert auth_status.is_authenticated is True assert auth_status.login == "alice" assert auth_status.copilot_plan == "individual_pro" @@ -77,8 +77,8 @@ async def test_should_isolate_auth_between_sessions_with_different_tokens( github_token="token-bob", ) - status_a = await session_a.rpc.auth.get_status() - status_b = await session_b.rpc.auth.get_status() + status_a = await session_a.rpc.git_hub_auth.get_status() + status_b = await session_b.rpc.git_hub_auth.get_status() assert status_a.is_authenticated is True assert status_a.login == "alice" @@ -108,7 +108,7 @@ async def test_should_return_unauthenticated_when_no_token_provided( on_permission_request=PermissionHandler.approve_all, ) - auth_status = await session.rpc.auth.get_status() + auth_status = await session.rpc.git_hub_auth.get_status() # Without a per-session token, there is no per-session identity. # In CI the process-level fake token may still authenticate globally, # so we check login rather than is_authenticated. On some platforms diff --git a/python/e2e/test_rpc_server_plugins_e2e.py b/python/e2e/test_rpc_server_plugins_e2e.py index a325242e9e..538d1692fd 100644 --- a/python/e2e/test_rpc_server_plugins_e2e.py +++ b/python/e2e/test_rpc_server_plugins_e2e.py @@ -113,9 +113,7 @@ async def _dispose_isolated(client: CopilotClient, home: Path, fixture_dir: Path class TestRpcServerPlugins: - async def test_should_install_list_and_uninstall_plugin_from_local_marketplace( - self, ctx: E2ETestContext - ): + async def test_should_install_and_list_plugin_from_local_marketplace(self, ctx: E2ETestContext): marketplace_dir = _create_local_marketplace_fixture(ctx) client, home = await _create_isolated_client(ctx) try: @@ -141,13 +139,6 @@ async def test_should_install_list_and_uninstall_plugin_from_local_marketplace( assert len(listed) == 1 assert listed[0].enabled is True - await client.rpc.plugins.uninstall(PluginsUninstallRequest(name=spec)) - - after_uninstall = await client.rpc.plugins.list() - assert not any( - p.name == PLUGIN_NAME and p.marketplace == MARKETPLACE_NAME - for p in after_uninstall.plugins - ) finally: await _dispose_isolated(client, home, marketplace_dir) @@ -229,8 +220,14 @@ async def test_should_install_direct_local_plugin_with_deprecation_warning( after_install = await client.rpc.plugins.list() assert len([p for p in after_install.plugins if p.name == DIRECT_PLUGIN_NAME]) == 1 + assert install.plugin.direct_source_id - await client.rpc.plugins.uninstall(PluginsUninstallRequest(name=DIRECT_PLUGIN_NAME)) + await client.rpc.plugins.uninstall( + PluginsUninstallRequest( + name=DIRECT_PLUGIN_NAME, + direct_source_id=install.plugin.direct_source_id, + ) + ) after_uninstall = await client.rpc.plugins.list() assert not any(p.name == DIRECT_PLUGIN_NAME for p in after_uninstall.plugins) diff --git a/python/e2e/test_rpc_session_state_e2e.py b/python/e2e/test_rpc_session_state_e2e.py index 7bd94679d6..12688f2803 100644 --- a/python/e2e/test_rpc_session_state_e2e.py +++ b/python/e2e/test_rpc_session_state_e2e.py @@ -442,7 +442,7 @@ async def test_should_set_auth_credentials(self, ctx: E2ETestContext): ) try: login = f"sdk-rpc-{uuid.uuid4().hex}" - result = await session.rpc.auth.set_credentials( + result = await session.rpc.git_hub_auth.set_credentials( SessionSetCredentialsParams( credentials=UserAuthInfo( host="https://github.com", @@ -462,7 +462,7 @@ async def test_should_set_auth_credentials(self, ctx: E2ETestContext): ) assert result.success is True - status = await session.rpc.auth.get_status() + status = await session.rpc.git_hub_auth.get_status() assert status.is_authenticated is True assert status.auth_type == AuthInfoType.USER assert status.host == "https://github.com" diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index b1d85c0a58..711aed2e3f 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use super::session_events::{ AbortReason, ContextTier, McpServerSource, McpServerStatus, PermissionPromptRequest, - PermissionRule, ReasoningSummary, SessionMode, ShutdownType, SkillSource, + PermissionRule, ReasoningSummary, ResponseBudgetConfig, SessionMode, ShutdownType, SkillSource, UserToolSessionApproval, }; use crate::types::{RequestId, SessionEvent, SessionId}; @@ -172,10 +172,10 @@ pub mod rpc_methods { pub const SESSION_ABORT: &str = "session.abort"; /// `session.shutdown` pub const SESSION_SHUTDOWN: &str = "session.shutdown"; - /// `session.auth.getStatus` - pub const SESSION_AUTH_GETSTATUS: &str = "session.auth.getStatus"; - /// `session.auth.setCredentials` - pub const SESSION_AUTH_SETCREDENTIALS: &str = "session.auth.setCredentials"; + /// `session.gitHubAuth.getStatus` + pub const SESSION_GITHUBAUTH_GETSTATUS: &str = "session.gitHubAuth.getStatus"; + /// `session.gitHubAuth.setCredentials` + pub const SESSION_GITHUBAUTH_SETCREDENTIALS: &str = "session.gitHubAuth.setCredentials"; /// `session.canvas.list` pub const SESSION_CANVAS_LIST: &str = "session.canvas.list"; /// `session.canvas.listOpen` @@ -321,6 +321,9 @@ pub mod rpc_methods { "session.mcp.oauth.handlePendingRequest"; /// `session.mcp.oauth.login` pub const SESSION_MCP_OAUTH_LOGIN: &str = "session.mcp.oauth.login"; + /// `session.mcp.headers.handlePendingHeadersRefreshRequest` + pub const SESSION_MCP_HEADERS_HANDLEPENDINGHEADERSREFRESHREQUEST: &str = + "session.mcp.headers.handlePendingHeadersRefreshRequest"; /// `session.mcp.apps.readResource` pub const SESSION_MCP_APPS_READRESOURCE: &str = "session.mcp.apps.readResource"; /// `session.mcp.apps.listTools` @@ -1493,6 +1496,142 @@ pub struct AttachmentFile { pub r#type: AttachmentFileType, } +/// Pointer to a GitHub repository. +/// +///

+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GitHubRepoRef { + /// Numeric GitHub repository id + #[serde(skip_serializing_if = "Option::is_none")] + pub id: Option, + /// Repository name (without owner) + pub name: String, + /// Repository owner login (user or organization) + pub owner: String, +} + +/// Pointer to a GitHub Actions job. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubActionsJob { + /// Terminal conclusion of the job when finished (e.g., success, failure, cancelled). Absent for in-progress jobs. + #[serde(skip_serializing_if = "Option::is_none")] + pub conclusion: Option, + /// Job id within the workflow run + pub job_id: i64, + /// Display name of the job + pub job_name: String, + /// Repository the workflow run belongs to + pub repo: GitHubRepoRef, + /// Attachment type discriminator + pub r#type: AttachmentGitHubActionsJobType, + /// URL to the job on GitHub + pub url: String, + /// Display name of the workflow the job ran in + pub workflow_name: String, +} + +/// Pointer to a GitHub commit. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubCommit { + /// First line of the commit message + pub message: String, + /// Full commit SHA + pub oid: String, + /// Repository the commit belongs to + pub repo: GitHubRepoRef, + /// Attachment type discriminator + pub r#type: AttachmentGitHubCommitType, + /// URL to the commit on GitHub + pub url: String, +} + +/// Pointer to a file in a GitHub repository at a specific ref. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubFile { + /// Repository-relative path to the file + pub path: String, + /// Git ref the file is read at (branch, tag, or commit SHA) + pub r#ref: String, + /// Repository the file lives in + pub repo: GitHubRepoRef, + /// Attachment type discriminator + pub r#type: AttachmentGitHubFileType, + /// URL to the file on GitHub + pub url: String, +} + +/// One side of a file diff (head or base) +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubFileDiffSide { + /// Repository-relative path to the file + pub path: String, + /// Git ref (branch, tag, or commit SHA) the file is read at + pub r#ref: String, + /// Repository the file lives in + pub repo: GitHubRepoRef, +} + +/// Pointer to a single-file diff. At least one of `head` and `base` must be present. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubFileDiff { + /// File location on the base side of the diff. Absent for additions. + #[serde(skip_serializing_if = "Option::is_none")] + pub base: Option, + /// File location on the head side of the diff. Absent for deletions. + #[serde(skip_serializing_if = "Option::is_none")] + pub head: Option, + /// Attachment type discriminator + pub r#type: AttachmentGitHubFileDiffType, + /// URL to the diff on GitHub (e.g., a commit, compare, or PR-file URL) + pub url: String, +} + /// GitHub issue, pull request, or discussion reference /// ///
@@ -1518,6 +1657,134 @@ pub struct AttachmentGitHubReference { pub url: String, } +/// Pointer to a GitHub release. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubRelease { + /// Human-readable release name + pub name: String, + /// Repository the release belongs to + pub repo: GitHubRepoRef, + /// Git tag the release is anchored to + pub tag_name: String, + /// Attachment type discriminator + pub r#type: AttachmentGitHubReleaseType, + /// URL to the release on GitHub + pub url: String, +} + +/// Pointer to a GitHub repository. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubRepository { + /// Short description of the repository + #[serde(skip_serializing_if = "Option::is_none")] + pub description: Option, + /// Git ref this attachment is anchored at (branch, tag, or commit). When absent the default branch is implied. + #[serde(skip_serializing_if = "Option::is_none")] + pub r#ref: Option, + /// Repository pointer + pub repo: GitHubRepoRef, + /// Attachment type discriminator + pub r#type: AttachmentGitHubRepositoryType, + /// URL to the repository on GitHub + pub url: String, +} + +/// Pointer to a line range inside a file in a GitHub repository. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubSnippet { + /// Line range the snippet covers + pub line_range: AttachmentFileLineRange, + /// Repository-relative path to the file + pub path: String, + /// Git ref the file is read at (branch, tag, or commit SHA) + pub r#ref: String, + /// Repository the file lives in + pub repo: GitHubRepoRef, + /// Attachment type discriminator + pub r#type: AttachmentGitHubSnippetType, + /// URL to the snippet on GitHub (with line anchor) + pub url: String, +} + +/// One side of a tree comparison (head or base) +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubTreeComparisonSide { + /// Repository the revision belongs to + pub repo: GitHubRepoRef, + /// Git revision (branch, tag, or commit SHA) + pub revision: String, +} + +/// Pointer to a comparison between two git revisions. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubTreeComparison { + /// Base side of the comparison + pub base: AttachmentGitHubTreeComparisonSide, + /// Head side of the comparison + pub head: AttachmentGitHubTreeComparisonSide, + /// Attachment type discriminator + pub r#type: AttachmentGitHubTreeComparisonType, + /// URL to the comparison on GitHub + pub url: String, +} + +/// Generic GitHub URL reference. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AttachmentGitHubUrl { + /// Attachment type discriminator + pub r#type: AttachmentGitHubUrlType, + /// URL to the GitHub resource + pub url: String, +} + /// End position of the selection /// ///
@@ -3142,6 +3409,9 @@ pub struct InstalledPlugin { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct InstalledPluginInfo { + /// Opaque, stable hash identifying a direct (non-marketplace) install source. Present only for direct repo / URL / local installs; absent for marketplace plugins. Same source yields the same id; distinct sources never collide. + #[serde(skip_serializing_if = "Option::is_none")] + pub direct_source_id: Option, /// Whether the plugin is currently enabled for new sessions pub enabled: bool, /// Marketplace the plugin came from. Empty string ("") for direct repo / URL / local installs. @@ -4285,6 +4555,52 @@ pub struct McpFilteredServer { pub redacted_reason: Option, } +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct McpHeadersHandlePendingHeadersRefreshRequestHeaders { + /// Headers to overlay onto the MCP request. Dynamic headers override static config headers but do not replace SDK-managed request headers. + pub headers: HashMap, + pub kind: McpHeadersHandlePendingHeadersRefreshRequestHeadersKind, +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct McpHeadersHandlePendingHeadersRefreshRequestNone { + pub kind: McpHeadersHandlePendingHeadersRefreshRequestNoneKind, +} + +/// MCP headers refresh request id and the host response. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct McpHeadersHandlePendingHeadersRefreshRequestRequest { + /// Headers refresh request identifier from mcp.headers_refresh_required + pub request_id: RequestId, + /// Host response: supply dynamic headers or decline this refresh. + pub result: McpHeadersHandlePendingHeadersRefreshRequest, +} + +/// Indicates whether the pending MCP headers refresh response was accepted. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct McpHeadersHandlePendingHeadersRefreshRequestResult { + /// Whether the response was accepted. False if the request was unknown, timed out, or already resolved. + pub success: bool, +} + /// Recorded MCP server connection failure. /// ///
@@ -4431,9 +4747,6 @@ pub struct McpOauthPendingRequestResponseToken { #[serde(skip_serializing_if = "Option::is_none")] pub expires_in: Option, pub kind: McpOauthPendingRequestResponseTokenKind, - /// Refresh token supplied by the host, if available. - #[serde(skip_serializing_if = "Option::is_none")] - pub refresh_token: Option, /// OAuth token type. Defaults to Bearer when omitted. #[serde(skip_serializing_if = "Option::is_none")] pub token_type: Option, @@ -5221,6 +5534,9 @@ pub struct ModelBillingTokenPrices { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ModelBilling { + /// Whole-number percentage discount (0-100) applied to usage billed through this model. Populated for the synthetic `auto` model, where requests routed by auto-mode are billed at a reduced rate; absent for concrete models. + #[serde(skip_serializing_if = "Option::is_none")] + pub discount_percent: Option, /// Billing cost multiplier relative to the base rate #[serde(skip_serializing_if = "Option::is_none")] pub multiplier: Option, @@ -7508,6 +7824,9 @@ pub struct PluginsReloadRequest { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct PluginsUninstallRequest { + /// Stable source identity for a direct (non-marketplace) install. Disambiguates uninstall when multiple installed plugins share the same name. + #[serde(skip_serializing_if = "Option::is_none")] + pub direct_source_id: Option, /// Plugin name or "plugin@marketplace" spec to uninstall. When ambiguous, prefer the fully-qualified spec. pub name: String, } @@ -7934,6 +8253,142 @@ pub struct PushAttachmentFile { pub r#type: PushAttachmentFileType, } +/// Pointer to a GitHub repository. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushGitHubRepoRef { + /// Numeric GitHub repository id + #[serde(skip_serializing_if = "Option::is_none")] + pub id: Option, + /// Repository name (without owner) + pub name: String, + /// Repository owner login (user or organization) + pub owner: String, +} + +/// Pointer to a GitHub Actions job. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubActionsJob { + /// Terminal conclusion of the job when finished (e.g., success, failure, cancelled). Absent for in-progress jobs. + #[serde(skip_serializing_if = "Option::is_none")] + pub conclusion: Option, + /// Job id within the workflow run + pub job_id: i64, + /// Display name of the job + pub job_name: String, + /// Repository the workflow run belongs to + pub repo: PushGitHubRepoRef, + /// Attachment type discriminator + pub r#type: PushAttachmentGitHubActionsJobType, + /// URL to the job on GitHub + pub url: String, + /// Display name of the workflow the job ran in + pub workflow_name: String, +} + +/// Pointer to a GitHub commit. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubCommit { + /// First line of the commit message + pub message: String, + /// Full commit SHA + pub oid: String, + /// Repository the commit belongs to + pub repo: PushGitHubRepoRef, + /// Attachment type discriminator + pub r#type: PushAttachmentGitHubCommitType, + /// URL to the commit on GitHub + pub url: String, +} + +/// Pointer to a file in a GitHub repository at a specific ref. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubFile { + /// Repository-relative path to the file + pub path: String, + /// Git ref the file is read at (branch, tag, or commit SHA) + pub r#ref: String, + /// Repository the file lives in + pub repo: PushGitHubRepoRef, + /// Attachment type discriminator + pub r#type: PushAttachmentGitHubFileType, + /// URL to the file on GitHub + pub url: String, +} + +/// One side of a file diff (head or base) +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubFileDiffSide { + /// Repository-relative path to the file + pub path: String, + /// Git ref (branch, tag, or commit SHA) the file is read at + pub r#ref: String, + /// Repository the file lives in + pub repo: PushGitHubRepoRef, +} + +/// Pointer to a single-file diff. At least one of `head` and `base` must be present. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubFileDiff { + /// File location on the base side of the diff. Absent for additions. + #[serde(skip_serializing_if = "Option::is_none")] + pub base: Option, + /// File location on the head side of the diff. Absent for deletions. + #[serde(skip_serializing_if = "Option::is_none")] + pub head: Option, + /// Attachment type discriminator + pub r#type: PushAttachmentGitHubFileDiffType, + /// URL to the diff on GitHub (e.g., a commit, compare, or PR-file URL) + pub url: String, +} + /// GitHub issue, pull request, or discussion reference /// ///
@@ -7959,6 +8414,134 @@ pub struct PushAttachmentGitHubReference { pub url: String, } +/// Pointer to a GitHub release. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubRelease { + /// Human-readable release name + pub name: String, + /// Repository the release belongs to + pub repo: PushGitHubRepoRef, + /// Git tag the release is anchored to + pub tag_name: String, + /// Attachment type discriminator + pub r#type: PushAttachmentGitHubReleaseType, + /// URL to the release on GitHub + pub url: String, +} + +/// Pointer to a GitHub repository. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubRepository { + /// Short description of the repository + #[serde(skip_serializing_if = "Option::is_none")] + pub description: Option, + /// Git ref this attachment is anchored at (branch, tag, or commit). When absent the default branch is implied. + #[serde(skip_serializing_if = "Option::is_none")] + pub r#ref: Option, + /// Repository pointer + pub repo: PushGitHubRepoRef, + /// Attachment type discriminator + pub r#type: PushAttachmentGitHubRepositoryType, + /// URL to the repository on GitHub + pub url: String, +} + +/// Pointer to a line range inside a file in a GitHub repository. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubSnippet { + /// Line range the snippet covers + pub line_range: PushAttachmentFileLineRange, + /// Repository-relative path to the file + pub path: String, + /// Git ref the file is read at (branch, tag, or commit SHA) + pub r#ref: String, + /// Repository the file lives in + pub repo: PushGitHubRepoRef, + /// Attachment type discriminator + pub r#type: PushAttachmentGitHubSnippetType, + /// URL to the snippet on GitHub (with line anchor) + pub url: String, +} + +/// One side of a tree comparison (head or base) +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubTreeComparisonSide { + /// Repository the revision belongs to + pub repo: PushGitHubRepoRef, + /// Git revision (branch, tag, or commit SHA) + pub revision: String, +} + +/// Pointer to a comparison between two git revisions. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubTreeComparison { + /// Base side of the comparison + pub base: PushAttachmentGitHubTreeComparisonSide, + /// Head side of the comparison + pub head: PushAttachmentGitHubTreeComparisonSide, + /// Attachment type discriminator + pub r#type: PushAttachmentGitHubTreeComparisonType, + /// URL to the comparison on GitHub + pub url: String, +} + +/// Generic GitHub URL reference. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PushAttachmentGitHubUrl { + /// Attachment type discriminator + pub r#type: PushAttachmentGitHubUrlType, + /// URL to the GitHub resource + pub url: String, +} + /// End position of the selection /// ///
@@ -9793,6 +10376,9 @@ pub struct SessionOpenOptions { /// Runtime context discriminator for agent filtering. #[serde(skip_serializing_if = "Option::is_none")] pub agent_context: Option, + /// Whether to include instructions from every MCP server in the system prompt instead of only allowlisted servers. + #[serde(skip_serializing_if = "Option::is_none")] + pub allow_all_mcp_server_instructions: Option, /// Whether ask_user is explicitly disabled. #[serde(skip_serializing_if = "Option::is_none")] pub ask_user_disabled: Option, @@ -9941,6 +10527,9 @@ pub struct SessionOpenOptions { /// Whether this session supports remote steering. #[serde(skip_serializing_if = "Option::is_none")] pub remote_steerable: Option, + /// Initial response budget limits for the session. + #[serde(skip_serializing_if = "Option::is_none")] + pub response_budget: Option, /// Whether the host is an interactive UI. #[serde(skip_serializing_if = "Option::is_none")] pub running_in_interactive_mode: Option, @@ -10317,7 +10906,7 @@ pub struct SessionsEnrichMetadataRequest { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SessionSetCredentialsParams { - /// The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime stores the value verbatim and uses it for outbound model/API requests; it does NOT re-validate or re-fetch the associated Copilot user response. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. + /// The new auth credentials to install on the session. When omitted or `undefined`, the call is a no-op and the session's existing credentials are preserved. The runtime installs the supplied value immediately for outbound model/API requests. When the credential carries a raw token (`token`, `env`, or `gh-cli`) but no `copilotUser`, the runtime additionally re-resolves `copilotUser` server-side (best-effort, asynchronously, after the synchronous install) so plan/quota/billing metadata regains fidelity; on resolution failure the verbatim credential remains installed. It does NOT otherwise validate the credential. Several variants carry secret material; treat this method's params as containing secrets at rest and in transit. #[serde(skip_serializing_if = "Option::is_none")] pub credentials: Option, } @@ -10333,6 +10922,9 @@ pub struct SessionSetCredentialsParams { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SessionSetCredentialsResult { + /// Whether the session ended up with a populated `copilotUser` for the installed credentials. `true` when the supplied credential already carried `copilotUser` or it was successfully re-resolved server-side. `false` when the credential is installed without `copilotUser` — either re-resolution failed, or the variant cannot be re-resolved from the credential alone (only the raw-token variants `token`, `env`, and `gh-cli` can). In both `false` cases the token swap still applied, but plan/quota/billing metadata is degraded. Present whenever a credential was supplied; omitted only when no credential was supplied (no-op call). + #[serde(skip_serializing_if = "Option::is_none")] + pub copilot_user_resolved: Option, /// Whether the operation succeeded pub success: bool, } @@ -10884,6 +11476,9 @@ pub struct SessionUpdateOptionsParams { /// Runtime context discriminator (e.g., `cli`, `actions`). #[serde(skip_serializing_if = "Option::is_none")] pub agent_context: Option, + /// Whether to include instructions from every MCP server in the system prompt instead of only allowlisted servers. + #[serde(skip_serializing_if = "Option::is_none")] + pub allow_all_mcp_server_instructions: Option, /// Whether to disable the `ask_user` tool (encourages autonomous behavior). #[serde(skip_serializing_if = "Option::is_none")] pub ask_user_disabled: Option, @@ -10992,6 +11587,9 @@ pub struct SessionUpdateOptionsParams { /// Reasoning summary mode for supported model clients. #[serde(skip_serializing_if = "Option::is_none")] pub reasoning_summary: Option, + /// Optional response budget limits. Pass null to clear the response budget. + #[serde(skip_serializing_if = "Option::is_none")] + pub response_budget: Option, /// Whether the session is running in an interactive UI. #[serde(skip_serializing_if = "Option::is_none")] pub running_in_interactive_mode: Option, @@ -11532,6 +12130,12 @@ pub struct SubagentSettings { /// Names of subagents the user has turned off; they cannot be dispatched #[serde(skip_serializing_if = "Option::is_none")] pub disabled_subagents: Option>, + /// Maximum number of subagents that can run concurrently; applies to usage-based billing users only + #[serde(skip_serializing_if = "Option::is_none")] + pub max_concurrency: Option, + /// Maximum subagent nesting depth; applies to usage-based billing users only + #[serde(skip_serializing_if = "Option::is_none")] + pub max_depth: Option, } /// Schema for the `TaskAgentInfo` type. @@ -12658,6 +13262,12 @@ pub struct UpdateSubagentSettingsRequestSubagents { /// Names of subagents the user has turned off; they cannot be dispatched #[serde(skip_serializing_if = "Option::is_none")] pub disabled_subagents: Option>, + /// Maximum number of subagents that can run concurrently; applies to usage-based billing users only + #[serde(skip_serializing_if = "Option::is_none")] + pub max_concurrency: Option, + /// Maximum subagent nesting depth; applies to usage-based billing users only + #[serde(skip_serializing_if = "Option::is_none")] + pub max_depth: Option, } /// Subagent settings to apply to the current session @@ -13800,7 +14410,7 @@ pub struct SessionAbortResult { ///
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct SessionAuthGetStatusParams { +pub struct SessionGitHubAuthGetStatusParams { /// Target session identifier pub session_id: SessionId, } @@ -13815,7 +14425,7 @@ pub struct SessionAuthGetStatusParams { ///
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct SessionAuthGetStatusResult { +pub struct SessionGitHubAuthGetStatusResult { /// Authentication type #[serde(skip_serializing_if = "Option::is_none")] pub auth_type: Option, @@ -13845,7 +14455,10 @@ pub struct SessionAuthGetStatusResult { ///
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct SessionAuthSetCredentialsResult { +pub struct SessionGitHubAuthSetCredentialsResult { + /// Whether the session ended up with a populated `copilotUser` for the installed credentials. `true` when the supplied credential already carried `copilotUser` or it was successfully re-resolved server-side. `false` when the credential is installed without `copilotUser` — either re-resolution failed, or the variant cannot be re-resolved from the credential alone (only the raw-token variants `token`, `env`, and `gh-cli` can). In both `false` cases the token swap still applied, but plan/quota/billing metadata is degraded. Present whenever a credential was supplied; omitted only when no credential was supplied (no-op call). + #[serde(skip_serializing_if = "Option::is_none")] + pub copilot_user_resolved: Option, /// Whether the operation succeeded pub success: bool, } @@ -15178,6 +15791,21 @@ pub struct SessionMcpOauthLoginResult { pub authorization_url: Option, } +/// Indicates whether the pending MCP headers refresh response was accepted. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SessionMcpHeadersHandlePendingHeadersRefreshRequestResult { + /// Whether the response was accepted. False if the request was unknown, timed out, or already resolved. + pub success: bool, +} + /// Resource contents returned by the MCP server. /// ///
@@ -17305,6 +17933,38 @@ pub enum AttachmentFileType { File, } +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttachmentGitHubActionsJobType { + #[serde(rename = "github_actions_job")] + #[default] + GitHubActionsJob, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttachmentGitHubCommitType { + #[serde(rename = "github_commit")] + #[default] + GitHubCommit, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttachmentGitHubFileType { + #[serde(rename = "github_file")] + #[default] + GitHubFile, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttachmentGitHubFileDiffType { + #[serde(rename = "github_file_diff")] + #[default] + GitHubFileDiff, +} + /// Type of GitHub reference /// ///
@@ -17330,6 +17990,46 @@ pub enum AttachmentGitHubReferenceType { Unknown, } +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttachmentGitHubReleaseType { + #[serde(rename = "github_release")] + #[default] + GitHubRelease, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttachmentGitHubRepositoryType { + #[serde(rename = "github_repository")] + #[default] + GitHubRepository, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttachmentGitHubSnippetType { + #[serde(rename = "github_snippet")] + #[default] + GitHubSnippet, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttachmentGitHubTreeComparisonType { + #[serde(rename = "github_tree_comparison")] + #[default] + GitHubTreeComparison, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum AttachmentGitHubUrlType { + #[serde(rename = "github_url")] + #[default] + GitHubUrl, +} + /// Attachment type discriminator #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum AttachmentSelectionType { @@ -18123,6 +18823,35 @@ pub enum McpAppsSetHostContextDetailsTheme { Unknown, } +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum McpHeadersHandlePendingHeadersRefreshRequestHeadersKind { + #[serde(rename = "headers")] + #[default] + Headers, +} + +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum McpHeadersHandlePendingHeadersRefreshRequestNoneKind { + #[serde(rename = "none")] + #[default] + None, +} + +/// Host response: supply dynamic headers or decline this refresh. +/// +///
+/// +/// **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, Serialize, Deserialize)] +#[serde(untagged)] +pub enum McpHeadersHandlePendingHeadersRefreshRequest { + Headers(McpHeadersHandlePendingHeadersRefreshRequestHeaders), + None(McpHeadersHandlePendingHeadersRefreshRequestNone), +} + #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum McpOauthPendingRequestResponseTokenKind { #[serde(rename = "token")] @@ -19223,6 +19952,38 @@ pub enum PushAttachmentFileType { File, } +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum PushAttachmentGitHubActionsJobType { + #[serde(rename = "github_actions_job")] + #[default] + GitHubActionsJob, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum PushAttachmentGitHubCommitType { + #[serde(rename = "github_commit")] + #[default] + GitHubCommit, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum PushAttachmentGitHubFileType { + #[serde(rename = "github_file")] + #[default] + GitHubFile, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum PushAttachmentGitHubFileDiffType { + #[serde(rename = "github_file_diff")] + #[default] + GitHubFileDiff, +} + /// Type of GitHub reference /// ///
@@ -19248,6 +20009,46 @@ pub enum PushAttachmentGitHubReferenceType { Unknown, } +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum PushAttachmentGitHubReleaseType { + #[serde(rename = "github_release")] + #[default] + GitHubRelease, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum PushAttachmentGitHubRepositoryType { + #[serde(rename = "github_repository")] + #[default] + GitHubRepository, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum PushAttachmentGitHubSnippetType { + #[serde(rename = "github_snippet")] + #[default] + GitHubSnippet, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum PushAttachmentGitHubTreeComparisonType { + #[serde(rename = "github_tree_comparison")] + #[default] + GitHubTreeComparison, +} + +/// Attachment type discriminator +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum PushAttachmentGitHubUrlType { + #[serde(rename = "github_url")] + #[default] + GitHubUrl, +} + /// Attachment type discriminator #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum PushAttachmentSelectionType { @@ -19945,7 +20746,7 @@ pub enum SlashCommandSelectSubcommandResultKind { SelectSubcommand, } -/// Result of invoking the slash command (text output, prompt to send to the agent, or completion). +/// Result of invoking the slash command (text output, prompt to send to the agent, completion, or subcommand selection). /// ///
/// diff --git a/rust/src/generated/rpc.rs b/rust/src/generated/rpc.rs index 57a5192dca..c5a99ece11 100644 --- a/rust/src/generated/rpc.rs +++ b/rust/src/generated/rpc.rs @@ -2358,13 +2358,6 @@ impl<'a> SessionRpc<'a> { } } - /// `session.auth.*` sub-namespace. - pub fn auth(&self) -> SessionRpcAuth<'a> { - SessionRpcAuth { - session: self.session, - } - } - /// `session.canvas.*` sub-namespace. pub fn canvas(&self) -> SessionRpcCanvas<'a> { SessionRpcCanvas { @@ -2400,6 +2393,13 @@ impl<'a> SessionRpc<'a> { } } + /// `session.gitHubAuth.*` sub-namespace. + pub fn git_hub_auth(&self) -> SessionRpcGitHubAuth<'a> { + SessionRpcGitHubAuth { + session: self.session, + } + } + /// `session.history.*` sub-namespace. pub fn history(&self) -> SessionRpcHistory<'a> { SessionRpcHistory { @@ -2840,72 +2840,6 @@ impl<'a> SessionRpcAgent<'a> { } } -/// `session.auth.*` RPCs. -#[derive(Clone, Copy)] -pub struct SessionRpcAuth<'a> { - pub(crate) session: &'a Session, -} - -impl<'a> SessionRpcAuth<'a> { - /// Gets authentication status and account metadata for the session. - /// - /// Wire method: `session.auth.getStatus`. - /// - /// # Returns - /// - /// Authentication status and account metadata for the session. - /// - ///
- /// - /// **Experimental.** This API is part of an experimental wire-protocol surface - /// and may change or be removed in future SDK or CLI releases. Pin both the - /// SDK and CLI versions if your code depends on it. - /// - ///
- pub async fn get_status(&self) -> Result { - let wire_params = serde_json::json!({ "sessionId": self.session.id() }); - let _value = self - .session - .client() - .call(rpc_methods::SESSION_AUTH_GETSTATUS, Some(wire_params)) - .await?; - Ok(serde_json::from_value(_value)?) - } - - /// Updates the session's auth credentials used for outbound model and API requests. - /// - /// Wire method: `session.auth.setCredentials`. - /// - /// # Parameters - /// - /// * `params` - New auth credentials to install on the session. Omit to leave credentials unchanged. - /// - /// # Returns - /// - /// Indicates whether the credential update succeeded. - /// - ///
- /// - /// **Experimental.** This API is part of an experimental wire-protocol surface - /// and may change or be removed in future SDK or CLI releases. Pin both the - /// SDK and CLI versions if your code depends on it. - /// - ///
- pub async fn set_credentials( - &self, - params: SessionSetCredentialsParams, - ) -> Result { - let mut wire_params = serde_json::to_value(params)?; - wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); - let _value = self - .session - .client() - .call(rpc_methods::SESSION_AUTH_SETCREDENTIALS, Some(wire_params)) - .await?; - Ok(serde_json::from_value(_value)?) - } -} - /// `session.canvas.*` RPCs. #[derive(Clone, Copy)] pub struct SessionRpcCanvas<'a> { @@ -3143,7 +3077,7 @@ impl<'a> SessionRpcCommands<'a> { /// /// # Returns /// - /// Result of invoking the slash command (text output, prompt to send to the agent, or completion). + /// Result of invoking the slash command (text output, prompt to send to the agent, completion, or subcommand selection). /// ///
/// @@ -3616,6 +3550,75 @@ impl<'a> SessionRpcFleet<'a> { } } +/// `session.gitHubAuth.*` RPCs. +#[derive(Clone, Copy)] +pub struct SessionRpcGitHubAuth<'a> { + pub(crate) session: &'a Session, +} + +impl<'a> SessionRpcGitHubAuth<'a> { + /// Gets authentication status and account metadata for the session. + /// + /// Wire method: `session.gitHubAuth.getStatus`. + /// + /// # Returns + /// + /// Authentication status and account metadata for the session. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn get_status(&self) -> Result { + let wire_params = serde_json::json!({ "sessionId": self.session.id() }); + let _value = self + .session + .client() + .call(rpc_methods::SESSION_GITHUBAUTH_GETSTATUS, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Updates the session's auth credentials used for outbound model and API requests. + /// + /// Wire method: `session.gitHubAuth.setCredentials`. + /// + /// # Parameters + /// + /// * `params` - New auth credentials to install on the session. Omit to leave credentials unchanged. + /// + /// # Returns + /// + /// Indicates whether the credential update succeeded. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn set_credentials( + &self, + params: SessionSetCredentialsParams, + ) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call( + rpc_methods::SESSION_GITHUBAUTH_SETCREDENTIALS, + Some(wire_params), + ) + .await?; + Ok(serde_json::from_value(_value)?) + } +} + /// `session.history.*` RPCs. #[derive(Clone, Copy)] pub struct SessionRpcHistory<'a> { @@ -3887,6 +3890,13 @@ impl<'a> SessionRpcMcp<'a> { } } + /// `session.mcp.headers.*` sub-namespace. + pub fn headers(&self) -> SessionRpcMcpHeaders<'a> { + SessionRpcMcpHeaders { + session: self.session, + } + } + /// `session.mcp.oauth.*` sub-namespace. pub fn oauth(&self) -> SessionRpcMcpOauth<'a> { SessionRpcMcpOauth { @@ -4600,6 +4610,50 @@ impl<'a> SessionRpcMcpApps<'a> { } } +/// `session.mcp.headers.*` RPCs. +#[derive(Clone, Copy)] +pub struct SessionRpcMcpHeaders<'a> { + pub(crate) session: &'a Session, +} + +impl<'a> SessionRpcMcpHeaders<'a> { + /// Responds to a pending MCP dynamic headers refresh request. Hosts that subscribe to `mcp.headers_refresh_required` use this to provide short-lived per-server headers or to indicate that no dynamic headers are available for this refresh. + /// + /// Wire method: `session.mcp.headers.handlePendingHeadersRefreshRequest`. + /// + /// # Parameters + /// + /// * `params` - MCP headers refresh request id and the host response. + /// + /// # Returns + /// + /// Indicates whether the pending MCP headers refresh response was accepted. + /// + ///
+ /// + /// **Experimental.** This API is part of an experimental wire-protocol surface + /// and may change or be removed in future SDK or CLI releases. Pin both the + /// SDK and CLI versions if your code depends on it. + /// + ///
+ pub async fn handle_pending_headers_refresh_request( + &self, + params: McpHeadersHandlePendingHeadersRefreshRequestRequest, + ) -> Result { + let mut wire_params = serde_json::to_value(params)?; + wire_params["sessionId"] = serde_json::Value::String(self.session.id().to_string()); + let _value = self + .session + .client() + .call( + rpc_methods::SESSION_MCP_HEADERS_HANDLEPENDINGHEADERSREFRESHREQUEST, + Some(wire_params), + ) + .await?; + Ok(serde_json::from_value(_value)?) + } +} + /// `session.mcp.oauth.*` RPCs. #[derive(Clone, Copy)] pub struct SessionRpcMcpOauth<'a> { diff --git a/rust/src/generated/session_events.rs b/rust/src/generated/session_events.rs index e094ec3655..36fecc054b 100644 --- a/rust/src/generated/session_events.rs +++ b/rust/src/generated/session_events.rs @@ -85,6 +85,8 @@ pub enum SessionEventType { AssistantMessageDelta, #[serde(rename = "assistant.turn_end")] AssistantTurnEnd, + #[serde(rename = "assistant.idle")] + AssistantIdle, #[serde(rename = "assistant.usage")] AssistantUsage, #[serde(rename = "model.call_failure")] @@ -152,6 +154,10 @@ pub enum SessionEventType { McpOauthRequired, #[serde(rename = "mcp.oauth_completed")] McpOauthCompleted, + #[serde(rename = "mcp.headers_refresh_required")] + McpHeadersRefreshRequired, + #[serde(rename = "mcp.headers_refresh_completed")] + McpHeadersRefreshCompleted, #[serde(rename = "session.custom_notification")] SessionCustomNotification, #[serde(rename = "external_tool.requested")] @@ -336,6 +342,8 @@ pub enum SessionEventData { AssistantMessageDelta(AssistantMessageDeltaData), #[serde(rename = "assistant.turn_end")] AssistantTurnEnd(AssistantTurnEndData), + #[serde(rename = "assistant.idle")] + AssistantIdle(AssistantIdleData), #[serde(rename = "assistant.usage")] AssistantUsage(AssistantUsageData), #[serde(rename = "model.call_failure")] @@ -396,6 +404,10 @@ pub enum SessionEventData { McpOauthRequired(McpOauthRequiredData), #[serde(rename = "mcp.oauth_completed")] McpOauthCompleted(McpOauthCompletedData), + #[serde(rename = "mcp.headers_refresh_required")] + McpHeadersRefreshRequired(McpHeadersRefreshRequiredData), + #[serde(rename = "mcp.headers_refresh_completed")] + McpHeadersRefreshCompleted(McpHeadersRefreshCompletedData), #[serde(rename = "session.custom_notification")] SessionCustomNotification(SessionCustomNotificationData), #[serde(rename = "external_tool.requested")] @@ -550,6 +562,18 @@ pub struct WorkingDirectoryContext { pub repository_host: Option, } +/// Optional response budget limits. +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ResponseBudgetConfig { + /// Maximum AI Credits allowed while responding to one top-level user message. + #[serde(skip_serializing_if = "Option::is_none")] + pub max_ai_credits: Option, + /// Maximum model-call iterations allowed while responding to one top-level user message. + #[serde(skip_serializing_if = "Option::is_none")] + pub max_model_iterations: Option, +} + /// Session event "session.start". Session initialization metadata including context and configuration #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -579,6 +603,9 @@ pub struct SessionStartData { /// Whether this session supports remote steering via GitHub #[serde(skip_serializing_if = "Option::is_none")] pub remote_steerable: Option, + /// Response budget limits configured at session creation time, if any + #[serde(skip_serializing_if = "Option::is_none")] + pub response_budget: Option, /// Model selected at session creation time, if any #[serde(skip_serializing_if = "Option::is_none")] pub selected_model: Option, @@ -620,6 +647,9 @@ pub struct SessionResumeData { /// Whether this session supports remote steering via GitHub #[serde(skip_serializing_if = "Option::is_none")] pub remote_steerable: Option, + /// Response budget limits currently configured at resume time; null when no budget is active + #[serde(skip_serializing_if = "Option::is_none")] + pub response_budget: Option, /// ISO 8601 timestamp when the session was resumed pub resume_time: String, /// Model currently selected at resume time @@ -1274,6 +1304,9 @@ pub struct UserMessageData { pub attachments: Option>, /// The user's message text as displayed in the timeline pub content: String, + /// How this message was delivered to the agentic loop relative to loop state (idle-start vs. steering/queued while busy). The timing axis; combine with `source` (origin) for the full picture. Used for telemetry attribution. + #[serde(skip_serializing_if = "Option::is_none")] + pub delivery: Option, /// CAPI interaction ID for correlating this user message with its turn #[serde(skip_serializing_if = "Option::is_none")] pub interaction_id: Option, @@ -1583,6 +1616,15 @@ pub struct AssistantTurnEndData { pub turn_id: String, } +/// Session event "assistant.idle". Payload emitted whenever the main agent's processing loop goes idle, including while related background work (running agents or in-flight attached shell commands) is still pending and the session-level idle event is therefore deferred +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AssistantIdleData { + /// True when the preceding agentic loop was cancelled via abort signal + #[serde(skip_serializing_if = "Option::is_none")] + pub aborted: Option, +} + /// Token usage detail for a single billing category #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -1820,6 +1862,16 @@ pub struct ToolUserRequestedData { pub tool_name: String, } +/// Shell-aware path hints for a shell tool's command, captured at start time so consumers can snapshot a file's pre-image before the tool runs. +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ToolExecutionStartShellToolInfo { + /// Whether the command includes a file write redirection (e.g., > or >>). + pub has_write_file_redirection: bool, + /// File paths the command may read or write, derived from the command at start time. Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. + pub possible_paths: Vec, +} + /// Schema for the `ToolExecutionStartToolDescriptionMetaUI` type. #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -1879,6 +1931,9 @@ pub struct ToolExecutionStartData { #[deprecated] #[serde(skip_serializing_if = "Option::is_none")] pub parent_tool_call_id: Option, + /// Shell-tool path hints derived from the command at start time for shell tools (bash/powershell/local_shell). Produced by the same shell-aware extractor as PermissionRequestShell.possiblePaths, so it is present even when the command is auto-approved and no permission request fires. Absent for non-shell tools. + #[serde(skip_serializing_if = "Option::is_none")] + pub shell_tool_info: Option, /// Unique identifier for this tool call pub tool_call_id: String, /// Tool definition metadata, present for MCP tools with MCP Apps support @@ -3274,6 +3329,9 @@ pub struct SamplingCompletedData { pub struct McpOauthRequiredStaticClientConfig { /// OAuth client ID for the server pub client_id: String, + /// Optional OAuth client secret for confidential static clients, when the runtime can resolve one + #[serde(skip_serializing_if = "Option::is_none")] + pub client_secret: Option, /// Optional non-default OAuth grant type. When set to 'client_credentials', the OAuth flow runs headlessly using the client_id + keychain-stored secret (no browser, no callback server). #[serde(skip_serializing_if = "Option::is_none")] pub grant_type: Option, @@ -3289,8 +3347,9 @@ pub struct McpOauthWWWAuthenticateParams { /// OAuth error from the WWW-Authenticate error parameter, if present #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, - /// Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter - pub resource_metadata_url: String, + /// Protected resource metadata URL from the WWW-Authenticate resource_metadata parameter, if present + #[serde(skip_serializing_if = "Option::is_none")] + pub resource_metadata_url: Option, /// Requested OAuth scopes from the WWW-Authenticate scope parameter, if present #[serde(skip_serializing_if = "Option::is_none")] pub scope: Option, @@ -3300,6 +3359,8 @@ pub struct McpOauthWWWAuthenticateParams { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct McpOauthRequiredData { + /// Why the runtime is requesting host-provided OAuth credentials. + pub reason: McpOauthRequestReason, /// Unique identifier for this OAuth request; used to respond via session.mcp.oauth.handlePendingRequest pub request_id: RequestId, /// Raw OAuth protected-resource metadata document fetched for the MCP server, if available @@ -3327,6 +3388,30 @@ pub struct McpOauthCompletedData { pub request_id: RequestId, } +/// Session event "mcp.headers_refresh_required". Dynamic headers refresh request for a remote MCP server +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct McpHeadersRefreshRequiredData { + /// Why dynamic headers are being requested. + pub reason: McpHeadersRefreshRequiredReason, + /// Unique identifier for this headers refresh request; used to respond via session.mcp.headers.handlePendingHeadersRefreshRequest() + pub request_id: RequestId, + /// Display name of the remote MCP server requesting headers + pub server_name: String, + /// URL of the remote MCP server requesting headers + pub server_url: String, +} + +/// Session event "mcp.headers_refresh_completed". MCP headers refresh request completion notification +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct McpHeadersRefreshCompletedData { + /// How the pending MCP headers refresh request resolved. + pub outcome: McpHeadersRefreshCompletedOutcome, + /// Request ID of the resolved headers refresh request + pub request_id: RequestId, +} + /// Session event "session.custom_notification". Opaque custom notification data. Consumers may branch on source and name, but payload semantics are source-defined. #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -4094,6 +4179,24 @@ pub enum UserMessageAgentMode { Unknown, } +/// How this user message was delivered to the agentic loop, relative to whether the loop was already running. This is the timing axis only; the message's origin (human vs. system/command/schedule/skill/etc.) is carried separately by `source`. A system-injected message has a delivery too — e.g. a background-task notification waking an idle agent is `idle`, the same mechanism as a human starting a fresh turn. +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum UserMessageDelivery { + /// Delivered while the loop was idle; starts its own run immediately (a human's fresh turn, or a system notification waking an idle agent). + #[serde(rename = "idle")] + Idle, + /// Injected into the current in-flight run while the agent was busy (immediate mode). + #[serde(rename = "steering")] + Steering, + /// Enqueued while the agent was busy; processed as its own run afterward. + #[serde(rename = "queued")] + Queued, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + /// The system that produced a citation. /// ///
@@ -4824,6 +4927,27 @@ pub enum ElicitationCompletedAction { Unknown, } +/// Reason the runtime is requesting host-provided MCP OAuth credentials +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum McpOauthRequestReason { + /// Initial credentials are required before connecting to the MCP server. + #[serde(rename = "initial")] + Initial, + /// The current host-provided credential was rejected and a replacement is requested. + #[serde(rename = "refresh")] + Refresh, + /// The server requires a new host authorization flow before continuing. + #[serde(rename = "reauth")] + Reauth, + /// The server requires a credential with additional scope or audience. + #[serde(rename = "upscope")] + Upscope, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + /// Optional non-default OAuth grant type. When set to 'client_credentials', the OAuth flow runs headlessly using the client_id + keychain-stored secret (no browser, no callback server). #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum McpOauthRequiredStaticClientConfigGrantType { @@ -4847,6 +4971,42 @@ pub enum McpOauthCompletionOutcome { Unknown, } +/// Why dynamic headers are being requested. +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum McpHeadersRefreshRequiredReason { + /// The transport is making its first dynamic header request for this server. + #[serde(rename = "startup")] + Startup, + /// The previously cached dynamic headers expired. + #[serde(rename = "ttl-expired")] + TtlExpired, + /// The server returned 401 and stale dynamic headers were invalidated. + #[serde(rename = "auth-failed")] + AuthFailed, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + +/// How the pending MCP headers refresh request resolved. +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub enum McpHeadersRefreshCompletedOutcome { + /// The host supplied dynamic headers. + #[serde(rename = "headers")] + Headers, + /// The host responded with no dynamic headers. + #[serde(rename = "none")] + None, + /// No response arrived within the bounded window. + #[serde(rename = "timeout")] + Timeout, + /// Unknown variant for forward compatibility. + #[default] + #[serde(other)] + Unknown, +} + /// The user's auto-mode-switch choice #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] pub enum AutoModeSwitchResponse { diff --git a/rust/tests/e2e/per_session_auth.rs b/rust/tests/e2e/per_session_auth.rs index 24d3794484..b2fd11e4d4 100644 --- a/rust/tests/e2e/per_session_auth.rs +++ b/rust/tests/e2e/per_session_auth.rs @@ -29,7 +29,7 @@ async fn session_uses_client_token_when_no_session_token_is_supplied() { .expect("create session"); let status = session .rpc() - .auth() + .git_hub_auth() .get_status() .await .expect("auth status"); @@ -70,7 +70,7 @@ async fn session_token_overrides_client_token() { .expect("create session"); let status = session .rpc() - .auth() + .git_hub_auth() .get_status() .await .expect("auth status"); @@ -103,7 +103,7 @@ async fn session_auth_status_is_unauthenticated_without_token() { .expect("create session"); let status = session .rpc() - .auth() + .git_hub_auth() .get_status() .await .expect("auth status"); diff --git a/rust/tests/e2e/rpc_server_plugins.rs b/rust/tests/e2e/rpc_server_plugins.rs index 895ab28014..dc841b0af6 100644 --- a/rust/tests/e2e/rpc_server_plugins.rs +++ b/rust/tests/e2e/rpc_server_plugins.rs @@ -15,10 +15,10 @@ const PLUGIN_NAME: &str = "csharp-e2e-plugin"; const DIRECT_PLUGIN_NAME: &str = "csharp-e2e-direct"; #[tokio::test] -async fn should_install_list_and_uninstall_plugin_from_local_marketplace() { +async fn should_install_and_list_plugin_from_local_marketplace() { with_e2e_context( "rpc_server_plugins", - "should_install_list_and_uninstall_plugin_from_local_marketplace", + "should_install_and_list_plugin_from_local_marketplace", |ctx| { Box::pin(async move { let marketplace = create_local_marketplace_fixture(); @@ -39,7 +39,7 @@ async fn should_install_list_and_uninstall_plugin_from_local_marketplace() { .rpc() .plugins() .install(PluginsInstallRequest { - source: spec.clone(), + source: spec, working_directory: None, }) .await @@ -55,25 +55,6 @@ async fn should_install_list_and_uninstall_plugin_from_local_marketplace() { let listed = single_plugin(&after_install, PLUGIN_NAME, MARKETPLACE_NAME); assert!(listed.enabled); - client - .rpc() - .plugins() - .uninstall(PluginsUninstallRequest { name: spec }) - .await - .expect("uninstall marketplace plugin"); - - let after_uninstall = client - .rpc() - .plugins() - .list() - .await - .expect("list after uninstall"); - assert!(!contains_plugin( - &after_uninstall, - PLUGIN_NAME, - MARKETPLACE_NAME - )); - client.stop().await.expect("stop client"); }) }, @@ -293,11 +274,17 @@ async fn should_install_direct_local_plugin_with_deprecation_warning() { direct_matches, 1, "expected direct plugin in {after_install:?}" ); + let direct_source_id = install.plugin.direct_source_id.clone(); + assert!( + direct_source_id.is_some(), + "expected direct plugin install to include direct_source_id" + ); client .rpc() .plugins() .uninstall(PluginsUninstallRequest { + direct_source_id, name: DIRECT_PLUGIN_NAME.to_string(), }) .await @@ -546,9 +533,3 @@ fn single_plugin<'a>( assert_eq!(matches.len(), 1, "expected one plugin in {list:?}"); matches[0] } - -fn contains_plugin(list: &PluginListResult, name: &str, marketplace: &str) -> bool { - list.plugins - .iter() - .any(|plugin| plugin.name == name && plugin.marketplace == marketplace) -} diff --git a/rust/tests/e2e/rpc_session_state.rs b/rust/tests/e2e/rpc_session_state.rs index 8b68aeb3a8..199ff2a2b5 100644 --- a/rust/tests/e2e/rpc_session_state.rs +++ b/rust/tests/e2e/rpc_session_state.rs @@ -867,7 +867,7 @@ async fn should_set_auth_credentials() { let set = session .rpc() - .auth() + .git_hub_auth() .set_credentials(SessionSetCredentialsParams { credentials: Some(json!({ "type": "user", @@ -880,7 +880,7 @@ async fn should_set_auth_credentials() { assert!(set.success); let status = session .rpc() - .auth() + .git_hub_auth() .get_status() .await .expect("auth status"); diff --git a/test/harness/package-lock.json b/test/harness/package-lock.json index 80a2d239f6..edcdf87e4d 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.65", + "@github/copilot": "^1.0.66-1", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "@types/node-forge": "^1.3.14", @@ -501,9 +501,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.65.tgz", - "integrity": "sha512-J1XvLuOiVpiAi/E1MBICBymszCgdGLnZxokosXzGcmcjEVZd+QSDoW/kPRHq6oEyBT9SDASPcjCEZ9Q0rLJllg==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.66-1.tgz", + "integrity": "sha512-Cf0rTsG1wfdRzGmD9PC0TPYxQojItwo6Hv/Jp6GwakrBswLn4PlxW/pCQA7n3o2DahTQDX2y6Z9olAdx0dHFQA==", "dev": true, "license": "SEE LICENSE IN LICENSE.md", "dependencies": { @@ -513,20 +513,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.65", - "@github/copilot-darwin-x64": "1.0.65", - "@github/copilot-linux-arm64": "1.0.65", - "@github/copilot-linux-x64": "1.0.65", - "@github/copilot-linuxmusl-arm64": "1.0.65", - "@github/copilot-linuxmusl-x64": "1.0.65", - "@github/copilot-win32-arm64": "1.0.65", - "@github/copilot-win32-x64": "1.0.65" + "@github/copilot-darwin-arm64": "1.0.66-1", + "@github/copilot-darwin-x64": "1.0.66-1", + "@github/copilot-linux-arm64": "1.0.66-1", + "@github/copilot-linux-x64": "1.0.66-1", + "@github/copilot-linuxmusl-arm64": "1.0.66-1", + "@github/copilot-linuxmusl-x64": "1.0.66-1", + "@github/copilot-win32-arm64": "1.0.66-1", + "@github/copilot-win32-x64": "1.0.66-1" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.65.tgz", - "integrity": "sha512-NFc4xIstZNiIuAYkurQT5DVtbZjBoZ/z6yt/Ffcom7Y5QGjfpN4BFuekv9k+OADRioxxR99NgmhjbuNPWtQhNQ==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.66-1.tgz", + "integrity": "sha512-HTum+52pVBlrUrUjn/r/Q6kd2c0pvGsi6NyfuaGLRKStSQj00Iz5urYlo0hcq5JKF9eGB7ow+aeYc7BDIUVnhw==", "cpu": [ "arm64" ], @@ -541,9 +541,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.65.tgz", - "integrity": "sha512-0wtV22KmTa12VbqWRRkgvJcBz/oIbszfcIpyDWGc4MzbCVksajQ3TWVQ6c7Sdzj5RifCaYdkHAX2zuIYXYlLoQ==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.66-1.tgz", + "integrity": "sha512-gniq5/n2nX8cBQncjwvU7nAGYj21ALSknNUqhPWIQYwx+IM6KnGeBgSpldubJCMDjkZkbPYqskVcxTGvw0GGHA==", "cpu": [ "x64" ], @@ -558,9 +558,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.65.tgz", - "integrity": "sha512-dOwdy/YbTXQN/+x2v4ZgiDycdRtWElyHxPuA6ail3yJDt0nagwn8OYAA/diBLPMAJuuBXiOZGvvb9fGRuh7Xgg==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.66-1.tgz", + "integrity": "sha512-PG/xIIndXo0NpKYXR8GYPXAA3p/kuf4lsA898Pq+9UH5wU9ybqo5P/n5HBLXNOQnpP8+u9pjL9rPbvtwxMkzaQ==", "cpu": [ "arm64" ], @@ -575,9 +575,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.65.tgz", - "integrity": "sha512-al/1a/l/GrpHtygTxt7PZspmv0eHBPdAZ5B31J7Hv/GRdVZM4STCC9dCIOSUFsOX2fhaKD8yLfz4HureSYs23g==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.66-1.tgz", + "integrity": "sha512-Tb11uVan2f8YjFLiTvPUC8yLSYdmoMru9J8axZRuiSgOtRfmaJGxHoM/axPYW+874YAn4gSygs7OPUt1C+67Xw==", "cpu": [ "x64" ], @@ -592,9 +592,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.65.tgz", - "integrity": "sha512-xccQeJSR45xyoaL7J5mZjtU++dmte+ZCDQkIlrpTn2yuMl2LWriBvorQ1P2MwVnXmIiW/GHi93B+lNtsybA9yw==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.66-1.tgz", + "integrity": "sha512-GJEVj60B5MeJ8kfnf/dRmyX4EwU4HWL7yUZkrAG6xznSyHHPoTWtZ/tudQX/mf69emXtO7Nt9cLOcNIEdYRPMg==", "cpu": [ "arm64" ], @@ -609,9 +609,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.65.tgz", - "integrity": "sha512-RHPVUaqjSrhKHQ2EpfGKWErnV+R5elGIZaHXPKO10zpSaQD9b/C9u6nLigZnBuT/8sCaJpVrazPMwOYvYA62aw==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.66-1.tgz", + "integrity": "sha512-I5k9mMRuIO+pmPGDiblFXd+HOBJo92XEIBwbZMaAW3qRuyF5UcEFuWlczOCYzcTreXfBqNkG1P9qsBeDDNXfnQ==", "cpu": [ "x64" ], @@ -626,9 +626,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.65.tgz", - "integrity": "sha512-/vSE/t9Wm3eFSWpxlKyn/oL8OAVOB0yFO7ECxhgbtiqNrBd1tgpYh1k7IXBIWa/saxlV1+de6DEmPuQfx3Z0bg==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.66-1.tgz", + "integrity": "sha512-tUkNUkx5F2TIefY3KDORon3THo256hr/ZVUMEph5fr6xSib4d8gGgNjzok/4kEfIR3a7L/45g0Qi+CzQNtjSdA==", "cpu": [ "arm64" ], @@ -643,9 +643,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.65", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.65.tgz", - "integrity": "sha512-wjVWXepET+SpFg8z8V43ZiTy6X1OerCb7yu3QZKNNJ3zY9z20goihPXQCDWkiJpGzszNSgfrsiqUzpUsC9qS0A==", + "version": "1.0.66-1", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.66-1.tgz", + "integrity": "sha512-ktTbksWav2WSVi8BbTYxD4CJ+OrPximk5zPWff3stsU1MrG0XjZtlML1KUY3d/rrq2lpfZqh0ooF+A4bt8IFsQ==", "cpu": [ "x64" ], diff --git a/test/harness/package.json b/test/harness/package.json index d13dbb99a7..0052364850 100644 --- a/test/harness/package.json +++ b/test/harness/package.json @@ -14,7 +14,7 @@ "node": "^20.19.0 || >=22.12.0" }, "devDependencies": { - "@github/copilot": "^1.0.65", + "@github/copilot": "^1.0.66-1", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "@types/node-forge": "^1.3.14",