diff --git a/dotnet/src/Client.cs b/dotnet/src/Client.cs index eaf9859bc..d0e00b56d 100644 --- a/dotnet/src/Client.cs +++ b/dotnet/src/Client.cs @@ -1648,6 +1648,11 @@ private static string FormatCliExitedMessage(string message, string stderrOutput Message = "CopilotClient.ConnectToServerAsync connecting to CLI server. Host={Host}, Port={Port}")] private static partial void LogConnectingToCliServer(ILogger logger, string host, int port); + [LoggerMessage( + Level = LogLevel.Warning, + Message = "[CLI] {Line}")] + private static partial void LogCliStderrLine(ILogger logger, string line); + private static IOException CreateCliExitedException(string message, StringBuilder stderrBuffer) { string stderrOutput; @@ -2324,7 +2329,7 @@ private async Task PumpAsync(Process process, ILogger logger, CancellationToken Buffer.AppendLine(line); } - logger.LogWarning("[CLI] {Line}", line); + LogCliStderrLine(logger, line); } } catch (Exception e) when (cancellationToken.IsCancellationRequested diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index 7ec632a5e..91caad1e3 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -69,7 +69,9 @@ internal sealed class ConnectRequest /// Long context tier pricing (available for models with extended context windows). public sealed class ModelBillingTokenPricesLongContext { - /// Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens. + /// Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens. + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This member is deprecated and will be removed in a future version.")] [JsonPropertyName("cachePrice")] public double? CachePrice { get; set; } @@ -81,7 +83,9 @@ public sealed class ModelBillingTokenPricesLongContext [JsonPropertyName("cacheWritePrice")] public double? CacheWritePrice { get; set; } - /// Deprecated: use maxPromptTokens. Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. + /// Use maxPromptTokens instead. Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This member is deprecated and will be removed in a future version.")] [JsonPropertyName("contextMax")] public long? ContextMax { get; set; } @@ -105,7 +109,9 @@ public sealed class ModelBillingTokenPrices [JsonPropertyName("batchSize")] public long? BatchSize { get; set; } - /// Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens. + /// Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens. + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This member is deprecated and will be removed in a future version.")] [JsonPropertyName("cachePrice")] public double? CachePrice { get; set; } @@ -117,7 +123,9 @@ public sealed class ModelBillingTokenPrices [JsonPropertyName("cacheWritePrice")] public double? CacheWritePrice { get; set; } - /// Deprecated: use maxPromptTokens. Prompt token budget for the default tier. The total context window is this value plus the model's max_output_tokens. + /// Use maxPromptTokens instead. Prompt token budget for the default tier. The total context window is this value plus the model's max_output_tokens. + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("This member is deprecated and will be removed in a future version.")] [JsonPropertyName("contextMax")] public long? ContextMax { get; set; } @@ -370,2956 +378,3010 @@ internal sealed class AccountGetQuotaRequest public string? GitHubToken { get; set; } } -/// Confirmation that the secret values were registered. -public sealed class SecretsAddFilterValuesResult +/// Initial authentication info for the session. +/// Polymorphic base type discriminated by type. +[JsonPolymorphic( + TypeDiscriminatorPropertyName = "type", + UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] +[JsonDerivedType(typeof(AuthInfoHmac), "hmac")] +[JsonDerivedType(typeof(AuthInfoEnv), "env")] +[JsonDerivedType(typeof(AuthInfoToken), "token")] +[JsonDerivedType(typeof(AuthInfoCopilotApiToken), "copilot-api-token")] +[JsonDerivedType(typeof(AuthInfoUser), "user")] +[JsonDerivedType(typeof(AuthInfoGhCli), "gh-cli")] +[JsonDerivedType(typeof(AuthInfoApiKey), "api-key")] +public partial class AuthInfo { - /// Whether the values were successfully registered. - [JsonPropertyName("ok")] - public bool Ok { get; set; } + /// The type discriminator. + [JsonPropertyName("type")] + public virtual string Type { get; set; } = string.Empty; } -/// Secret values to add to the redaction filter. -internal sealed class SecretsAddFilterValuesRequest -{ - /// Raw secret values to register for redaction. - [JsonPropertyName("values")] - public IList Values { get => field ??= []; set; } -} -/// Schema for the `DiscoveredMcpServer` type. -public sealed class DiscoveredMcpServer +/// Schema for the `CopilotUserResponseEndpoints` type. +public sealed class CopilotUserResponseEndpoints { - /// Whether the server is enabled (not in the disabled list). - [JsonPropertyName("enabled")] - public bool Enabled { get; set; } - - /// Server name (config key). - [RegularExpression("^[^\\x00-\\x1f/\\x7f-\\x9f}]+(?:\\/[^\\x00-\\x1f/\\x7f-\\x9f}]+)*$")] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Safe for generated string properties: JSON Schema minLength/maxLength map to string length validation, not reflection over trimmed Count members")] - [MinLength(1)] - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; - - /// Configuration source: user, workspace, plugin, or builtin. - [JsonPropertyName("source")] - public McpServerSource Source { get; set; } + /// Gets or sets the api value. + [JsonPropertyName("api")] + public string? Api { get; set; } - /// Plugin name that provided this server, when source is plugin. - [JsonPropertyName("sourcePlugin")] - public string? SourcePlugin { get; set; } + /// Gets or sets the origin-tracker value. + [JsonPropertyName("origin-tracker")] + public string? OriginTracker { get; set; } - /// Plugin version that provided this server, when source is plugin. - [JsonPropertyName("sourcePluginVersion")] - public string? SourcePluginVersion { get; set; } + /// Gets or sets the proxy value. + [JsonPropertyName("proxy")] + public string? Proxy { get; set; } - /// Server transport type: stdio, http, sse (deprecated), or memory. - [JsonPropertyName("type")] - public DiscoveredMcpServerType? Type { get; set; } + /// Gets or sets the telemetry value. + [JsonPropertyName("telemetry")] + public string? Telemetry { get; set; } } -/// MCP servers discovered from user, workspace, plugin, and built-in sources. -public sealed class McpDiscoverResult +/// RPC data type for CopilotUserResponseOrganizationListItem operations. +public sealed class CopilotUserResponseOrganizationListItem { - /// MCP servers discovered from all sources. - [JsonPropertyName("servers")] - public IList Servers { get => field ??= []; set; } -} + /// Gets or sets the login value. + [JsonPropertyName("login")] + public string? Login { get; set; } -/// Optional working directory used as context for MCP server discovery. -internal sealed class McpDiscoverRequest -{ - /// Working directory used as context for discovery (e.g., plugin resolution). - [JsonPropertyName("workingDirectory")] - public string? WorkingDirectory { get; set; } + /// Gets or sets the name value. + [JsonPropertyName("name")] + public string? Name { get; set; } } -/// User-configured MCP servers, keyed by server name. -public sealed class McpConfigList +/// Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. +public sealed class CopilotUserResponseQuotaSnapshotsChat { - /// All MCP servers from user config, keyed by name. - [JsonPropertyName("servers")] - public IDictionary Servers { get => field ??= new Dictionary(); set; } -} + /// Gets or sets the entitlement value. + [JsonPropertyName("entitlement")] + public double? Entitlement { get; set; } -/// MCP server name and configuration to add to user configuration. -internal sealed class McpConfigAddRequest -{ - /// MCP server configuration (stdio process or remote HTTP/SSE). - [JsonPropertyName("config")] - public JsonElement Config { get; set; } + /// Gets or sets the has_quota value. + [JsonPropertyName("has_quota")] + public bool? HasQuota { get; set; } - /// Unique name for the MCP server. - [RegularExpression("^[^\\x00-\\x1f/\\x7f-\\x9f}]+(?:\\/[^\\x00-\\x1f/\\x7f-\\x9f}]+)*$")] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Safe for generated string properties: JSON Schema minLength/maxLength map to string length validation, not reflection over trimmed Count members")] - [MinLength(1)] - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; -} + /// Gets or sets the overage_count value. + [JsonPropertyName("overage_count")] + public double? OverageCount { get; set; } -/// MCP server name and replacement configuration to write to user configuration. -internal sealed class McpConfigUpdateRequest -{ - /// MCP server configuration (stdio process or remote HTTP/SSE). - [JsonPropertyName("config")] - public JsonElement Config { get; set; } + /// Gets or sets the overage_permitted value. + [JsonPropertyName("overage_permitted")] + public bool? OveragePermitted { get; set; } - /// Name of the MCP server to update. - [RegularExpression("^[^\\x00-\\x1f/\\x7f-\\x9f}]+(?:\\/[^\\x00-\\x1f/\\x7f-\\x9f}]+)*$")] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Safe for generated string properties: JSON Schema minLength/maxLength map to string length validation, not reflection over trimmed Count members")] - [MinLength(1)] - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; -} + /// Gets or sets the percent_remaining value. + [JsonPropertyName("percent_remaining")] + public double? PercentRemaining { get; set; } -/// MCP server name to remove from user configuration. -internal sealed class McpConfigRemoveRequest -{ - /// Name of the MCP server to remove. - [RegularExpression("^[^\\x00-\\x1f/\\x7f-\\x9f}]+(?:\\/[^\\x00-\\x1f/\\x7f-\\x9f}]+)*$")] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Safe for generated string properties: JSON Schema minLength/maxLength map to string length validation, not reflection over trimmed Count members")] - [MinLength(1)] - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; -} + /// Gets or sets the quota_id value. + [JsonPropertyName("quota_id")] + public string? QuotaId { get; set; } -/// MCP server names to enable for new sessions. -internal sealed class McpConfigEnableRequest -{ - /// Names of MCP servers to enable. Each server is removed from the persisted disabled list so new sessions spawn it. Unknown or already-enabled names are ignored. - [JsonPropertyName("names")] - public IList Names { get => field ??= []; set; } -} + /// Gets or sets the quota_remaining value. + [JsonPropertyName("quota_remaining")] + public double? QuotaRemaining { get; set; } -/// MCP server names to disable for new sessions. -internal sealed class McpConfigDisableRequest -{ - /// Names of MCP servers to disable. Each server is added to the persisted disabled list so new sessions skip it. Already-disabled names are ignored. Active sessions keep their current connections until they end. - [JsonPropertyName("names")] - public IList Names { get => field ??= []; set; } -} + /// Gets or sets the quota_reset_at value. + [JsonPropertyName("quota_reset_at")] + public double? QuotaResetAt { get; set; } -/// Information about an installed plugin tracked in global state. -[Experimental(Diagnostics.Experimental)] -public sealed class InstalledPluginInfo -{ - /// Whether the plugin is currently enabled for new sessions. - [JsonPropertyName("enabled")] - public bool Enabled { get; set; } + /// Gets or sets the remaining value. + [JsonPropertyName("remaining")] + public double? Remaining { get; set; } - /// Marketplace the plugin came from. Empty string ("") for direct repo / URL / local installs. - [JsonPropertyName("marketplace")] - public string Marketplace { get; set; } = string.Empty; + /// Gets or sets the timestamp_utc value. + [JsonPropertyName("timestamp_utc")] + public string? TimestampUtc { get; set; } - /// Plugin name. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// Gets or sets the token_based_billing value. + [JsonPropertyName("token_based_billing")] + public bool? TokenBasedBilling { get; set; } - /// Installed version (when reported by the plugin manifest). - [JsonPropertyName("version")] - public string? Version { get; set; } + /// Gets or sets the unlimited value. + [JsonPropertyName("unlimited")] + public bool? Unlimited { get; set; } } -/// Plugins installed in user/global state. -[Experimental(Diagnostics.Experimental)] -public sealed class PluginListResult +/// Schema for the `CopilotUserResponseQuotaSnapshotsCompletions` type. +public sealed class CopilotUserResponseQuotaSnapshotsCompletions { - /// Installed plugins. - [JsonPropertyName("plugins")] - public IList Plugins { get => field ??= []; set; } -} + /// Gets or sets the entitlement value. + [JsonPropertyName("entitlement")] + public double? Entitlement { get; set; } -/// Result of installing a plugin. -[Experimental(Diagnostics.Experimental)] -public sealed class PluginInstallResult -{ - /// Set when the install path is deprecated (e.g. direct repo / URL / local installs). Callers should surface this to end users. - [JsonPropertyName("deprecationWarning")] - public string? DeprecationWarning { get; set; } + /// Gets or sets the has_quota value. + [JsonPropertyName("has_quota")] + public bool? HasQuota { get; set; } - /// The newly installed plugin's metadata. - [JsonPropertyName("plugin")] - public InstalledPluginInfo Plugin { get => field ??= new(); set; } + /// Gets or sets the overage_count value. + [JsonPropertyName("overage_count")] + public double? OverageCount { get; set; } - /// Optional post-install message provided by the plugin (e.g. setup instructions). - [JsonPropertyName("postInstallMessage")] - public string? PostInstallMessage { get; set; } + /// Gets or sets the overage_permitted value. + [JsonPropertyName("overage_permitted")] + public bool? OveragePermitted { get; set; } - /// Number of skills discovered and installed from the plugin. - [JsonPropertyName("skillsInstalled")] - public long SkillsInstalled { get; set; } -} + /// Gets or sets the percent_remaining value. + [JsonPropertyName("percent_remaining")] + public double? PercentRemaining { get; set; } -/// Plugin source and optional working directory for relative-path resolution. -[Experimental(Diagnostics.Experimental)] -internal sealed class PluginsInstallRequest -{ - /// Plugin install spec. Accepts the same forms as the CLI: "plugin@marketplace" (marketplace install), "owner/repo" or "owner/repo:subpath" (GitHub direct), an http/https/ssh URL, or a local path. Direct (non-marketplace) installs are deprecated and will produce a deprecationWarning in the result. - [JsonPropertyName("source")] - public string Source { get; set; } = string.Empty; + /// Gets or sets the quota_id value. + [JsonPropertyName("quota_id")] + public string? QuotaId { get; set; } - /// Working directory used to resolve relative local paths in `source`. Defaults to the server's current working directory. - [JsonPropertyName("workingDirectory")] - public string? WorkingDirectory { get; set; } -} + /// Gets or sets the quota_remaining value. + [JsonPropertyName("quota_remaining")] + public double? QuotaRemaining { get; set; } -/// Name (or spec) of the plugin to uninstall. -[Experimental(Diagnostics.Experimental)] -internal sealed class PluginsUninstallRequest -{ - /// Plugin name or "plugin@marketplace" spec to uninstall. When ambiguous, prefer the fully-qualified spec. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; -} + /// Gets or sets the quota_reset_at value. + [JsonPropertyName("quota_reset_at")] + public double? QuotaResetAt { get; set; } -/// Result of updating a single plugin. -[Experimental(Diagnostics.Experimental)] -public sealed class PluginUpdateResult -{ - /// Version after the update, when reported by the plugin manifest. - [JsonPropertyName("newVersion")] - public string? NewVersion { get; set; } + /// Gets or sets the remaining value. + [JsonPropertyName("remaining")] + public double? Remaining { get; set; } - /// Version that was previously installed, when available. - [JsonPropertyName("previousVersion")] - public string? PreviousVersion { get; set; } + /// Gets or sets the timestamp_utc value. + [JsonPropertyName("timestamp_utc")] + public string? TimestampUtc { get; set; } - /// Number of skills discovered and installed after the update. - [JsonPropertyName("skillsInstalled")] - public long SkillsInstalled { get; set; } -} + /// Gets or sets the token_based_billing value. + [JsonPropertyName("token_based_billing")] + public bool? TokenBasedBilling { get; set; } -/// Name (or spec) of the plugin to update. -[Experimental(Diagnostics.Experimental)] -internal sealed class PluginsUpdateRequest -{ - /// Plugin name or "plugin@marketplace" spec to update. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// Gets or sets the unlimited value. + [JsonPropertyName("unlimited")] + public bool? Unlimited { get; set; } } -/// Schema for the `PluginUpdateAllEntry` type. -[Experimental(Diagnostics.Experimental)] -public sealed class PluginUpdateAllEntry +/// Schema for the `CopilotUserResponseQuotaSnapshotsPremiumInteractions` type. +public sealed class CopilotUserResponseQuotaSnapshotsPremiumInteractions { - /// Error message (failure only). - [JsonPropertyName("error")] - public string? Error { get; set; } + /// Gets or sets the entitlement value. + [JsonPropertyName("entitlement")] + public double? Entitlement { get; set; } - /// Marketplace the plugin came from. Empty string ("") for direct installs. - [JsonPropertyName("marketplace")] - public string Marketplace { get; set; } = string.Empty; + /// Gets or sets the has_quota value. + [JsonPropertyName("has_quota")] + public bool? HasQuota { get; set; } - /// Plugin name that was updated. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// Gets or sets the overage_count value. + [JsonPropertyName("overage_count")] + public double? OverageCount { get; set; } - /// Version after the update, when available. - [JsonPropertyName("newVersion")] - public string? NewVersion { get; set; } + /// Gets or sets the overage_permitted value. + [JsonPropertyName("overage_permitted")] + public bool? OveragePermitted { get; set; } - /// Previously installed version, when available. - [JsonPropertyName("previousVersion")] - public string? PreviousVersion { get; set; } + /// Gets or sets the percent_remaining value. + [JsonPropertyName("percent_remaining")] + public double? PercentRemaining { get; set; } - /// Number of skills installed after the update (success only). - [JsonPropertyName("skillsInstalled")] - public long? SkillsInstalled { get; set; } + /// Gets or sets the quota_id value. + [JsonPropertyName("quota_id")] + public string? QuotaId { get; set; } - /// Whether the update succeeded for this plugin. - [JsonPropertyName("success")] - public bool Success { get; set; } + /// Gets or sets the quota_remaining value. + [JsonPropertyName("quota_remaining")] + public double? QuotaRemaining { get; set; } + + /// Gets or sets the quota_reset_at value. + [JsonPropertyName("quota_reset_at")] + public double? QuotaResetAt { get; set; } + + /// Gets or sets the remaining value. + [JsonPropertyName("remaining")] + public double? Remaining { get; set; } + + /// Gets or sets the timestamp_utc value. + [JsonPropertyName("timestamp_utc")] + public string? TimestampUtc { get; set; } + + /// Gets or sets the token_based_billing value. + [JsonPropertyName("token_based_billing")] + public bool? TokenBasedBilling { get; set; } + + /// Gets or sets the unlimited value. + [JsonPropertyName("unlimited")] + public bool? Unlimited { get; set; } } -/// Result of updating all installed plugins. -[Experimental(Diagnostics.Experimental)] -public sealed class PluginUpdateAllResult +/// Schema for the `CopilotUserResponseQuotaSnapshots` type. +public sealed class CopilotUserResponseQuotaSnapshots { - /// Per-plugin update results in deterministic order. - [JsonPropertyName("results")] - public IList Results { get => field ??= []; set; } + /// Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. + [JsonPropertyName("chat")] + public CopilotUserResponseQuotaSnapshotsChat? Chat { get; set; } + + /// Schema for the `CopilotUserResponseQuotaSnapshotsCompletions` type. + [JsonPropertyName("completions")] + public CopilotUserResponseQuotaSnapshotsCompletions? Completions { get; set; } + + /// Schema for the `CopilotUserResponseQuotaSnapshotsPremiumInteractions` type. + [JsonPropertyName("premium_interactions")] + public CopilotUserResponseQuotaSnapshotsPremiumInteractions? PremiumInteractions { get; set; } } -/// Plugin names (or specs) to enable. -[Experimental(Diagnostics.Experimental)] -internal sealed class PluginsEnableRequest +/// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. +public sealed class CopilotUserResponse { - /// Plugin names or "plugin@marketplace" specs to enable. Unknown names are ignored. Non-marketplace direct installs are always enabled and cannot be toggled via this API. - [JsonPropertyName("names")] - public IList Names { get => field ??= []; set; } + /// Gets or sets the access_type_sku value. + [JsonPropertyName("access_type_sku")] + public string? AccessTypeSku { get; set; } + + /// Gets or sets the analytics_tracking_id value. + [JsonPropertyName("analytics_tracking_id")] + public string? AnalyticsTrackingId { get; set; } + + /// Gets or sets the assigned_date value. + [JsonPropertyName("assigned_date")] + public string? AssignedDate { get; set; } + + /// Gets or sets the can_signup_for_limited value. + [JsonPropertyName("can_signup_for_limited")] + public bool? CanSignupForLimited { get; set; } + + /// Gets or sets the can_upgrade_plan value. + [JsonPropertyName("can_upgrade_plan")] + public bool? CanUpgradePlan { get; set; } + + /// Gets or sets the chat_enabled value. + [JsonPropertyName("chat_enabled")] + public bool? ChatEnabled { get; set; } + + /// Gets or sets the cli_remote_control_enabled value. + [JsonPropertyName("cli_remote_control_enabled")] + public bool? CliRemoteControlEnabled { get; set; } + + /// Gets or sets the cloud_session_storage_enabled value. + [JsonPropertyName("cloud_session_storage_enabled")] + public bool? CloudSessionStorageEnabled { get; set; } + + /// Gets or sets the codex_agent_enabled value. + [JsonPropertyName("codex_agent_enabled")] + public bool? CodexAgentEnabled { get; set; } + + /// Gets or sets the copilot_plan value. + [JsonPropertyName("copilot_plan")] + public string? CopilotPlan { get; set; } + + /// Gets or sets the copilotignore_enabled value. + [JsonPropertyName("copilotignore_enabled")] + public bool? CopilotignoreEnabled { get; set; } + + /// Schema for the `CopilotUserResponseEndpoints` type. + [JsonPropertyName("endpoints")] + public CopilotUserResponseEndpoints? Endpoints { get; set; } + + /// Gets or sets the is_mcp_enabled value. + [JsonPropertyName("is_mcp_enabled")] + public bool? IsMcpEnabled { get; set; } + + /// Gets or sets the is_staff value. + [JsonPropertyName("is_staff")] + public bool? IsStaff { get; set; } + + /// Gets or sets the limited_user_quotas value. + [JsonPropertyName("limited_user_quotas")] + public IDictionary? LimitedUserQuotas { get; set; } + + /// Gets or sets the limited_user_reset_date value. + [JsonPropertyName("limited_user_reset_date")] + public string? LimitedUserResetDate { get; set; } + + /// Gets or sets the login value. + [JsonPropertyName("login")] + public string? Login { get; set; } + + /// Gets or sets the monthly_quotas value. + [JsonPropertyName("monthly_quotas")] + public IDictionary? MonthlyQuotas { get; set; } + + /// Gets or sets the organization_list value. + [JsonPropertyName("organization_list")] + public IList? OrganizationList { get; set; } + + /// Gets or sets the organization_login_list value. + [JsonPropertyName("organization_login_list")] + public IList? OrganizationLoginList { get; set; } + + /// Gets or sets the quota_reset_date value. + [JsonPropertyName("quota_reset_date")] + public string? QuotaResetDate { get; set; } + + /// Gets or sets the quota_reset_date_utc value. + [JsonPropertyName("quota_reset_date_utc")] + public string? QuotaResetDateUtc { get; set; } + + /// Schema for the `CopilotUserResponseQuotaSnapshots` type. + [JsonPropertyName("quota_snapshots")] + public CopilotUserResponseQuotaSnapshots? QuotaSnapshots { get; set; } + + /// Gets or sets the restricted_telemetry value. + [JsonPropertyName("restricted_telemetry")] + public bool? RestrictedTelemetry { get; set; } + + /// Gets or sets the token_based_billing value. + [JsonPropertyName("token_based_billing")] + public bool? TokenBasedBilling { get; set; } } -/// Plugin names (or specs) to disable. -[Experimental(Diagnostics.Experimental)] -internal sealed class PluginsDisableRequest +/// Schema for the `HMACAuthInfo` type. +/// The hmac variant of . +public partial class AuthInfoHmac : AuthInfo { - /// Plugin names or "plugin@marketplace" specs to disable. Unknown names are ignored. Non-marketplace direct installs cannot be disabled via this API; uninstall them instead. Plugin-owned MCP servers are stopped in active sessions immediately; other plugin contributions remain available until each session reloads plugins. - [JsonPropertyName("names")] - public IList Names { get => field ??= []; set; } + /// + [JsonIgnore] + public override string Type => "hmac"; + + /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("copilotUser")] + public CopilotUserResponse? CopilotUser { get; set; } + + /// HMAC secret used to sign requests. + [JsonPropertyName("hmac")] + public required string Hmac { get; set; } + + /// Authentication host. HMAC auth always targets the public GitHub host. + [JsonPropertyName("host")] + public required string Host { get; set; } } -/// Registered marketplace summary. -[Experimental(Diagnostics.Experimental)] -public sealed class MarketplaceInfo +/// Schema for the `EnvAuthInfo` type. +/// The env variant of . +public partial class AuthInfoEnv : AuthInfo { - /// True when this is a default marketplace shipped with the runtime. Defaults are not removable. - [JsonPropertyName("isDefault")] - public bool? IsDefault { get; set; } + /// + [JsonIgnore] + public override string Type => "env"; - /// Marketplace name (matches the @marketplace suffix in plugin specs). - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("copilotUser")] + public CopilotUserResponse? CopilotUser { get; set; } - /// Human-readable description of where the marketplace data is fetched from (e.g. "GitHub: owner/repo"). - [JsonPropertyName("source")] - public string Source { get; set; } = string.Empty; + /// Name of the environment variable the token was sourced from. + [JsonPropertyName("envVar")] + public required string EnvVar { get; set; } + + /// Authentication host (e.g. https://github.com or a GHES host). + [JsonPropertyName("host")] + public required string Host { get; set; } + + /// User login associated with the token. Undefined for server-to-server tokens (those starting with `ghs_`). + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("login")] + public string? Login { get; set; } + + /// The token value itself. Treat as a secret. + [JsonPropertyName("token")] + public required string Token { get; set; } } -/// All registered marketplaces, including built-in defaults. -[Experimental(Diagnostics.Experimental)] -public sealed class MarketplaceListResult +/// Schema for the `TokenAuthInfo` type. +/// The token variant of . +public partial class AuthInfoToken : AuthInfo { - /// Registered marketplaces. - [JsonPropertyName("marketplaces")] - public IList Marketplaces { get => field ??= []; set; } + /// + [JsonIgnore] + public override string Type => "token"; + + /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("copilotUser")] + public CopilotUserResponse? CopilotUser { get; set; } + + /// Authentication host. + [JsonPropertyName("host")] + public required string Host { get; set; } + + /// The token value itself. Treat as a secret. + [JsonPropertyName("token")] + public required string Token { get; set; } } -/// Result of registering a new marketplace. -[Experimental(Diagnostics.Experimental)] -public sealed class MarketplaceAddResult +/// Schema for the `CopilotApiTokenAuthInfo` type. +/// The copilot-api-token variant of . +public partial class AuthInfoCopilotApiToken : AuthInfo { - /// Final name of the marketplace as resolved from its manifest. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// + [JsonIgnore] + public override string Type => "copilot-api-token"; + + /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("copilotUser")] + public CopilotUserResponse? CopilotUser { get; set; } + + /// Authentication host (always the public GitHub host). + [JsonPropertyName("host")] + public required string Host { get; set; } } -/// Marketplace source to register. -[Experimental(Diagnostics.Experimental)] -internal sealed class PluginsMarketplacesAddRequest +/// Schema for the `UserAuthInfo` type. +/// The user variant of . +public partial class AuthInfoUser : AuthInfo { - /// Marketplace source. Accepts the same forms as the CLI: "owner/repo" or "owner/repo#ref" (GitHub), an http/https/ssh URL (optionally with #ref), a git scp-style URL (user@host:path), or a local path. The marketplace's own name (from its manifest) is used as the registration key. - [JsonPropertyName("source")] - public string Source { get; set; } = string.Empty; + /// + [JsonIgnore] + public override string Type => "user"; + + /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("copilotUser")] + public CopilotUserResponse? CopilotUser { get; set; } + + /// Authentication host. + [JsonPropertyName("host")] + public required string Host { get; set; } + + /// OAuth user login. + [JsonPropertyName("login")] + public required string Login { get; set; } } -/// Outcome of the remove attempt, including dependent-plugin info when applicable. -[Experimental(Diagnostics.Experimental)] -public sealed class MarketplaceRemoveResult +/// Schema for the `GhCliAuthInfo` type. +/// The gh-cli variant of . +public partial class AuthInfoGhCli : AuthInfo { - /// Names of installed plugins that prevented removal. Populated only when `removed=false`. - [JsonPropertyName("dependentPlugins")] - public IList? DependentPlugins { get; set; } + /// + [JsonIgnore] + public override string Type => "gh-cli"; - /// True when the marketplace was actually removed. False when removal was skipped because the marketplace has dependent plugins and `force` was not set. - [JsonPropertyName("removed")] - public bool Removed { get; set; } + /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("copilotUser")] + public CopilotUserResponse? CopilotUser { get; set; } + + /// Authentication host. + [JsonPropertyName("host")] + public required string Host { get; set; } + + /// User login as reported by `gh auth status`. + [JsonPropertyName("login")] + public required string Login { get; set; } + + /// The token returned by `gh auth token`. Treat as a secret. + [JsonPropertyName("token")] + public required string Token { get; set; } } -/// Name of the marketplace to remove and an optional force flag. -[Experimental(Diagnostics.Experimental)] -internal sealed class PluginsMarketplacesRemoveRequest +/// Schema for the `ApiKeyAuthInfo` type. +/// The api-key variant of . +public partial class AuthInfoApiKey : AuthInfo { - /// When true, also uninstall every plugin sourced from this marketplace. When false (default), removal is a no-op if any plugin from this marketplace is installed and the dependent plugin names are returned in the result. - [JsonPropertyName("force")] - public bool? Force { get; set; } + /// + [JsonIgnore] + public override string Type => "api-key"; - /// Marketplace name to remove. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// The API key. Treat as a secret. + [JsonPropertyName("apiKey")] + public required string ApiKey { get; set; } + + /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("copilotUser")] + public CopilotUserResponse? CopilotUser { get; set; } + + /// Authentication host. + [JsonPropertyName("host")] + public required string Host { get; set; } } -/// Plugin entry advertised by a marketplace. -[Experimental(Diagnostics.Experimental)] -public sealed class MarketplacePluginInfo +/// Current authentication state. +public sealed class AccountGetCurrentAuthResult { - /// Short description from the marketplace catalog, when present. - [JsonPropertyName("description")] - public string? Description { get; set; } + /// Authentication errors from the last auth attempt, if any. + [JsonPropertyName("authErrors")] + public IList? AuthErrors { get; set; } - /// Plugin name as listed in the marketplace catalog. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// Current authentication information, if authenticated. + [JsonPropertyName("authInfo")] + public AuthInfo? AuthInfo { get; set; } } -/// Plugins advertised by the marketplace. -[Experimental(Diagnostics.Experimental)] -public sealed class MarketplaceBrowseResult +/// Schema for the `AccountAllUsers` type. +public sealed class AccountAllUsers { - /// Plugins advertised by the marketplace. - [JsonPropertyName("plugins")] - public IList Plugins { get => field ??= []; set; } + /// Authentication information for this user. + [JsonPropertyName("authInfo")] + public AuthInfo AuthInfo { get => field ??= new(); set; } + + /// Associated token, if available. + [JsonPropertyName("token")] + public string? Token { get; set; } } -/// Name of the marketplace whose plugin catalog to fetch. -[Experimental(Diagnostics.Experimental)] -internal sealed class PluginsMarketplacesBrowseRequest +/// Result of a successful login; throws on failure. +public sealed class AccountLoginResult { - /// Marketplace name to browse. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// Whether the credential was persisted to a secure store (system keychain, or the config file when plaintext storage is enabled). False when no secure store was available and the token was not saved, so the consumer can decide how to proceed. + [JsonPropertyName("storedInVault")] + public bool StoredInVault { get; set; } } -/// Schema for the `MarketplaceRefreshEntry` type. -[Experimental(Diagnostics.Experimental)] -public sealed class MarketplaceRefreshEntry +/// Credentials to store after successful authentication. +internal sealed class AccountLoginRequest { - /// Error message (failure only). - [JsonPropertyName("error")] - public string? Error { get; set; } + /// GitHub host URL. + [JsonPropertyName("host")] + public string Host { get; set; } = string.Empty; - /// Marketplace name that was refreshed. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// User login/username. + [JsonPropertyName("login")] + public string Login { get; set; } = string.Empty; - /// Whether the refresh succeeded. - [JsonPropertyName("success")] - public bool Success { get; set; } + /// GitHub authentication token. + [JsonPropertyName("token")] + public string Token { get; set; } = string.Empty; } -/// Result of refreshing one or more marketplace catalogs. -[Experimental(Diagnostics.Experimental)] -public sealed class MarketplaceRefreshResult +/// Logout result indicating if more users remain. +public sealed class AccountLogoutResult { - /// Per-marketplace refresh results in deterministic order. - [JsonPropertyName("results")] - public IList Results { get => field ??= []; set; } + /// Whether other authenticated users remain after logout. + [JsonPropertyName("hasMoreUsers")] + public bool HasMoreUsers { get; set; } } -/// RPC data type for PluginsMarketplacesRefresh operations. -[Experimental(Diagnostics.Experimental)] -internal sealed class PluginsMarketplacesRefreshRequest +/// User to log out. +internal sealed class AccountLogoutRequest { - /// Marketplace name to refresh. When omitted, every registered marketplace is refreshed. - [JsonPropertyName("name")] - public string? Name { get; set; } + /// Authentication information for the user to log out. + [JsonPropertyName("authInfo")] + public AuthInfo AuthInfo { get => field ??= new(); set; } +} + +/// Confirmation that the secret values were registered. +public sealed class SecretsAddFilterValuesResult +{ + /// Whether the values were successfully registered. + [JsonPropertyName("ok")] + public bool Ok { get; set; } } -/// Schema for the `ServerSkill` type. -public sealed class ServerSkill +/// Secret values to add to the redaction filter. +internal sealed class SecretsAddFilterValuesRequest { - /// Description of what the skill does. - [JsonPropertyName("description")] - public string Description { get; set; } = string.Empty; + /// Raw secret values to register for redaction. + [JsonPropertyName("values")] + public IList Values { get => field ??= []; set; } +} - /// Whether the skill is currently enabled (based on global config). +/// Schema for the `DiscoveredMcpServer` type. +public sealed class DiscoveredMcpServer +{ + /// Whether the server is enabled (not in the disabled list). [JsonPropertyName("enabled")] public bool Enabled { get; set; } - /// Unique identifier for the skill. + /// Server name (config key). + [RegularExpression("^[^\\x00-\\x1f/\\x7f-\\x9f}]+(?:\\/[^\\x00-\\x1f/\\x7f-\\x9f}]+)*$")] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Safe for generated string properties: JSON Schema minLength/maxLength map to string length validation, not reflection over trimmed Count members")] + [MinLength(1)] [JsonPropertyName("name")] public string Name { get; set; } = string.Empty; - /// Absolute path to the skill file. - [JsonPropertyName("path")] - public string? Path { get; set; } + /// Configuration source: user, workspace, plugin, or builtin. + [JsonPropertyName("source")] + public McpServerSource Source { get; set; } - /// The project path this skill belongs to (only for project/inherited skills). - [JsonPropertyName("projectPath")] - public string? ProjectPath { get; set; } + /// Plugin name that provided this server, when source is plugin. + [JsonPropertyName("sourcePlugin")] + public string? SourcePlugin { get; set; } - /// Source location type (e.g., project, personal-copilot, plugin, builtin). - [JsonPropertyName("source")] - public SkillSource Source { get; set; } + /// Plugin version that provided this server, when source is plugin. + [JsonPropertyName("sourcePluginVersion")] + public string? SourcePluginVersion { get; set; } - /// Whether the skill can be invoked by the user as a slash command. - [JsonPropertyName("userInvocable")] - public bool UserInvocable { get; set; } + /// Server transport type: stdio, http, sse (deprecated), or memory. + [JsonPropertyName("type")] + public DiscoveredMcpServerType? Type { get; set; } } -/// Skills discovered across global and project sources. -public sealed class ServerSkillList +/// MCP servers discovered from user, workspace, plugin, and built-in sources. +public sealed class McpDiscoverResult { - /// All discovered skills across all sources. - [JsonPropertyName("skills")] - public IList Skills { get => field ??= []; set; } + /// MCP servers discovered from all sources. + [JsonPropertyName("servers")] + public IList Servers { get => field ??= []; set; } } -/// Optional project paths and additional skill directories to include in discovery. -internal sealed class SkillsDiscoverRequest +/// Optional working directory used as context for MCP server discovery. +internal sealed class McpDiscoverRequest { - /// When true, omit skills from the host's global sources (personal, custom, plugin, and built-in), returning only project-scoped skills. For multitenant deployments. - [JsonPropertyName("excludeHostSkills")] - public bool? ExcludeHostSkills { get; set; } - - /// Optional list of project directory paths to scan for project-scoped skills. - [JsonPropertyName("projectPaths")] - public IList? ProjectPaths { get; set; } + /// Working directory used as context for discovery (e.g., plugin resolution). + [JsonPropertyName("workingDirectory")] + public string? WorkingDirectory { get; set; } +} - /// Optional list of additional skill directory paths to include. - [JsonPropertyName("skillDirectories")] - public IList? SkillDirectories { get; set; } +/// User-configured MCP servers, keyed by server name. +public sealed class McpConfigList +{ + /// All MCP servers from user config, keyed by name. + [JsonPropertyName("servers")] + public IDictionary Servers { get => field ??= new Dictionary(); set; } } -/// Schema for the `SkillDiscoveryPath` type. -[Experimental(Diagnostics.Experimental)] -public sealed class SkillDiscoveryPath +/// MCP server name and configuration to add to user configuration. +internal sealed class McpConfigAddRequest { - /// Absolute path of the create/discovery target (may not exist on disk yet). - [JsonPropertyName("path")] - public string Path { get; set; } = string.Empty; + /// MCP server configuration (stdio process or remote HTTP/SSE). + [JsonPropertyName("config")] + public JsonElement Config { get; set; } - /// Whether this is the canonical directory to create a new skill in its tier. At most one entry per tier is preferred; the `personal-agents` and `custom` scopes are never preferred. - [JsonPropertyName("preferredForCreation")] - public bool PreferredForCreation { get; set; } + /// Unique name for the MCP server. + [RegularExpression("^[^\\x00-\\x1f/\\x7f-\\x9f}]+(?:\\/[^\\x00-\\x1f/\\x7f-\\x9f}]+)*$")] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Safe for generated string properties: JSON Schema minLength/maxLength map to string length validation, not reflection over trimmed Count members")] + [MinLength(1)] + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; +} - /// The input project path this directory was derived from (only for project scope). - [JsonPropertyName("projectPath")] - public string? ProjectPath { get; set; } +/// MCP server name and replacement configuration to write to user configuration. +internal sealed class McpConfigUpdateRequest +{ + /// MCP server configuration (stdio process or remote HTTP/SSE). + [JsonPropertyName("config")] + public JsonElement Config { get; set; } - /// Which tier this directory belongs to. - [JsonPropertyName("scope")] - public SkillDiscoveryScope Scope { get; set; } + /// Name of the MCP server to update. + [RegularExpression("^[^\\x00-\\x1f/\\x7f-\\x9f}]+(?:\\/[^\\x00-\\x1f/\\x7f-\\x9f}]+)*$")] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Safe for generated string properties: JSON Schema minLength/maxLength map to string length validation, not reflection over trimmed Count members")] + [MinLength(1)] + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; } -/// Canonical locations where skills can be created so the runtime will recognize them. -[Experimental(Diagnostics.Experimental)] -public sealed class SkillDiscoveryPathList +/// MCP server name to remove from user configuration. +internal sealed class McpConfigRemoveRequest { - /// Canonical skill create/discovery directories, in priority order. - [JsonPropertyName("paths")] - public IList Paths { get => field ??= []; set; } + /// Name of the MCP server to remove. + [RegularExpression("^[^\\x00-\\x1f/\\x7f-\\x9f}]+(?:\\/[^\\x00-\\x1f/\\x7f-\\x9f}]+)*$")] + [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Safe for generated string properties: JSON Schema minLength/maxLength map to string length validation, not reflection over trimmed Count members")] + [MinLength(1)] + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; } -/// Optional project paths to enumerate. -[Experimental(Diagnostics.Experimental)] -internal sealed class SkillsGetDiscoveryPathsRequest +/// MCP server names to enable for new sessions. +internal sealed class McpConfigEnableRequest { - /// When true, omit the host's personal and custom skill directories, leaving only project directories. For multitenant deployments. - [JsonPropertyName("excludeHostSkills")] - public bool? ExcludeHostSkills { get; set; } - - /// Optional list of project directory paths. When omitted or empty, only personal and custom directories are returned. - [JsonPropertyName("projectPaths")] - public IList? ProjectPaths { get; set; } + /// Names of MCP servers to enable. Each server is removed from the persisted disabled list so new sessions spawn it. Unknown or already-enabled names are ignored. + [JsonPropertyName("names")] + public IList Names { get => field ??= []; set; } } -/// Skill names to mark as disabled in global configuration, replacing any previous list. -internal sealed class SkillsConfigSetDisabledSkillsRequest +/// MCP server names to disable for new sessions. +internal sealed class McpConfigDisableRequest { - /// List of skill names to disable. - [JsonPropertyName("disabledSkills")] - public IList DisabledSkills { get => field ??= []; set; } + /// Names of MCP servers to disable. Each server is added to the persisted disabled list so new sessions skip it. Already-disabled names are ignored. Active sessions keep their current connections until they end. + [JsonPropertyName("names")] + public IList Names { get => field ??= []; set; } } -/// Schema for the `AgentInfo` type. +/// Information about an installed plugin tracked in global state. [Experimental(Diagnostics.Experimental)] -public sealed class AgentInfo +public sealed class InstalledPluginInfo { - /// Description of the agent's purpose. - [JsonPropertyName("description")] - public string Description { get; set; } = string.Empty; - - /// Human-readable display name. - [JsonPropertyName("displayName")] - public string DisplayName { get; set; } = string.Empty; - - /// Stable identifier for selection. For most agents this is the same as `name`; for plugin/builtin agents it may differ. Always populated; defaults to `name` when no distinct id was assigned. - [JsonPropertyName("id")] - public string Id { get; set; } = string.Empty; - - /// MCP server configurations attached to this agent, keyed by server name. Server config shape mirrors the MCP `mcpServers` schema. - [Experimental(Diagnostics.Experimental)] - [JsonPropertyName("mcpServers")] - public IDictionary? McpServers { get; set; } + /// Whether the plugin is currently enabled for new sessions. + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } - /// Preferred model id for this agent. When omitted, inherits the outer agent's model. - [JsonPropertyName("model")] - public string? Model { get; set; } + /// Marketplace the plugin came from. Empty string ("") for direct repo / URL / local installs. + [JsonPropertyName("marketplace")] + public string Marketplace { get; set; } = string.Empty; - /// Unique identifier of the custom agent. + /// Plugin name. [JsonPropertyName("name")] public string Name { get; set; } = string.Empty; - /// Absolute local file path of the agent definition. Only set for file-based agents loaded from disk; remote agents do not have a path. - [JsonPropertyName("path")] - public string? Path { get; set; } - - /// Skill names preloaded into this agent's context. Omitted means none. - [JsonPropertyName("skills")] - public IList? Skills { get; set; } - - /// Where the agent definition was loaded from. - [JsonPropertyName("source")] - public AgentInfoSource? Source { get; set; } - - /// Allowed tool names for this agent. Empty array means none; omitted means inherit defaults. - [JsonPropertyName("tools")] - public IList? Tools { get; set; } - - /// Whether the agent can be selected directly by the user. Agents marked `false` are subagent-only. - [JsonPropertyName("userInvocable")] - public bool? UserInvocable { get; set; } -} - -/// Agents discovered across user, project, plugin, and remote sources. -[Experimental(Diagnostics.Experimental)] -public sealed class ServerAgentList -{ - /// All discovered agents across all sources. - [JsonPropertyName("agents")] - public IList Agents { get => field ??= []; set; } + /// Installed version (when reported by the plugin manifest). + [JsonPropertyName("version")] + public string? Version { get; set; } } -/// Optional project paths to include in agent discovery. +/// Plugins installed in user/global state. [Experimental(Diagnostics.Experimental)] -internal sealed class AgentsDiscoverRequest +public sealed class PluginListResult { - /// When true, omit the host's agents (the user-level agent directory and all plugin agents), leaving only project and remote agents. For multitenant deployments. - [JsonPropertyName("excludeHostAgents")] - public bool? ExcludeHostAgents { get; set; } - - /// Optional list of project directory paths to scan for project-scoped agents. When omitted or empty, only user/plugin/remote-independent agents are returned (no project scan). - [JsonPropertyName("projectPaths")] - public IList? ProjectPaths { get; set; } + /// Installed plugins. + [JsonPropertyName("plugins")] + public IList Plugins { get => field ??= []; set; } } -/// Schema for the `AgentDiscoveryPath` type. +/// Result of installing a plugin. [Experimental(Diagnostics.Experimental)] -public sealed class AgentDiscoveryPath +public sealed class PluginInstallResult { - /// Absolute path of the search/create directory (may not exist on disk yet). - [JsonPropertyName("path")] - public string Path { get; set; } = string.Empty; + /// Set when the install path is deprecated (e.g. direct repo / URL / local installs). Callers should surface this to end users. + [JsonPropertyName("deprecationWarning")] + public string? DeprecationWarning { get; set; } - /// Whether this is the canonical directory to create a new agent in its tier. At most one entry per tier is preferred. - [JsonPropertyName("preferredForCreation")] - public bool PreferredForCreation { get; set; } + /// The newly installed plugin's metadata. + [JsonPropertyName("plugin")] + public InstalledPluginInfo Plugin { get => field ??= new(); set; } - /// The input project path this directory was derived from (only for project scope). - [JsonPropertyName("projectPath")] - public string? ProjectPath { get; set; } + /// Optional post-install message provided by the plugin (e.g. setup instructions). + [JsonPropertyName("postInstallMessage")] + public string? PostInstallMessage { get; set; } - /// Which tier this directory belongs to. - [JsonPropertyName("scope")] - public AgentDiscoveryPathScope Scope { get; set; } + /// Number of skills discovered and installed from the plugin. + [JsonPropertyName("skillsInstalled")] + public long SkillsInstalled { get; set; } } -/// Canonical locations where custom agents can be created so the runtime will recognize them. +/// Plugin source and optional working directory for relative-path resolution. [Experimental(Diagnostics.Experimental)] -public sealed class AgentDiscoveryPathList +internal sealed class PluginsInstallRequest { - /// Canonical agent create/discovery directories, in priority order. - [JsonPropertyName("paths")] - public IList Paths { get => field ??= []; set; } + /// Plugin install spec. Accepts the same forms as the CLI: "plugin@marketplace" (marketplace install), "owner/repo" or "owner/repo:subpath" (GitHub direct), an http/https/ssh URL, or a local path. Direct (non-marketplace) installs are deprecated and will produce a deprecationWarning in the result. + [JsonPropertyName("source")] + public string Source { get; set; } = string.Empty; + + /// Working directory used to resolve relative local paths in `source`. Defaults to the server's current working directory. + [JsonPropertyName("workingDirectory")] + public string? WorkingDirectory { get; set; } } -/// Optional project paths to include when enumerating agent discovery directories. +/// Name (or spec) of the plugin to uninstall. [Experimental(Diagnostics.Experimental)] -internal sealed class AgentsGetDiscoveryPathsRequest +internal sealed class PluginsUninstallRequest { - /// When true, omit the host's user-level agent directory, leaving only project directories. For multitenant deployments (mirrors `discover`'s `excludeHostAgents`). - [JsonPropertyName("excludeHostAgents")] - public bool? ExcludeHostAgents { get; set; } - - /// Optional list of project directory paths. When omitted or empty, only the user-level directory is returned. - [JsonPropertyName("projectPaths")] - public IList? ProjectPaths { 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; } -/// Schema for the `InstructionSource` type. +/// Result of updating a single plugin. [Experimental(Diagnostics.Experimental)] -public sealed class InstructionSource +public sealed class PluginUpdateResult { - /// Glob pattern(s) from frontmatter — when set, this instruction applies only to matching files. - [JsonPropertyName("applyTo")] - public IList? ApplyTo { get; set; } + /// Version after the update, when reported by the plugin manifest. + [JsonPropertyName("newVersion")] + public string? NewVersion { get; set; } - /// Raw content of the instruction file. - [JsonPropertyName("content")] - public string Content { get; set; } = string.Empty; + /// Version that was previously installed, when available. + [JsonPropertyName("previousVersion")] + public string? PreviousVersion { get; set; } - /// When true, this source starts disabled and must be toggled on by the user. - [JsonPropertyName("defaultDisabled")] - public bool? DefaultDisabled { get; set; } + /// Number of skills discovered and installed after the update. + [JsonPropertyName("skillsInstalled")] + public long SkillsInstalled { get; set; } +} - /// Short description (body after frontmatter) for use in instruction tables. - [JsonPropertyName("description")] - public string? Description { get; set; } +/// Name (or spec) of the plugin to update. +[Experimental(Diagnostics.Experimental)] +internal sealed class PluginsUpdateRequest +{ + /// Plugin name or "plugin@marketplace" spec to update. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; +} - /// Unique identifier for this source (used for toggling). - [JsonPropertyName("id")] - public string Id { get; set; } = string.Empty; +/// Schema for the `PluginUpdateAllEntry` type. +[Experimental(Diagnostics.Experimental)] +public sealed class PluginUpdateAllEntry +{ + /// Error message (failure only). + [JsonPropertyName("error")] + public string? Error { get; set; } - /// Human-readable label. - [JsonPropertyName("label")] - public string Label { get; set; } = string.Empty; + /// Marketplace the plugin came from. Empty string ("") for direct installs. + [JsonPropertyName("marketplace")] + public string Marketplace { get; set; } = string.Empty; - /// Where this source lives — used for UI grouping. - [JsonPropertyName("location")] - public InstructionSourceLocation Location { get; set; } + /// Plugin name that was updated. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; - /// The project path this source was discovered from. Only set by sessionless discovery for repository/working-directory sources, where it disambiguates same-named files (e.g. .github/copilot-instructions.md) across multiple workspace roots. The session-scoped getSources leaves it unset. - [JsonPropertyName("projectPath")] - public string? ProjectPath { get; set; } + /// Version after the update, when available. + [JsonPropertyName("newVersion")] + public string? NewVersion { get; set; } - /// File path relative to repo or absolute for home. - [JsonPropertyName("sourcePath")] - public string SourcePath { get; set; } = string.Empty; + /// Previously installed version, when available. + [JsonPropertyName("previousVersion")] + public string? PreviousVersion { get; set; } - /// Category of instruction source — used for merge logic. - [JsonPropertyName("type")] - public InstructionSourceType Type { get; set; } + /// Number of skills installed after the update (success only). + [JsonPropertyName("skillsInstalled")] + public long? SkillsInstalled { get; set; } + + /// Whether the update succeeded for this plugin. + [JsonPropertyName("success")] + public bool Success { get; set; } } -/// Instruction sources discovered across user, repository, and plugin sources. +/// Result of updating all installed plugins. [Experimental(Diagnostics.Experimental)] -public sealed class ServerInstructionSourceList +public sealed class PluginUpdateAllResult { - /// All discovered instruction sources. - [JsonPropertyName("sources")] - public IList Sources { get => field ??= []; set; } + /// Per-plugin update results in deterministic order. + [JsonPropertyName("results")] + public IList Results { get => field ??= []; set; } } -/// Optional project paths to include in instruction discovery. +/// Plugin names (or specs) to enable. [Experimental(Diagnostics.Experimental)] -internal sealed class InstructionsDiscoverRequest +internal sealed class PluginsEnableRequest { - /// When true, omit the host's instruction sources (user/home-level files and plugin rules), leaving only repository and working-directory sources. For multitenant deployments. - [JsonPropertyName("excludeHostInstructions")] - public bool? ExcludeHostInstructions { get; set; } - - /// Optional list of project directory paths to scan for repository/working-directory instruction sources. When omitted or empty, only user-level and plugin instruction sources are returned (no project scan). - [JsonPropertyName("projectPaths")] - public IList? ProjectPaths { get; set; } + /// Plugin names or "plugin@marketplace" specs to enable. Unknown names are ignored. Non-marketplace direct installs are always enabled and cannot be toggled via this API. + [JsonPropertyName("names")] + public IList Names { get => field ??= []; set; } } -/// Schema for the `InstructionDiscoveryPath` type. +/// Plugin names (or specs) to disable. [Experimental(Diagnostics.Experimental)] -public sealed class InstructionDiscoveryPath +internal sealed class PluginsDisableRequest { - /// Whether the target is a single file or a directory of instruction files. - [JsonPropertyName("kind")] - public InstructionDiscoveryPathKind Kind { get; set; } - - /// Which tier this target belongs to. - [JsonPropertyName("location")] - public InstructionDiscoveryPathLocation Location { get; set; } + /// Plugin names or "plugin@marketplace" specs to disable. Unknown names are ignored. Non-marketplace direct installs cannot be disabled via this API; uninstall them instead. Plugin-owned MCP servers are stopped in active sessions immediately; other plugin contributions remain available until each session reloads plugins. + [JsonPropertyName("names")] + public IList Names { get => field ??= []; set; } +} - /// Absolute path of the file or directory (may not exist on disk yet). - [JsonPropertyName("path")] - public string Path { get; set; } = string.Empty; +/// Registered marketplace summary. +[Experimental(Diagnostics.Experimental)] +public sealed class MarketplaceInfo +{ + /// True when this is a default marketplace shipped with the runtime. Defaults are not removable. + [JsonPropertyName("isDefault")] + public bool? IsDefault { get; set; } - /// Whether this is the canonical target to create new instructions in its tier. At most one entry per tier is preferred. - [JsonPropertyName("preferredForCreation")] - public bool PreferredForCreation { get; set; } + /// Marketplace name (matches the @marketplace suffix in plugin specs). + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; - /// The input project path this target was derived from (only for repository targets). - [JsonPropertyName("projectPath")] - public string? ProjectPath { get; set; } + /// Human-readable description of where the marketplace data is fetched from (e.g. "GitHub: owner/repo"). + [JsonPropertyName("source")] + public string Source { get; set; } = string.Empty; } -/// Canonical files and directories where custom instructions can be created so the runtime will recognize them. +/// All registered marketplaces, including built-in defaults. [Experimental(Diagnostics.Experimental)] -public sealed class InstructionDiscoveryPathList +public sealed class MarketplaceListResult { - /// Canonical instruction create/discovery files and directories, in priority order. - [JsonPropertyName("paths")] - public IList Paths { get => field ??= []; set; } + /// Registered marketplaces. + [JsonPropertyName("marketplaces")] + public IList Marketplaces { get => field ??= []; set; } } -/// Optional project paths to include when enumerating instruction discovery targets. +/// Result of registering a new marketplace. [Experimental(Diagnostics.Experimental)] -internal sealed class InstructionsGetDiscoveryPathsRequest +public sealed class MarketplaceAddResult { - /// When true, omit the host's user-level instruction targets, leaving only repository targets. For multitenant deployments (mirrors `discover`'s `excludeHostInstructions`). - [JsonPropertyName("excludeHostInstructions")] - public bool? ExcludeHostInstructions { get; set; } - - /// Optional list of project directory paths. When omitted or empty, only the user-level targets are returned. - [JsonPropertyName("projectPaths")] - public IList? ProjectPaths { get; set; } + /// Final name of the marketplace as resolved from its manifest. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; } -/// Indicates whether the calling client was registered as the session filesystem provider. -public sealed class SessionFsSetProviderResult +/// Marketplace source to register. +[Experimental(Diagnostics.Experimental)] +internal sealed class PluginsMarketplacesAddRequest { - /// Whether the provider was set successfully. - [JsonPropertyName("success")] - public bool Success { get; set; } + /// Marketplace source. Accepts the same forms as the CLI: "owner/repo" or "owner/repo#ref" (GitHub), an http/https/ssh URL (optionally with #ref), a git scp-style URL (user@host:path), or a local path. The marketplace's own name (from its manifest) is used as the registration key. + [JsonPropertyName("source")] + public string Source { get; set; } = string.Empty; } -/// Optional capabilities declared by the provider. -public sealed class SessionFsSetProviderCapabilities +/// Outcome of the remove attempt, including dependent-plugin info when applicable. +[Experimental(Diagnostics.Experimental)] +public sealed class MarketplaceRemoveResult { - /// Whether the provider supports SQLite query/exists operations. - [JsonPropertyName("sqlite")] - public bool? Sqlite { get; set; } + /// Names of installed plugins that prevented removal. Populated only when `removed=false`. + [JsonPropertyName("dependentPlugins")] + public IList? DependentPlugins { get; set; } + + /// True when the marketplace was actually removed. False when removal was skipped because the marketplace has dependent plugins and `force` was not set. + [JsonPropertyName("removed")] + public bool Removed { get; set; } } -/// Initial working directory, session-state path layout, and path conventions used to register the calling SDK client as the session filesystem provider. -internal sealed class SessionFsSetProviderRequest +/// Name of the marketplace to remove and an optional force flag. +[Experimental(Diagnostics.Experimental)] +internal sealed class PluginsMarketplacesRemoveRequest { - /// Optional capabilities declared by the provider. - [JsonPropertyName("capabilities")] - public SessionFsSetProviderCapabilities? Capabilities { get; set; } + /// When true, also uninstall every plugin sourced from this marketplace. When false (default), removal is a no-op if any plugin from this marketplace is installed and the dependent plugin names are returned in the result. + [JsonPropertyName("force")] + public bool? Force { get; set; } - /// Path conventions used by this filesystem. - [JsonPropertyName("conventions")] - public SessionFsSetProviderConventions Conventions { get; set; } + /// Marketplace name to remove. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; +} - /// Initial working directory for sessions. - [JsonPropertyName("initialCwd")] - public string InitialCwd { get; set; } = string.Empty; +/// Plugin entry advertised by a marketplace. +[Experimental(Diagnostics.Experimental)] +public sealed class MarketplacePluginInfo +{ + /// Short description from the marketplace catalog, when present. + [JsonPropertyName("description")] + public string? Description { get; set; } - /// Path within each session's SessionFs where the runtime stores files for that session. - [JsonPropertyName("sessionStatePath")] - public string SessionStatePath { get; set; } = string.Empty; + /// Plugin name as listed in the marketplace catalog. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; } -/// Indicates whether the calling client was registered as the LLM inference provider. +/// Plugins advertised by the marketplace. [Experimental(Diagnostics.Experimental)] -public sealed class LlmInferenceSetProviderResult +public sealed class MarketplaceBrowseResult { - /// Whether the provider was set successfully. - [JsonPropertyName("success")] - public bool Success { get; set; } + /// Plugins advertised by the marketplace. + [JsonPropertyName("plugins")] + public IList Plugins { get => field ??= []; set; } } -/// Whether the start frame was accepted. +/// Name of the marketplace whose plugin catalog to fetch. [Experimental(Diagnostics.Experimental)] -public sealed class LlmInferenceHttpResponseStartResult +internal sealed class PluginsMarketplacesBrowseRequest { - /// True when the response start was matched to a pending request; false when unknown. - [JsonPropertyName("accepted")] - public bool Accepted { get; set; } + /// Marketplace name to browse. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; } -/// Response head. +/// Schema for the `MarketplaceRefreshEntry` type. [Experimental(Diagnostics.Experimental)] -internal sealed class LlmInferenceHttpResponseStartRequest +public sealed class MarketplaceRefreshEntry { - /// Gets or sets the headers value. - [JsonPropertyName("headers")] - public IDictionary> Headers { get => field ??= new Dictionary>(); set; } - - /// Matches the requestId from the originating httpRequestStart frame. - [JsonPropertyName("requestId")] - public string RequestId { get; set; } = string.Empty; + /// Error message (failure only). + [JsonPropertyName("error")] + public string? Error { get; set; } - /// HTTP status code. - [JsonPropertyName("status")] - public long Status { get; set; } + /// Marketplace name that was refreshed. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; - /// Optional HTTP status reason phrase. - [JsonPropertyName("statusText")] - public string? StatusText { get; set; } + /// Whether the refresh succeeded. + [JsonPropertyName("success")] + public bool Success { get; set; } } -/// Whether the chunk was accepted. +/// Result of refreshing one or more marketplace catalogs. [Experimental(Diagnostics.Experimental)] -public sealed class LlmInferenceHttpResponseChunkResult +public sealed class MarketplaceRefreshResult { - /// True when the chunk was matched to a pending request; false when unknown. - [JsonPropertyName("accepted")] - public bool Accepted { get; set; } + /// Per-marketplace refresh results in deterministic order. + [JsonPropertyName("results")] + public IList Results { get => field ??= []; set; } } -/// Set to terminate the response with a transport-level failure. Implies end-of-stream; any further chunks for this requestId are ignored. +/// RPC data type for PluginsMarketplacesRefresh operations. [Experimental(Diagnostics.Experimental)] -public sealed class LlmInferenceHttpResponseChunkError +internal sealed class PluginsMarketplacesRefreshRequest { - /// Optional machine-readable error code. - [JsonPropertyName("code")] - public string? Code { get; set; } - - /// Human-readable failure description. - [JsonPropertyName("message")] - public string Message { get; set; } = string.Empty; + /// Marketplace name to refresh. When omitted, every registered marketplace is refreshed. + [JsonPropertyName("name")] + public string? Name { get; set; } } -/// A response body chunk or terminal error. -[Experimental(Diagnostics.Experimental)] -internal sealed class LlmInferenceHttpResponseChunkRequest +/// Schema for the `ServerSkill` type. +public sealed class ServerSkill { - /// When true, `data` is base64-encoded bytes. When absent or false, `data` is UTF-8 text. - [JsonPropertyName("binary")] - public bool? Binary { get; set; } + /// Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field. + [JsonPropertyName("argumentHint")] + public string? ArgumentHint { get; set; } - /// Body byte range. UTF-8 text when `binary` is absent or false; base64-encoded bytes when `binary` is true. May be empty (e.g. when the response body is empty: send a single chunk with empty data and end=true). - [JsonPropertyName("data")] - public string Data { get; set; } = string.Empty; + /// Description of what the skill does. + [JsonPropertyName("description")] + public string Description { get; set; } = string.Empty; - /// When true, this is the final body chunk for the response. The runtime treats the response body as complete after receiving an end-marked chunk. - [JsonPropertyName("end")] - public bool? End { get; set; } + /// Whether the skill is currently enabled (based on global config). + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } - /// Set to terminate the response with a transport-level failure. Implies end-of-stream; any further chunks for this requestId are ignored. - [JsonPropertyName("error")] - public LlmInferenceHttpResponseChunkError? Error { get; set; } + /// Unique identifier for the skill. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; - /// Matches the requestId from the originating httpRequestStart frame. - [JsonPropertyName("requestId")] - public string RequestId { get; set; } = string.Empty; + /// Absolute path to the skill file. + [JsonPropertyName("path")] + public string? Path { get; set; } + + /// The project path this skill belongs to (only for project/inherited skills). + [JsonPropertyName("projectPath")] + public string? ProjectPath { get; set; } + + /// Source location type (e.g., project, personal-copilot, plugin, builtin). + [JsonPropertyName("source")] + public SkillSource Source { get; set; } + + /// Whether the skill can be invoked by the user as a slash command. + [JsonPropertyName("userInvocable")] + public bool UserInvocable { get; set; } } -/// Pre-resolved working-directory context for session startup. -[Experimental(Diagnostics.Experimental)] -public sealed class SessionContext +/// Skills discovered across global and project sources. +public sealed class ServerSkillList { - /// Active git branch. - [JsonPropertyName("branch")] - public string? Branch { get; set; } - - /// Most recent working directory for this session. - [JsonPropertyName("cwd")] - public string Cwd { get; set; } = string.Empty; + /// All discovered skills across all sources. + [JsonPropertyName("skills")] + public IList Skills { get => field ??= []; set; } +} - /// Git repository root, if the cwd was inside a git repo. - [JsonPropertyName("gitRoot")] - public string? GitRoot { get; set; } +/// Optional project paths and additional skill directories to include in discovery. +internal sealed class SkillsDiscoverRequest +{ + /// When true, omit skills from the host's global sources (personal, custom, plugin, and built-in), returning only project-scoped skills. For multitenant deployments. + [JsonPropertyName("excludeHostSkills")] + public bool? ExcludeHostSkills { get; set; } - /// Repository host type. - [JsonPropertyName("hostType")] - public SessionContextHostType? HostType { get; set; } + /// Optional list of project directory paths to scan for project-scoped skills. + [JsonPropertyName("projectPaths")] + public IList? ProjectPaths { get; set; } - /// Repository slug in `owner/name` form, when known. - [JsonPropertyName("repository")] - public string? Repository { get; set; } + /// Optional list of additional skill directory paths to include. + [JsonPropertyName("skillDirectories")] + public IList? SkillDirectories { get; set; } } -/// GitHub repository the remote session belongs to. +/// Schema for the `SkillDiscoveryPath` type. [Experimental(Diagnostics.Experimental)] -public sealed class RemoteSessionMetadataRepository +public sealed class SkillDiscoveryPath { - /// Branch associated with the remote session. - [JsonPropertyName("branch")] - public string Branch { get; set; } = string.Empty; + /// Absolute path of the create/discovery target (may not exist on disk yet). + [JsonPropertyName("path")] + public string Path { get; set; } = string.Empty; - /// Repository name. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// Whether this is the canonical directory to create a new skill in its tier. At most one entry per tier is preferred; the `personal-agents` and `custom` scopes are never preferred. + [JsonPropertyName("preferredForCreation")] + public bool PreferredForCreation { get; set; } - /// Repository owner. - [JsonPropertyName("owner")] - public string Owner { get; set; } = string.Empty; + /// The input project path this directory was derived from (only for project scope). + [JsonPropertyName("projectPath")] + public string? ProjectPath { get; set; } + + /// Which tier this directory belongs to. + [JsonPropertyName("scope")] + public SkillDiscoveryScope Scope { get; set; } } -/// Remote session metadata for the session to hand off (typically obtained from `sessions.list` with `source: "remote"`). +/// Canonical locations where skills can be created so the runtime will recognize them. [Experimental(Diagnostics.Experimental)] -public sealed class RemoteSessionMetadataValue +public sealed class SkillDiscoveryPathList { - /// Most recent working directory context. - [JsonPropertyName("context")] - public SessionContext? Context { get; set; } + /// Canonical skill create/discovery directories, in priority order. + [JsonPropertyName("paths")] + public IList Paths { get => field ??= []; set; } +} - /// Always true for remote sessions. - [JsonPropertyName("isRemote")] - public bool IsRemote { get; set; } +/// Optional project paths to enumerate. +[Experimental(Diagnostics.Experimental)] +internal sealed class SkillsGetDiscoveryPathsRequest +{ + /// When true, omit the host's personal and custom skill directories, leaving only project directories. For multitenant deployments. + [JsonPropertyName("excludeHostSkills")] + public bool? ExcludeHostSkills { get; set; } - /// Last-modified time as an ISO 8601 timestamp. - [JsonPropertyName("modifiedTime")] - public string ModifiedTime { get; set; } = string.Empty; + /// Optional list of project directory paths. When omitted or empty, only personal and custom directories are returned. + [JsonPropertyName("projectPaths")] + public IList? ProjectPaths { get; set; } +} - /// Optional human-friendly name set via /rename. - [JsonPropertyName("name")] - public string? Name { get; set; } +/// Skill names to mark as disabled in global configuration, replacing any previous list. +internal sealed class SkillsConfigSetDisabledSkillsRequest +{ + /// List of skill names to disable. + [JsonPropertyName("disabledSkills")] + public IList DisabledSkills { get => field ??= []; set; } +} - /// Pull request number associated with the session. - [JsonPropertyName("pullRequestNumber")] - public long? PullRequestNumber { get; set; } +/// Schema for the `AgentInfo` type. +[Experimental(Diagnostics.Experimental)] +public sealed class AgentInfo +{ + /// Description of the agent's purpose. + [JsonPropertyName("description")] + public string Description { get; set; } = string.Empty; - /// Backing remote session IDs (most recent first). - [JsonPropertyName("remoteSessionIds")] - public IList RemoteSessionIds { get => field ??= []; set; } + /// Human-readable display name. + [JsonPropertyName("displayName")] + public string DisplayName { get; set; } = string.Empty; - /// GitHub repository the remote session belongs to. - [JsonPropertyName("repository")] - public RemoteSessionMetadataRepository Repository { get => field ??= new(); set; } + /// Stable identifier for selection. For most agents this is the same as `name`; for plugin/builtin agents it may differ. Always populated; defaults to `name` when no distinct id was assigned. + [JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; - /// Original remote resource identifier (task ID or PR node ID). - [JsonPropertyName("resourceId")] - public string? ResourceId { get; set; } + /// MCP server configurations attached to this agent, keyed by server name. Server config shape mirrors the MCP `mcpServers` schema. + [Experimental(Diagnostics.Experimental)] + [JsonPropertyName("mcpServers")] + public IDictionary? McpServers { get; set; } - /// Stable session identifier. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// Preferred model id for this agent. When omitted, inherits the outer agent's model. + [JsonPropertyName("model")] + public string? Model { get; set; } - /// Deadline (ISO 8601) at which a CLI remote session becomes stale without further heartbeats. - [JsonPropertyName("staleAt")] - public string? StaleAt { get; set; } + /// Unique identifier of the custom agent. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; - /// Session creation time as an ISO 8601 timestamp. - [JsonPropertyName("startTime")] - public string StartTime { get; set; } = string.Empty; + /// Absolute local file path of the agent definition. Only set for file-based agents loaded from disk; remote agents do not have a path. + [JsonPropertyName("path")] + public string? Path { get; set; } - /// Server-side task state returned by GitHub. - [JsonPropertyName("state")] - public string? State { get; set; } + /// Skill names preloaded into this agent's context. Omitted means none. + [JsonPropertyName("skills")] + public IList? Skills { get; set; } - /// Short summary of the session, when one has been derived. - [JsonPropertyName("summary")] - public string? Summary { get; set; } + /// Where the agent definition was loaded from. + [JsonPropertyName("source")] + public AgentInfoSource? Source { get; set; } - /// Whether the remote task originated from CCA or CLI `--remote`. - [JsonPropertyName("taskType")] - public RemoteSessionMetadataTaskType? TaskType { get; set; } + /// Allowed tool names for this agent. Empty array means none; omitted means inherit defaults. + [JsonPropertyName("tools")] + public IList? Tools { get; set; } + + /// Whether the agent can be selected directly by the user. Agents marked `false` are subagent-only. + [JsonPropertyName("userInvocable")] + public bool? UserInvocable { get; set; } } -/// Schema for the `SessionsOpenProgress` type. +/// Agents discovered across user, project, plugin, and remote sources. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsOpenProgress +public sealed class ServerAgentList { - /// Optional step message. - [JsonPropertyName("message")] - public string? Message { get; set; } - - /// Step status. - [JsonPropertyName("status")] - public SessionsOpenProgressStatus Status { get; set; } - - /// Handoff step. - [JsonPropertyName("step")] - public SessionsOpenProgressStep Step { get; set; } + /// All discovered agents across all sources. + [JsonPropertyName("agents")] + public IList Agents { get => field ??= []; set; } } -/// Result of opening a session. +/// Optional project paths to include in agent discovery. [Experimental(Diagnostics.Experimental)] -public sealed class SessionOpenResult +internal sealed class AgentsDiscoverRequest { - /// Remote session metadata, present when status is `connected`. - [JsonPropertyName("metadata")] - public RemoteSessionMetadataValue? Metadata { get; set; } - - /// Handoff progress steps, present when status is `handed_off`. - [JsonPropertyName("progress")] - public IList? Progress { get; set; } + /// When true, omit the host's agents (the user-level agent directory and all plugin agents), leaving only project and remote agents. For multitenant deployments. + [JsonPropertyName("excludeHostAgents")] + public bool? ExcludeHostAgents { get; set; } - /// Remote session ID, present when status is `connected`. - [JsonPropertyName("remoteSessionId")] - public string? RemoteSessionId { get; set; } + /// Optional list of project directory paths to scan for project-scoped agents. When omitted or empty, only user/plugin/remote-independent agents are returned (no project scan). + [JsonPropertyName("projectPaths")] + public IList? ProjectPaths { get; set; } +} - /// In-process SessionClientApi handle for the opened session, returned to CLI callers as a transitional shortcut. Marked internal so the public SDK surface does not expose it; SDK consumers should construct per-session clients from `sessionId` instead. - [JsonInclude] - [JsonPropertyName("sessionApi")] - internal JsonElement? SessionApi { get; set; } +/// Schema for the `AgentDiscoveryPath` type. +[Experimental(Diagnostics.Experimental)] +public sealed class AgentDiscoveryPath +{ + /// Absolute path of the search/create directory (may not exist on disk yet). + [JsonPropertyName("path")] + public string Path { get; set; } = string.Empty; - /// Opened session ID. Omitted when status is `not_found`. - [JsonPropertyName("sessionId")] - public string? SessionId { get; set; } + /// Whether this is the canonical directory to create a new agent in its tier. At most one entry per tier is preferred. + [JsonPropertyName("preferredForCreation")] + public bool PreferredForCreation { get; set; } - /// Startup prompts queued by user-level hook configs at session creation. Only populated when status is `created`; resumed sessions return an empty array. - [JsonPropertyName("startupPrompts")] - public IList? StartupPrompts { get; set; } + /// The input project path this directory was derived from (only for project scope). + [JsonPropertyName("projectPath")] + public string? ProjectPath { get; set; } - /// Outcome of the open request. - [JsonPropertyName("status")] - public SessionsOpenStatus Status { get; set; } + /// Which tier this directory belongs to. + [JsonPropertyName("scope")] + public AgentDiscoveryPathScope Scope { get; set; } } -/// Identifier and optional friendly name assigned to the newly forked session. +/// Canonical locations where custom agents can be created so the runtime will recognize them. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsForkResult +public sealed class AgentDiscoveryPathList { - /// Friendly name assigned to the forked session, if any. - [JsonPropertyName("name")] - public string? Name { get; set; } - - /// The new forked session's ID. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// Canonical agent create/discovery directories, in priority order. + [JsonPropertyName("paths")] + public IList Paths { get => field ??= []; set; } } -/// Source session identifier to fork from, optional event-ID boundary, and optional friendly name for the new session. +/// Optional project paths to include when enumerating agent discovery directories. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsForkRequest +internal sealed class AgentsGetDiscoveryPathsRequest { - /// Optional friendly name to assign to the forked session. - [JsonPropertyName("name")] - public string? Name { get; set; } - - /// Source session ID to fork from. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// When true, omit the host's user-level agent directory, leaving only project directories. For multitenant deployments (mirrors `discover`'s `excludeHostAgents`). + [JsonPropertyName("excludeHostAgents")] + public bool? ExcludeHostAgents { get; set; } - /// Optional event ID boundary. When provided, the fork includes only events before this ID (exclusive). When omitted, all events are included. - [JsonPropertyName("toEventId")] - public string? ToEventId { get; set; } + /// Optional list of project directory paths. When omitted or empty, only the user-level directory is returned. + [JsonPropertyName("projectPaths")] + public IList? ProjectPaths { get; set; } } -/// Repository associated with the connected remote session. +/// Schema for the `InstructionSource` type. [Experimental(Diagnostics.Experimental)] -public sealed class ConnectedRemoteSessionMetadataRepository +public sealed class InstructionSource { - /// Branch associated with the remote session. - [JsonPropertyName("branch")] - public string Branch { get; set; } = string.Empty; - - /// Repository name. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; + /// Glob pattern(s) from frontmatter — when set, this instruction applies only to matching files. + [JsonPropertyName("applyTo")] + public IList? ApplyTo { get; set; } - /// Repository owner or organization login. - [JsonPropertyName("owner")] - public string Owner { get; set; } = string.Empty; -} + /// Raw content of the instruction file. + [JsonPropertyName("content")] + public string Content { get; set; } = string.Empty; -/// Metadata for a connected remote session. -[Experimental(Diagnostics.Experimental)] -public sealed class ConnectedRemoteSessionMetadata -{ - /// Neutral SDK discriminator for the connected remote session kind. - [JsonPropertyName("kind")] - public ConnectedRemoteSessionMetadataKind Kind { get; set; } + /// When true, this source starts disabled and must be toggled on by the user. + [JsonPropertyName("defaultDisabled")] + public bool? DefaultDisabled { get; set; } - /// Last session update time as an ISO 8601 string. - [JsonPropertyName("modifiedTime")] - public DateTimeOffset ModifiedTime { get; set; } + /// Short description (body after frontmatter) for use in instruction tables. + [JsonPropertyName("description")] + public string? Description { get; set; } - /// Optional friendly session name. - [JsonPropertyName("name")] - public string? Name { get; set; } + /// Unique identifier for this source (used for toggling). + [JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; - /// Pull request number associated with the session. - [JsonPropertyName("pullRequestNumber")] - public long? PullRequestNumber { get; set; } + /// Human-readable label. + [JsonPropertyName("label")] + public string Label { get; set; } = string.Empty; - /// Repository associated with the connected remote session. - [JsonPropertyName("repository")] - public ConnectedRemoteSessionMetadataRepository Repository { get => field ??= new(); set; } + /// Where this source lives — used for UI grouping. + [JsonPropertyName("location")] + public InstructionSourceLocation Location { get; set; } - /// Original remote resource identifier. - [JsonPropertyName("resourceId")] - public string? ResourceId { get; set; } + /// The project path this source was discovered from. Only set by sessionless discovery for repository/working-directory sources, where it disambiguates same-named files (e.g. .github/copilot-instructions.md) across multiple workspace roots. The session-scoped getSources leaves it unset. + [JsonPropertyName("projectPath")] + public string? ProjectPath { get; set; } - /// SDK session ID for the connected remote session. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// File path relative to repo or absolute for home. + [JsonPropertyName("sourcePath")] + public string SourcePath { get; set; } = string.Empty; - /// Remote session staleness deadline as an ISO 8601 string. - [JsonPropertyName("staleAt")] - public DateTimeOffset? StaleAt { get; set; } + /// Category of instruction source — used for merge logic. + [JsonPropertyName("type")] + public InstructionSourceType Type { get; set; } +} - /// Session start time as an ISO 8601 string. - [JsonPropertyName("startTime")] - public DateTimeOffset StartTime { get; set; } +/// Instruction sources discovered across user, repository, and plugin sources. +[Experimental(Diagnostics.Experimental)] +public sealed class ServerInstructionSourceList +{ + /// All discovered instruction sources. + [JsonPropertyName("sources")] + public IList Sources { get => field ??= []; set; } +} - /// Remote session state returned by the backing service. - [JsonPropertyName("state")] - public string? State { get; set; } +/// Optional project paths to include in instruction discovery. +[Experimental(Diagnostics.Experimental)] +internal sealed class InstructionsDiscoverRequest +{ + /// When true, omit the host's instruction sources (user/home-level files and plugin rules), leaving only repository and working-directory sources. For multitenant deployments. + [JsonPropertyName("excludeHostInstructions")] + public bool? ExcludeHostInstructions { get; set; } - /// Optional session summary. - [JsonPropertyName("summary")] - public string? Summary { get; set; } + /// Optional list of project directory paths to scan for repository/working-directory instruction sources. When omitted or empty, only user-level and plugin instruction sources are returned (no project scan). + [JsonPropertyName("projectPaths")] + public IList? ProjectPaths { get; set; } } -/// Remote session connection result. +/// Schema for the `InstructionDiscoveryPath` type. [Experimental(Diagnostics.Experimental)] -public sealed class RemoteSessionConnectionResult +public sealed class InstructionDiscoveryPath { - /// Metadata for a connected remote session. - [JsonPropertyName("metadata")] - public ConnectedRemoteSessionMetadata Metadata { get => field ??= new(); set; } + /// Whether the target is a single file or a directory of instruction files. + [JsonPropertyName("kind")] + public InstructionDiscoveryPathKind Kind { get; set; } - /// SDK session ID for the connected remote session. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// Which tier this target belongs to. + [JsonPropertyName("location")] + public InstructionDiscoveryPathLocation Location { get; set; } + + /// Absolute path of the file or directory (may not exist on disk yet). + [JsonPropertyName("path")] + public string Path { get; set; } = string.Empty; + + /// Whether this is the canonical target to create new instructions in its tier. At most one entry per tier is preferred. + [JsonPropertyName("preferredForCreation")] + public bool PreferredForCreation { get; set; } + + /// The input project path this target was derived from (only for repository targets). + [JsonPropertyName("projectPath")] + public string? ProjectPath { get; set; } } -/// Remote session connection parameters. +/// Canonical files and directories where custom instructions can be created so the runtime will recognize them. [Experimental(Diagnostics.Experimental)] -internal sealed class ConnectRemoteSessionParams +public sealed class InstructionDiscoveryPathList { - /// Session ID to connect to. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// Canonical instruction create/discovery files and directories, in priority order. + [JsonPropertyName("paths")] + public IList Paths { get => field ??= []; set; } } -/// Local or remote session metadata entry. Narrow on `isRemote` to access source-specific fields. -/// Data type discriminated by isRemote. +/// Optional project paths to include when enumerating instruction discovery targets. [Experimental(Diagnostics.Experimental)] -public partial class SessionListEntry +internal sealed class InstructionsGetDiscoveryPathsRequest { - /// The boolean discriminator. - [JsonPropertyName("isRemote")] - public bool IsRemote { get; set; } - - /// Runtime client name that created/last resumed this session. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("clientName")] - public string? ClientName { get; set; } - - /// Pre-resolved working-directory context for session startup. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("context")] - public SessionContext? Context { get; set; } - - /// True for detached maintenance sessions that should be hidden from normal resume lists. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("isDetached")] - public bool? IsDetached { get; set; } + /// When true, omit the host's user-level instruction targets, leaving only repository targets. For multitenant deployments (mirrors `discover`'s `excludeHostInstructions`). + [JsonPropertyName("excludeHostInstructions")] + public bool? ExcludeHostInstructions { get; set; } - /// GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("mcTaskId")] - public string? McTaskId { get; set; } + /// Optional list of project directory paths. When omitted or empty, only the user-level targets are returned. + [JsonPropertyName("projectPaths")] + public IList? ProjectPaths { get; set; } +} - /// Last-modified time of the session's persisted state, as ISO 8601. - [JsonPropertyName("modifiedTime")] - public required string ModifiedTime { get; set; } +/// Indicates whether the calling client was registered as the session filesystem provider. +public sealed class SessionFsSetProviderResult +{ + /// Whether the provider was set successfully. + [JsonPropertyName("success")] + public bool Success { get; set; } +} - /// Optional human-friendly name set via /rename. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("name")] - public string? Name { get; set; } +/// Optional capabilities declared by the provider. +public sealed class SessionFsSetProviderCapabilities +{ + /// Whether the provider supports SQLite query/exists operations. + [JsonPropertyName("sqlite")] + public bool? Sqlite { get; set; } +} - /// Pull request number associated with the session. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("pullRequestNumber")] - public long? PullRequestNumber { get; set; } +/// Initial working directory, session-state path layout, and path conventions used to register the calling SDK client as the session filesystem provider. +internal sealed class SessionFsSetProviderRequest +{ + /// Optional capabilities declared by the provider. + [JsonPropertyName("capabilities")] + public SessionFsSetProviderCapabilities? Capabilities { get; set; } - /// Backing remote session IDs (most recent first). - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("remoteSessionIds")] - public IList? RemoteSessionIds { get; set; } + /// Path conventions used by this filesystem. + [JsonPropertyName("conventions")] + public SessionFsSetProviderConventions Conventions { get; set; } - /// GitHub repository the remote session belongs to. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("repository")] - public RemoteSessionMetadataRepository? Repository { get; set; } + /// Initial working directory for sessions. + [JsonPropertyName("initialCwd")] + public string InitialCwd { get; set; } = string.Empty; - /// Original remote resource identifier (task ID or PR node ID). - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("resourceId")] - public string? ResourceId { get; set; } + /// Path within each session's SessionFs where the runtime stores files for that session. + [JsonPropertyName("sessionStatePath")] + public string SessionStatePath { get; set; } = string.Empty; +} - /// Stable session identifier. - [JsonPropertyName("sessionId")] - public required string SessionId { get; set; } +/// Indicates whether the calling client was registered as the LLM inference provider. +[Experimental(Diagnostics.Experimental)] +public sealed class LlmInferenceSetProviderResult +{ + /// Whether the provider was set successfully. + [JsonPropertyName("success")] + public bool Success { get; set; } +} - /// Deadline (ISO 8601) at which a CLI remote session becomes stale without further heartbeats. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("staleAt")] - public string? StaleAt { get; set; } +/// Whether the start frame was accepted. +[Experimental(Diagnostics.Experimental)] +public sealed class LlmInferenceHttpResponseStartResult +{ + /// True when the response start was matched to a pending request; false when unknown. + [JsonPropertyName("accepted")] + public bool Accepted { get; set; } +} - /// Session creation time as an ISO 8601 timestamp. - [JsonPropertyName("startTime")] - public required string StartTime { get; set; } +/// Response head. +[Experimental(Diagnostics.Experimental)] +internal sealed class LlmInferenceHttpResponseStartRequest +{ + /// Gets or sets the headers value. + [JsonPropertyName("headers")] + public IDictionary> Headers { get => field ??= new Dictionary>(); set; } - /// Server-side task state returned by GitHub. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("state")] - public string? State { get; set; } + /// Matches the requestId from the originating httpRequestStart frame. + [JsonPropertyName("requestId")] + public string RequestId { get; set; } = string.Empty; - /// Short summary of the session, when one has been derived. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("summary")] - public string? Summary { get; set; } + /// HTTP status code. + [JsonPropertyName("status")] + public long Status { get; set; } - /// Whether the remote task originated from CCA or CLI `--remote`. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("taskType")] - public RemoteSessionMetadataTaskType? TaskType { get; set; } + /// Optional HTTP status reason phrase. + [JsonPropertyName("statusText")] + public string? StatusText { get; set; } } -/// Sessions matching the filter, ordered most-recently-modified first. +/// Whether the chunk was accepted. [Experimental(Diagnostics.Experimental)] -public sealed class SessionList +public sealed class LlmInferenceHttpResponseChunkResult { - /// Sessions ordered most-recently-modified first. Discriminated by `isRemote`. - [JsonPropertyName("sessions")] - public IList Sessions { get => field ??= []; set; } + /// True when the chunk was matched to a pending request; false when unknown. + [JsonPropertyName("accepted")] + public bool Accepted { get; set; } } -/// Optional filter applied to the returned sessions. +/// Set to terminate the response with a transport-level failure. Implies end-of-stream; any further chunks for this requestId are ignored. [Experimental(Diagnostics.Experimental)] -public sealed class SessionListFilter +public sealed class LlmInferenceHttpResponseChunkError { - /// Match sessions whose context.branch equals this value. - [JsonPropertyName("branch")] - public string? Branch { get; set; } - - /// Match sessions whose context.cwd equals this value. - [JsonPropertyName("cwd")] - public string? Cwd { get; set; } - - /// Match sessions whose context.gitRoot equals this value. - [JsonPropertyName("gitRoot")] - public string? GitRoot { get; set; } + /// Optional machine-readable error code. + [JsonPropertyName("code")] + public string? Code { get; set; } - /// Match sessions whose context.repository equals this value. - [JsonPropertyName("repository")] - public string? Repository { get; set; } + /// Human-readable failure description. + [JsonPropertyName("message")] + public string Message { get; set; } = string.Empty; } -/// Optional source filter, metadata-load limit, and context filter applied to the returned sessions. +/// A response body chunk or terminal error. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsListRequest +internal sealed class LlmInferenceHttpResponseChunkRequest { - /// Optional filter applied to the returned sessions. - [JsonPropertyName("filter")] - public SessionListFilter? Filter { get; set; } + /// When true, `data` is base64-encoded bytes. When absent or false, `data` is UTF-8 text. + [JsonPropertyName("binary")] + public bool? Binary { get; set; } - /// When true, include detached maintenance sessions. Defaults to false for user-facing session lists. - [JsonPropertyName("includeDetached")] - public bool? IncludeDetached { get; set; } + /// Body byte range. UTF-8 text when `binary` is absent or false; base64-encoded bytes when `binary` is true. May be empty (e.g. when the response body is empty: send a single chunk with empty data and end=true). + [JsonPropertyName("data")] + public string Data { get; set; } = string.Empty; - /// When provided, only the first N local sessions (sorted by modification time, newest first) load full metadata; remaining sessions return basic info only. Use 0 to return only basic info for every local session. Has no effect on remote entries (which always carry their full shape). - [JsonPropertyName("metadataLimit")] - public long? MetadataLimit { get; set; } + /// When true, this is the final body chunk for the response. The runtime treats the response body as complete after receiving an end-marked chunk. + [JsonPropertyName("end")] + public bool? End { get; set; } - /// Which session sources to include. Defaults to `local` for backward compatibility. - [JsonPropertyName("source")] - public SessionSource? Source { get; set; } + /// Set to terminate the response with a transport-level failure. Implies end-of-stream; any further chunks for this requestId are ignored. + [JsonPropertyName("error")] + public LlmInferenceHttpResponseChunkError? Error { get; set; } - /// Only meaningful when `source` includes remote. When true, propagates errors from the remote service instead of silently returning an empty remote list. Defaults to false. - [JsonPropertyName("throwOnError")] - public bool? ThrowOnError { get; set; } + /// Matches the requestId from the originating httpRequestStart frame. + [JsonPropertyName("requestId")] + public string RequestId { get; set; } = string.Empty; } -/// ID of the local session bound to the given GitHub task, or omitted when none. +/// Pre-resolved working-directory context for session startup. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsFindByTaskIDResult +public sealed class SessionContext { - /// Omitted when no local session is bound to that GitHub task. - [JsonPropertyName("sessionId")] - public string? SessionId { get; set; } -} + /// Active git branch. + [JsonPropertyName("branch")] + public string? Branch { get; set; } -/// GitHub task ID to look up. -[Experimental(Diagnostics.Experimental)] -internal sealed class SessionsFindByTaskIDRequest -{ - /// GitHub task ID to look up. - [JsonPropertyName("taskId")] - public string TaskId { get; set; } = string.Empty; + /// Most recent working directory for this session. + [JsonPropertyName("cwd")] + public string Cwd { get; set; } = string.Empty; + + /// Git repository root, if the cwd was inside a git repo. + [JsonPropertyName("gitRoot")] + public string? GitRoot { get; set; } + + /// Repository host type. + [JsonPropertyName("hostType")] + public SessionContextHostType? HostType { get; set; } + + /// Repository slug in `owner/name` form, when known. + [JsonPropertyName("repository")] + public string? Repository { get; set; } } -/// Session ID matching the prefix, omitted when no unique match exists. +/// GitHub repository the remote session belongs to. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsFindByPrefixResult +public sealed class RemoteSessionMetadataRepository { - /// Omitted when no unique session matches the prefix (no match or ambiguous). - [JsonPropertyName("sessionId")] - public string? SessionId { get; set; } -} + /// Branch associated with the remote session. + [JsonPropertyName("branch")] + public string Branch { get; set; } = string.Empty; -/// UUID prefix to resolve to a unique session ID. -[Experimental(Diagnostics.Experimental)] -internal sealed class SessionsFindByPrefixRequest -{ - /// UUID prefix (>=7 hex chars, <36 chars). Returns the unique session ID, or undefined when there is no match or the prefix matches multiple sessions. - [JsonPropertyName("prefix")] - public string Prefix { get; set; } = string.Empty; -} + /// Repository name. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; -/// Most-relevant session ID for the supplied context, or omitted when no sessions exist. -[Experimental(Diagnostics.Experimental)] -public sealed class SessionsGetLastForContextResult -{ - /// Most-relevant session ID for the supplied context, or omitted when no sessions exist. - [JsonPropertyName("sessionId")] - public string? SessionId { get; set; } + /// Repository owner. + [JsonPropertyName("owner")] + public string Owner { get; set; } = string.Empty; } -/// Optional working-directory context used to score session relevance. +/// Remote session metadata for the session to hand off (typically obtained from `sessions.list` with `source: "remote"`). [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsGetLastForContextRequest +public sealed class RemoteSessionMetadataValue { - /// Optional working-directory context used to score session relevance. When omitted the most-recently-modified session wins. + /// Most recent working directory context. [JsonPropertyName("context")] public SessionContext? Context { get; set; } -} -/// Absolute path to the session's events.jsonl file on disk. -[Experimental(Diagnostics.Experimental)] -internal sealed class SessionsGetEventFilePathResult -{ - /// Absolute path to the session's events.jsonl file. - [JsonPropertyName("filePath")] - public string FilePath { get; set; } = string.Empty; -} + /// Always true for remote sessions. + [JsonPropertyName("isRemote")] + public bool IsRemote { get; set; } -/// Session ID whose event-log file path to compute. -[Experimental(Diagnostics.Experimental)] -internal sealed class SessionsGetEventFilePathRequest -{ - /// Session ID whose event-log file path to compute. + /// Last-modified time as an ISO 8601 timestamp. + [JsonPropertyName("modifiedTime")] + public string ModifiedTime { get; set; } = string.Empty; + + /// Optional human-friendly name set via /rename. + [JsonPropertyName("name")] + public string? Name { get; set; } + + /// Pull request number associated with the session. + [JsonPropertyName("pullRequestNumber")] + public long? PullRequestNumber { get; set; } + + /// Backing remote session IDs (most recent first). + [JsonPropertyName("remoteSessionIds")] + public IList RemoteSessionIds { get => field ??= []; set; } + + /// GitHub repository the remote session belongs to. + [JsonPropertyName("repository")] + public RemoteSessionMetadataRepository Repository { get => field ??= new(); set; } + + /// Original remote resource identifier (task ID or PR node ID). + [JsonPropertyName("resourceId")] + public string? ResourceId { get; set; } + + /// Stable session identifier. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; -} -/// Map of sessionId -> on-disk size in bytes for each session's workspace directory. -[Experimental(Diagnostics.Experimental)] -public sealed class SessionSizes -{ - /// Map of sessionId -> on-disk size in bytes for the session's workspace directory. - [JsonPropertyName("sizes")] - public IDictionary Sizes { get => field ??= new Dictionary(); set; } -} + /// Deadline (ISO 8601) at which a CLI remote session becomes stale without further heartbeats. + [JsonPropertyName("staleAt")] + public string? StaleAt { get; set; } -/// Session IDs from the input set that are currently in use by another process. -[Experimental(Diagnostics.Experimental)] -public sealed class SessionsCheckInUseResult -{ - /// Session IDs from the input set that are currently held by another running process via an alive lock file. - [JsonPropertyName("inUse")] - public IList InUse { get => field ??= []; set; } + /// Session creation time as an ISO 8601 timestamp. + [JsonPropertyName("startTime")] + public string StartTime { get; set; } = string.Empty; + + /// Server-side task state returned by GitHub. + [JsonPropertyName("state")] + public string? State { get; set; } + + /// Short summary of the session, when one has been derived. + [JsonPropertyName("summary")] + public string? Summary { get; set; } + + /// Whether the remote task originated from CCA or CLI `--remote`. + [JsonPropertyName("taskType")] + public RemoteSessionMetadataTaskType? TaskType { get; set; } } -/// Session IDs to test for live in-use locks. +/// Schema for the `SessionsOpenProgress` type. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsCheckInUseRequest +public sealed class SessionsOpenProgress { - /// Session IDs to test for live in-use locks. - [JsonPropertyName("sessionIds")] - public IList SessionIds { get => field ??= []; set; } + /// Optional step message. + [JsonPropertyName("message")] + public string? Message { get; set; } + + /// Step status. + [JsonPropertyName("status")] + public SessionsOpenProgressStatus Status { get; set; } + + /// Handoff step. + [JsonPropertyName("step")] + public SessionsOpenProgressStep Step { get; set; } } -/// The session's persisted remote-steerable flag, or omitted when no value has been persisted. +/// Result of opening a session. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsGetPersistedRemoteSteerableResult +public sealed class SessionOpenResult { - /// The session's persisted remote-steerable flag if recorded; omitted when no value has been persisted. - [JsonPropertyName("remoteSteerable")] - public bool? RemoteSteerable { get; set; } + /// Remote session metadata, present when status is `connected`. + [JsonPropertyName("metadata")] + public RemoteSessionMetadataValue? Metadata { get; set; } + + /// Handoff progress steps, present when status is `handed_off`. + [JsonPropertyName("progress")] + public IList? Progress { get; set; } + + /// Remote session ID, present when status is `connected`. + [JsonPropertyName("remoteSessionId")] + public string? RemoteSessionId { get; set; } + + /// In-process SessionClientApi handle for the opened session, returned to CLI callers as a transitional shortcut. Marked internal so the public SDK surface does not expose it; SDK consumers should construct per-session clients from `sessionId` instead. + [JsonInclude] + [JsonPropertyName("sessionApi")] + internal JsonElement? SessionApi { get; set; } + + /// Opened session ID. Omitted when status is `not_found`. + [JsonPropertyName("sessionId")] + public string? SessionId { get; set; } + + /// Startup prompts queued by user-level hook configs at session creation. Only populated when status is `created`; resumed sessions return an empty array. + [JsonPropertyName("startupPrompts")] + public IList? StartupPrompts { get; set; } + + /// Outcome of the open request. + [JsonPropertyName("status")] + public SessionsOpenStatus Status { get; set; } } -/// Session ID to look up the persisted remote-steerable flag for. +/// Identifier and optional friendly name assigned to the newly forked session. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsGetPersistedRemoteSteerableRequest +public sealed class SessionsForkResult { - /// Session ID to look up the persisted remote-steerable flag for. + /// Friendly name assigned to the forked session, if any. + [JsonPropertyName("name")] + public string? Name { get; set; } + + /// The new forked session's ID. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; } -/// Closes a session: emits shutdown, flushes pending events to disk, releases the in-use lock, disposes the active session. Idempotent: succeeds even if the session is not currently active. +/// Source session identifier to fork from, optional event-ID boundary, and optional friendly name for the new session. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsCloseResult +internal sealed class SessionsForkRequest { -} + /// Optional friendly name to assign to the forked session. + [JsonPropertyName("name")] + public string? Name { get; set; } -/// Session ID to close. -[Experimental(Diagnostics.Experimental)] -internal sealed class SessionsCloseRequest -{ - /// Session ID to close. + /// Source session ID to fork from. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; -} -/// Map of sessionId -> bytes freed by removing the session's workspace directory. -[Experimental(Diagnostics.Experimental)] -public sealed class SessionBulkDeleteResult -{ - /// Map of sessionId -> bytes freed by removing the session's workspace directory. Sessions whose deletion failed are omitted from this map (failures are logged on the server but not surfaced per-id; check the map for absent IDs to detect them). - [JsonPropertyName("freedBytes")] - public IDictionary FreedBytes { get => field ??= new Dictionary(); set; } + /// Optional event ID boundary. When provided, the fork includes only events before this ID (exclusive). When omitted, all events are included. + [JsonPropertyName("toEventId")] + public string? ToEventId { get; set; } } -/// Session IDs to close, deactivate, and delete from disk. +/// Repository associated with the connected remote session. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsBulkDeleteRequest +public sealed class ConnectedRemoteSessionMetadataRepository { - /// Session IDs to close, deactivate, and delete from disk. - [JsonPropertyName("sessionIds")] - public IList SessionIds { get => field ??= []; set; } + /// Branch associated with the remote session. + [JsonPropertyName("branch")] + public string Branch { get; set; } = string.Empty; + + /// Repository name. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// Repository owner or organization login. + [JsonPropertyName("owner")] + public string Owner { get; set; } = string.Empty; } -/// Outcome of the prune operation: deleted IDs, dry-run candidates, skipped IDs, total bytes freed, and the dry-run flag. +/// Metadata for a connected remote session. [Experimental(Diagnostics.Experimental)] -public sealed class SessionPruneResult +public sealed class ConnectedRemoteSessionMetadata { - /// Session IDs that would be deleted in dry-run mode (always empty otherwise). - [JsonPropertyName("candidates")] - public IList Candidates { get => field ??= []; set; } + /// Neutral SDK discriminator for the connected remote session kind. + [JsonPropertyName("kind")] + public ConnectedRemoteSessionMetadataKind Kind { get; set; } - /// Session IDs that were deleted (always empty in dry-run mode). - [JsonPropertyName("deleted")] - public IList Deleted { get => field ??= []; set; } + /// Last session update time as an ISO 8601 string. + [JsonPropertyName("modifiedTime")] + public DateTimeOffset ModifiedTime { get; set; } - /// True when no deletions were actually performed. - [JsonPropertyName("dryRun")] - public bool DryRun { get; set; } + /// Optional friendly session name. + [JsonPropertyName("name")] + public string? Name { get; set; } - /// Total bytes freed (actual when not dry-run, projected when dry-run). - [JsonPropertyName("freedBytes")] - public long FreedBytes { get; set; } + /// Pull request number associated with the session. + [JsonPropertyName("pullRequestNumber")] + public long? PullRequestNumber { get; set; } + + /// Repository associated with the connected remote session. + [JsonPropertyName("repository")] + public ConnectedRemoteSessionMetadataRepository Repository { get => field ??= new(); set; } + + /// Original remote resource identifier. + [JsonPropertyName("resourceId")] + public string? ResourceId { get; set; } - /// Session IDs that were skipped (e.g., named sessions). - [JsonPropertyName("skipped")] - public IList Skipped { get => field ??= []; set; } -} + /// SDK session ID for the connected remote session. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; -/// Age threshold and optional flags controlling which old sessions are pruned (or simulated when dryRun is true). -[Experimental(Diagnostics.Experimental)] -internal sealed class SessionsPruneOldRequest -{ - /// When true, only report what would be deleted without performing any deletion. - [JsonPropertyName("dryRun")] - public bool? DryRun { get; set; } + /// Remote session staleness deadline as an ISO 8601 string. + [JsonPropertyName("staleAt")] + public DateTimeOffset? StaleAt { get; set; } - /// Session IDs that should never be considered for pruning. - [JsonPropertyName("excludeSessionIds")] - public IList? ExcludeSessionIds { get; set; } + /// Session start time as an ISO 8601 string. + [JsonPropertyName("startTime")] + public DateTimeOffset StartTime { get; set; } - /// When true, named sessions (set via /rename) are also eligible for pruning. - [JsonPropertyName("includeNamed")] - public bool? IncludeNamed { get; set; } + /// Remote session state returned by the backing service. + [JsonPropertyName("state")] + public string? State { get; set; } - /// Delete sessions whose modifiedTime is at least this many days old. - [JsonPropertyName("olderThanDays")] - public long OlderThanDays { get; set; } + /// Optional session summary. + [JsonPropertyName("summary")] + public string? Summary { get; set; } } -/// Flush a session's pending events to disk. No-op when no writer exists for the session (e.g., already closed). +/// Remote session connection result. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsSaveResult +public sealed class RemoteSessionConnectionResult { -} + /// Metadata for a connected remote session. + [JsonPropertyName("metadata")] + public ConnectedRemoteSessionMetadata Metadata { get => field ??= new(); set; } -/// Session ID whose pending events should be flushed to disk. -[Experimental(Diagnostics.Experimental)] -internal sealed class SessionsSaveRequest -{ - /// Session ID whose pending events should be flushed to disk. + /// SDK session ID for the connected remote session. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; } -/// Release the in-use lock held by this process for the given session. No-op when this process does not currently hold a lock for the session. -[Experimental(Diagnostics.Experimental)] -public sealed class SessionsReleaseLockResult -{ -} - -/// Session ID whose in-use lock should be released. +/// Remote session connection parameters. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsReleaseLockRequest +internal sealed class ConnectRemoteSessionParams { - /// Session ID whose in-use lock should be released. + /// Session ID to connect to. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; } -/// Schema for the `LocalSessionMetadataValue` type. +/// Local or remote session metadata entry. Narrow on `isRemote` to access source-specific fields. +/// Data type discriminated by isRemote. [Experimental(Diagnostics.Experimental)] -public sealed class LocalSessionMetadataValue +public partial class SessionListEntry { + /// The boolean discriminator. + [JsonPropertyName("isRemote")] + public bool IsRemote { get; set; } + /// Runtime client name that created/last resumed this session. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("clientName")] public string? ClientName { get; set; } /// Pre-resolved working-directory context for session startup. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("context")] public SessionContext? Context { get; set; } /// True for detached maintenance sessions that should be hidden from normal resume lists. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("isDetached")] public bool? IsDetached { get; set; } - /// Always false for local sessions. - [JsonPropertyName("isRemote")] - public bool IsRemote { get; set; } - /// GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("mcTaskId")] public string? McTaskId { get; set; } /// Last-modified time of the session's persisted state, as ISO 8601. [JsonPropertyName("modifiedTime")] - public string ModifiedTime { get; set; } = string.Empty; + public required string ModifiedTime { get; set; } /// Optional human-friendly name set via /rename. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("name")] public string? Name { get; set; } + /// Pull request number associated with the session. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("pullRequestNumber")] + public long? PullRequestNumber { get; set; } + + /// Backing remote session IDs (most recent first). + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("remoteSessionIds")] + public IList? RemoteSessionIds { get; set; } + + /// GitHub repository the remote session belongs to. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("repository")] + public RemoteSessionMetadataRepository? Repository { get; set; } + + /// Original remote resource identifier (task ID or PR node ID). + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("resourceId")] + public string? ResourceId { get; set; } + /// Stable session identifier. [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + public required string SessionId { get; set; } + + /// Deadline (ISO 8601) at which a CLI remote session becomes stale without further heartbeats. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("staleAt")] + public string? StaleAt { get; set; } /// Session creation time as an ISO 8601 timestamp. [JsonPropertyName("startTime")] - public string StartTime { get; set; } = string.Empty; + public required string StartTime { get; set; } + + /// Server-side task state returned by GitHub. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("state")] + public string? State { get; set; } /// Short summary of the session, when one has been derived. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("summary")] public string? Summary { get; set; } + + /// Whether the remote task originated from CCA or CLI `--remote`. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("taskType")] + public RemoteSessionMetadataTaskType? TaskType { get; set; } } -/// The enriched metadata records, with summary and context fields backfilled where available. Sessions confirmed empty and unnamed are omitted. +/// Sessions matching the filter, ordered most-recently-modified first. [Experimental(Diagnostics.Experimental)] -public sealed class SessionEnrichMetadataResult +public sealed class SessionList { - /// Enriched records, with summary and context backfilled. Sessions confirmed empty and unnamed may be omitted. + /// Sessions ordered most-recently-modified first. Discriminated by `isRemote`. [JsonPropertyName("sessions")] - public IList Sessions { get => field ??= []; set; } + public IList Sessions { get => field ??= []; set; } } -/// Session metadata records to enrich with summary and context information. +/// Optional filter applied to the returned sessions. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsEnrichMetadataRequest +public sealed class SessionListFilter { - /// Session metadata records to enrich. Records that already have summary and context are returned unchanged. - [JsonPropertyName("sessions")] - public IList Sessions { get => field ??= []; set; } + /// Match sessions whose context.branch equals this value. + [JsonPropertyName("branch")] + public string? Branch { get; set; } + + /// Match sessions whose context.cwd equals this value. + [JsonPropertyName("cwd")] + public string? Cwd { get; set; } + + /// Match sessions whose context.gitRoot equals this value. + [JsonPropertyName("gitRoot")] + public string? GitRoot { get; set; } + + /// Match sessions whose context.repository equals this value. + [JsonPropertyName("repository")] + public string? Repository { get; set; } } -/// Reload all hooks (user, plugin, optionally repo) and apply them to the active session. Call after installing or removing plugins so their hooks take effect immediately. No-op when no active session matches the given sessionId. +/// Optional source filter, metadata-load limit, and context filter applied to the returned sessions. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsReloadPluginHooksResult +internal sealed class SessionsListRequest { + /// Optional filter applied to the returned sessions. + [JsonPropertyName("filter")] + public SessionListFilter? Filter { get; set; } + + /// When true, include detached maintenance sessions. Defaults to false for user-facing session lists. + [JsonPropertyName("includeDetached")] + public bool? IncludeDetached { get; set; } + + /// When provided, only the first N local sessions (sorted by modification time, newest first) load full metadata; remaining sessions return basic info only. Use 0 to return only basic info for every local session. Has no effect on remote entries (which always carry their full shape). + [JsonPropertyName("metadataLimit")] + public long? MetadataLimit { get; set; } + + /// Which session sources to include. Defaults to `local` for backward compatibility. + [JsonPropertyName("source")] + public SessionSource? Source { get; set; } + + /// Only meaningful when `source` includes remote. When true, propagates errors from the remote service instead of silently returning an empty remote list. Defaults to false. + [JsonPropertyName("throwOnError")] + public bool? ThrowOnError { get; set; } } -/// Active session ID and an optional flag for deferring repo-level hooks until folder trust. +/// ID of the local session bound to the given GitHub task, or omitted when none. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsReloadPluginHooksRequest +public sealed class SessionsFindByTaskIDResult { - /// When true, skip repo-level hooks. Use before folder trust is confirmed; loadDeferredRepoHooks loads them post-trust. - [JsonPropertyName("deferRepoHooks")] - public bool? DeferRepoHooks { get; set; } - - /// Active session ID to reload hooks for. + /// Omitted when no local session is bound to that GitHub task. [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + public string? SessionId { get; set; } } -/// Queued repo-level startup prompts and the total hook command count after loading. +/// GitHub task ID to look up. [Experimental(Diagnostics.Experimental)] -public sealed class SessionLoadDeferredRepoHooksResult +internal sealed class SessionsFindByTaskIDRequest { - /// Total hook command count (user + plugin + repo) loaded for the session by this call. Captured atomically with startupPrompts so callers don't need to read a separate counter. - [JsonPropertyName("hookCount")] - public long HookCount { get; set; } - - /// Repo-level startup prompts queued from repo hook configs. Empty on resume, when no repo configs were pending, or when disableAllHooks is set. - [JsonPropertyName("startupPrompts")] - public IList StartupPrompts { get => field ??= []; set; } + /// GitHub task ID to look up. + [JsonPropertyName("taskId")] + public string TaskId { get; set; } = string.Empty; } -/// Active session ID whose deferred repo-level hooks should be loaded. +/// Session ID matching the prefix, omitted when no unique match exists. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsLoadDeferredRepoHooksRequest +public sealed class SessionsFindByPrefixResult { - /// Active session ID whose deferred repo-level hooks should be loaded. + /// Omitted when no unique session matches the prefix (no match or ambiguous). [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + public string? SessionId { get; set; } } -/// Replace the manager-wide additional plugins. New session creations and subsequent hook reloads see the new set; already-running sessions keep their existing hook installation until the next reload. +/// UUID prefix to resolve to a unique session ID. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsSetAdditionalPluginsResult +internal sealed class SessionsFindByPrefixRequest { + /// UUID prefix (>=7 hex chars, <36 chars). Returns the unique session ID, or undefined when there is no match or the prefix matches multiple sessions. + [JsonPropertyName("prefix")] + public string Prefix { get; set; } = string.Empty; } -/// Schema for the `InstalledPlugin` type. +/// Most-relevant session ID for the supplied context, or omitted when no sessions exist. [Experimental(Diagnostics.Experimental)] -public sealed class InstalledPlugin +public sealed class SessionsGetLastForContextResult { - /// Path where the plugin is cached locally. - [JsonPropertyName("cache_path")] - public string? CachePath { get; set; } - - /// Whether the plugin is currently enabled. - [JsonPropertyName("enabled")] - public bool Enabled { get; set; } - - /// Installation timestamp. - [JsonPropertyName("installed_at")] - public string InstalledAt { get; set; } = string.Empty; - - /// Marketplace the plugin came from (empty string for direct repo installs). - [JsonPropertyName("marketplace")] - public string Marketplace { get; set; } = string.Empty; - - /// Plugin name. - [JsonPropertyName("name")] - public string Name { get; set; } = string.Empty; - - /// Source for direct repo installs (when marketplace is empty). - [JsonPropertyName("source")] - public JsonElement? Source { get; set; } - - /// Version installed (if available). - [JsonPropertyName("version")] - public string? Version { get; set; } + /// Most-relevant session ID for the supplied context, or omitted when no sessions exist. + [JsonPropertyName("sessionId")] + public string? SessionId { get; set; } } -/// Manager-wide additional plugins to register; replaces any previously-configured set. +/// Optional working-directory context used to score session relevance. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsSetAdditionalPluginsRequest -{ - /// Manager-wide additional plugins to register. Replaces any previously-configured set. Pass an empty array to clear. - [JsonPropertyName("plugins")] - public IList Plugins { get => field ??= []; set; } +internal sealed class SessionsGetLastForContextRequest +{ + /// Optional working-directory context used to score session relevance. When omitted the most-recently-modified session wins. + [JsonPropertyName("context")] + public SessionContext? Context { get; set; } } -/// Dynamic-context board entry count, when available. +/// Absolute path to the session's events.jsonl file on disk. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsGetBoardEntryCountResult +internal sealed class SessionsGetEventFilePathResult { - /// Board entry count, when available. - [JsonPropertyName("count")] - public long? Count { get; set; } + /// Absolute path to the session's events.jsonl file. + [JsonPropertyName("filePath")] + public string FilePath { get; set; } = string.Empty; } -/// Session ID whose board entry count should be returned. +/// Session ID whose event-log file path to compute. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsGetBoardEntryCountRequest +internal sealed class SessionsGetEventFilePathRequest { - /// Session ID whose board entry count should be returned. + /// Session ID whose event-log file path to compute. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; } -/// State of the runtime-managed remote-control singleton. -/// Polymorphic base type discriminated by state. +/// Map of sessionId -> on-disk size in bytes for each session's workspace directory. [Experimental(Diagnostics.Experimental)] -[JsonPolymorphic( - TypeDiscriminatorPropertyName = "state", - UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] -[JsonDerivedType(typeof(RemoteControlStatusOff), "off")] -[JsonDerivedType(typeof(RemoteControlStatusConnecting), "connecting")] -[JsonDerivedType(typeof(RemoteControlStatusActive), "active")] -[JsonDerivedType(typeof(RemoteControlStatusError), "error")] -public partial class RemoteControlStatus +public sealed class SessionSizes { - /// The type discriminator. - [JsonPropertyName("state")] - public virtual string State { get; set; } = string.Empty; + /// Map of sessionId -> on-disk size in bytes for the session's workspace directory. + [JsonPropertyName("sizes")] + public IDictionary Sizes { get => field ??= new Dictionary(); set; } } - -/// Remote control is not connected. -/// The off variant of . +/// Session IDs from the input set that are currently in use by another process. [Experimental(Diagnostics.Experimental)] -public partial class RemoteControlStatusOff : RemoteControlStatus +public sealed class SessionsCheckInUseResult { - /// - [JsonIgnore] - public override string State => "off"; + /// Session IDs from the input set that are currently held by another running process via an alive lock file. + [JsonPropertyName("inUse")] + public IList InUse { get => field ??= []; set; } } -/// Remote control is in the middle of initial setup. -/// The connecting variant of . +/// Session IDs to test for live in-use locks. [Experimental(Diagnostics.Experimental)] -public partial class RemoteControlStatusConnecting : RemoteControlStatus +internal sealed class SessionsCheckInUseRequest { - /// - [JsonIgnore] - public override string State => "connecting"; - - /// Session id the connection is attaching to. - [JsonPropertyName("attachedSessionId")] - public required string AttachedSessionId { get; set; } + /// Session IDs to test for live in-use locks. + [JsonPropertyName("sessionIds")] + public IList SessionIds { get => field ??= []; set; } } -/// Remote control is connected to a local session. -/// The active variant of . +/// The session's persisted remote-steerable flag, or omitted when no value has been persisted. [Experimental(Diagnostics.Experimental)] -public partial class RemoteControlStatusActive : RemoteControlStatus +internal sealed class SessionsGetPersistedRemoteSteerableResult { - /// - [JsonIgnore] - public override string State => "active"; - - /// Session id remote control is pointed at. - [JsonPropertyName("attachedSessionId")] - public required string AttachedSessionId { get; set; } - - /// MC frontend URL for this session, when known. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("frontendUrl")] - public string? FrontendUrl { get; set; } - - /// Whether the MC session may steer this session. - [JsonPropertyName("isSteerable")] - public required bool IsSteerable { get; set; } - - /// In-process prompt-manager handle (CLI-only optimization). Marked internal: this field is excluded from the public SDK surface. When the CLI migrates to a process-separated SDK, the same bidirectional prompt-routing handshake is expressed via dedicated remote-control RPCs (register/resolve) rather than a shared in-process object. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonInclude] - [JsonPropertyName("promptManager")] - internal JsonElement? PromptManager { get; set; } + /// The session's persisted remote-steerable flag if recorded; omitted when no value has been persisted. + [JsonPropertyName("remoteSteerable")] + public bool? RemoteSteerable { get; set; } } -/// The last setup attempt failed. The singleton is otherwise off. -/// The error variant of . +/// Session ID to look up the persisted remote-steerable flag for. [Experimental(Diagnostics.Experimental)] -public partial class RemoteControlStatusError : RemoteControlStatus +internal sealed class SessionsGetPersistedRemoteSteerableRequest { - /// - [JsonIgnore] - public override string State => "error"; - - /// Session id the failing setup attempt targeted, when known. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("attachedSessionId")] - public string? AttachedSessionId { get; set; } - - /// Human-readable error message from the last setup attempt. - [JsonPropertyName("error")] - public required string Error { get; set; } + /// Session ID to look up the persisted remote-steerable flag for. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; } -/// Wrapper for the singleton's current status. +/// Closes a session: emits shutdown, flushes pending events to disk, releases the in-use lock, disposes the active session. Idempotent: succeeds even if the session is not currently active. [Experimental(Diagnostics.Experimental)] -public sealed class RemoteControlStatusResult +public sealed class SessionsCloseResult { - /// State of the runtime-managed remote-control singleton. - [JsonPropertyName("status")] - public RemoteControlStatus Status { get => field ??= new(); set; } } -/// Reattach to an existing MC session without creating a new one. +/// Session ID to close. [Experimental(Diagnostics.Experimental)] -public sealed class RemoteControlConfigExistingMcSession +internal sealed class SessionsCloseRequest { - /// Existing MC session ID to reattach to. - [JsonPropertyName("mcSessionId")] - public string McSessionId { get; set; } = string.Empty; - - /// Existing MC task ID for the reattached session. - [JsonPropertyName("mcTaskId")] - public string McTaskId { get; set; } = string.Empty; + /// Session ID to close. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; } -/// Configuration for the runtime-managed remote-control singleton. +/// Map of sessionId -> bytes freed by removing the session's workspace directory. [Experimental(Diagnostics.Experimental)] -public sealed class RemoteControlConfig +public sealed class SessionBulkDeleteResult { - /// Reattach to an existing MC session without creating a new one. - [JsonPropertyName("existingMcSession")] - public RemoteControlConfigExistingMcSession? ExistingMcSession { get; set; } - - /// Whether the user explicitly requested remote (vs. implicit session-sync). Controls warning surfacing for missing-repo cases. - [JsonPropertyName("explicit")] - public bool Explicit { get; set; } - - /// Whether remote export should be enabled. - [JsonPropertyName("remote")] - public bool Remote { get; set; } - - /// When true, suppresses timeline messages on successful setup. - [JsonPropertyName("silent")] - public bool Silent { get; set; } - - /// Whether the MC session may steer the local session (write mode). - [JsonPropertyName("steerable")] - public bool Steerable { get; set; } - - /// Existing Mission Control task ID to attach the exported session to. - [JsonPropertyName("taskId")] - public string? TaskId { get; set; } + /// Map of sessionId -> bytes freed by removing the session's workspace directory. Sessions whose deletion failed are omitted from this map (failures are logged on the server but not surfaced per-id; check the map for absent IDs to detect them). + [JsonPropertyName("freedBytes")] + public IDictionary FreedBytes { get => field ??= new Dictionary(); set; } } -/// Parameters for attaching the remote-control singleton to a session. +/// Session IDs to close, deactivate, and delete from disk. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsStartRemoteControlRequest +internal sealed class SessionsBulkDeleteRequest { - /// Configuration for the runtime-managed remote-control singleton. - [JsonPropertyName("config")] - public RemoteControlConfig Config { get => field ??= new(); set; } - - /// Local session id to attach remote control to. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// Session IDs to close, deactivate, and delete from disk. + [JsonPropertyName("sessionIds")] + public IList SessionIds { get => field ??= []; set; } } -/// Outcome of a transferRemoteControl call. +/// Outcome of the prune operation: deleted IDs, dry-run candidates, skipped IDs, total bytes freed, and the dry-run flag. [Experimental(Diagnostics.Experimental)] -public sealed class RemoteControlTransferResult +public sealed class SessionPruneResult { - /// State of the runtime-managed remote-control singleton. - [JsonPropertyName("status")] - public RemoteControlStatus Status { get => field ??= new(); set; } + /// Session IDs that would be deleted in dry-run mode (always empty otherwise). + [JsonPropertyName("candidates")] + public IList Candidates { get => field ??= []; set; } - /// Whether the rebinding actually happened. - [JsonPropertyName("transferred")] - public bool Transferred { get; set; } + /// Session IDs that were deleted (always empty in dry-run mode). + [JsonPropertyName("deleted")] + public IList Deleted { get => field ??= []; set; } + + /// True when no deletions were actually performed. + [JsonPropertyName("dryRun")] + public bool DryRun { get; set; } + + /// Total bytes freed (actual when not dry-run, projected when dry-run). + [JsonPropertyName("freedBytes")] + public long FreedBytes { get; set; } + + /// Session IDs that were skipped (e.g., named sessions). + [JsonPropertyName("skipped")] + public IList Skipped { get => field ??= []; set; } } -/// Parameters for atomically rebinding the remote-control singleton. +/// Age threshold and optional flags controlling which old sessions are pruned (or simulated when dryRun is true). [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsTransferRemoteControlRequest +internal sealed class SessionsPruneOldRequest { - /// When provided, the transfer is rejected unless the singleton currently points at this session id (compare-and-swap semantics to avoid clobbering newer state). - [JsonPropertyName("expectedFromSessionId")] - public string? ExpectedFromSessionId { get; set; } + /// When true, only report what would be deleted without performing any deletion. + [JsonPropertyName("dryRun")] + public bool? DryRun { get; set; } - /// Local session id to point remote control at. - [JsonPropertyName("toSessionId")] - public string ToSessionId { get; set; } = string.Empty; + /// Session IDs that should never be considered for pruning. + [JsonPropertyName("excludeSessionIds")] + public IList? ExcludeSessionIds { get; set; } + + /// When true, named sessions (set via /rename) are also eligible for pruning. + [JsonPropertyName("includeNamed")] + public bool? IncludeNamed { get; set; } + + /// Delete sessions whose modifiedTime is at least this many days old. + [JsonPropertyName("olderThanDays")] + public long OlderThanDays { get; set; } } -/// Patch for the singleton's steering state. +/// Flush a session's pending events to disk. No-op when no writer exists for the session (e.g., already closed). [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsSetRemoteControlSteeringRequest +public sealed class SessionsSaveResult { - /// Target steering state. Today only `true` is actionable on the underlying exporter; `false` is reserved for future use. - [JsonPropertyName("enabled")] - public bool Enabled { get; set; } } -/// Outcome of a stopRemoteControl call. +/// Session ID whose pending events should be flushed to disk. [Experimental(Diagnostics.Experimental)] -public sealed class RemoteControlStopResult +internal sealed class SessionsSaveRequest { - /// State of the runtime-managed remote-control singleton. - [JsonPropertyName("status")] - public RemoteControlStatus Status { get => field ??= new(); set; } - - /// Whether the singleton was actually torn down by this call. - [JsonPropertyName("stopped")] - public bool Stopped { get; set; } + /// Session ID whose pending events should be flushed to disk. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; } -/// RPC data type for SessionsStopRemoteControl operations. +/// Release the in-use lock held by this process for the given session. No-op when this process does not currently hold a lock for the session. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsStopRemoteControlRequest +public sealed class SessionsReleaseLockResult { - /// When provided, the stop is rejected unless the singleton currently points at this session id (compare-and-swap semantics). - [JsonPropertyName("expectedSessionId")] - public string? ExpectedSessionId { get; set; } - - /// When true, the singleton is unconditionally torn down regardless of `expectedSessionId`. Use during shutdown or explicit `/remote off`. - [JsonPropertyName("force")] - public bool? Force { get; set; } } -/// Schema for the `SessionsPollSpawnedSessionsEvent` type. +/// Session ID whose in-use lock should be released. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsPollSpawnedSessionsEvent +internal sealed class SessionsReleaseLockRequest { - /// Session id of the newly-spawned session. + /// Session ID whose in-use lock should be released. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; } -/// Batch of spawn events plus a cursor for follow-up polls. +/// Schema for the `LocalSessionMetadataValue` type. [Experimental(Diagnostics.Experimental)] -internal sealed class PollSpawnedSessionsResult +public sealed class LocalSessionMetadataValue { - /// Opaque cursor to pass back to receive only events after this batch. - [JsonPropertyName("cursor")] - public string Cursor { get; set; } = string.Empty; + /// Runtime client name that created/last resumed this session. + [JsonPropertyName("clientName")] + public string? ClientName { get; set; } - /// Spawn events emitted since the supplied cursor. - [JsonPropertyName("events")] - public IList Events { get => field ??= []; set; } + /// Pre-resolved working-directory context for session startup. + [JsonPropertyName("context")] + public SessionContext? Context { get; set; } + + /// True for detached maintenance sessions that should be hidden from normal resume lists. + [JsonPropertyName("isDetached")] + public bool? IsDetached { get; set; } + + /// Always false for local sessions. + [JsonPropertyName("isRemote")] + public bool IsRemote { get; set; } + + /// GitHub task ID, when this local session is bound to one. Only present for local sessions exported to remote control. + [JsonPropertyName("mcTaskId")] + public string? McTaskId { get; set; } + + /// Last-modified time of the session's persisted state, as ISO 8601. + [JsonPropertyName("modifiedTime")] + public string ModifiedTime { get; set; } = string.Empty; + + /// Optional human-friendly name set via /rename. + [JsonPropertyName("name")] + public string? Name { get; set; } + + /// Stable session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; + + /// Session creation time as an ISO 8601 timestamp. + [JsonPropertyName("startTime")] + public string StartTime { get; set; } = string.Empty; + + /// Short summary of the session, when one has been derived. + [JsonPropertyName("summary")] + public string? Summary { get; set; } } -/// RPC data type for SessionsPollSpawnedSessions operations. +/// The enriched metadata records, with summary and context fields backfilled where available. Sessions confirmed empty and unnamed are omitted. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionsPollSpawnedSessionsRequest +public sealed class SessionEnrichMetadataResult { - /// Opaque cursor returned by a previous poll. Omit on the first call to receive any spawn events buffered since the runtime started. - [JsonPropertyName("cursor")] - public string? Cursor { get; set; } - - /// Milliseconds to wait for new spawn events when the cursor is at the tail. 0 (default) returns immediately even if no events are buffered. Capped at 60000ms. - [JsonConverter(typeof(MillisecondsTimeSpanConverter))] - [JsonPropertyName("waitMs")] - public TimeSpan? Wait { get; set; } + /// Enriched records, with summary and context backfilled. Sessions confirmed empty and unnamed may be omitted. + [JsonPropertyName("sessions")] + public IList Sessions { get => field ??= []; set; } } -/// Handle for releasing the extension tool registration. +/// Session metadata records to enrich with summary and context information. [Experimental(Diagnostics.Experimental)] -internal sealed class RegisterExtensionToolsResult +internal sealed class SessionsEnrichMetadataRequest { - /// In-process unsubscribe function (CLI-only optimization). Marked internal: replaced by an explicit `extensions.unregister` RPC in the SDK migration. - [JsonInclude] - [JsonPropertyName("unsubscribe")] - internal JsonElement Unsubscribe { get; set; } + /// Session metadata records to enrich. Records that already have summary and context are returned unchanged. + [JsonPropertyName("sessions")] + public IList Sessions { get => field ??= []; set; } } -/// Optional registration options. +/// Reload all hooks (user, plugin, optionally repo) and apply them to the active session. Call after installing or removing plugins so their hooks take effect immediately. No-op when no active session matches the given sessionId. [Experimental(Diagnostics.Experimental)] -public sealed class SessionsRegisterExtensionToolsOnSessionOptions +public sealed class SessionsReloadPluginHooksResult { - /// In-process `() => boolean` gating callback (CLI-only optimization). Marked internal: replaced by runtime-side enable/disable RPCs in the SDK migration. - [JsonInclude] - [JsonPropertyName("enabled")] - internal JsonElement? Enabled { get; set; } } -/// Params to attach an extension loader's tools to a session. +/// Active session ID and an optional flag for deferring repo-level hooks until folder trust. [Experimental(Diagnostics.Experimental)] -internal sealed class RegisterExtensionToolsParams +internal sealed class SessionsReloadPluginHooksRequest { - /// In-process ExtensionLoader handle (CLI-only optimization). Marked internal: this field is excluded from the public SDK surface. When the CLI migrates to a process-separated SDK, extension discovery/launch moves entirely into the runtime — the CLI passes pure config (search paths, disabled ids) via SessionOptions instead. - [JsonInclude] - [JsonPropertyName("loader")] - internal JsonElement Loader { get; set; } - - /// Optional registration options. - [JsonPropertyName("options")] - public SessionsRegisterExtensionToolsOnSessionOptions? Options { get; set; } + /// When true, skip repo-level hooks. Use before folder trust is confirmed; loadDeferredRepoHooks loads them post-trust. + [JsonPropertyName("deferRepoHooks")] + public bool? DeferRepoHooks { get; set; } - /// Session to register extension tools on. + /// Active session ID to reload hooks for. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; } -/// Params to attach or detach an in-process ExtensionController delegate. +/// Queued repo-level startup prompts and the total hook command count after loading. [Experimental(Diagnostics.Experimental)] -internal sealed class ConfigureSessionExtensionsParams +public sealed class SessionLoadDeferredRepoHooksResult { - /// In-process ExtensionController delegate (CLI-only optimization). Marked internal: this field is excluded from the public SDK surface. The post-SDK extension surface exposes list/enable/disable/reload via dedicated RPCs served by the runtime. - [JsonInclude] - [JsonPropertyName("controller")] - internal JsonElement? Controller { get; set; } + /// Total hook command count (user + plugin + repo) loaded for the session by this call. Captured atomically with startupPrompts so callers don't need to read a separate counter. + [JsonPropertyName("hookCount")] + public long HookCount { get; set; } - /// Session to attach the extension controller delegate to. + /// Repo-level startup prompts queued from repo hook configs. Empty on resume, when no repo configs were pending, or when disableAllHooks is set. + [JsonPropertyName("startupPrompts")] + public IList StartupPrompts { get => field ??= []; set; } +} + +/// Active session ID whose deferred repo-level hooks should be loaded. +[Experimental(Diagnostics.Experimental)] +internal sealed class SessionsLoadDeferredRepoHooksRequest +{ + /// Active session ID whose deferred repo-level hooks should be loaded. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; } -/// Outcome of an agentRegistry.spawn call. -/// Polymorphic base type discriminated by kind. +/// Replace the manager-wide additional plugins. New session creations and subsequent hook reloads see the new set; already-running sessions keep their existing hook installation until the next reload. [Experimental(Diagnostics.Experimental)] -[JsonPolymorphic( - TypeDiscriminatorPropertyName = "kind", - UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] -[JsonDerivedType(typeof(AgentRegistrySpawnResultSpawned), "spawned")] -[JsonDerivedType(typeof(AgentRegistrySpawnResultSpawnError), "spawn-error")] -[JsonDerivedType(typeof(AgentRegistrySpawnResultRegistryTimeout), "registry-timeout")] -[JsonDerivedType(typeof(AgentRegistrySpawnResultValidationError), "validation-error")] -public partial class AgentRegistrySpawnResult +public sealed class SessionsSetAdditionalPluginsResult { - /// The type discriminator. - [JsonPropertyName("kind")] - public virtual string Kind { get; set; } = string.Empty; } - -/// Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). +/// Schema for the `InstalledPlugin` type. [Experimental(Diagnostics.Experimental)] -public sealed class AgentRegistryLiveTargetEntry +public sealed class InstalledPlugin { - /// Kind of attention required when status === "attention". Meaningful only when status === "attention". - [JsonPropertyName("attentionKind")] - public AgentRegistryLiveTargetEntryAttentionKind? AttentionKind { get; set; } - - /// Git branch of the session (when known). - [JsonPropertyName("branch")] - public string? Branch { get; set; } - - /// Copilot CLI version that wrote the entry. - [JsonPropertyName("copilotVersion")] - public string CopilotVersion { get; set; } = string.Empty; - - /// Working directory of the session (when known). - [JsonPropertyName("cwd")] - public string? Cwd { get; set; } - - /// Bind host for the entry's JSON-RPC server. - [JsonPropertyName("host")] - public string Host { get; set; } = string.Empty; - - /// Process kind tag for the registry entry. - [JsonPropertyName("kind")] - public AgentRegistryLiveTargetEntryKind Kind { get; set; } - - /// Wall-clock milliseconds since the watcher last observed this entry (heartbeat freshness). - [JsonPropertyName("lastSeenMs")] - public long LastSeenMs { get; set; } - - /// How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done from done_cancelled. - [JsonPropertyName("lastTerminalEvent")] - public AgentRegistryLiveTargetEntryLastTerminalEvent? LastTerminalEvent { get; set; } - - /// Model identifier currently selected for the session. - [JsonPropertyName("model")] - public string? Model { get; set; } - - /// Operating-system pid of the process owning this entry. - [JsonPropertyName("pid")] - public long Pid { get; set; } + /// Path where the plugin is cached locally. + [JsonPropertyName("cache_path")] + public string? CachePath { get; set; } - /// TCP port the entry's JSON-RPC server is listening on. - [JsonPropertyName("port")] - public long Port { get; set; } + /// Whether the plugin is currently enabled. + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } - /// Registry entry schema version (1 = ui-server, 2 = managed-server). - [JsonPropertyName("schemaVersion")] - public long SchemaVersion { get; set; } + /// Installation timestamp. + [JsonPropertyName("installed_at")] + public string InstalledAt { get; set; } = string.Empty; - /// Session ID of the foreground session for this entry. - [JsonPropertyName("sessionId")] - public string? SessionId { get; set; } + /// Marketplace the plugin came from (empty string for direct repo installs). + [JsonPropertyName("marketplace")] + public string Marketplace { get; set; } = string.Empty; - /// Friendly session name (when set). - [JsonPropertyName("sessionName")] - public string? SessionName { get; set; } + /// Plugin name. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; - /// ISO 8601 timestamp captured at registration. - [JsonPropertyName("startedAt")] - public string StartedAt { get; set; } = string.Empty; + /// Source for direct repo installs (when marketplace is empty). + [JsonPropertyName("source")] + public JsonElement? Source { get; set; } - /// Coarse lifecycle status of the foreground session. - [JsonPropertyName("status")] - public AgentRegistryLiveTargetEntryStatus? Status { get; set; } + /// Version installed (if available). + [JsonPropertyName("version")] + public string? Version { get; set; } +} - /// Monotonic per-publisher revision counter incremented on every status update. Lets watchers detect transient flips. - [JsonPropertyName("statusRevision")] - public long? StatusRevision { get; set; } +/// Manager-wide additional plugins to register; replaces any previously-configured set. +[Experimental(Diagnostics.Experimental)] +internal sealed class SessionsSetAdditionalPluginsRequest +{ + /// Manager-wide additional plugins to register. Replaces any previously-configured set. Pass an empty array to clear. + [JsonPropertyName("plugins")] + public IList Plugins { get => field ??= []; set; } +} - /// Connection token (null when the target is unauthenticated). - [JsonInclude] - [JsonPropertyName("token")] - internal string? Token { get; set; } +/// Dynamic-context board entry count, when available. +[Experimental(Diagnostics.Experimental)] +internal sealed class SessionsGetBoardEntryCountResult +{ + /// Board entry count, when available. + [JsonPropertyName("count")] + public long? Count { get; set; } } -/// Per-spawn log-capture outcome; populated from spawnLiveTarget. +/// Session ID whose board entry count should be returned. [Experimental(Diagnostics.Experimental)] -public sealed class AgentRegistryLogCapture +internal sealed class SessionsGetBoardEntryCountRequest { - /// Whether per-spawn log capture is on (false when env-disabled or open failed). - [JsonPropertyName("enabled")] - public bool Enabled { get; set; } - - /// Human-readable open failure message (only set when enabled === false AND the env-disable opt-out was NOT used). - [JsonPropertyName("openError")] - public string? OpenError { get; set; } - - /// Categorized reason for log-open failure. - [JsonPropertyName("openErrorReason")] - public AgentRegistryLogCaptureOpenErrorReason? OpenErrorReason { get; set; } - - /// Absolute path to the per-spawn log file (only set when enabled). - [JsonPropertyName("path")] - public string? Path { get; set; } + /// Session ID whose board entry count should be returned. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; } -/// Managed-server child was spawned and registered successfully. -/// The spawned variant of . +/// State of the runtime-managed remote-control singleton. +/// Polymorphic base type discriminated by state. [Experimental(Diagnostics.Experimental)] -public partial class AgentRegistrySpawnResultSpawned : AgentRegistrySpawnResult +[JsonPolymorphic( + TypeDiscriminatorPropertyName = "state", + UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] +[JsonDerivedType(typeof(RemoteControlStatusOff), "off")] +[JsonDerivedType(typeof(RemoteControlStatusConnecting), "connecting")] +[JsonDerivedType(typeof(RemoteControlStatusActive), "active")] +[JsonDerivedType(typeof(RemoteControlStatusError), "error")] +public partial class RemoteControlStatus { - /// - [JsonIgnore] - public override string Kind => "spawned"; - - /// Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). - [JsonPropertyName("entry")] - public required AgentRegistryLiveTargetEntry Entry { get; set; } - - /// If the delegate attempted to send the initial prompt and failed, the categorized error message. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("initialPromptError")] - public string? InitialPromptError { get; set; } - - /// Whether the delegate already sent the initial prompt. Always omitted in the current wiring: the controller sends the prompt post-attach via the standard LocalRpcSession.send path. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("initialPromptSent")] - public bool? InitialPromptSent { get; set; } - - /// Per-spawn log-capture outcome; populated from spawnLiveTarget. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("logCapture")] - public AgentRegistryLogCapture? LogCapture { get; set; } + /// The type discriminator. + [JsonPropertyName("state")] + public virtual string State { get; set; } = string.Empty; } -/// `child_process.spawn` itself failed before the child entered the registry. -/// The spawn-error variant of . + +/// Remote control is not connected. +/// The off variant of . [Experimental(Diagnostics.Experimental)] -public partial class AgentRegistrySpawnResultSpawnError : AgentRegistrySpawnResult +public partial class RemoteControlStatusOff : RemoteControlStatus { /// [JsonIgnore] - public override string Kind => "spawn-error"; - - /// Underlying errno code (e.g. ENOENT, EACCES) when available. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("code")] - public string? Code { get; set; } - - /// Human-readable error message. - [JsonPropertyName("message")] - public required string Message { get; set; } + public override string State => "off"; } -/// Spawn succeeded but the child did not publish a matching managed-server entry within the timeout. -/// The registry-timeout variant of . +/// Remote control is in the middle of initial setup. +/// The connecting variant of . [Experimental(Diagnostics.Experimental)] -public partial class AgentRegistrySpawnResultRegistryTimeout : AgentRegistrySpawnResult +public partial class RemoteControlStatusConnecting : RemoteControlStatus { /// [JsonIgnore] - public override string Kind => "registry-timeout"; - - /// Process ID of the orphaned child (so the caller can offer 'kill the pid' guidance). - [JsonPropertyName("childPid")] - public required long ChildPid { get; set; } + public override string State => "connecting"; - /// Per-spawn log-capture outcome; populated from spawnLiveTarget. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("logCapture")] - public AgentRegistryLogCapture? LogCapture { get; set; } + /// Session id the connection is attaching to. + [JsonPropertyName("attachedSessionId")] + public required string AttachedSessionId { get; set; } } -/// Synchronous pre-validation rejected the spawn request. -/// The validation-error variant of . +/// Remote control is connected to a local session. +/// The active variant of . [Experimental(Diagnostics.Experimental)] -public partial class AgentRegistrySpawnResultValidationError : AgentRegistrySpawnResult +public partial class RemoteControlStatusActive : RemoteControlStatus { /// [JsonIgnore] - public override string Kind => "validation-error"; + public override string State => "active"; - /// Which parameter field was invalid. Omitted when the rejection is not field-specific. + /// Session id remote control is pointed at. + [JsonPropertyName("attachedSessionId")] + public required string AttachedSessionId { get; set; } + + /// MC frontend URL for this session, when known. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("field")] - public AgentRegistrySpawnValidationErrorField? Field { get; set; } + [JsonPropertyName("frontendUrl")] + public string? FrontendUrl { get; set; } - /// Human-readable explanation; safe to surface in the UI banner. Never logged to unrestricted telemetry. - [JsonPropertyName("message")] - public required string Message { get; set; } + /// Whether the MC session may steer this session. + [JsonPropertyName("isSteerable")] + public required bool IsSteerable { get; set; } - /// Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by reason without leaking raw paths or agent/model names. - [JsonPropertyName("reason")] - public required AgentRegistrySpawnValidationErrorReason Reason { get; set; } + /// In-process prompt-manager handle (CLI-only optimization). Marked internal: this field is excluded from the public SDK surface. When the CLI migrates to a process-separated SDK, the same bidirectional prompt-routing handshake is expressed via dedicated remote-control RPCs (register/resolve) rather than a shared in-process object. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonInclude] + [JsonPropertyName("promptManager")] + internal JsonElement? PromptManager { get; set; } } -/// Inputs to spawn a managed-server child via the controller's spawn delegate. +/// The last setup attempt failed. The singleton is otherwise off. +/// The error variant of . [Experimental(Diagnostics.Experimental)] -internal sealed class AgentRegistrySpawnRequest +public partial class RemoteControlStatusError : RemoteControlStatus { - /// Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own default. - [JsonPropertyName("agentName")] - public string? AgentName { get; set; } - - /// Working directory for the spawned child (must be an existing directory). - [JsonPropertyName("cwd")] - public string Cwd { get; set; } = string.Empty; - - /// Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it post-attach via the standard LocalRpcSession.send path). - [JsonPropertyName("initialPrompt")] - public string? InitialPrompt { get; set; } - - /// Model identifier to apply to the new session. - [JsonPropertyName("model")] - public string? Model { get; set; } + /// + [JsonIgnore] + public override string State => "error"; - /// Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing whitespace, <=100 chars, no control chars, no double quotes. - [JsonPropertyName("name")] - public string? Name { get; set; } + /// Session id the failing setup attempt targeted, when known. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("attachedSessionId")] + public string? AttachedSessionId { get; set; } - /// Permission posture for the new session. 'yolo' requires the controller-local session to currently be in allow-all mode. - [JsonPropertyName("permissionMode")] - public AgentRegistrySpawnPermissionMode? PermissionMode { get; set; } + /// Human-readable error message from the last setup attempt. + [JsonPropertyName("error")] + public required string Error { get; set; } } -/// Identifies the target session. +/// Wrapper for the singleton's current status. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionSuspendRequest +public sealed class RemoteControlStatusResult { - /// Target session identifier. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// State of the runtime-managed remote-control singleton. + [JsonPropertyName("status")] + public RemoteControlStatus Status { get => field ??= new(); set; } } -/// Result of sending a user message. +/// Reattach to an existing MC session without creating a new one. [Experimental(Diagnostics.Experimental)] -public sealed class SendResult +public sealed class RemoteControlConfigExistingMcSession { - /// Unique identifier assigned to the message. - [JsonPropertyName("messageId")] - public string MessageId { get; set; } = string.Empty; + /// Existing MC session ID to reattach to. + [JsonPropertyName("mcSessionId")] + public string McSessionId { get; set; } = string.Empty; + + /// Existing MC task ID for the reattached session. + [JsonPropertyName("mcTaskId")] + public string McTaskId { get; set; } = string.Empty; } -/// Parameters for sending a user message to the session. +/// Configuration for the runtime-managed remote-control singleton. [Experimental(Diagnostics.Experimental)] -internal sealed class SendRequest +public sealed class RemoteControlConfig { - /// The UI mode the agent was in when this message was sent. Defaults to the session's current mode. - [JsonPropertyName("agentMode")] - public SendAgentMode? AgentMode { get; set; } - - /// Optional attachments (files, directories, selections, blobs, GitHub references) to include with the message. - [JsonPropertyName("attachments")] - public IList? Attachments { get; set; } - - /// If false, this message will not trigger a Premium Request Unit charge. User messages default to billable. - [JsonPropertyName("billable")] - public bool? Billable { get; set; } - - /// If provided, this is shown in the timeline instead of `prompt`. - [JsonPropertyName("displayPrompt")] - public string? DisplayPrompt { get; set; } - - /// How to deliver the message. `enqueue` (default) appends to the message queue. `immediate` interjects during an in-progress turn. - [JsonPropertyName("mode")] - public SendMode? Mode { get; set; } - - /// If true, adds the message to the front of the queue instead of the end. - [JsonPropertyName("prepend")] - public bool? Prepend { get; set; } - - /// The user message text. - [JsonPropertyName("prompt")] - public string Prompt { get; set; } = string.Empty; - - /// Custom HTTP headers to include in outbound model requests for this turn. Merged with session-level provider headers; per-turn headers augment and overwrite session-level headers with the same key. - [JsonPropertyName("requestHeaders")] - public IDictionary? RequestHeaders { get; set; } - - /// If set, the request will fail if the named tool is not available when this message is among the user messages at the start of the current exchange. - [JsonPropertyName("requiredTool")] - public string? RequiredTool { get; set; } + /// Reattach to an existing MC session without creating a new one. + [JsonPropertyName("existingMcSession")] + public RemoteControlConfigExistingMcSession? ExistingMcSession { get; set; } - /// Target session identifier. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// Whether the user explicitly requested remote (vs. implicit session-sync). Controls warning surfacing for missing-repo cases. + [JsonPropertyName("explicit")] + public bool Explicit { get; set; } - /// Optional provenance tag copied to the resulting user.message event. Must match one of three forms: the literal `system`, `command-<command-id>` for messages originating from a command (e.g. slash command, Mission Control command), or `schedule-<numeric-id>` for messages originating from a scheduled job. - [RegularExpression("^(system|command-.*|schedule-\\d+)$")] - [JsonInclude] - [JsonPropertyName("source")] - internal string? Source { get; set; } + /// Whether remote export should be enabled. + [JsonPropertyName("remote")] + public bool Remote { get; set; } - /// W3C Trace Context traceparent header for distributed tracing of this agent turn. - [JsonPropertyName("traceparent")] - public string? Traceparent { get; set; } + /// When true, suppresses timeline messages on successful setup. + [JsonPropertyName("silent")] + public bool Silent { get; set; } - /// W3C Trace Context tracestate header for distributed tracing. - [JsonPropertyName("tracestate")] - public string? Tracestate { get; set; } + /// Whether the MC session may steer the local session (write mode). + [JsonPropertyName("steerable")] + public bool Steerable { get; set; } - /// If true, await completion of the agentic loop for this message before returning. Defaults to false (fire-and-forget). When true, the result still contains the same `messageId`; the caller can rely on the agent having processed the message before the call resolves. - [JsonPropertyName("wait")] - public bool? Wait { get; set; } + /// Existing Mission Control task ID to attach the exported session to. + [JsonPropertyName("taskId")] + public string? TaskId { get; set; } } -/// Result of aborting the current turn. +/// Parameters for attaching the remote-control singleton to a session. [Experimental(Diagnostics.Experimental)] -public sealed class AbortResult +internal sealed class SessionsStartRemoteControlRequest { - /// Error message if the abort failed. - [JsonPropertyName("error")] - public string? Error { get; set; } + /// Configuration for the runtime-managed remote-control singleton. + [JsonPropertyName("config")] + public RemoteControlConfig Config { get => field ??= new(); set; } - /// Whether the abort completed successfully. - [JsonPropertyName("success")] - public bool Success { get; set; } + /// Local session id to attach remote control to. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; } -/// Parameters for aborting the current turn. +/// Outcome of a transferRemoteControl call. [Experimental(Diagnostics.Experimental)] -internal sealed class AbortRequest +public sealed class RemoteControlTransferResult { - /// Finite reason code describing why the current turn was aborted. - [JsonPropertyName("reason")] - public AbortReason? Reason { get; set; } + /// State of the runtime-managed remote-control singleton. + [JsonPropertyName("status")] + public RemoteControlStatus Status { get => field ??= new(); set; } - /// Target session identifier. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// Whether the rebinding actually happened. + [JsonPropertyName("transferred")] + public bool Transferred { get; set; } } -/// Parameters for shutting down the session. +/// Parameters for atomically rebinding the remote-control singleton. [Experimental(Diagnostics.Experimental)] -internal sealed class ShutdownRequest +internal sealed class SessionsTransferRemoteControlRequest { - /// Optional human-readable reason. Typically the message of the error that triggered shutdown when type is 'error'. - [JsonPropertyName("reason")] - public string? Reason { get; set; } - - /// Target session identifier. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// When provided, the transfer is rejected unless the singleton currently points at this session id (compare-and-swap semantics to avoid clobbering newer state). + [JsonPropertyName("expectedFromSessionId")] + public string? ExpectedFromSessionId { get; set; } - /// Why the session is being shut down. Defaults to "routine" when omitted. - [JsonPropertyName("type")] - public ShutdownType? Type { get; set; } + /// Local session id to point remote control at. + [JsonPropertyName("toSessionId")] + public string ToSessionId { get; set; } = string.Empty; } -/// Identifier of the session event that was emitted for the log message. +/// Patch for the singleton's steering state. [Experimental(Diagnostics.Experimental)] -public sealed class LogResult +internal sealed class SessionsSetRemoteControlSteeringRequest { - /// The unique identifier of the emitted session event. - [JsonPropertyName("eventId")] - public Guid EventId { get; set; } + /// Target steering state. Today only `true` is actionable on the underlying exporter; `false` is reserved for future use. + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } } -/// Message text, optional severity level, persistence flag, optional follow-up URL, and optional tip. +/// Outcome of a stopRemoteControl call. [Experimental(Diagnostics.Experimental)] -internal sealed class LogRequest +public sealed class RemoteControlStopResult { - /// When true, the message is transient and not persisted to the session event log on disk. - [JsonPropertyName("ephemeral")] - public bool? Ephemeral { get; set; } + /// State of the runtime-managed remote-control singleton. + [JsonPropertyName("status")] + public RemoteControlStatus Status { get => field ??= new(); set; } - /// Log severity level. Determines how the message is displayed in the timeline. Defaults to "info". - [JsonPropertyName("level")] - public SessionLogLevel? Level { get; set; } + /// Whether the singleton was actually torn down by this call. + [JsonPropertyName("stopped")] + public bool Stopped { get; set; } +} - /// Human-readable message. - [JsonPropertyName("message")] - public string Message { get; set; } = string.Empty; +/// RPC data type for SessionsStopRemoteControl operations. +[Experimental(Diagnostics.Experimental)] +internal sealed class SessionsStopRemoteControlRequest +{ + /// When provided, the stop is rejected unless the singleton currently points at this session id (compare-and-swap semantics). + [JsonPropertyName("expectedSessionId")] + public string? ExpectedSessionId { get; set; } - /// Target session identifier. + /// When true, the singleton is unconditionally torn down regardless of `expectedSessionId`. Use during shutdown or explicit `/remote off`. + [JsonPropertyName("force")] + public bool? Force { get; set; } +} + +/// Schema for the `SessionsPollSpawnedSessionsEvent` type. +[Experimental(Diagnostics.Experimental)] +public sealed class SessionsPollSpawnedSessionsEvent +{ + /// Session id of the newly-spawned session. [JsonPropertyName("sessionId")] public string SessionId { get; set; } = string.Empty; - - /// Optional actionable tip displayed alongside the message. Only honored on `level: "info"`. - [JsonPropertyName("tip")] - public string? Tip { get; set; } - - /// Domain category for this log entry (e.g., "mcp", "subscription", "policy", "model"). Maps to `infoType`/`warningType`/`errorType` on the emitted event. Defaults to "notification". - [JsonPropertyName("type")] - public string? Type { get; set; } - - /// Optional URL the user can open in their browser for more details. - [Url] - [StringSyntax(StringSyntaxAttribute.Uri)] - [JsonPropertyName("url")] - public string? Url { get; set; } } -/// Authentication status and account metadata for the session. +/// Batch of spawn events plus a cursor for follow-up polls. [Experimental(Diagnostics.Experimental)] -public sealed class SessionAuthStatus +internal sealed class PollSpawnedSessionsResult { - /// Authentication type. - [JsonPropertyName("authType")] - public AuthInfoType? AuthType { get; set; } - - /// Copilot plan tier (e.g., individual_pro, business). - [JsonPropertyName("copilotPlan")] - public string? CopilotPlan { get; set; } - - /// Authentication host URL. - [Url] - [StringSyntax(StringSyntaxAttribute.Uri)] - [JsonPropertyName("host")] - public string? Host { get; set; } - - /// Whether the session has resolved authentication. - [JsonPropertyName("isAuthenticated")] - public bool IsAuthenticated { get; set; } - - /// Authenticated login/username, if available. - [JsonPropertyName("login")] - public string? Login { get; set; } + /// Opaque cursor to pass back to receive only events after this batch. + [JsonPropertyName("cursor")] + public string Cursor { get; set; } = string.Empty; - /// Human-readable authentication status description. - [JsonPropertyName("statusMessage")] - public string? StatusMessage { get; set; } + /// Spawn events emitted since the supplied cursor. + [JsonPropertyName("events")] + public IList Events { get => field ??= []; set; } } -/// Identifies the target session. +/// RPC data type for SessionsPollSpawnedSessions operations. [Experimental(Diagnostics.Experimental)] -internal sealed class SessionAuthGetStatusRequest +internal sealed class SessionsPollSpawnedSessionsRequest { - /// Target session identifier. - [JsonPropertyName("sessionId")] - public string SessionId { get; set; } = string.Empty; + /// Opaque cursor returned by a previous poll. Omit on the first call to receive any spawn events buffered since the runtime started. + [JsonPropertyName("cursor")] + public string? Cursor { get; set; } + + /// Milliseconds to wait for new spawn events when the cursor is at the tail. 0 (default) returns immediately even if no events are buffered. Capped at 60000ms. + [JsonConverter(typeof(MillisecondsTimeSpanConverter))] + [JsonPropertyName("waitMs")] + public TimeSpan? Wait { get; set; } } -/// Indicates whether the credential update succeeded. +/// Handle for releasing the extension tool registration. [Experimental(Diagnostics.Experimental)] -public sealed class SessionSetCredentialsResult +internal sealed class RegisterExtensionToolsResult { - /// Whether the operation succeeded. - [JsonPropertyName("success")] - public bool Success { get; set; } + /// In-process unsubscribe function (CLI-only optimization). Marked internal: replaced by an explicit `extensions.unregister` RPC in the SDK migration. + [JsonInclude] + [JsonPropertyName("unsubscribe")] + internal JsonElement Unsubscribe { get; set; } } -/// Initial authentication info for the session. -/// Polymorphic base type discriminated by type. +/// Optional registration options. [Experimental(Diagnostics.Experimental)] -[JsonPolymorphic( - TypeDiscriminatorPropertyName = "type", - UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] -[JsonDerivedType(typeof(AuthInfoHmac), "hmac")] -[JsonDerivedType(typeof(AuthInfoEnv), "env")] -[JsonDerivedType(typeof(AuthInfoToken), "token")] -[JsonDerivedType(typeof(AuthInfoCopilotApiToken), "copilot-api-token")] -[JsonDerivedType(typeof(AuthInfoUser), "user")] -[JsonDerivedType(typeof(AuthInfoGhCli), "gh-cli")] -[JsonDerivedType(typeof(AuthInfoApiKey), "api-key")] -public partial class AuthInfo +public sealed class SessionsRegisterExtensionToolsOnSessionOptions { - /// The type discriminator. - [JsonPropertyName("type")] - public virtual string Type { get; set; } = string.Empty; + /// In-process `() => boolean` gating callback (CLI-only optimization). Marked internal: replaced by runtime-side enable/disable RPCs in the SDK migration. + [JsonInclude] + [JsonPropertyName("enabled")] + internal JsonElement? Enabled { get; set; } } - -/// Schema for the `CopilotUserResponseEndpoints` type. +/// Params to attach an extension loader's tools to a session. [Experimental(Diagnostics.Experimental)] -public sealed class CopilotUserResponseEndpoints +internal sealed class RegisterExtensionToolsParams { - /// Gets or sets the api value. - [JsonPropertyName("api")] - public string? Api { get; set; } + /// In-process ExtensionLoader handle (CLI-only optimization). Marked internal: this field is excluded from the public SDK surface. When the CLI migrates to a process-separated SDK, extension discovery/launch moves entirely into the runtime — the CLI passes pure config (search paths, disabled ids) via SessionOptions instead. + [JsonInclude] + [JsonPropertyName("loader")] + internal JsonElement Loader { get; set; } - /// Gets or sets the origin-tracker value. - [JsonPropertyName("origin-tracker")] - public string? OriginTracker { get; set; } + /// Optional registration options. + [JsonPropertyName("options")] + public SessionsRegisterExtensionToolsOnSessionOptions? Options { get; set; } - /// Gets or sets the proxy value. - [JsonPropertyName("proxy")] - public string? Proxy { get; set; } + /// Session to register extension tools on. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} - /// Gets or sets the telemetry value. - [JsonPropertyName("telemetry")] - public string? Telemetry { get; set; } +/// Params to attach or detach an in-process ExtensionController delegate. +[Experimental(Diagnostics.Experimental)] +internal sealed class ConfigureSessionExtensionsParams +{ + /// In-process ExtensionController delegate (CLI-only optimization). Marked internal: this field is excluded from the public SDK surface. The post-SDK extension surface exposes list/enable/disable/reload via dedicated RPCs served by the runtime. + [JsonInclude] + [JsonPropertyName("controller")] + internal JsonElement? Controller { get; set; } + + /// Session to attach the extension controller delegate to. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; } -/// RPC data type for CopilotUserResponseOrganizationListItem operations. -public sealed class CopilotUserResponseOrganizationListItem +/// Outcome of an agentRegistry.spawn call. +/// Polymorphic base type discriminated by kind. +[Experimental(Diagnostics.Experimental)] +[JsonPolymorphic( + TypeDiscriminatorPropertyName = "kind", + UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] +[JsonDerivedType(typeof(AgentRegistrySpawnResultSpawned), "spawned")] +[JsonDerivedType(typeof(AgentRegistrySpawnResultSpawnError), "spawn-error")] +[JsonDerivedType(typeof(AgentRegistrySpawnResultRegistryTimeout), "registry-timeout")] +[JsonDerivedType(typeof(AgentRegistrySpawnResultValidationError), "validation-error")] +public partial class AgentRegistrySpawnResult { - /// Gets or sets the login value. - [JsonPropertyName("login")] - public string? Login { get; set; } - - /// Gets or sets the name value. - [JsonPropertyName("name")] - public string? Name { get; set; } + /// The type discriminator. + [JsonPropertyName("kind")] + public virtual string Kind { get; set; } = string.Empty; } -/// Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. + +/// Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). [Experimental(Diagnostics.Experimental)] -public sealed class CopilotUserResponseQuotaSnapshotsChat +public sealed class AgentRegistryLiveTargetEntry { - /// Gets or sets the entitlement value. - [JsonPropertyName("entitlement")] - public double? Entitlement { get; set; } - - /// Gets or sets the has_quota value. - [JsonPropertyName("has_quota")] - public bool? HasQuota { get; set; } - - /// Gets or sets the overage_count value. - [JsonPropertyName("overage_count")] - public double? OverageCount { get; set; } + /// Kind of attention required when status === "attention". Meaningful only when status === "attention". + [JsonPropertyName("attentionKind")] + public AgentRegistryLiveTargetEntryAttentionKind? AttentionKind { get; set; } - /// Gets or sets the overage_permitted value. - [JsonPropertyName("overage_permitted")] - public bool? OveragePermitted { get; set; } + /// Git branch of the session (when known). + [JsonPropertyName("branch")] + public string? Branch { get; set; } - /// Gets or sets the percent_remaining value. - [JsonPropertyName("percent_remaining")] - public double? PercentRemaining { get; set; } + /// Copilot CLI version that wrote the entry. + [JsonPropertyName("copilotVersion")] + public string CopilotVersion { get; set; } = string.Empty; - /// Gets or sets the quota_id value. - [JsonPropertyName("quota_id")] - public string? QuotaId { get; set; } + /// Working directory of the session (when known). + [JsonPropertyName("cwd")] + public string? Cwd { get; set; } - /// Gets or sets the quota_remaining value. - [JsonPropertyName("quota_remaining")] - public double? QuotaRemaining { get; set; } + /// Bind host for the entry's JSON-RPC server. + [JsonPropertyName("host")] + public string Host { get; set; } = string.Empty; - /// Gets or sets the quota_reset_at value. - [JsonPropertyName("quota_reset_at")] - public double? QuotaResetAt { get; set; } + /// Process kind tag for the registry entry. + [JsonPropertyName("kind")] + public AgentRegistryLiveTargetEntryKind Kind { get; set; } - /// Gets or sets the remaining value. - [JsonPropertyName("remaining")] - public double? Remaining { get; set; } + /// Wall-clock milliseconds since the watcher last observed this entry (heartbeat freshness). + [JsonPropertyName("lastSeenMs")] + public long LastSeenMs { get; set; } - /// Gets or sets the timestamp_utc value. - [JsonPropertyName("timestamp_utc")] - public string? TimestampUtc { get; set; } + /// How the most recent turn ended (clean vs aborted). Lets the renderer distinguish done from done_cancelled. + [JsonPropertyName("lastTerminalEvent")] + public AgentRegistryLiveTargetEntryLastTerminalEvent? LastTerminalEvent { get; set; } - /// Gets or sets the token_based_billing value. - [JsonPropertyName("token_based_billing")] - public bool? TokenBasedBilling { get; set; } + /// Model identifier currently selected for the session. + [JsonPropertyName("model")] + public string? Model { get; set; } - /// Gets or sets the unlimited value. - [JsonPropertyName("unlimited")] - public bool? Unlimited { get; set; } -} + /// Operating-system pid of the process owning this entry. + [JsonPropertyName("pid")] + public long Pid { get; set; } -/// Schema for the `CopilotUserResponseQuotaSnapshotsCompletions` type. -[Experimental(Diagnostics.Experimental)] -public sealed class CopilotUserResponseQuotaSnapshotsCompletions -{ - /// Gets or sets the entitlement value. - [JsonPropertyName("entitlement")] - public double? Entitlement { get; set; } + /// TCP port the entry's JSON-RPC server is listening on. + [JsonPropertyName("port")] + public long Port { get; set; } - /// Gets or sets the has_quota value. - [JsonPropertyName("has_quota")] - public bool? HasQuota { get; set; } + /// Registry entry schema version (1 = ui-server, 2 = managed-server). + [JsonPropertyName("schemaVersion")] + public long SchemaVersion { get; set; } - /// Gets or sets the overage_count value. - [JsonPropertyName("overage_count")] - public double? OverageCount { get; set; } + /// Session ID of the foreground session for this entry. + [JsonPropertyName("sessionId")] + public string? SessionId { get; set; } - /// Gets or sets the overage_permitted value. - [JsonPropertyName("overage_permitted")] - public bool? OveragePermitted { get; set; } + /// Friendly session name (when set). + [JsonPropertyName("sessionName")] + public string? SessionName { get; set; } - /// Gets or sets the percent_remaining value. - [JsonPropertyName("percent_remaining")] - public double? PercentRemaining { get; set; } + /// ISO 8601 timestamp captured at registration. + [JsonPropertyName("startedAt")] + public string StartedAt { get; set; } = string.Empty; - /// Gets or sets the quota_id value. - [JsonPropertyName("quota_id")] - public string? QuotaId { get; set; } + /// Coarse lifecycle status of the foreground session. + [JsonPropertyName("status")] + public AgentRegistryLiveTargetEntryStatus? Status { get; set; } - /// Gets or sets the quota_remaining value. - [JsonPropertyName("quota_remaining")] - public double? QuotaRemaining { get; set; } + /// Monotonic per-publisher revision counter incremented on every status update. Lets watchers detect transient flips. + [JsonPropertyName("statusRevision")] + public long? StatusRevision { get; set; } - /// Gets or sets the quota_reset_at value. - [JsonPropertyName("quota_reset_at")] - public double? QuotaResetAt { get; set; } + /// Connection token (null when the target is unauthenticated). + [JsonInclude] + [JsonPropertyName("token")] + internal string? Token { get; set; } +} - /// Gets or sets the remaining value. - [JsonPropertyName("remaining")] - public double? Remaining { get; set; } +/// Per-spawn log-capture outcome; populated from spawnLiveTarget. +[Experimental(Diagnostics.Experimental)] +public sealed class AgentRegistryLogCapture +{ + /// Whether per-spawn log capture is on (false when env-disabled or open failed). + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } - /// Gets or sets the timestamp_utc value. - [JsonPropertyName("timestamp_utc")] - public string? TimestampUtc { get; set; } + /// Human-readable open failure message (only set when enabled === false AND the env-disable opt-out was NOT used). + [JsonPropertyName("openError")] + public string? OpenError { get; set; } - /// Gets or sets the token_based_billing value. - [JsonPropertyName("token_based_billing")] - public bool? TokenBasedBilling { get; set; } + /// Categorized reason for log-open failure. + [JsonPropertyName("openErrorReason")] + public AgentRegistryLogCaptureOpenErrorReason? OpenErrorReason { get; set; } - /// Gets or sets the unlimited value. - [JsonPropertyName("unlimited")] - public bool? Unlimited { get; set; } + /// Absolute path to the per-spawn log file (only set when enabled). + [JsonPropertyName("path")] + public string? Path { get; set; } } -/// Schema for the `CopilotUserResponseQuotaSnapshotsPremiumInteractions` type. +/// Managed-server child was spawned and registered successfully. +/// The spawned variant of . [Experimental(Diagnostics.Experimental)] -public sealed class CopilotUserResponseQuotaSnapshotsPremiumInteractions +public partial class AgentRegistrySpawnResultSpawned : AgentRegistrySpawnResult { - /// Gets or sets the entitlement value. - [JsonPropertyName("entitlement")] - public double? Entitlement { get; set; } - - /// Gets or sets the has_quota value. - [JsonPropertyName("has_quota")] - public bool? HasQuota { get; set; } - - /// Gets or sets the overage_count value. - [JsonPropertyName("overage_count")] - public double? OverageCount { get; set; } + /// + [JsonIgnore] + public override string Kind => "spawned"; - /// Gets or sets the overage_permitted value. - [JsonPropertyName("overage_permitted")] - public bool? OveragePermitted { get; set; } + /// Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). + [JsonPropertyName("entry")] + public required AgentRegistryLiveTargetEntry Entry { get; set; } - /// Gets or sets the percent_remaining value. - [JsonPropertyName("percent_remaining")] - public double? PercentRemaining { get; set; } + /// If the delegate attempted to send the initial prompt and failed, the categorized error message. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("initialPromptError")] + public string? InitialPromptError { get; set; } - /// Gets or sets the quota_id value. - [JsonPropertyName("quota_id")] - public string? QuotaId { get; set; } + /// Whether the delegate already sent the initial prompt. Always omitted in the current wiring: the controller sends the prompt post-attach via the standard LocalRpcSession.send path. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("initialPromptSent")] + public bool? InitialPromptSent { get; set; } - /// Gets or sets the quota_remaining value. - [JsonPropertyName("quota_remaining")] - public double? QuotaRemaining { get; set; } + /// Per-spawn log-capture outcome; populated from spawnLiveTarget. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("logCapture")] + public AgentRegistryLogCapture? LogCapture { get; set; } +} - /// Gets or sets the quota_reset_at value. - [JsonPropertyName("quota_reset_at")] - public double? QuotaResetAt { get; set; } +/// `child_process.spawn` itself failed before the child entered the registry. +/// The spawn-error variant of . +[Experimental(Diagnostics.Experimental)] +public partial class AgentRegistrySpawnResultSpawnError : AgentRegistrySpawnResult +{ + /// + [JsonIgnore] + public override string Kind => "spawn-error"; - /// Gets or sets the remaining value. - [JsonPropertyName("remaining")] - public double? Remaining { get; set; } + /// Underlying errno code (e.g. ENOENT, EACCES) when available. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("code")] + public string? Code { get; set; } - /// Gets or sets the timestamp_utc value. - [JsonPropertyName("timestamp_utc")] - public string? TimestampUtc { get; set; } + /// Human-readable error message. + [JsonPropertyName("message")] + public required string Message { get; set; } +} - /// Gets or sets the token_based_billing value. - [JsonPropertyName("token_based_billing")] - public bool? TokenBasedBilling { get; set; } +/// Spawn succeeded but the child did not publish a matching managed-server entry within the timeout. +/// The registry-timeout variant of . +[Experimental(Diagnostics.Experimental)] +public partial class AgentRegistrySpawnResultRegistryTimeout : AgentRegistrySpawnResult +{ + /// + [JsonIgnore] + public override string Kind => "registry-timeout"; - /// Gets or sets the unlimited value. - [JsonPropertyName("unlimited")] - public bool? Unlimited { get; set; } + /// Process ID of the orphaned child (so the caller can offer 'kill the pid' guidance). + [JsonPropertyName("childPid")] + public required long ChildPid { get; set; } + + /// Per-spawn log-capture outcome; populated from spawnLiveTarget. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("logCapture")] + public AgentRegistryLogCapture? LogCapture { get; set; } } -/// Schema for the `CopilotUserResponseQuotaSnapshots` type. +/// Synchronous pre-validation rejected the spawn request. +/// The validation-error variant of . [Experimental(Diagnostics.Experimental)] -public sealed class CopilotUserResponseQuotaSnapshots +public partial class AgentRegistrySpawnResultValidationError : AgentRegistrySpawnResult { - /// Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. - [JsonPropertyName("chat")] - public CopilotUserResponseQuotaSnapshotsChat? Chat { get; set; } + /// + [JsonIgnore] + public override string Kind => "validation-error"; - /// Schema for the `CopilotUserResponseQuotaSnapshotsCompletions` type. - [JsonPropertyName("completions")] - public CopilotUserResponseQuotaSnapshotsCompletions? Completions { get; set; } + /// Which parameter field was invalid. Omitted when the rejection is not field-specific. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("field")] + public AgentRegistrySpawnValidationErrorField? Field { get; set; } - /// Schema for the `CopilotUserResponseQuotaSnapshotsPremiumInteractions` type. - [JsonPropertyName("premium_interactions")] - public CopilotUserResponseQuotaSnapshotsPremiumInteractions? PremiumInteractions { get; set; } + /// Human-readable explanation; safe to surface in the UI banner. Never logged to unrestricted telemetry. + [JsonPropertyName("message")] + public required string Message { get; set; } + + /// Categorized reason for the rejection. Low-cardinality enum so telemetry can aggregate by reason without leaking raw paths or agent/model names. + [JsonPropertyName("reason")] + public required AgentRegistrySpawnValidationErrorReason Reason { get; set; } } -/// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. +/// Inputs to spawn a managed-server child via the controller's spawn delegate. [Experimental(Diagnostics.Experimental)] -public sealed class CopilotUserResponse +internal sealed class AgentRegistrySpawnRequest { - /// Gets or sets the access_type_sku value. - [JsonPropertyName("access_type_sku")] - public string? AccessTypeSku { get; set; } - - /// Gets or sets the analytics_tracking_id value. - [JsonPropertyName("analytics_tracking_id")] - public string? AnalyticsTrackingId { get; set; } - - /// Gets or sets the assigned_date value. - [JsonPropertyName("assigned_date")] - public string? AssignedDate { get; set; } - - /// Gets or sets the can_signup_for_limited value. - [JsonPropertyName("can_signup_for_limited")] - public bool? CanSignupForLimited { get; set; } + /// Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own default. + [JsonPropertyName("agentName")] + public string? AgentName { get; set; } - /// Gets or sets the can_upgrade_plan value. - [JsonPropertyName("can_upgrade_plan")] - public bool? CanUpgradePlan { get; set; } + /// Working directory for the spawned child (must be an existing directory). + [JsonPropertyName("cwd")] + public string Cwd { get; set; } = string.Empty; - /// Gets or sets the chat_enabled value. - [JsonPropertyName("chat_enabled")] - public bool? ChatEnabled { get; set; } + /// Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it post-attach via the standard LocalRpcSession.send path). + [JsonPropertyName("initialPrompt")] + public string? InitialPrompt { get; set; } - /// Gets or sets the cli_remote_control_enabled value. - [JsonPropertyName("cli_remote_control_enabled")] - public bool? CliRemoteControlEnabled { get; set; } + /// Model identifier to apply to the new session. + [JsonPropertyName("model")] + public string? Model { get; set; } - /// Gets or sets the cloud_session_storage_enabled value. - [JsonPropertyName("cloud_session_storage_enabled")] - public bool? CloudSessionStorageEnabled { get; set; } + /// Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing whitespace, <=100 chars, no control chars, no double quotes. + [JsonPropertyName("name")] + public string? Name { get; set; } - /// Gets or sets the codex_agent_enabled value. - [JsonPropertyName("codex_agent_enabled")] - public bool? CodexAgentEnabled { get; set; } + /// Permission posture for the new session. 'yolo' requires the controller-local session to currently be in allow-all mode. + [JsonPropertyName("permissionMode")] + public AgentRegistrySpawnPermissionMode? PermissionMode { get; set; } +} - /// Gets or sets the copilot_plan value. - [JsonPropertyName("copilot_plan")] - public string? CopilotPlan { get; set; } +/// Identifies the target session. +[Experimental(Diagnostics.Experimental)] +internal sealed class SessionSuspendRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} - /// Gets or sets the copilotignore_enabled value. - [JsonPropertyName("copilotignore_enabled")] - public bool? CopilotignoreEnabled { get; set; } +/// Result of sending a user message. +[Experimental(Diagnostics.Experimental)] +public sealed class SendResult +{ + /// Unique identifier assigned to the message. + [JsonPropertyName("messageId")] + public string MessageId { get; set; } = string.Empty; +} - /// Schema for the `CopilotUserResponseEndpoints` type. - [JsonPropertyName("endpoints")] - public CopilotUserResponseEndpoints? Endpoints { get; set; } +/// Parameters for sending a user message to the session. +[Experimental(Diagnostics.Experimental)] +internal sealed class SendRequest +{ + /// The UI mode the agent was in when this message was sent. Defaults to the session's current mode. + [JsonPropertyName("agentMode")] + public SendAgentMode? AgentMode { get; set; } - /// Gets or sets the is_mcp_enabled value. - [JsonPropertyName("is_mcp_enabled")] - public bool? IsMcpEnabled { get; set; } + /// Optional attachments (files, directories, selections, blobs, GitHub references) to include with the message. + [JsonPropertyName("attachments")] + public IList? Attachments { get; set; } - /// Gets or sets the is_staff value. - [JsonPropertyName("is_staff")] - public bool? IsStaff { get; set; } + /// If false, this message will not trigger a Premium Request Unit charge. User messages default to billable. + [JsonPropertyName("billable")] + public bool? Billable { get; set; } - /// Gets or sets the limited_user_quotas value. - [JsonPropertyName("limited_user_quotas")] - public IDictionary? LimitedUserQuotas { get; set; } + /// If provided, this is shown in the timeline instead of `prompt`. + [JsonPropertyName("displayPrompt")] + public string? DisplayPrompt { get; set; } - /// Gets or sets the limited_user_reset_date value. - [JsonPropertyName("limited_user_reset_date")] - public string? LimitedUserResetDate { get; set; } + /// How to deliver the message. `enqueue` (default) appends to the message queue. `immediate` interjects during an in-progress turn. + [JsonPropertyName("mode")] + public SendMode? Mode { get; set; } - /// Gets or sets the login value. - [JsonPropertyName("login")] - public string? Login { get; set; } + /// If true, adds the message to the front of the queue instead of the end. + [JsonPropertyName("prepend")] + public bool? Prepend { get; set; } - /// Gets or sets the monthly_quotas value. - [JsonPropertyName("monthly_quotas")] - public IDictionary? MonthlyQuotas { get; set; } + /// The user message text. + [JsonPropertyName("prompt")] + public string Prompt { get; set; } = string.Empty; - /// Gets or sets the organization_list value. - [JsonPropertyName("organization_list")] - public IList? OrganizationList { get; set; } + /// Custom HTTP headers to include in outbound model requests for this turn. Merged with session-level provider headers; per-turn headers augment and overwrite session-level headers with the same key. + [JsonPropertyName("requestHeaders")] + public IDictionary? RequestHeaders { get; set; } - /// Gets or sets the organization_login_list value. - [JsonPropertyName("organization_login_list")] - public IList? OrganizationLoginList { get; set; } + /// If set, the request will fail if the named tool is not available when this message is among the user messages at the start of the current exchange. + [JsonPropertyName("requiredTool")] + public string? RequiredTool { get; set; } - /// Gets or sets the quota_reset_date value. - [JsonPropertyName("quota_reset_date")] - public string? QuotaResetDate { get; set; } + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; - /// Gets or sets the quota_reset_date_utc value. - [JsonPropertyName("quota_reset_date_utc")] - public string? QuotaResetDateUtc { get; set; } + /// Optional provenance tag copied to the resulting user.message event. Must match one of three forms: the literal `system`, `command-<command-id>` for messages originating from a command (e.g. slash command, Mission Control command), or `schedule-<numeric-id>` for messages originating from a scheduled job. + [RegularExpression("^(system|command-.*|schedule-\\d+)$")] + [JsonInclude] + [JsonPropertyName("source")] + internal string? Source { get; set; } - /// Schema for the `CopilotUserResponseQuotaSnapshots` type. - [JsonPropertyName("quota_snapshots")] - public CopilotUserResponseQuotaSnapshots? QuotaSnapshots { get; set; } + /// W3C Trace Context traceparent header for distributed tracing of this agent turn. + [JsonPropertyName("traceparent")] + public string? Traceparent { get; set; } - /// Gets or sets the restricted_telemetry value. - [JsonPropertyName("restricted_telemetry")] - public bool? RestrictedTelemetry { get; set; } + /// W3C Trace Context tracestate header for distributed tracing. + [JsonPropertyName("tracestate")] + public string? Tracestate { get; set; } - /// Gets or sets the token_based_billing value. - [JsonPropertyName("token_based_billing")] - public bool? TokenBasedBilling { get; set; } + /// If true, await completion of the agentic loop for this message before returning. Defaults to false (fire-and-forget). When true, the result still contains the same `messageId`; the caller can rely on the agent having processed the message before the call resolves. + [JsonPropertyName("wait")] + public bool? Wait { get; set; } } -/// Schema for the `HMACAuthInfo` type. -/// The hmac variant of . +/// Result of aborting the current turn. [Experimental(Diagnostics.Experimental)] -public partial class AuthInfoHmac : AuthInfo +public sealed class AbortResult { - /// - [JsonIgnore] - public override string Type => "hmac"; - - /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("copilotUser")] - public CopilotUserResponse? CopilotUser { get; set; } - - /// HMAC secret used to sign requests. - [JsonPropertyName("hmac")] - public required string Hmac { get; set; } + /// Error message if the abort failed. + [JsonPropertyName("error")] + public string? Error { get; set; } - /// Authentication host. HMAC auth always targets the public GitHub host. - [JsonPropertyName("host")] - public required string Host { get; set; } + /// Whether the abort completed successfully. + [JsonPropertyName("success")] + public bool Success { get; set; } } -/// Schema for the `EnvAuthInfo` type. -/// The env variant of . +/// Parameters for aborting the current turn. [Experimental(Diagnostics.Experimental)] -public partial class AuthInfoEnv : AuthInfo +internal sealed class AbortRequest { - /// - [JsonIgnore] - public override string Type => "env"; - - /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("copilotUser")] - public CopilotUserResponse? CopilotUser { get; set; } - - /// Name of the environment variable the token was sourced from. - [JsonPropertyName("envVar")] - public required string EnvVar { get; set; } - - /// Authentication host (e.g. https://github.com or a GHES host). - [JsonPropertyName("host")] - public required string Host { get; set; } - - /// User login associated with the token. Undefined for server-to-server tokens (those starting with `ghs_`). - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("login")] - public string? Login { get; set; } + /// Finite reason code describing why the current turn was aborted. + [JsonPropertyName("reason")] + public AbortReason? Reason { get; set; } - /// The token value itself. Treat as a secret. - [JsonPropertyName("token")] - public required string Token { get; set; } + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; } -/// Schema for the `TokenAuthInfo` type. -/// The token variant of . +/// Parameters for shutting down the session. [Experimental(Diagnostics.Experimental)] -public partial class AuthInfoToken : AuthInfo +internal sealed class ShutdownRequest { - /// - [JsonIgnore] - public override string Type => "token"; - - /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("copilotUser")] - public CopilotUserResponse? CopilotUser { get; set; } + /// Optional human-readable reason. Typically the message of the error that triggered shutdown when type is 'error'. + [JsonPropertyName("reason")] + public string? Reason { get; set; } - /// Authentication host. - [JsonPropertyName("host")] - public required string Host { get; set; } + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; - /// The token value itself. Treat as a secret. - [JsonPropertyName("token")] - public required string Token { get; set; } + /// Why the session is being shut down. Defaults to "routine" when omitted. + [JsonPropertyName("type")] + public ShutdownType? Type { get; set; } } -/// Schema for the `CopilotApiTokenAuthInfo` type. -/// The copilot-api-token variant of . +/// Identifier of the session event that was emitted for the log message. [Experimental(Diagnostics.Experimental)] -public partial class AuthInfoCopilotApiToken : AuthInfo +public sealed class LogResult { - /// - [JsonIgnore] - public override string Type => "copilot-api-token"; - - /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("copilotUser")] - public CopilotUserResponse? CopilotUser { get; set; } - - /// Authentication host (always the public GitHub host). - [JsonPropertyName("host")] - public required string Host { get; set; } + /// The unique identifier of the emitted session event. + [JsonPropertyName("eventId")] + public Guid EventId { get; set; } } -/// Schema for the `UserAuthInfo` type. -/// The user variant of . +/// Message text, optional severity level, persistence flag, optional follow-up URL, and optional tip. [Experimental(Diagnostics.Experimental)] -public partial class AuthInfoUser : AuthInfo +internal sealed class LogRequest { - /// - [JsonIgnore] - public override string Type => "user"; + /// When true, the message is transient and not persisted to the session event log on disk. + [JsonPropertyName("ephemeral")] + public bool? Ephemeral { get; set; } - /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("copilotUser")] - public CopilotUserResponse? CopilotUser { get; set; } + /// Log severity level. Determines how the message is displayed in the timeline. Defaults to "info". + [JsonPropertyName("level")] + public SessionLogLevel? Level { get; set; } - /// Authentication host. - [JsonPropertyName("host")] - public required string Host { get; set; } + /// Human-readable message. + [JsonPropertyName("message")] + public string Message { get; set; } = string.Empty; - /// OAuth user login. - [JsonPropertyName("login")] - public required string Login { get; set; } + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; + + /// Optional actionable tip displayed alongside the message. Only honored on `level: "info"`. + [JsonPropertyName("tip")] + public string? Tip { get; set; } + + /// Domain category for this log entry (e.g., "mcp", "subscription", "policy", "model"). Maps to `infoType`/`warningType`/`errorType` on the emitted event. Defaults to "notification". + [JsonPropertyName("type")] + public string? Type { get; set; } + + /// Optional URL the user can open in their browser for more details. + [Url] + [StringSyntax(StringSyntaxAttribute.Uri)] + [JsonPropertyName("url")] + public string? Url { get; set; } } -/// Schema for the `GhCliAuthInfo` type. -/// The gh-cli variant of . +/// Authentication status and account metadata for the session. [Experimental(Diagnostics.Experimental)] -public partial class AuthInfoGhCli : AuthInfo +public sealed class SessionAuthStatus { - /// - [JsonIgnore] - public override string Type => "gh-cli"; + /// Authentication type. + [JsonPropertyName("authType")] + public AuthInfoType? AuthType { get; set; } - /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("copilotUser")] - public CopilotUserResponse? CopilotUser { get; set; } + /// Copilot plan tier (e.g., individual_pro, business). + [JsonPropertyName("copilotPlan")] + public string? CopilotPlan { get; set; } - /// Authentication host. + /// Authentication host URL. + [Url] + [StringSyntax(StringSyntaxAttribute.Uri)] [JsonPropertyName("host")] - public required string Host { get; set; } + public string? Host { get; set; } - /// User login as reported by `gh auth status`. + /// Whether the session has resolved authentication. + [JsonPropertyName("isAuthenticated")] + public bool IsAuthenticated { get; set; } + + /// Authenticated login/username, if available. [JsonPropertyName("login")] - public required string Login { get; set; } + public string? Login { get; set; } - /// The token returned by `gh auth token`. Treat as a secret. - [JsonPropertyName("token")] - public required string Token { get; set; } + /// Human-readable authentication status description. + [JsonPropertyName("statusMessage")] + public string? StatusMessage { get; set; } } -/// Schema for the `ApiKeyAuthInfo` type. -/// The api-key variant of . +/// Identifies the target session. [Experimental(Diagnostics.Experimental)] -public partial class AuthInfoApiKey : AuthInfo +internal sealed class SessionAuthGetStatusRequest { - /// - [JsonIgnore] - public override string Type => "api-key"; - - /// The API key. Treat as a secret. - [JsonPropertyName("apiKey")] - public required string ApiKey { get; set; } - - /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - [JsonPropertyName("copilotUser")] - public CopilotUserResponse? CopilotUser { get; set; } + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} - /// Authentication host. - [JsonPropertyName("host")] - public required string Host { get; set; } +/// Indicates whether the credential update succeeded. +[Experimental(Diagnostics.Experimental)] +public sealed class SessionSetCredentialsResult +{ + /// Whether the operation succeeded. + [JsonPropertyName("success")] + public bool Success { get; set; } } /// New auth credentials to install on the session. Omit to leave credentials unchanged. @@ -4841,6 +4903,10 @@ internal sealed class TasksSendMessageRequest [Experimental(Diagnostics.Experimental)] public sealed class Skill { + /// Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field. + [JsonPropertyName("argumentHint")] + public string? ArgumentHint { get; set; } + /// Description of what the skill does. [JsonPropertyName("description")] public string Description { get; set; } = string.Empty; @@ -6059,11 +6125,124 @@ public sealed class ProviderGetEndpointRequest /// Optional model identifier to scope the endpoint snapshot to. [Experimental(Diagnostics.Experimental)] -internal sealed class ProviderGetEndpointRequestWithSession +internal sealed class ProviderGetEndpointRequestWithSession +{ + /// Model identifier the caller intends to use against the returned endpoint. Used to pick the correct wire shape. Omit to use whichever model the session is currently using. + [JsonPropertyName("modelId")] + public string? ModelId { get; set; } + + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// The selectable model entries synthesized for the models added by this call. +[Experimental(Diagnostics.Experimental)] +public sealed class ProviderAddResult +{ + /// Synthesized selectable model entries for the newly added BYOK models, each under its provider-qualified selection id (`provider/id`). Empty when only providers were added. + [JsonPropertyName("models")] + public IList Models { get => field ??= []; set; } +} + +/// A BYOK model definition referencing a named provider. +[Experimental(Diagnostics.Experimental)] +public sealed class ProviderModelConfig +{ + /// Optional capability overrides (vision, tool_calls, reasoning, etc.). + [JsonPropertyName("capabilities")] + public ModelCapabilitiesOverride? Capabilities { get; set; } + + /// Provider-local model id, unique within its provider. The session-wide selection id (shown in the model list and passed to switchTo) is the provider-qualified `provider/id`. + [JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; + + /// Maximum context window tokens for the model. + [JsonPropertyName("maxContextWindowTokens")] + public double? MaxContextWindowTokens { get; set; } + + /// Maximum output tokens for the model. + [JsonPropertyName("maxOutputTokens")] + public double? MaxOutputTokens { get; set; } + + /// Maximum prompt/input tokens for the model. + [JsonPropertyName("maxPromptTokens")] + public double? MaxPromptTokens { get; set; } + + /// Well-known base model id used for behavior/capability/config lookup. Defaults to `id`. + [JsonPropertyName("modelId")] + public string? ModelId { get; set; } + + /// Display name for model pickers. Defaults to the provider-qualified selection id (`provider/id`). + [JsonPropertyName("name")] + public string? Name { get; set; } + + /// Name of the NamedProviderConfig that serves this model. + [JsonPropertyName("provider")] + public string Provider { get; set; } = string.Empty; + + /// The model name sent to the provider API for inference. Defaults to `id`. + [JsonPropertyName("wireModel")] + public string? WireModel { get; set; } +} + +/// Azure-specific provider options. +[Experimental(Diagnostics.Experimental)] +public sealed class ProviderConfigAzure +{ + /// API version. When set, uses the versioned deployment route. When omitted, uses the GA versionless v1 route. + [JsonPropertyName("apiVersion")] + public string? ApiVersion { get; set; } +} + +/// A named BYOK provider connection (transport + credentials). +[Experimental(Diagnostics.Experimental)] +public sealed class NamedProviderConfig +{ + /// API key. Optional for local providers like Ollama. + [JsonPropertyName("apiKey")] + public string? ApiKey { get; set; } + + /// Azure-specific provider options. + [JsonPropertyName("azure")] + public ProviderConfigAzure? Azure { get; set; } + + /// API endpoint URL. + [JsonPropertyName("baseUrl")] + public string BaseUrl { get; set; } = string.Empty; + + /// Bearer token for authentication. Sets the Authorization header directly. Takes precedence over apiKey when both are set. + [JsonPropertyName("bearerToken")] + public string? BearerToken { get; set; } + + /// Custom HTTP headers to include in all outbound requests to the provider. + [JsonPropertyName("headers")] + public IDictionary? Headers { get; set; } + + /// Stable identifier referenced by BYOK model definitions. Must not contain '/'. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// Provider type. Defaults to "openai" for generic OpenAI-compatible APIs. + [JsonPropertyName("type")] + public ProviderConfigType? Type { get; set; } + + /// Wire API format (openai/azure only). Defaults to "completions". + [JsonPropertyName("wireApi")] + public ProviderConfigWireApi? WireApi { get; set; } +} + +/// BYOK providers and/or models to add to the session's registry at runtime. Both fields are optional; provide providers, models, or both. +[Experimental(Diagnostics.Experimental)] +internal sealed class ProviderAddRequest { - /// Model identifier the caller intends to use against the returned endpoint. Used to pick the correct wire shape. Omit to use whichever model the session is currently using. - [JsonPropertyName("modelId")] - public string? ModelId { get; set; } + /// BYOK model definitions to register. Each must reference a provider that is already registered or included in this same call. Selection ids (`provider/id`) must be unique across the registry. + [JsonPropertyName("models")] + public IList? Models { get; set; } + + /// Named BYOK provider connections to register, additive to any providers already in the registry. Each name must be unique across the registry and must not contain '/'. + [JsonPropertyName("providers")] + public IList? Providers { get; set; } /// Target session identifier. [JsonPropertyName("sessionId")] @@ -6163,15 +6342,6 @@ public sealed class SessionInstalledPlugin public string? Version { get; set; } } -/// Azure-specific provider options. -[Experimental(Diagnostics.Experimental)] -public sealed class ProviderConfigAzure -{ - /// API version. When set, uses the versioned deployment route. When omitted, uses the GA versionless v1 route. - [JsonPropertyName("apiVersion")] - public string? ApiVersion { get; set; } -} - /// Custom model-provider configuration (BYOK). [Experimental(Diagnostics.Experimental)] public sealed class ProviderConfig @@ -13907,43 +14077,46 @@ public override void Write(Utf8JsonWriter writer, ProviderEndpointWireApi value, } -/// Allowed values for the `OptionsUpdateAdditionalContentExclusionPolicyScope` enumeration. +/// Provider type. Defaults to "openai" for generic OpenAI-compatible APIs. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct OptionsUpdateAdditionalContentExclusionPolicyScope : IEquatable +public readonly struct ProviderConfigType : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] - public OptionsUpdateAdditionalContentExclusionPolicyScope(string value) + public ProviderConfigType(string value) { ArgumentException.ThrowIfNullOrWhiteSpace(value); _value = value; } - /// Gets the value associated with this . + /// Gets the value associated with this . public string Value => _value ?? string.Empty; - /// The content exclusion policy applies to the current repository. - public static OptionsUpdateAdditionalContentExclusionPolicyScope Repo { get; } = new("repo"); + /// Generic OpenAI-compatible API. + public static ProviderConfigType Openai { get; } = new("openai"); - /// The content exclusion policy applies across all repositories. - public static OptionsUpdateAdditionalContentExclusionPolicyScope All { get; } = new("all"); + /// Azure OpenAI Service endpoint. + public static ProviderConfigType Azure { get; } = new("azure"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(OptionsUpdateAdditionalContentExclusionPolicyScope left, OptionsUpdateAdditionalContentExclusionPolicyScope right) => left.Equals(right); + /// Anthropic API endpoint. + public static ProviderConfigType Anthropic { get; } = new("anthropic"); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(OptionsUpdateAdditionalContentExclusionPolicyScope left, OptionsUpdateAdditionalContentExclusionPolicyScope right) => !(left == right); + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(ProviderConfigType left, ProviderConfigType right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(ProviderConfigType left, ProviderConfigType right) => !(left == right); /// - public override bool Equals(object? obj) => obj is OptionsUpdateAdditionalContentExclusionPolicyScope other && Equals(other); + public override bool Equals(object? obj) => obj is ProviderConfigType other && Equals(other); /// - public bool Equals(OptionsUpdateAdditionalContentExclusionPolicyScope other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(ProviderConfigType other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -13951,62 +14124,62 @@ public OptionsUpdateAdditionalContentExclusionPolicyScope(string value) /// public override string ToString() => Value; - /// Provides a for serializing instances. + /// Provides a for serializing instances. [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter + public sealed class Converter : JsonConverter { /// - public override OptionsUpdateAdditionalContentExclusionPolicyScope Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override ProviderConfigType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); } /// - public override void Write(Utf8JsonWriter writer, OptionsUpdateAdditionalContentExclusionPolicyScope value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, ProviderConfigType value, JsonSerializerOptions options) { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(OptionsUpdateAdditionalContentExclusionPolicyScope)); + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ProviderConfigType)); } } } -/// 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. +/// Wire API format (openai/azure only). Defaults to "completions". [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct OptionsUpdateContextTier : IEquatable +public readonly struct ProviderConfigWireApi : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] - public OptionsUpdateContextTier(string value) + public ProviderConfigWireApi(string value) { ArgumentException.ThrowIfNullOrWhiteSpace(value); _value = value; } - /// Gets the value associated with this . + /// Gets the value associated with this . public string Value => _value ?? string.Empty; - /// Use the model's default context tier and its standard token limits / pricing. - public static OptionsUpdateContextTier Default { get; } = new("default"); + /// OpenAI Chat Completions wire format. + public static ProviderConfigWireApi Completions { get; } = new("completions"); - /// Use the model's long-context tier (when available) so larger inputs are accepted and tier-specific pricing applies. - public static OptionsUpdateContextTier LongContext { get; } = new("long_context"); + /// OpenAI Responses API wire format. + public static ProviderConfigWireApi Responses { get; } = new("responses"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(OptionsUpdateContextTier left, OptionsUpdateContextTier right) => left.Equals(right); + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(ProviderConfigWireApi left, ProviderConfigWireApi right) => left.Equals(right); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(OptionsUpdateContextTier left, OptionsUpdateContextTier right) => !(left == right); + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(ProviderConfigWireApi left, ProviderConfigWireApi right) => !(left == right); /// - public override bool Equals(object? obj) => obj is OptionsUpdateContextTier other && Equals(other); + public override bool Equals(object? obj) => obj is ProviderConfigWireApi other && Equals(other); /// - public bool Equals(OptionsUpdateContextTier other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(ProviderConfigWireApi other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -14014,62 +14187,62 @@ public OptionsUpdateContextTier(string value) /// public override string ToString() => Value; - /// Provides a for serializing instances. + /// Provides a for serializing instances. [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter + public sealed class Converter : JsonConverter { /// - public override OptionsUpdateContextTier Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override ProviderConfigWireApi Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); } /// - public override void Write(Utf8JsonWriter writer, OptionsUpdateContextTier value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, ProviderConfigWireApi value, JsonSerializerOptions options) { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(OptionsUpdateContextTier)); + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ProviderConfigWireApi)); } } } -/// How env values are passed to MCP servers (`direct` inlines literal values; `indirect` resolves at launch). +/// Allowed values for the `OptionsUpdateAdditionalContentExclusionPolicyScope` enumeration. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct OptionsUpdateEnvValueMode : IEquatable +public readonly struct OptionsUpdateAdditionalContentExclusionPolicyScope : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] - public OptionsUpdateEnvValueMode(string value) + public OptionsUpdateAdditionalContentExclusionPolicyScope(string value) { ArgumentException.ThrowIfNullOrWhiteSpace(value); _value = value; } - /// Gets the value associated with this . + /// Gets the value associated with this . public string Value => _value ?? string.Empty; - /// Pass MCP server environment values as literal strings. - public static OptionsUpdateEnvValueMode Direct { get; } = new("direct"); + /// The content exclusion policy applies to the current repository. + public static OptionsUpdateAdditionalContentExclusionPolicyScope Repo { get; } = new("repo"); - /// Resolve MCP server environment values from host-side references. - public static OptionsUpdateEnvValueMode Indirect { get; } = new("indirect"); + /// The content exclusion policy applies across all repositories. + public static OptionsUpdateAdditionalContentExclusionPolicyScope All { get; } = new("all"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(OptionsUpdateEnvValueMode left, OptionsUpdateEnvValueMode right) => left.Equals(right); + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(OptionsUpdateAdditionalContentExclusionPolicyScope left, OptionsUpdateAdditionalContentExclusionPolicyScope right) => left.Equals(right); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(OptionsUpdateEnvValueMode left, OptionsUpdateEnvValueMode right) => !(left == right); + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(OptionsUpdateAdditionalContentExclusionPolicyScope left, OptionsUpdateAdditionalContentExclusionPolicyScope right) => !(left == right); /// - public override bool Equals(object? obj) => obj is OptionsUpdateEnvValueMode other && Equals(other); + public override bool Equals(object? obj) => obj is OptionsUpdateAdditionalContentExclusionPolicyScope other && Equals(other); /// - public bool Equals(OptionsUpdateEnvValueMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(OptionsUpdateAdditionalContentExclusionPolicyScope other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -14077,65 +14250,62 @@ public OptionsUpdateEnvValueMode(string value) /// public override string ToString() => Value; - /// Provides a for serializing instances. + /// Provides a for serializing instances. [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter + public sealed class Converter : JsonConverter { /// - public override OptionsUpdateEnvValueMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override OptionsUpdateAdditionalContentExclusionPolicyScope Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); } /// - public override void Write(Utf8JsonWriter writer, OptionsUpdateEnvValueMode value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, OptionsUpdateAdditionalContentExclusionPolicyScope value, JsonSerializerOptions options) { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(OptionsUpdateEnvValueMode)); + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(OptionsUpdateAdditionalContentExclusionPolicyScope)); } } } -/// Provider type. Defaults to "openai" for generic OpenAI-compatible APIs. +/// 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. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct ProviderConfigType : IEquatable +public readonly struct OptionsUpdateContextTier : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] - public ProviderConfigType(string value) + public OptionsUpdateContextTier(string value) { ArgumentException.ThrowIfNullOrWhiteSpace(value); _value = value; } - /// Gets the value associated with this . + /// Gets the value associated with this . public string Value => _value ?? string.Empty; - /// Generic OpenAI-compatible API. - public static ProviderConfigType Openai { get; } = new("openai"); - - /// Azure OpenAI Service endpoint. - public static ProviderConfigType Azure { get; } = new("azure"); + /// Use the model's default context tier and its standard token limits / pricing. + public static OptionsUpdateContextTier Default { get; } = new("default"); - /// Anthropic API endpoint. - public static ProviderConfigType Anthropic { get; } = new("anthropic"); + /// Use the model's long-context tier (when available) so larger inputs are accepted and tier-specific pricing applies. + public static OptionsUpdateContextTier LongContext { get; } = new("long_context"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(ProviderConfigType left, ProviderConfigType right) => left.Equals(right); + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(OptionsUpdateContextTier left, OptionsUpdateContextTier right) => left.Equals(right); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(ProviderConfigType left, ProviderConfigType right) => !(left == right); + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(OptionsUpdateContextTier left, OptionsUpdateContextTier right) => !(left == right); /// - public override bool Equals(object? obj) => obj is ProviderConfigType other && Equals(other); + public override bool Equals(object? obj) => obj is OptionsUpdateContextTier other && Equals(other); /// - public bool Equals(ProviderConfigType other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(OptionsUpdateContextTier other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -14143,62 +14313,62 @@ public ProviderConfigType(string value) /// public override string ToString() => Value; - /// Provides a for serializing instances. + /// Provides a for serializing instances. [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter + public sealed class Converter : JsonConverter { /// - public override ProviderConfigType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override OptionsUpdateContextTier Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); } /// - public override void Write(Utf8JsonWriter writer, ProviderConfigType value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, OptionsUpdateContextTier value, JsonSerializerOptions options) { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ProviderConfigType)); + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(OptionsUpdateContextTier)); } } } -/// Wire API format (openai/azure only). Defaults to "completions". +/// How env values are passed to MCP servers (`direct` inlines literal values; `indirect` resolves at launch). [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct ProviderConfigWireApi : IEquatable +public readonly struct OptionsUpdateEnvValueMode : IEquatable { private readonly string? _value; - /// Initializes a new instance of the struct. - /// The value to associate with this . + /// Initializes a new instance of the struct. + /// The value to associate with this . [JsonConstructor] - public ProviderConfigWireApi(string value) + public OptionsUpdateEnvValueMode(string value) { ArgumentException.ThrowIfNullOrWhiteSpace(value); _value = value; } - /// Gets the value associated with this . + /// Gets the value associated with this . public string Value => _value ?? string.Empty; - /// OpenAI Chat Completions wire format. - public static ProviderConfigWireApi Completions { get; } = new("completions"); + /// Pass MCP server environment values as literal strings. + public static OptionsUpdateEnvValueMode Direct { get; } = new("direct"); - /// OpenAI Responses API wire format. - public static ProviderConfigWireApi Responses { get; } = new("responses"); + /// Resolve MCP server environment values from host-side references. + public static OptionsUpdateEnvValueMode Indirect { get; } = new("indirect"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(ProviderConfigWireApi left, ProviderConfigWireApi right) => left.Equals(right); + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(OptionsUpdateEnvValueMode left, OptionsUpdateEnvValueMode right) => left.Equals(right); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(ProviderConfigWireApi left, ProviderConfigWireApi right) => !(left == right); + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(OptionsUpdateEnvValueMode left, OptionsUpdateEnvValueMode right) => !(left == right); /// - public override bool Equals(object? obj) => obj is ProviderConfigWireApi other && Equals(other); + public override bool Equals(object? obj) => obj is OptionsUpdateEnvValueMode other && Equals(other); /// - public bool Equals(ProviderConfigWireApi other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(OptionsUpdateEnvValueMode other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -14206,20 +14376,20 @@ public ProviderConfigWireApi(string value) /// public override string ToString() => Value; - /// Provides a for serializing instances. + /// Provides a for serializing instances. [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter + public sealed class Converter : JsonConverter { /// - public override ProviderConfigWireApi Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override OptionsUpdateEnvValueMode Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); } /// - public override void Write(Utf8JsonWriter writer, ProviderConfigWireApi value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, OptionsUpdateEnvValueMode value, JsonSerializerOptions options) { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(ProviderConfigWireApi)); + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(OptionsUpdateEnvValueMode)); } } } @@ -16318,6 +16488,50 @@ public async Task GetQuotaAsync(string? gitHubToken = nul var request = new AccountGetQuotaRequest { GitHubToken = gitHubToken }; return await CopilotClient.InvokeRpcAsync(_rpc, "account.getQuota", [request], cancellationToken); } + + /// Gets the currently active authentication credentials from the global auth manager. + /// The to monitor for cancellation requests. The default is . + /// Current authentication state. + public async Task GetCurrentAuthAsync(CancellationToken cancellationToken = default) + { + return await CopilotClient.InvokeRpcAsync(_rpc, "account.getCurrentAuth", [], cancellationToken); + } + + /// Gets all authenticated users available for account switching. + /// The to monitor for cancellation requests. The default is . + /// List of all authenticated users. + public async Task> GetAllUsersAsync(CancellationToken cancellationToken = default) + { + return await CopilotClient.InvokeRpcAsync>(_rpc, "account.getAllUsers", [], cancellationToken); + } + + /// Stores authentication credentials after successful login (e.g., device code flow). + /// GitHub host URL. + /// User login/username. + /// GitHub authentication token. + /// The to monitor for cancellation requests. The default is . + /// Result of a successful login; throws on failure. + public async Task LoginAsync(string host, string login, string token, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(host); + ArgumentNullException.ThrowIfNull(login); + ArgumentNullException.ThrowIfNull(token); + + var request = new AccountLoginRequest { Host = host, Login = login, Token = token }; + return await CopilotClient.InvokeRpcAsync(_rpc, "account.login", [request], cancellationToken); + } + + /// Removes user authentication from keychain and persisted state. + /// Authentication information for the user to log out. + /// The to monitor for cancellation requests. The default is . + /// Logout result indicating if more users remain. + public async Task LogoutAsync(AuthInfo authInfo, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(authInfo); + + var request = new AccountLogoutRequest { AuthInfo = authInfo }; + return await CopilotClient.InvokeRpcAsync(_rpc, "account.logout", [request], cancellationToken); + } } /// Provides server-scoped Secrets APIs. @@ -18801,6 +19015,19 @@ public async Task GetEndpointAsync(ProviderGetEndpointRequest? var rpcRequest = new ProviderGetEndpointRequestWithSession { SessionId = _session.SessionId, ModelId = request?.ModelId }; return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.provider.getEndpoint", [rpcRequest], cancellationToken); } + + /// Adds BYOK providers and/or models to the session's registry at runtime, extending the additive registry built from the session's `providers`/`models` options. Both fields are optional, so a call may add providers only, models only, or both. Within a single call providers are registered before models, so a model may reference a provider added in the same call; across calls a model may reference any provider already registered (from session creation or a prior add). A model whose referenced provider is not registered by the end of the call is rejected. Newly added models become selectable via `model.list` / `model.switchTo` and are inherited by sub-agents spawned afterwards. + /// Named BYOK provider connections to register, additive to any providers already in the registry. Each name must be unique across the registry and must not contain '/'. + /// BYOK model definitions to register. Each must reference a provider that is already registered or included in this same call. Selection ids (`provider/id`) must be unique across the registry. + /// The to monitor for cancellation requests. The default is . + /// The selectable model entries synthesized for the models added by this call. + public async Task AddAsync(IList? providers = null, IList? models = null, CancellationToken cancellationToken = default) + { + _session.ThrowIfDisposed(); + + var request = new ProviderAddRequest { SessionId = _session.SessionId, Providers = providers, Models = models }; + return await CopilotClient.InvokeRpcAsync(_session.Rpc, "session.provider.add", [request], cancellationToken); + } } /// Provides session-scoped Options APIs. @@ -20444,6 +20671,7 @@ public static void RegisterClientSessionApiHandlers(JsonRpc rpc, FuncContent-free structural summary of the failing request. Contains only counts and shape flags (no prompt content), so it is safe for unrestricted telemetry. Populated only for client-error (4xx) failures. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("requestFingerprint")] + public ModelCallFailureRequestFingerprint? RequestFingerprint { get; set; } + /// Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("serviceRequestId")] @@ -4414,6 +4419,40 @@ internal sealed partial class AssistantUsageQuotaSnapshot internal required long UsedRequests { get; set; } } +/// Content-free structural summary of the failing request for diagnosing malformed 4xx calls. +/// Nested data type for ModelCallFailureRequestFingerprint. +public sealed partial class ModelCallFailureRequestFingerprint +{ + /// Total number of image content parts. + [JsonPropertyName("imagePartCount")] + public required long ImagePartCount { get; set; } + + /// Image parts whose media type cannot be determined (rejected by strict providers). + [JsonPropertyName("imagePartsMissingMediaType")] + public required long ImagePartsMissingMediaType { get; set; } + + /// Role of the final message in the request. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("lastMessageRole")] + public string? LastMessageRole { get; set; } + + /// Total number of messages in the request. + [JsonPropertyName("messageCount")] + public required long MessageCount { get; set; } + + /// Tool calls whose name is missing or empty (rejected by strict providers). + [JsonPropertyName("namelessToolCallCount")] + public required long NamelessToolCallCount { get; set; } + + /// Total number of tool calls across assistant messages. + [JsonPropertyName("toolCallCount")] + public required long ToolCallCount { get; set; } + + /// Number of "tool" result messages in the request. + [JsonPropertyName("toolResultMessageCount")] + public required long ToolResultMessageCount { get; set; } +} + /// Schema for the `ToolExecutionStartToolDescriptionMetaUI` type. /// Nested data type for ToolExecutionStartToolDescriptionMetaUI. public sealed partial class ToolExecutionStartToolDescriptionMetaUI @@ -6459,6 +6498,11 @@ public sealed partial class CapabilitiesChangedUI /// Nested data type for SkillsLoadedSkill. public sealed partial class SkillsLoadedSkill { + /// Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("argumentHint")] + public string? ArgumentHint { get; set; } + /// Description of what the skill does. [JsonPropertyName("description")] public required string Description { get; set; } @@ -9582,6 +9626,7 @@ public override void Write(Utf8JsonWriter writer, CanvasOpenedAvailability value [JsonSerializable(typeof(McpServersLoadedServer))] [JsonSerializable(typeof(ModelCallFailureData))] [JsonSerializable(typeof(ModelCallFailureEvent))] +[JsonSerializable(typeof(ModelCallFailureRequestFingerprint))] [JsonSerializable(typeof(OmittedBinaryResult))] [JsonSerializable(typeof(PendingMessagesModifiedData))] [JsonSerializable(typeof(PendingMessagesModifiedEvent))] diff --git a/dotnet/src/JsonRpc.cs b/dotnet/src/JsonRpc.cs index 912d5a529..edd0534ab 100644 --- a/dotnet/src/JsonRpc.cs +++ b/dotnet/src/JsonRpc.cs @@ -470,7 +470,7 @@ private void HandleResponse(JsonElement message, JsonElement idProp) } catch (Exception ex) { - _logger.LogWarning(ex, "Inline response callback for request {RequestId} threw", id); + LogInlineResponseCallbackThrew(_logger, ex, id); pending.TrySetException(ex); return; } @@ -935,6 +935,11 @@ private sealed class CancelRequestParams public long Id { get; set; } } + [LoggerMessage( + Level = LogLevel.Warning, + Message = "Inline response callback for request {RequestId} threw")] + private static partial void LogInlineResponseCallbackThrew(ILogger logger, Exception exception, long requestId); + [JsonSerializable(typeof(CancelRequestParams))] private partial class CancelRequestParamsContext : JsonSerializerContext; } diff --git a/dotnet/test/Unit/SerializationTests.cs b/dotnet/test/Unit/SerializationTests.cs index baf71c299..ee95c8ea0 100644 --- a/dotnet/test/Unit/SerializationTests.cs +++ b/dotnet/test/Unit/SerializationTests.cs @@ -83,15 +83,17 @@ public void ModelBilling_CanSerializeTokenPrices_WithSdkOptions() { InputPrice = 2.0, OutputPrice = 8.0, - CachePrice = 0.5, + CacheReadPrice = 0.5, + CacheWritePrice = 0.75, BatchSize = 1_000_000L, - ContextMax = 128_000L, + MaxPromptTokens = 128_000L, LongContext = new GitHub.Copilot.Rpc.ModelBillingTokenPricesLongContext { InputPrice = 4.0, OutputPrice = 16.0, - CachePrice = 1.0, - ContextMax = 1_000_000L + CacheReadPrice = 1.0, + CacheWritePrice = 1.25, + MaxPromptTokens = 1_000_000L } } }; @@ -103,12 +105,14 @@ public void ModelBilling_CanSerializeTokenPrices_WithSdkOptions() var tokenPrices = root.GetProperty("tokenPrices"); Assert.Equal(2.0, tokenPrices.GetProperty("inputPrice").GetDouble()); Assert.Equal(8.0, tokenPrices.GetProperty("outputPrice").GetDouble()); - Assert.Equal(0.5, tokenPrices.GetProperty("cachePrice").GetDouble()); + Assert.Equal(0.5, tokenPrices.GetProperty("cacheReadPrice").GetDouble()); + Assert.Equal(0.75, tokenPrices.GetProperty("cacheWritePrice").GetDouble()); Assert.Equal(1_000_000L, tokenPrices.GetProperty("batchSize").GetInt64()); - Assert.Equal(128_000L, tokenPrices.GetProperty("contextMax").GetInt64()); + Assert.Equal(128_000L, tokenPrices.GetProperty("maxPromptTokens").GetInt64()); var longContext = tokenPrices.GetProperty("longContext"); Assert.Equal(4.0, longContext.GetProperty("inputPrice").GetDouble()); - Assert.Equal(1_000_000L, longContext.GetProperty("contextMax").GetInt64()); + Assert.Equal(1.25, longContext.GetProperty("cacheWritePrice").GetDouble()); + Assert.Equal(1_000_000L, longContext.GetProperty("maxPromptTokens").GetInt64()); var deserialized = JsonSerializer.Deserialize(json, options); Assert.NotNull(deserialized); @@ -116,10 +120,10 @@ public void ModelBilling_CanSerializeTokenPrices_WithSdkOptions() Assert.NotNull(deserialized.TokenPrices); Assert.Equal(2.0, deserialized.TokenPrices.InputPrice); Assert.Equal(1_000_000L, deserialized.TokenPrices.BatchSize); - Assert.Equal(128_000L, deserialized.TokenPrices.ContextMax); + Assert.Equal(128_000L, deserialized.TokenPrices.MaxPromptTokens); Assert.NotNull(deserialized.TokenPrices.LongContext); Assert.Equal(16.0, deserialized.TokenPrices.LongContext.OutputPrice); - Assert.Equal(1_000_000L, deserialized.TokenPrices.LongContext.ContextMax); + Assert.Equal(1_000_000L, deserialized.TokenPrices.LongContext.MaxPromptTokens); } [Fact] diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go index b5c10e9b3..990b45b07 100644 --- a/go/rpc/zrpc.go +++ b/go/rpc/zrpc.go @@ -28,6 +28,25 @@ type AbortResult struct { Success bool `json:"success"` } +// Schema for the `AccountAllUsers` type. +type AccountAllUsers struct { + // Authentication information for this user + AuthInfo AuthInfo `json:"authInfo"` + // Associated token, if available + Token *string `json:"token,omitempty"` +} + +// List of all authenticated users +type AccountGetAllUsersResult []AccountAllUsers + +// Current authentication state +type AccountGetCurrentAuthResult struct { + // Authentication errors from the last auth attempt, if any + AuthErrors []string `json:"authErrors,omitzero"` + // Current authentication information, if authenticated + AuthInfo AuthInfo `json:"authInfo,omitempty"` +} + type AccountGetQuotaRequest struct { // GitHub token for per-user quota lookup. When provided, resolves this token to determine // the user's quota instead of using the global auth. @@ -40,6 +59,36 @@ type AccountGetQuotaResult struct { QuotaSnapshots map[string]AccountQuotaSnapshot `json:"quotaSnapshots"` } +// Credentials to store after successful authentication +type AccountLoginRequest struct { + // GitHub host URL + Host string `json:"host"` + // User login/username + Login string `json:"login"` + // GitHub authentication token + Token string `json:"token"` +} + +// Result of a successful login; throws on failure +type AccountLoginResult struct { + // Whether the credential was persisted to a secure store (system keychain, or the config + // file when plaintext storage is enabled). False when no secure store was available and the + // token was not saved, so the consumer can decide how to proceed. + StoredInVault bool `json:"storedInVault"` +} + +// User to log out +type AccountLogoutRequest struct { + // Authentication information for the user to log out + AuthInfo AuthInfo `json:"authInfo"` +} + +// Logout result indicating if more users remain +type AccountLogoutResult struct { + // Whether other authenticated users remain after logout + HasMoreUsers bool `json:"hasMoreUsers"` +} + // Schema for the `AccountQuotaSnapshot` type. type AccountQuotaSnapshot struct { // Number of requests included in the entitlement, or -1 for unlimited entitlements @@ -567,7 +616,6 @@ type AttachmentSelectionDetailsStart struct { } // Initial authentication info for the session. -// Experimental: AuthInfo is part of an experimental API and may change or be removed. type AuthInfo interface { authInfo() Type() AuthInfoType @@ -584,7 +632,6 @@ func (r RawAuthInfoData) Type() AuthInfoType { } // Schema for the `ApiKeyAuthInfo` type. -// Experimental: APIKeyAuthInfo is part of an experimental API and may change or be removed. type APIKeyAuthInfo struct { // The API key. Treat as a secret. APIKey string `json:"apiKey"` @@ -602,8 +649,6 @@ func (APIKeyAuthInfo) Type() AuthInfoType { } // Schema for the `CopilotApiTokenAuthInfo` type. -// Experimental: CopilotAPITokenAuthInfo is part of an experimental API and may change or be -// removed. type CopilotAPITokenAuthInfo struct { // Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the // GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this @@ -619,7 +664,6 @@ func (CopilotAPITokenAuthInfo) Type() AuthInfoType { } // Schema for the `EnvAuthInfo` type. -// Experimental: EnvAuthInfo is part of an experimental API and may change or be removed. type EnvAuthInfo struct { // Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the // GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this @@ -642,7 +686,6 @@ func (EnvAuthInfo) Type() AuthInfoType { } // Schema for the `GhCliAuthInfo` type. -// Experimental: GhCLIAuthInfo is part of an experimental API and may change or be removed. type GhCLIAuthInfo struct { // Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the // GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this @@ -662,7 +705,6 @@ func (GhCLIAuthInfo) Type() AuthInfoType { } // Schema for the `HMACAuthInfo` type. -// Experimental: HMACAuthInfo is part of an experimental API and may change or be removed. type HMACAuthInfo struct { // Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the // GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this @@ -680,7 +722,6 @@ func (HMACAuthInfo) Type() AuthInfoType { } // Schema for the `TokenAuthInfo` type. -// Experimental: TokenAuthInfo is part of an experimental API and may change or be removed. type TokenAuthInfo struct { // Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the // GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this @@ -698,7 +739,6 @@ func (TokenAuthInfo) Type() AuthInfoType { } // Schema for the `UserAuthInfo` type. -// Experimental: UserAuthInfo is part of an experimental API and may change or be removed. type UserAuthInfo struct { // Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the // GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this @@ -1051,8 +1091,6 @@ type ConnectResult struct { // Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the // GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this // verbatim and does not re-fetch when set. -// Experimental: CopilotUserResponse is part of an experimental API and may change or be -// removed. type CopilotUserResponse struct { AccessTypeSku *string `json:"access_type_sku,omitempty"` AnalyticsTrackingID *string `json:"analytics_tracking_id,omitempty"` @@ -1084,8 +1122,6 @@ type CopilotUserResponse struct { } // Schema for the `CopilotUserResponseEndpoints` type. -// Experimental: CopilotUserResponseEndpoints is part of an experimental API and may change -// or be removed. type CopilotUserResponseEndpoints struct { API *string `json:"api,omitempty"` OriginTracker *string `json:"origin-tracker,omitempty"` @@ -1099,8 +1135,6 @@ type CopilotUserResponseOrganizationListItem struct { } // Schema for the `CopilotUserResponseQuotaSnapshots` type. -// Experimental: CopilotUserResponseQuotaSnapshots is part of an experimental API and may -// change or be removed. type CopilotUserResponseQuotaSnapshots struct { // Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. Chat *CopilotUserResponseQuotaSnapshotsChat `json:"chat,omitempty"` @@ -1111,8 +1145,6 @@ type CopilotUserResponseQuotaSnapshots struct { } // Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. -// Experimental: CopilotUserResponseQuotaSnapshotsChat is part of an experimental API and -// may change or be removed. type CopilotUserResponseQuotaSnapshotsChat struct { Entitlement *float64 `json:"entitlement,omitempty"` HasQuota *bool `json:"has_quota,omitempty"` @@ -1129,8 +1161,6 @@ type CopilotUserResponseQuotaSnapshotsChat struct { } // Schema for the `CopilotUserResponseQuotaSnapshotsCompletions` type. -// Experimental: CopilotUserResponseQuotaSnapshotsCompletions is part of an experimental API -// and may change or be removed. type CopilotUserResponseQuotaSnapshotsCompletions struct { Entitlement *float64 `json:"entitlement,omitempty"` HasQuota *bool `json:"has_quota,omitempty"` @@ -1147,8 +1177,6 @@ type CopilotUserResponseQuotaSnapshotsCompletions struct { } // Schema for the `CopilotUserResponseQuotaSnapshotsPremiumInteractions` type. -// Experimental: CopilotUserResponseQuotaSnapshotsPremiumInteractions is part of an -// experimental API and may change or be removed. type CopilotUserResponseQuotaSnapshotsPremiumInteractions struct { Entitlement *float64 `json:"entitlement,omitempty"` HasQuota *bool `json:"has_quota,omitempty"` @@ -3182,14 +3210,16 @@ type ModelBilling struct { type ModelBillingTokenPrices struct { // Number of tokens per standard billing batch BatchSize *int64 `json:"batchSize,omitempty"` - // Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens + // Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens + // Deprecated: CachePrice is deprecated. CachePrice *float64 `json:"cachePrice,omitempty"` // AI Credits cost per billing batch of cached (read) tokens CacheReadPrice *float64 `json:"cacheReadPrice,omitempty"` // AI Credits cost per billing batch of cache-write (cache creation) tokens. CacheWritePrice *float64 `json:"cacheWritePrice,omitempty"` - // Deprecated: use maxPromptTokens. Prompt token budget for the default tier. The total - // context window is this value plus the model's max_output_tokens. + // Use maxPromptTokens instead. Prompt token budget for the default tier. The total context + // window is this value plus the model's max_output_tokens. + // Deprecated: ContextMax is deprecated. ContextMax *int64 `json:"contextMax,omitempty"` // AI Credits cost per billing batch of input tokens InputPrice *float64 `json:"inputPrice,omitempty"` @@ -3204,14 +3234,16 @@ type ModelBillingTokenPrices struct { // Long context tier pricing (available for models with extended context windows) type ModelBillingTokenPricesLongContext struct { - // Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens + // Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens + // Deprecated: CachePrice is deprecated. CachePrice *float64 `json:"cachePrice,omitempty"` // AI Credits cost per billing batch of cached (read) tokens CacheReadPrice *float64 `json:"cacheReadPrice,omitempty"` // AI Credits cost per billing batch of cache-write (cache creation) tokens. CacheWritePrice *float64 `json:"cacheWritePrice,omitempty"` - // Deprecated: use maxPromptTokens. Prompt token budget for the long context tier. The total + // Use maxPromptTokens instead. Prompt token budget for the long context tier. The total // context window is this value plus the model's max_output_tokens. + // Deprecated: ContextMax is deprecated. ContextMax *int64 `json:"contextMax,omitempty"` // AI Credits cost per billing batch of input tokens InputPrice *float64 `json:"inputPrice,omitempty"` @@ -4882,6 +4914,29 @@ type PollSpawnedSessionsResult struct { Events []SessionsPollSpawnedSessionsEvent `json:"events"` } +// BYOK providers and/or models to add to the session's registry at runtime. Both fields are +// optional; provide providers, models, or both. +// Experimental: ProviderAddRequest is part of an experimental API and may change or be +// removed. +type ProviderAddRequest struct { + // BYOK model definitions to register. Each must reference a provider that is already + // registered or included in this same call. Selection ids (`provider/id`) must be unique + // across the registry. + Models []ProviderModelConfig `json:"models,omitzero"` + // Named BYOK provider connections to register, additive to any providers already in the + // registry. Each name must be unique across the registry and must not contain '/'. + Providers []NamedProviderConfig `json:"providers,omitzero"` +} + +// The selectable model entries synthesized for the models added by this call. +// Experimental: ProviderAddResult is part of an experimental API and may change or be +// removed. +type ProviderAddResult struct { + // Synthesized selectable model entries for the newly added BYOK models, each under its + // provider-qualified selection id (`provider/id`). Empty when only providers were added. + Models []any `json:"models"` +} + // Custom model-provider configuration (BYOK). // Experimental: ProviderConfig is part of an experimental API and may change or be removed. type ProviderConfig struct { @@ -5719,6 +5774,9 @@ type ServerInstructionSourceList struct { // Schema for the `ServerSkill` type. type ServerSkill struct { + // Optional freeform hint describing the skill's expected arguments, from the + // `argument-hint` frontmatter field + ArgumentHint *string `json:"argumentHint,omitempty"` // Description of what the skill does Description string `json:"description"` // Whether the skill is currently enabled (based on global config) @@ -7452,6 +7510,9 @@ type ShutdownRequest struct { // Schema for the `Skill` type. // Experimental: Skill is part of an experimental API and may change or be removed. type Skill struct { + // Optional freeform hint describing the skill's expected arguments, from the + // `argument-hint` frontmatter field + ArgumentHint *string `json:"argumentHint,omitempty"` // Description of what the skill does Description string `json:"description"` // Whether the skill is currently enabled @@ -10789,6 +10850,41 @@ type serverAPI struct { type ServerAccountAPI serverAPI +// GetAllUsers gets all authenticated users available for account switching. +// +// RPC method: account.getAllUsers. +// +// Returns: List of all authenticated users +func (a *ServerAccountAPI) GetAllUsers(ctx context.Context) (*AccountGetAllUsersResult, error) { + raw, err := a.client.Request(ctx, "account.getAllUsers", nil) + if err != nil { + return nil, err + } + var result AccountGetAllUsersResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// GetCurrentAuth gets the currently active authentication credentials from the global auth +// manager. +// +// RPC method: account.getCurrentAuth. +// +// Returns: Current authentication state +func (a *ServerAccountAPI) GetCurrentAuth(ctx context.Context) (*AccountGetCurrentAuthResult, error) { + raw, err := a.client.Request(ctx, "account.getCurrentAuth", nil) + if err != nil { + return nil, err + } + var result AccountGetCurrentAuthResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + // GetQuota gets Copilot quota usage for the authenticated user or supplied GitHub token. // // RPC method: account.getQuota. @@ -10809,6 +10905,44 @@ func (a *ServerAccountAPI) GetQuota(ctx context.Context, params *AccountGetQuota return &result, nil } +// Login stores authentication credentials after successful login (e.g., device code flow). +// +// RPC method: account.login. +// +// Parameters: Credentials to store after successful authentication +// +// Returns: Result of a successful login; throws on failure +func (a *ServerAccountAPI) Login(ctx context.Context, params *AccountLoginRequest) (*AccountLoginResult, error) { + raw, err := a.client.Request(ctx, "account.login", params) + if err != nil { + return nil, err + } + var result AccountLoginResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Logout removes user authentication from keychain and persisted state. +// +// RPC method: account.logout. +// +// Parameters: User to log out +// +// Returns: Logout result indicating if more users remain +func (a *ServerAccountAPI) Logout(ctx context.Context, params *AccountLogoutRequest) (*AccountLogoutResult, error) { + raw, err := a.client.Request(ctx, "account.logout", params) + if err != nil { + return nil, err + } + var result AccountLogoutResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + // Experimental: ServerAgentRegistryAPI contains experimental APIs that may change or be // removed. type ServerAgentRegistryAPI serverAPI @@ -14919,6 +15053,42 @@ func (a *PluginsAPI) Reload(ctx context.Context, params ...*PluginsReloadRequest // Experimental: ProviderAPI contains experimental APIs that may change or be removed. type ProviderAPI sessionAPI +// Adds BYOK providers and/or models to the session's registry at runtime, extending the +// additive registry built from the session's `providers`/`models` options. Both fields are +// optional, so a call may add providers only, models only, or both. Within a single call +// providers are registered before models, so a model may reference a provider added in the +// same call; across calls a model may reference any provider already registered (from +// session creation or a prior add). A model whose referenced provider is not registered by +// the end of the call is rejected. Newly added models become selectable via `model.list` / +// `model.switchTo` and are inherited by sub-agents spawned afterwards. +// +// RPC method: session.provider.add. +// +// Parameters: BYOK providers and/or models to add to the session's registry at runtime. +// Both fields are optional; provide providers, models, or both. +// +// Returns: The selectable model entries synthesized for the models added by this call. +func (a *ProviderAPI) Add(ctx context.Context, params *ProviderAddRequest) (*ProviderAddResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + if params.Models != nil { + req["models"] = params.Models + } + if params.Providers != nil { + req["providers"] = params.Providers + } + } + raw, err := a.client.Request(ctx, "session.provider.add", req) + if err != nil { + return nil, err + } + var result ProviderAddResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + // GetEndpoint returns the provider endpoint and credentials the session is currently // configured to talk to, so the caller can make inference calls directly against the same // backend the session uses. diff --git a/go/rpc/zrpc_encoding.go b/go/rpc/zrpc_encoding.go index 12a5e0a45..84e0fb43e 100644 --- a/go/rpc/zrpc_encoding.go +++ b/go/rpc/zrpc_encoding.go @@ -8,240 +8,315 @@ import ( "errors" ) -func unmarshalAgentRegistrySpawnResult(data []byte) (AgentRegistrySpawnResult, error) { +func unmarshalAuthInfo(data []byte) (AuthInfo, error) { if string(data) == "null" { return nil, nil } type rawUnion struct { - Kind AgentRegistrySpawnResultKind `json:"kind"` + Type AuthInfoType `json:"type"` } var raw rawUnion if err := json.Unmarshal(data, &raw); err != nil { return nil, err } - switch raw.Kind { - case AgentRegistrySpawnResultKindRegistryTimeout: - var d AgentRegistrySpawnRegistryTimeout + switch raw.Type { + case AuthInfoTypeAPIKey: + var d APIKeyAuthInfo if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AgentRegistrySpawnResultKindSpawnError: - var d AgentRegistrySpawnError + case AuthInfoTypeCopilotAPIToken: + var d CopilotAPITokenAuthInfo if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AgentRegistrySpawnResultKindSpawned: - var d AgentRegistrySpawnSpawned + case AuthInfoTypeEnv: + var d EnvAuthInfo if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AgentRegistrySpawnResultKindValidationError: - var d AgentRegistrySpawnValidationError + case AuthInfoTypeGhCLI: + var d GhCLIAuthInfo + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AuthInfoTypeHMAC: + var d HMACAuthInfo + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AuthInfoTypeToken: + var d TokenAuthInfo + if err := json.Unmarshal(data, &d); err != nil { + return nil, err + } + return &d, nil + case AuthInfoTypeUser: + var d UserAuthInfo if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil default: - return &RawAgentRegistrySpawnResultData{Discriminator: raw.Kind, Raw: data}, nil + return &RawAuthInfoData{Discriminator: raw.Type, Raw: data}, nil } } -func (r RawAgentRegistrySpawnResultData) MarshalJSON() ([]byte, error) { +func (r RawAuthInfoData) MarshalJSON() ([]byte, error) { if r.Raw != nil { return r.Raw, nil } return json.Marshal(struct { - Kind AgentRegistrySpawnResultKind `json:"kind"` + Type AuthInfoType `json:"type"` }{ - Kind: r.Discriminator, + Type: r.Discriminator, }) } -func (r AgentRegistrySpawnError) MarshalJSON() ([]byte, error) { - type alias AgentRegistrySpawnError +func (r APIKeyAuthInfo) MarshalJSON() ([]byte, error) { + type alias APIKeyAuthInfo return json.Marshal(struct { - Kind AgentRegistrySpawnResultKind `json:"kind"` + Type AuthInfoType `json:"type"` alias }{ - Kind: r.Kind(), + Type: r.Type(), alias: alias(r), }) } -func (r AgentRegistrySpawnRegistryTimeout) MarshalJSON() ([]byte, error) { - type alias AgentRegistrySpawnRegistryTimeout +func (r CopilotAPITokenAuthInfo) MarshalJSON() ([]byte, error) { + type alias CopilotAPITokenAuthInfo return json.Marshal(struct { - Kind AgentRegistrySpawnResultKind `json:"kind"` + Type AuthInfoType `json:"type"` alias }{ - Kind: r.Kind(), + Type: r.Type(), alias: alias(r), }) } -func (r AgentRegistrySpawnSpawned) MarshalJSON() ([]byte, error) { - type alias AgentRegistrySpawnSpawned +func (r EnvAuthInfo) MarshalJSON() ([]byte, error) { + type alias EnvAuthInfo return json.Marshal(struct { - Kind AgentRegistrySpawnResultKind `json:"kind"` + Type AuthInfoType `json:"type"` alias }{ - Kind: r.Kind(), + Type: r.Type(), alias: alias(r), }) } -func (r AgentRegistrySpawnValidationError) MarshalJSON() ([]byte, error) { - type alias AgentRegistrySpawnValidationError +func (r GhCLIAuthInfo) MarshalJSON() ([]byte, error) { + type alias GhCLIAuthInfo return json.Marshal(struct { - Kind AgentRegistrySpawnResultKind `json:"kind"` + Type AuthInfoType `json:"type"` alias }{ - Kind: r.Kind(), + Type: r.Type(), alias: alias(r), }) } -func unmarshalAttachment(data []byte) (Attachment, error) { +func (r HMACAuthInfo) MarshalJSON() ([]byte, error) { + type alias HMACAuthInfo + return json.Marshal(struct { + Type AuthInfoType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r TokenAuthInfo) MarshalJSON() ([]byte, error) { + type alias TokenAuthInfo + return json.Marshal(struct { + Type AuthInfoType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r UserAuthInfo) MarshalJSON() ([]byte, error) { + type alias UserAuthInfo + return json.Marshal(struct { + Type AuthInfoType `json:"type"` + alias + }{ + Type: r.Type(), + alias: alias(r), + }) +} + +func (r *AccountAllUsers) UnmarshalJSON(data []byte) error { + type rawAccountAllUsers struct { + AuthInfo json.RawMessage `json:"authInfo"` + Token *string `json:"token,omitempty"` + } + var raw rawAccountAllUsers + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + if raw.AuthInfo != nil { + value, err := unmarshalAuthInfo(raw.AuthInfo) + if err != nil { + return err + } + r.AuthInfo = value + } + r.Token = raw.Token + return nil +} + +func (r *AccountGetCurrentAuthResult) UnmarshalJSON(data []byte) error { + type rawAccountGetCurrentAuthResult struct { + AuthErrors []string `json:"authErrors,omitzero"` + AuthInfo json.RawMessage `json:"authInfo,omitempty"` + } + var raw rawAccountGetCurrentAuthResult + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + r.AuthErrors = raw.AuthErrors + if raw.AuthInfo != nil { + value, err := unmarshalAuthInfo(raw.AuthInfo) + if err != nil { + return err + } + r.AuthInfo = value + } + return nil +} + +func (r *AccountLogoutRequest) UnmarshalJSON(data []byte) error { + type rawAccountLogoutRequest struct { + AuthInfo json.RawMessage `json:"authInfo"` + } + var raw rawAccountLogoutRequest + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + if raw.AuthInfo != nil { + value, err := unmarshalAuthInfo(raw.AuthInfo) + if err != nil { + return err + } + r.AuthInfo = value + } + return nil +} + +func unmarshalAgentRegistrySpawnResult(data []byte) (AgentRegistrySpawnResult, error) { if string(data) == "null" { return nil, nil } type rawUnion struct { - Type AttachmentType `json:"type"` + Kind AgentRegistrySpawnResultKind `json:"kind"` } var raw rawUnion if err := json.Unmarshal(data, &raw); err != nil { return nil, err } - switch raw.Type { - case AttachmentTypeBlob: - var d AttachmentBlob - if err := json.Unmarshal(data, &d); err != nil { - return nil, err - } - return &d, nil - case AttachmentTypeDirectory: - var d AttachmentDirectory - if err := json.Unmarshal(data, &d); err != nil { - return nil, err - } - return &d, nil - case AttachmentTypeExtensionContext: - var d AttachmentExtensionContext + switch raw.Kind { + case AgentRegistrySpawnResultKindRegistryTimeout: + var d AgentRegistrySpawnRegistryTimeout if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AttachmentTypeFile: - var d AttachmentFile + case AgentRegistrySpawnResultKindSpawnError: + var d AgentRegistrySpawnError if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AttachmentTypeGitHubReference: - var d AttachmentGitHubReference + case AgentRegistrySpawnResultKindSpawned: + var d AgentRegistrySpawnSpawned if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AttachmentTypeSelection: - var d AttachmentSelection + case AgentRegistrySpawnResultKindValidationError: + var d AgentRegistrySpawnValidationError if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil default: - return &RawAttachmentData{Discriminator: raw.Type, Raw: data}, nil + return &RawAgentRegistrySpawnResultData{Discriminator: raw.Kind, Raw: data}, nil } } -func (r RawAttachmentData) MarshalJSON() ([]byte, error) { +func (r RawAgentRegistrySpawnResultData) MarshalJSON() ([]byte, error) { if r.Raw != nil { return r.Raw, nil } return json.Marshal(struct { - Type AttachmentType `json:"type"` - }{ - Type: r.Discriminator, - }) -} - -func (r AttachmentBlob) MarshalJSON() ([]byte, error) { - type alias AttachmentBlob - return json.Marshal(struct { - Type AttachmentType `json:"type"` - alias - }{ - Type: r.Type(), - alias: alias(r), - }) -} - -func (r AttachmentDirectory) MarshalJSON() ([]byte, error) { - type alias AttachmentDirectory - return json.Marshal(struct { - Type AttachmentType `json:"type"` - alias + Kind AgentRegistrySpawnResultKind `json:"kind"` }{ - Type: r.Type(), - alias: alias(r), + Kind: r.Discriminator, }) } -func (r AttachmentExtensionContext) MarshalJSON() ([]byte, error) { - type alias AttachmentExtensionContext +func (r AgentRegistrySpawnError) MarshalJSON() ([]byte, error) { + type alias AgentRegistrySpawnError return json.Marshal(struct { - Type AttachmentType `json:"type"` + Kind AgentRegistrySpawnResultKind `json:"kind"` alias }{ - Type: r.Type(), + Kind: r.Kind(), alias: alias(r), }) } -func (r AttachmentFile) MarshalJSON() ([]byte, error) { - type alias AttachmentFile +func (r AgentRegistrySpawnRegistryTimeout) MarshalJSON() ([]byte, error) { + type alias AgentRegistrySpawnRegistryTimeout return json.Marshal(struct { - Type AttachmentType `json:"type"` + Kind AgentRegistrySpawnResultKind `json:"kind"` alias }{ - Type: r.Type(), + Kind: r.Kind(), alias: alias(r), }) } -func (r AttachmentGitHubReference) MarshalJSON() ([]byte, error) { - type alias AttachmentGitHubReference +func (r AgentRegistrySpawnSpawned) MarshalJSON() ([]byte, error) { + type alias AgentRegistrySpawnSpawned return json.Marshal(struct { - Type AttachmentType `json:"type"` + Kind AgentRegistrySpawnResultKind `json:"kind"` alias }{ - Type: r.Type(), + Kind: r.Kind(), alias: alias(r), }) } -func (r AttachmentSelection) MarshalJSON() ([]byte, error) { - type alias AttachmentSelection +func (r AgentRegistrySpawnValidationError) MarshalJSON() ([]byte, error) { + type alias AgentRegistrySpawnValidationError return json.Marshal(struct { - Type AttachmentType `json:"type"` + Kind AgentRegistrySpawnResultKind `json:"kind"` alias }{ - Type: r.Type(), + Kind: r.Kind(), alias: alias(r), }) } -func unmarshalAuthInfo(data []byte) (AuthInfo, error) { +func unmarshalAttachment(data []byte) (Attachment, error) { if string(data) == "null" { return nil, nil } type rawUnion struct { - Type AuthInfoType `json:"type"` + Type AttachmentType `json:"type"` } var raw rawUnion if err := json.Unmarshal(data, &raw); err != nil { @@ -249,79 +324,62 @@ func unmarshalAuthInfo(data []byte) (AuthInfo, error) { } switch raw.Type { - case AuthInfoTypeAPIKey: - var d APIKeyAuthInfo - if err := json.Unmarshal(data, &d); err != nil { - return nil, err - } - return &d, nil - case AuthInfoTypeCopilotAPIToken: - var d CopilotAPITokenAuthInfo + case AttachmentTypeBlob: + var d AttachmentBlob if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AuthInfoTypeEnv: - var d EnvAuthInfo + case AttachmentTypeDirectory: + var d AttachmentDirectory if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AuthInfoTypeGhCLI: - var d GhCLIAuthInfo + case AttachmentTypeExtensionContext: + var d AttachmentExtensionContext if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AuthInfoTypeHMAC: - var d HMACAuthInfo + case AttachmentTypeFile: + var d AttachmentFile if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AuthInfoTypeToken: - var d TokenAuthInfo + case AttachmentTypeGitHubReference: + var d AttachmentGitHubReference if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil - case AuthInfoTypeUser: - var d UserAuthInfo + case AttachmentTypeSelection: + var d AttachmentSelection if err := json.Unmarshal(data, &d); err != nil { return nil, err } return &d, nil default: - return &RawAuthInfoData{Discriminator: raw.Type, Raw: data}, nil + return &RawAttachmentData{Discriminator: raw.Type, Raw: data}, nil } } -func (r RawAuthInfoData) MarshalJSON() ([]byte, error) { +func (r RawAttachmentData) MarshalJSON() ([]byte, error) { if r.Raw != nil { return r.Raw, nil } return json.Marshal(struct { - Type AuthInfoType `json:"type"` + Type AttachmentType `json:"type"` }{ Type: r.Discriminator, }) } -func (r APIKeyAuthInfo) MarshalJSON() ([]byte, error) { - type alias APIKeyAuthInfo - return json.Marshal(struct { - Type AuthInfoType `json:"type"` - alias - }{ - Type: r.Type(), - alias: alias(r), - }) -} - -func (r CopilotAPITokenAuthInfo) MarshalJSON() ([]byte, error) { - type alias CopilotAPITokenAuthInfo +func (r AttachmentBlob) MarshalJSON() ([]byte, error) { + type alias AttachmentBlob return json.Marshal(struct { - Type AuthInfoType `json:"type"` + Type AttachmentType `json:"type"` alias }{ Type: r.Type(), @@ -329,10 +387,10 @@ func (r CopilotAPITokenAuthInfo) MarshalJSON() ([]byte, error) { }) } -func (r EnvAuthInfo) MarshalJSON() ([]byte, error) { - type alias EnvAuthInfo +func (r AttachmentDirectory) MarshalJSON() ([]byte, error) { + type alias AttachmentDirectory return json.Marshal(struct { - Type AuthInfoType `json:"type"` + Type AttachmentType `json:"type"` alias }{ Type: r.Type(), @@ -340,10 +398,10 @@ func (r EnvAuthInfo) MarshalJSON() ([]byte, error) { }) } -func (r GhCLIAuthInfo) MarshalJSON() ([]byte, error) { - type alias GhCLIAuthInfo +func (r AttachmentExtensionContext) MarshalJSON() ([]byte, error) { + type alias AttachmentExtensionContext return json.Marshal(struct { - Type AuthInfoType `json:"type"` + Type AttachmentType `json:"type"` alias }{ Type: r.Type(), @@ -351,10 +409,10 @@ func (r GhCLIAuthInfo) MarshalJSON() ([]byte, error) { }) } -func (r HMACAuthInfo) MarshalJSON() ([]byte, error) { - type alias HMACAuthInfo +func (r AttachmentFile) MarshalJSON() ([]byte, error) { + type alias AttachmentFile return json.Marshal(struct { - Type AuthInfoType `json:"type"` + Type AttachmentType `json:"type"` alias }{ Type: r.Type(), @@ -362,10 +420,10 @@ func (r HMACAuthInfo) MarshalJSON() ([]byte, error) { }) } -func (r TokenAuthInfo) MarshalJSON() ([]byte, error) { - type alias TokenAuthInfo +func (r AttachmentGitHubReference) MarshalJSON() ([]byte, error) { + type alias AttachmentGitHubReference return json.Marshal(struct { - Type AuthInfoType `json:"type"` + Type AttachmentType `json:"type"` alias }{ Type: r.Type(), @@ -373,10 +431,10 @@ func (r TokenAuthInfo) MarshalJSON() ([]byte, error) { }) } -func (r UserAuthInfo) MarshalJSON() ([]byte, error) { - type alias UserAuthInfo +func (r AttachmentSelection) MarshalJSON() ([]byte, error) { + type alias AttachmentSelection return json.Marshal(struct { - Type AuthInfoType `json:"type"` + Type AttachmentType `json:"type"` alias }{ Type: r.Type(), diff --git a/go/rpc/zsession_events.go b/go/rpc/zsession_events.go index 2144faed0..760752911 100644 --- a/go/rpc/zsession_events.go +++ b/go/rpc/zsession_events.go @@ -543,6 +543,8 @@ type ModelCallFailureData struct { Model *string `json:"model,omitempty"` // GitHub request tracing ID (x-github-request-id header) for server-side log correlation ProviderCallID *string `json:"providerCallId,omitempty"` + // Content-free structural summary of the failing request. Contains only counts and shape flags (no prompt content), so it is safe for unrestricted telemetry. Populated only for client-error (4xx) failures. + RequestFingerprint *ModelCallFailureRequestFingerprint `json:"requestFingerprint,omitempty"` // Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation ServiceRequestID *string `json:"serviceRequestId,omitempty"` // Where the failed model call originated @@ -2081,6 +2083,24 @@ type MCPServersLoadedServer struct { Transport *MCPServerTransport `json:"transport,omitempty"` } +// Content-free structural summary of the failing request for diagnosing malformed 4xx calls +type ModelCallFailureRequestFingerprint struct { + // Total number of image content parts + ImagePartCount int64 `json:"imagePartCount"` + // Image parts whose media type cannot be determined (rejected by strict providers) + ImagePartsMissingMediaType int64 `json:"imagePartsMissingMediaType"` + // Role of the final message in the request + LastMessageRole *string `json:"lastMessageRole,omitempty"` + // Total number of messages in the request + MessageCount int64 `json:"messageCount"` + // Tool calls whose name is missing or empty (rejected by strict providers) + NamelessToolCallCount int64 `json:"namelessToolCallCount"` + // Total number of tool calls across assistant messages + ToolCallCount int64 `json:"toolCallCount"` + // Number of "tool" result messages in the request + ToolResultMessageCount int64 `json:"toolResultMessageCount"` +} + // Derived user-facing permission prompt details for UI consumers type PermissionPromptRequest interface { permissionPromptRequest() @@ -2770,6 +2790,8 @@ type ShutdownTokenDetail struct { // Schema for the `SkillsLoadedSkill` type. type SkillsLoadedSkill struct { + // Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field + ArgumentHint *string `json:"argumentHint,omitempty"` // Description of what the skill does Description string `json:"description"` // Whether the skill is currently enabled diff --git a/go/zsession_events.go b/go/zsession_events.go index 5d76ec8e7..0f2d4a792 100644 --- a/go/zsession_events.go +++ b/go/zsession_events.go @@ -109,6 +109,7 @@ type ( MCPServerTransport = rpc.MCPServerTransport ModelCallFailureBadRequestKind = rpc.ModelCallFailureBadRequestKind ModelCallFailureData = rpc.ModelCallFailureData + ModelCallFailureRequestFingerprint = rpc.ModelCallFailureRequestFingerprint ModelCallFailureSource = rpc.ModelCallFailureSource OmittedBinaryOmittedReason = rpc.OmittedBinaryOmittedReason OmittedBinaryResult = rpc.OmittedBinaryResult diff --git a/java/pom.xml b/java/pom.xml index ac7b719b5..5224132d8 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.64-1 + ^1.0.64-3 diff --git a/java/scripts/codegen/java.ts b/java/scripts/codegen/java.ts index ba0ed3df1..c30836f7a 100644 --- a/java/scripts/codegen/java.ts +++ b/java/scripts/codegen/java.ts @@ -1393,6 +1393,14 @@ async function generateRpcTypes(schemaPath: string): Promise { generatedClasses.set(resultRefName, true); allFiles.push(await generateRpcDataClass(resultRefName, resultSchema, packageName, packageDir, method.rpcMethod, "result")); } + } else if (resultRefName && resultSchema.type === "array") { + // Named array aliases (e.g. AccountGetAllUsersResult) are returned + // as List by wrappers, but resolving them here discovers any + // referenced item records that need standalone generation. + schemaTypeToJava(resultSchema, false, resultRefName, "item", new Map()); + } else if (resultSchema.type === "array") { + // Inline arrays also need their referenced item records generated. + schemaTypeToJava(resultSchema, false, `${className}Result`, "item", new Map()); } } } @@ -1521,8 +1529,8 @@ function apiClassName(prefix: string, path: string[]): string { } /** - * Derive the result class name for an RPC method. - * Handles $ref to named definitions (enums, anyOf unions, objects with properties). + * Derive the Java result type for an RPC method. + * Handles $ref to named definitions (enums, anyOf unions, objects with properties, arrays). * Falls back to Void for null results or schemas with no meaningful type. */ function wrapperResultClassName(method: RpcMethodNode): string { @@ -1553,6 +1561,11 @@ function wrapperResultClassName(method: RpcMethodNode): string { if (resolved.type === "object" && !resolved.properties) { return refName; } + // Named array aliases → use the underlying List Java type. + if (resolved.type === "array") { + const result = schemaTypeToJava(resolved, false, refName, "item", new Map()); + return result.javaType; + } } } @@ -1568,6 +1581,11 @@ function wrapperResultClassName(method: RpcMethodNode): string { return rpcMethodToClassName(method.rpcMethod) + "Result"; } + if (result && typeof result === "object" && result.type === "array") { + const javaResult = schemaTypeToJava(result, false, `${rpcMethodToClassName(method.rpcMethod)}Result`, "item", new Map()); + return javaResult.javaType; + } + // Free-form object with additionalProperties (e.g., x-opaque-json) → JsonNode if ( result && @@ -1582,6 +1600,41 @@ function wrapperResultClassName(method: RpcMethodNode): string { return "Void"; } +function wrapperResultTypeExpression(resultType: string): string { + const listMatch = resultType.match(/^List<([^<>]+)>$/); + if (listMatch) { + return `RpcMapper.INSTANCE.getTypeFactory().constructCollectionType(List.class, ${javaClassLiteral(listMatch[1])})`; + } + + return javaClassLiteral(resultType); +} + +function javaClassLiteral(javaType: string): string { + return javaType === "Void" ? "Void.class" : `${javaType}.class`; +} + +function addWrapperResultImports(resultType: string, allImports: Set, packageName: string): void { + if (resultType === "Void") { + return; + } + + if (resultType === "JsonNode") { + allImports.add("com.fasterxml.jackson.databind.JsonNode"); + return; + } + + if (resultType.startsWith("List<")) { + allImports.add("java.util.List"); + } + + const builtInTypes = new Set(["Boolean", "Double", "Long", "List", "Object", "String", "Void"]); + for (const typeName of resultType.match(/\b[A-Z][A-Za-z0-9_]*\b/g) ?? []) { + if (!builtInTypes.has(typeName)) { + allImports.add(`${packageName}.${typeName}`); + } + } +} + /** * Return the params class name if the method has a params schema with properties * other than sessionId (i.e. there are user-supplied parameters). @@ -1659,18 +1712,18 @@ function generateApiMethod( needsMapper = true; lines.push(` com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params);`); lines.push(` _p.put("sessionId", ${sessionIdExpr});`); - lines.push(` return caller.invoke("${method.rpcMethod}", _p, ${resultClass}.class);`); + lines.push(` return caller.invoke("${method.rpcMethod}", _p, ${wrapperResultTypeExpression(resultClass)});`); } else if (hasSessionId) { - lines.push(` return caller.invoke("${method.rpcMethod}", java.util.Map.of("sessionId", ${sessionIdExpr}), ${resultClass}.class);`); + lines.push(` return caller.invoke("${method.rpcMethod}", java.util.Map.of("sessionId", ${sessionIdExpr}), ${wrapperResultTypeExpression(resultClass)});`); } else { - lines.push(` return caller.invoke("${method.rpcMethod}", java.util.Map.of(), ${resultClass}.class);`); + lines.push(` return caller.invoke("${method.rpcMethod}", java.util.Map.of(), ${wrapperResultTypeExpression(resultClass)});`); } } else { // Server-side: pass params directly (or empty map if no params) if (hasExtraParams) { - lines.push(` return caller.invoke("${method.rpcMethod}", params, ${resultClass}.class);`); + lines.push(` return caller.invoke("${method.rpcMethod}", params, ${wrapperResultTypeExpression(resultClass)});`); } else { - lines.push(` return caller.invoke("${method.rpcMethod}", java.util.Map.of(), ${resultClass}.class);`); + lines.push(` return caller.invoke("${method.rpcMethod}", java.util.Map.of(), ${wrapperResultTypeExpression(resultClass)});`); } } @@ -1723,13 +1776,7 @@ async function generateNamespaceApiFile( for (const [key, method] of tree.methods) { const resultClass = wrapperResultClassName(method); const paramsClass = wrapperParamsClassName(method); - if (resultClass !== "Void") { - if (resultClass === "JsonNode") { - allImports.add("com.fasterxml.jackson.databind.JsonNode"); - } else { - allImports.add(`${packageName}.${resultClass}`); - } - } + addWrapperResultImports(resultClass, allImports, packageName); if (paramsClass) allImports.add(`${packageName}.${paramsClass}`); const { lines, needsMapper: nm, needsExperimentalImport } = generateApiMethod(key, method, isSession, sessionIdExpr); @@ -1849,13 +1896,7 @@ async function generateRpcRootFile( for (const [key, method] of tree.methods) { const resultClass = wrapperResultClassName(method); const paramsClass = wrapperParamsClassName(method); - if (resultClass !== "Void") { - if (resultClass === "JsonNode") { - allImports.add("com.fasterxml.jackson.databind.JsonNode"); - } else { - allImports.add(`${packageName}.${resultClass}`); - } - } + addWrapperResultImports(resultClass, allImports, packageName); if (paramsClass) allImports.add(`${packageName}.${paramsClass}`); const { lines, needsMapper: nm, needsExperimentalImport } = generateApiMethod(key, method, isSession, sessionIdExpr); @@ -1959,7 +2000,10 @@ async function generateRpcCallerInterface(packageName: string, packageDir: strin lines.push(``); lines.push(`package ${packageName};`); lines.push(``); + lines.push(`import com.fasterxml.jackson.databind.JavaType;`); + lines.push(`import com.fasterxml.jackson.databind.JsonNode;`); lines.push(`import java.util.concurrent.CompletableFuture;`); + lines.push(`import java.util.concurrent.CompletionException;`); lines.push(`import javax.annotation.processing.Generated;`); lines.push(``); lines.push(`/**`); @@ -1987,6 +2031,28 @@ async function generateRpcCallerInterface(packageName: string, packageDir: strin lines.push(` * @return a {@link CompletableFuture} that completes with the deserialized result`); lines.push(` */`); lines.push(` CompletableFuture invoke(String method, Object params, Class resultType);`); + lines.push(``); + lines.push(` /**`); + lines.push(` * Invokes a JSON-RPC method and returns a future for the typed response.`); + lines.push(` *`); + lines.push(` * @param the expected response type`); + lines.push(` * @param method the JSON-RPC method name`); + lines.push(` * @param params the request parameters (may be a {@code Map}, DTO record, or {@code JsonNode})`); + lines.push(` * @param resultType the Jackson {@link JavaType} of the expected response type`); + lines.push(` * @return a {@link CompletableFuture} that completes with the deserialized result`); + lines.push(` */`); + lines.push(` default CompletableFuture invoke(String method, Object params, JavaType resultType) {`); + lines.push(` if (resultType.hasRawClass(Void.class) || resultType.hasRawClass(Void.TYPE)) {`); + lines.push(` return invoke(method, params, Void.class).thenApply(ignored -> null);`); + lines.push(` }`); + lines.push(` return invoke(method, params, JsonNode.class).thenApply(result -> {`); + lines.push(` try {`); + lines.push(` return RpcMapper.INSTANCE.readerFor(resultType).readValue(result);`); + lines.push(` } catch (java.io.IOException e) {`); + lines.push(` throw new CompletionException(e);`); + lines.push(` }`); + lines.push(` });`); + lines.push(` }`); lines.push(`}`); lines.push(``); diff --git a/java/scripts/codegen/package-lock.json b/java/scripts/codegen/package-lock.json index 0bce4a4fc..9a7b832c7 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.64-1", + "@github/copilot": "^1.0.64-3", "json-schema": "^0.4.0", "tsx": "^4.22.4" } @@ -428,9 +428,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-1.tgz", - "integrity": "sha512-lojV4Cb7oT4VJnYPEKBRH8KI3W43Q4Lh0Pc+V6sej+xjPJkoqwm68sNKn73/p3wXPBSTVTzPeCm9WhIisgf1Jw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-3.tgz", + "integrity": "sha512-Q9nBMYEHX1bJLXzzJocQx2nZvORJ0E9gvK6ly/FCtmtA7ad96BWZvf4EHzkCNDsn56aI3zNaUSfKHUKcmIAzSg==", "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.64-1", - "@github/copilot-darwin-x64": "1.0.64-1", - "@github/copilot-linux-arm64": "1.0.64-1", - "@github/copilot-linux-x64": "1.0.64-1", - "@github/copilot-linuxmusl-arm64": "1.0.64-1", - "@github/copilot-linuxmusl-x64": "1.0.64-1", - "@github/copilot-win32-arm64": "1.0.64-1", - "@github/copilot-win32-x64": "1.0.64-1" + "@github/copilot-darwin-arm64": "1.0.64-3", + "@github/copilot-darwin-x64": "1.0.64-3", + "@github/copilot-linux-arm64": "1.0.64-3", + "@github/copilot-linux-x64": "1.0.64-3", + "@github/copilot-linuxmusl-arm64": "1.0.64-3", + "@github/copilot-linuxmusl-x64": "1.0.64-3", + "@github/copilot-win32-arm64": "1.0.64-3", + "@github/copilot-win32-x64": "1.0.64-3" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-1.tgz", - "integrity": "sha512-MQHZT9LhmCiq+ogO1E8cPCWrurZ6x+r9lPJfYUSnOyMO+EHbREpiJwOOChxtLHgL2/tKJSZdId2pg3tDgUlcsw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-3.tgz", + "integrity": "sha512-wlV6mRoAd/wG2V08TG+BOJ0nyOjroya24FSyA5A49z7PnUUuQXYRpa/GljvI5j3PM8aUl0DyBkXuB/DcFU818g==", "cpu": [ "arm64" ], @@ -466,9 +466,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-1.tgz", - "integrity": "sha512-kOQY7CvI7He0eO3ObQAHePWdkNLWAOegCSzUqUmdcpa1SNVqbZ3GBMsQ7uAZQip2cQxnGZ7pS1v6tKQ0HJdkYw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-3.tgz", + "integrity": "sha512-mk48PIESL2keeemX7tLRmWRDxKwl0q3cFI1ORD2QcrieNK7pSqI3eVbfoB7MqoUUI27yzIkl67xqgl8Qq28IUQ==", "cpu": [ "x64" ], @@ -482,9 +482,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-1.tgz", - "integrity": "sha512-hIfuO7Q+pWs0SKfIRYqT+CjMaupudnhp4RMS6XoJ5s/e33rvpj2tkTkXYlHJo1PMDI823vvbqgpEdr+KeewMwg==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-3.tgz", + "integrity": "sha512-rCgtK3/rofQW5StSbeU0TwDUlOl2bvS2HGKyapVxow1Nvz3Q/TDB+eFRQc5ocBdv5tNSor+Caw2JGkRx5v508w==", "cpu": [ "arm64" ], @@ -498,9 +498,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-1.tgz", - "integrity": "sha512-VHaE62pha0rDDvuNN3bd97gf0EZ+EJebstM1ejHsMYoPT1IOUkYEXlNfGGHY+GfUGYxAiy/+Uew4xw5mJyy/Sw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-3.tgz", + "integrity": "sha512-FAiBMw1h07mURSBLi3ztj5yzbP+uTbo9mhxOym1Xysut5LDpO2kYUzTYk2DlIyLGZhmH/HDOZE+b6U7lOUQy0g==", "cpu": [ "x64" ], @@ -514,9 +514,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-1.tgz", - "integrity": "sha512-L/YrZPotRujAP0QERq+DlkR1SLr7abbTSz/56JqKKOqEdjKZPdQW1bUlhL/w1CZg1gXlTNUsNVyKz/fUfrEBgw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-3.tgz", + "integrity": "sha512-vn8P6grPf0y2mNskkdVbAz0i46b1sP9uSXv7z6kgycjprl0CdIYPDf3WEkG60vpyopfQna+iCqCLMWRnNyCk3g==", "cpu": [ "arm64" ], @@ -530,9 +530,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-1.tgz", - "integrity": "sha512-AGMjXqR128oyjiJhoI6Gd7JP5ddWkib+P4YH/JoHm05iNn23ZYl4tSc0XihHzeyMI1ix7Aacn8UINYB7lGOGOA==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-3.tgz", + "integrity": "sha512-atdHimNd6nzRRwHybXUY6/84bYzXeKbDOeYN/N/DsX23+AQOPSu5BD8MD8166I/5kNHui0XOmeTSydVNBUwcJw==", "cpu": [ "x64" ], @@ -546,9 +546,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-1.tgz", - "integrity": "sha512-vvv+gnemi9WKaxF41zz7Xmq6a493n8Yjps5UFaOY6a3WR222kKXZXfOpeRvIYsDgnIPHGBHIj1TBOmnHQT4V4w==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-3.tgz", + "integrity": "sha512-jUTS9meoHEXQR8nMDOjwC0baqV273lYtLxY46W7TiOFszhsqhbhWxQMkNQBfT3GEfPp+40igzMPq3reaUTuvag==", "cpu": [ "arm64" ], @@ -562,9 +562,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-1.tgz", - "integrity": "sha512-mcHvD0fjGDuqr/YXzy8mKuDmah1F+qjPujxoFuGmabmTJZ33cSIJ3nq7RRvxZNIdp8YJ57NkbcW30WvIcOeJ3w==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-3.tgz", + "integrity": "sha512-gHUhS500Q91hjtH9fqKDblaIs0mO09G4ifpZ1woDPXbkdKe/W29uwB7g2fn0+KczNRyPxFSWlqjnOon4Fe8svA==", "cpu": [ "x64" ], diff --git a/java/scripts/codegen/package.json b/java/scripts/codegen/package.json index ec0ade02a..5a6e0b777 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.64-1", + "@github/copilot": "^1.0.64-3", "json-schema": "^0.4.0", "tsx": "^4.22.4" } diff --git a/java/src/generated/java/com/github/copilot/generated/ModelCallFailureEvent.java b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureEvent.java index 40dc4c54e..067203ac3 100644 --- a/java/src/generated/java/com/github/copilot/generated/ModelCallFailureEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureEvent.java @@ -57,7 +57,9 @@ public record ModelCallFailureEventData( /** For HTTP 400 failures only: the `code` from the CAPI error envelope (e.g. 'model_max_prompt_tokens_exceeded') identifying which deterministic validation failure occurred. Raw server-controlled string, emitted only through restricted telemetry. Absent for bodyless or non-400 failures. */ @JsonProperty("errorCode") String errorCode, /** For HTTP 400 failures only: the `type` from the CAPI error envelope (e.g. 'websocket_error'), a coarser companion to errorCode for envelopes that carry no code. Raw server-controlled string, emitted only through restricted telemetry. Absent for bodyless or non-400 failures. */ - @JsonProperty("errorType") String errorType + @JsonProperty("errorType") String errorType, + /** Content-free structural summary of the failing request. Contains only counts and shape flags (no prompt content), so it is safe for unrestricted telemetry. Populated only for client-error (4xx) failures. */ + @JsonProperty("requestFingerprint") ModelCallFailureRequestFingerprint requestFingerprint ) { } } diff --git a/java/src/generated/java/com/github/copilot/generated/ModelCallFailureRequestFingerprint.java b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureRequestFingerprint.java new file mode 100644 index 000000000..b8d0622b6 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/ModelCallFailureRequestFingerprint.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 com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.processing.Generated; + +/** + * Content-free structural summary of the failing request for diagnosing malformed 4xx calls + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record ModelCallFailureRequestFingerprint( + /** Total number of messages in the request */ + @JsonProperty("messageCount") Long messageCount, + /** Number of "tool" result messages in the request */ + @JsonProperty("toolResultMessageCount") Long toolResultMessageCount, + /** Total number of tool calls across assistant messages */ + @JsonProperty("toolCallCount") Long toolCallCount, + /** Tool calls whose name is missing or empty (rejected by strict providers) */ + @JsonProperty("namelessToolCallCount") Long namelessToolCallCount, + /** Total number of image content parts */ + @JsonProperty("imagePartCount") Long imagePartCount, + /** Image parts whose media type cannot be determined (rejected by strict providers) */ + @JsonProperty("imagePartsMissingMediaType") Long imagePartsMissingMediaType, + /** Role of the final message in the request */ + @JsonProperty("lastMessageRole") String lastMessageRole +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/SkillsLoadedSkill.java b/java/src/generated/java/com/github/copilot/generated/SkillsLoadedSkill.java index 07ce97825..a3db9697f 100644 --- a/java/src/generated/java/com/github/copilot/generated/SkillsLoadedSkill.java +++ b/java/src/generated/java/com/github/copilot/generated/SkillsLoadedSkill.java @@ -32,6 +32,8 @@ public record SkillsLoadedSkill( /** Whether the skill is currently enabled */ @JsonProperty("enabled") Boolean enabled, /** Absolute path to the skill file, if available */ - @JsonProperty("path") String path + @JsonProperty("path") String path, + /** Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field */ + @JsonProperty("argumentHint") String argumentHint ) { } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/AccountAllUsers.java b/java/src/generated/java/com/github/copilot/generated/rpc/AccountAllUsers.java new file mode 100644 index 000000000..a544b8a30 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/AccountAllUsers.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; + +/** + * Schema for the `AccountAllUsers` type. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record AccountAllUsers( + /** Authentication information for this user */ + @JsonProperty("authInfo") Object authInfo, + /** Associated token, if available */ + @JsonProperty("token") String token +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/AccountGetCurrentAuthResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/AccountGetCurrentAuthResult.java new file mode 100644 index 000000000..9cbcd4906 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/AccountGetCurrentAuthResult.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 java.util.List; +import javax.annotation.processing.Generated; + +/** + * Current authentication state + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record AccountGetCurrentAuthResult( + /** Current authentication information, if authenticated */ + @JsonProperty("authInfo") Object authInfo, + /** Authentication errors from the last auth attempt, if any */ + @JsonProperty("authErrors") List authErrors +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/AccountLoginParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/AccountLoginParams.java new file mode 100644 index 000000000..6dd4266b2 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/AccountLoginParams.java @@ -0,0 +1,30 @@ +/*--------------------------------------------------------------------------------------------- + * 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; + +/** + * Credentials to store after successful authentication + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record AccountLoginParams( + /** GitHub host URL */ + @JsonProperty("host") String host, + /** User login/username */ + @JsonProperty("login") String login, + /** GitHub authentication token */ + @JsonProperty("token") String token +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/AccountLoginResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/AccountLoginResult.java new file mode 100644 index 000000000..33d65f7dc --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/AccountLoginResult.java @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * 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; + +/** + * Result of a successful login; throws on failure + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record AccountLoginResult( + /** Whether the credential was persisted to a secure store (system keychain, or the config file when plaintext storage is enabled). False when no secure store was available and the token was not saved, so the consumer can decide how to proceed. */ + @JsonProperty("storedInVault") Boolean storedInVault +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/AccountLogoutParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/AccountLogoutParams.java new file mode 100644 index 000000000..0d15fd123 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/AccountLogoutParams.java @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * 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; + +/** + * User to log out + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record AccountLogoutParams( + /** Authentication information for the user to log out */ + @JsonProperty("authInfo") Object authInfo +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/AccountLogoutResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/AccountLogoutResult.java new file mode 100644 index 000000000..c26df8524 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/AccountLogoutResult.java @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * 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; + +/** + * Logout result indicating if more users remain + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record AccountLogoutResult( + /** Whether other authenticated users remain after logout */ + @JsonProperty("hasMoreUsers") Boolean hasMoreUsers +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ModelBillingTokenPrices.java b/java/src/generated/java/com/github/copilot/generated/rpc/ModelBillingTokenPrices.java index 246d4e585..56e06fe22 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/ModelBillingTokenPrices.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ModelBillingTokenPrices.java @@ -25,7 +25,7 @@ public record ModelBillingTokenPrices( @JsonProperty("inputPrice") Double inputPrice, /** AI Credits cost per billing batch of output tokens */ @JsonProperty("outputPrice") Double outputPrice, - /** Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens */ + /** Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens */ @JsonProperty("cachePrice") Double cachePrice, /** AI Credits cost per billing batch of cached (read) tokens */ @JsonProperty("cacheReadPrice") Double cacheReadPrice, @@ -33,7 +33,7 @@ public record ModelBillingTokenPrices( @JsonProperty("cacheWritePrice") Double cacheWritePrice, /** Number of tokens per standard billing batch */ @JsonProperty("batchSize") Long batchSize, - /** Deprecated: use maxPromptTokens. Prompt token budget for the default tier. The total context window is this value plus the model's max_output_tokens. */ + /** Use maxPromptTokens instead. Prompt token budget for the default tier. The total context window is this value plus the model's max_output_tokens. */ @JsonProperty("contextMax") Long contextMax, /** Prompt token budget for the default tier. The total context window is this value plus the model's max_output_tokens. */ @JsonProperty("maxPromptTokens") Long maxPromptTokens, diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ModelBillingTokenPricesLongContext.java b/java/src/generated/java/com/github/copilot/generated/rpc/ModelBillingTokenPricesLongContext.java index 95ca05631..bb6751579 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/ModelBillingTokenPricesLongContext.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ModelBillingTokenPricesLongContext.java @@ -25,13 +25,13 @@ public record ModelBillingTokenPricesLongContext( @JsonProperty("inputPrice") Double inputPrice, /** AI Credits cost per billing batch of output tokens */ @JsonProperty("outputPrice") Double outputPrice, - /** Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens */ + /** Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens */ @JsonProperty("cachePrice") Double cachePrice, /** AI Credits cost per billing batch of cached (read) tokens */ @JsonProperty("cacheReadPrice") Double cacheReadPrice, /** AI Credits cost per billing batch of cache-write (cache creation) tokens. */ @JsonProperty("cacheWritePrice") Double cacheWritePrice, - /** Deprecated: use maxPromptTokens. Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. */ + /** Use maxPromptTokens instead. Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. */ @JsonProperty("contextMax") Long contextMax, /** Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. */ @JsonProperty("maxPromptTokens") Long maxPromptTokens diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/NamedProviderConfig.java b/java/src/generated/java/com/github/copilot/generated/rpc/NamedProviderConfig.java new file mode 100644 index 000000000..2d5bddaf8 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/NamedProviderConfig.java @@ -0,0 +1,42 @@ +/*--------------------------------------------------------------------------------------------- + * 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 java.util.Map; +import javax.annotation.processing.Generated; + +/** + * A named BYOK provider connection (transport + credentials). + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record NamedProviderConfig( + /** Stable identifier referenced by BYOK model definitions. Must not contain '/'. */ + @JsonProperty("name") String name, + /** Provider type. Defaults to "openai" for generic OpenAI-compatible APIs. */ + @JsonProperty("type") ProviderConfigType type, + /** Wire API format (openai/azure only). Defaults to "completions". */ + @JsonProperty("wireApi") ProviderConfigWireApi wireApi, + /** API endpoint URL. */ + @JsonProperty("baseUrl") String baseUrl, + /** API key. Optional for local providers like Ollama. */ + @JsonProperty("apiKey") String apiKey, + /** Bearer token for authentication. Sets the Authorization header directly. Takes precedence over apiKey when both are set. */ + @JsonProperty("bearerToken") String bearerToken, + /** Azure-specific provider options. */ + @JsonProperty("azure") ProviderConfigAzure azure, + /** Custom HTTP headers to include in all outbound requests to the provider. */ + @JsonProperty("headers") Map headers +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ProviderModelConfig.java b/java/src/generated/java/com/github/copilot/generated/rpc/ProviderModelConfig.java new file mode 100644 index 000000000..c9f2630ed --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ProviderModelConfig.java @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * 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; + +/** + * A BYOK model definition referencing a named provider. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record ProviderModelConfig( + /** Provider-local model id, unique within its provider. The session-wide selection id (shown in the model list and passed to switchTo) is the provider-qualified `provider/id`. */ + @JsonProperty("id") String id, + /** Name of the NamedProviderConfig that serves this model. */ + @JsonProperty("provider") String provider, + /** The model name sent to the provider API for inference. Defaults to `id`. */ + @JsonProperty("wireModel") String wireModel, + /** Well-known base model id used for behavior/capability/config lookup. Defaults to `id`. */ + @JsonProperty("modelId") String modelId, + /** Display name for model pickers. Defaults to the provider-qualified selection id (`provider/id`). */ + @JsonProperty("name") String name, + /** Maximum prompt/input tokens for the model. */ + @JsonProperty("maxPromptTokens") Double maxPromptTokens, + /** Maximum context window tokens for the model. */ + @JsonProperty("maxContextWindowTokens") Double maxContextWindowTokens, + /** Maximum output tokens for the model. */ + @JsonProperty("maxOutputTokens") Double maxOutputTokens, + /** Optional capability overrides (vision, tool_calls, reasoning, etc.). */ + @JsonProperty("capabilities") ModelCapabilitiesOverride capabilities +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/RpcCaller.java b/java/src/generated/java/com/github/copilot/generated/rpc/RpcCaller.java index 67e7571a1..eec46d688 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/RpcCaller.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/RpcCaller.java @@ -7,7 +7,10 @@ package com.github.copilot.generated.rpc; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonNode; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import javax.annotation.processing.Generated; /** @@ -35,4 +38,26 @@ public interface RpcCaller { * @return a {@link CompletableFuture} that completes with the deserialized result */ CompletableFuture invoke(String method, Object params, Class resultType); + + /** + * Invokes a JSON-RPC method and returns a future for the typed response. + * + * @param the expected response type + * @param method the JSON-RPC method name + * @param params the request parameters (may be a {@code Map}, DTO record, or {@code JsonNode}) + * @param resultType the Jackson {@link JavaType} of the expected response type + * @return a {@link CompletableFuture} that completes with the deserialized result + */ + default CompletableFuture invoke(String method, Object params, JavaType resultType) { + if (resultType.hasRawClass(Void.class) || resultType.hasRawClass(Void.TYPE)) { + return invoke(method, params, Void.class).thenApply(ignored -> null); + } + return invoke(method, params, JsonNode.class).thenApply(result -> { + try { + return RpcMapper.INSTANCE.readerFor(resultType).readValue(result); + } catch (java.io.IOException e) { + throw new CompletionException(e); + } + }); + } } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ServerAccountApi.java b/java/src/generated/java/com/github/copilot/generated/rpc/ServerAccountApi.java index d3bd44460..b750596b5 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/ServerAccountApi.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ServerAccountApi.java @@ -7,6 +7,7 @@ package com.github.copilot.generated.rpc; +import java.util.List; import java.util.concurrent.CompletableFuture; import javax.annotation.processing.Generated; @@ -33,4 +34,36 @@ public CompletableFuture getQuota() { return caller.invoke("account.getQuota", java.util.Map.of(), AccountGetQuotaResult.class); } + /** + * Current authentication state + * @since 1.0.0 + */ + public CompletableFuture getCurrentAuth() { + return caller.invoke("account.getCurrentAuth", java.util.Map.of(), AccountGetCurrentAuthResult.class); + } + + /** + * List of all authenticated users + * @since 1.0.0 + */ + public CompletableFuture> getAllUsers() { + return caller.invoke("account.getAllUsers", java.util.Map.of(), RpcMapper.INSTANCE.getTypeFactory().constructCollectionType(List.class, AccountAllUsers.class)); + } + + /** + * Credentials to store after successful authentication + * @since 1.0.0 + */ + public CompletableFuture login(AccountLoginParams params) { + return caller.invoke("account.login", params, AccountLoginResult.class); + } + + /** + * User to log out + * @since 1.0.0 + */ + public CompletableFuture logout(AccountLogoutParams params) { + return caller.invoke("account.logout", params, AccountLogoutResult.class); + } + } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ServerSkill.java b/java/src/generated/java/com/github/copilot/generated/rpc/ServerSkill.java index ba02ea28d..9752907e9 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/ServerSkill.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ServerSkill.java @@ -34,6 +34,8 @@ public record ServerSkill( /** Absolute path to the skill file */ @JsonProperty("path") String path, /** The project path this skill belongs to (only for project/inherited skills) */ - @JsonProperty("projectPath") String projectPath + @JsonProperty("projectPath") String projectPath, + /** Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field */ + @JsonProperty("argumentHint") String argumentHint ) { } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderAddParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderAddParams.java new file mode 100644 index 000000000..371c9d10d --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderAddParams.java @@ -0,0 +1,35 @@ +/*--------------------------------------------------------------------------------------------- + * 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 java.util.List; +import javax.annotation.processing.Generated; + +/** + * BYOK providers and/or models to add to the session's registry at runtime. Both fields are optional; provide providers, models, or both. + * + * @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 SessionProviderAddParams( + /** Target session identifier */ + @JsonProperty("sessionId") String sessionId, + /** Named BYOK provider connections to register, additive to any providers already in the registry. Each name must be unique across the registry and must not contain '/'. */ + @JsonProperty("providers") List providers, + /** BYOK model definitions to register. Each must reference a provider that is already registered or included in this same call. Selection ids (`provider/id`) must be unique across the registry. */ + @JsonProperty("models") List models +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderAddResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderAddResult.java new file mode 100644 index 000000000..c0a04eb8c --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderAddResult.java @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * 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 java.util.List; +import javax.annotation.processing.Generated; + +/** + * The selectable model entries synthesized for the models added by this call. + * + * @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 SessionProviderAddResult( + /** Synthesized selectable model entries for the newly added BYOK models, each under its provider-qualified selection id (`provider/id`). Empty when only providers were added. */ + @JsonProperty("models") List models +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderApi.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderApi.java index 428f916ae..4a6fdc186 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderApi.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionProviderApi.java @@ -19,6 +19,8 @@ @javax.annotation.processing.Generated("copilot-sdk-codegen") public final class SessionProviderApi { + private static final com.fasterxml.jackson.databind.ObjectMapper MAPPER = RpcMapper.INSTANCE; + private final RpcCaller caller; private final String sessionId; @@ -39,4 +41,20 @@ public CompletableFuture getEndpoint() { return caller.invoke("session.provider.getEndpoint", java.util.Map.of("sessionId", this.sessionId), SessionProviderGetEndpointResult.class); } + /** + * BYOK providers and/or models to add to the session's registry at runtime. Both fields are optional; provide providers, models, or both. + *

+ * 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 add(SessionProviderAddParams params) { + com.fasterxml.jackson.databind.node.ObjectNode _p = MAPPER.valueToTree(params); + _p.put("sessionId", this.sessionId); + return caller.invoke("session.provider.add", _p, SessionProviderAddResult.class); + } + } diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/Skill.java b/java/src/generated/java/com/github/copilot/generated/rpc/Skill.java index d64f01515..5b1cea9b7 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/Skill.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/Skill.java @@ -34,6 +34,8 @@ public record Skill( /** Absolute path to the skill file */ @JsonProperty("path") String path, /** Name of the plugin that provides the skill, when source is 'plugin' */ - @JsonProperty("pluginName") String pluginName + @JsonProperty("pluginName") String pluginName, + /** Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field */ + @JsonProperty("argumentHint") String argumentHint ) { } diff --git a/java/src/test/java/com/github/copilot/RpcWrappersTest.java b/java/src/test/java/com/github/copilot/RpcWrappersTest.java index feb78d896..9a3559d66 100644 --- a/java/src/test/java/com/github/copilot/RpcWrappersTest.java +++ b/java/src/test/java/com/github/copilot/RpcWrappersTest.java @@ -85,6 +85,28 @@ void serverRpc_models_list_invokes_correct_rpc_method() { assertEquals("models.list", stub.calls.get(0).method()); } + @Test + void serverRpc_account_getAllUsers_returns_typed_list() throws Exception { + var stub = new StubCaller(); + stub.nextResult = new ObjectMapper().readTree(""" + [ + { + "authInfo": { "kind": "oauth" }, + "token": "token-1" + } + ] + """); + + var server = new ServerRpc(stub); + var users = server.account.getAllUsers().get(); + + assertEquals(1, stub.calls.size()); + assertEquals("account.getAllUsers", stub.calls.get(0).method()); + assertEquals(1, users.size()); + assertInstanceOf(Map.class, users.get(0).authInfo()); + assertEquals("token-1", users.get(0).token()); + } + @Test void serverRpc_ping_passes_params_directly() { var stub = new StubCaller(); 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 dbfc15036..b5e83f17d 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 @@ -696,7 +696,8 @@ void sessionShellKillResult_record() { @Test void sessionSkillsListResult_nested() { - var item = new Skill("deploy", "Deploy the app", SkillSource.PROJECT, true, true, "/skills/deploy.md", null); + var item = new Skill("deploy", "Deploy the app", SkillSource.PROJECT, true, true, "/skills/deploy.md", null, + null); var result = new SessionSkillsListResult(List.of(item)); assertEquals(1, result.skills().size()); assertEquals("deploy", result.skills().get(0).name()); diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json index 08cd933c4..6727b3d33 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.64-1", + "@github/copilot": "^1.0.64-3", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, @@ -697,9 +697,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-1.tgz", - "integrity": "sha512-lojV4Cb7oT4VJnYPEKBRH8KI3W43Q4Lh0Pc+V6sej+xjPJkoqwm68sNKn73/p3wXPBSTVTzPeCm9WhIisgf1Jw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-3.tgz", + "integrity": "sha512-Q9nBMYEHX1bJLXzzJocQx2nZvORJ0E9gvK6ly/FCtmtA7ad96BWZvf4EHzkCNDsn56aI3zNaUSfKHUKcmIAzSg==", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "detect-libc": "^2.1.2" @@ -708,20 +708,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.64-1", - "@github/copilot-darwin-x64": "1.0.64-1", - "@github/copilot-linux-arm64": "1.0.64-1", - "@github/copilot-linux-x64": "1.0.64-1", - "@github/copilot-linuxmusl-arm64": "1.0.64-1", - "@github/copilot-linuxmusl-x64": "1.0.64-1", - "@github/copilot-win32-arm64": "1.0.64-1", - "@github/copilot-win32-x64": "1.0.64-1" + "@github/copilot-darwin-arm64": "1.0.64-3", + "@github/copilot-darwin-x64": "1.0.64-3", + "@github/copilot-linux-arm64": "1.0.64-3", + "@github/copilot-linux-x64": "1.0.64-3", + "@github/copilot-linuxmusl-arm64": "1.0.64-3", + "@github/copilot-linuxmusl-x64": "1.0.64-3", + "@github/copilot-win32-arm64": "1.0.64-3", + "@github/copilot-win32-x64": "1.0.64-3" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-1.tgz", - "integrity": "sha512-MQHZT9LhmCiq+ogO1E8cPCWrurZ6x+r9lPJfYUSnOyMO+EHbREpiJwOOChxtLHgL2/tKJSZdId2pg3tDgUlcsw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-3.tgz", + "integrity": "sha512-wlV6mRoAd/wG2V08TG+BOJ0nyOjroya24FSyA5A49z7PnUUuQXYRpa/GljvI5j3PM8aUl0DyBkXuB/DcFU818g==", "cpu": [ "arm64" ], @@ -735,9 +735,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-1.tgz", - "integrity": "sha512-kOQY7CvI7He0eO3ObQAHePWdkNLWAOegCSzUqUmdcpa1SNVqbZ3GBMsQ7uAZQip2cQxnGZ7pS1v6tKQ0HJdkYw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-3.tgz", + "integrity": "sha512-mk48PIESL2keeemX7tLRmWRDxKwl0q3cFI1ORD2QcrieNK7pSqI3eVbfoB7MqoUUI27yzIkl67xqgl8Qq28IUQ==", "cpu": [ "x64" ], @@ -751,9 +751,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-1.tgz", - "integrity": "sha512-hIfuO7Q+pWs0SKfIRYqT+CjMaupudnhp4RMS6XoJ5s/e33rvpj2tkTkXYlHJo1PMDI823vvbqgpEdr+KeewMwg==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-3.tgz", + "integrity": "sha512-rCgtK3/rofQW5StSbeU0TwDUlOl2bvS2HGKyapVxow1Nvz3Q/TDB+eFRQc5ocBdv5tNSor+Caw2JGkRx5v508w==", "cpu": [ "arm64" ], @@ -767,9 +767,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-1.tgz", - "integrity": "sha512-VHaE62pha0rDDvuNN3bd97gf0EZ+EJebstM1ejHsMYoPT1IOUkYEXlNfGGHY+GfUGYxAiy/+Uew4xw5mJyy/Sw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-3.tgz", + "integrity": "sha512-FAiBMw1h07mURSBLi3ztj5yzbP+uTbo9mhxOym1Xysut5LDpO2kYUzTYk2DlIyLGZhmH/HDOZE+b6U7lOUQy0g==", "cpu": [ "x64" ], @@ -783,9 +783,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-1.tgz", - "integrity": "sha512-L/YrZPotRujAP0QERq+DlkR1SLr7abbTSz/56JqKKOqEdjKZPdQW1bUlhL/w1CZg1gXlTNUsNVyKz/fUfrEBgw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-3.tgz", + "integrity": "sha512-vn8P6grPf0y2mNskkdVbAz0i46b1sP9uSXv7z6kgycjprl0CdIYPDf3WEkG60vpyopfQna+iCqCLMWRnNyCk3g==", "cpu": [ "arm64" ], @@ -799,9 +799,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-1.tgz", - "integrity": "sha512-AGMjXqR128oyjiJhoI6Gd7JP5ddWkib+P4YH/JoHm05iNn23ZYl4tSc0XihHzeyMI1ix7Aacn8UINYB7lGOGOA==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-3.tgz", + "integrity": "sha512-atdHimNd6nzRRwHybXUY6/84bYzXeKbDOeYN/N/DsX23+AQOPSu5BD8MD8166I/5kNHui0XOmeTSydVNBUwcJw==", "cpu": [ "x64" ], @@ -815,9 +815,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-1.tgz", - "integrity": "sha512-vvv+gnemi9WKaxF41zz7Xmq6a493n8Yjps5UFaOY6a3WR222kKXZXfOpeRvIYsDgnIPHGBHIj1TBOmnHQT4V4w==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-3.tgz", + "integrity": "sha512-jUTS9meoHEXQR8nMDOjwC0baqV273lYtLxY46W7TiOFszhsqhbhWxQMkNQBfT3GEfPp+40igzMPq3reaUTuvag==", "cpu": [ "arm64" ], @@ -831,9 +831,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-1.tgz", - "integrity": "sha512-mcHvD0fjGDuqr/YXzy8mKuDmah1F+qjPujxoFuGmabmTJZ33cSIJ3nq7RRvxZNIdp8YJ57NkbcW30WvIcOeJ3w==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-3.tgz", + "integrity": "sha512-gHUhS500Q91hjtH9fqKDblaIs0mO09G4ifpZ1woDPXbkdKe/W29uwB7g2fn0+KczNRyPxFSWlqjnOon4Fe8svA==", "cpu": [ "x64" ], diff --git a/nodejs/package.json b/nodejs/package.json index 140a50fd4..d9663006c 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -56,7 +56,7 @@ "author": "GitHub", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.64-1", + "@github/copilot": "^1.0.64-3", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/samples/package-lock.json b/nodejs/samples/package-lock.json index 1589ceb67..ddcf5a8e2 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.64-1", + "@github/copilot": "^1.0.64-3", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/src/client.ts b/nodejs/src/client.ts index 473479ac1..ade6c54fd 100644 --- a/nodejs/src/client.ts +++ b/nodejs/src/client.ts @@ -727,7 +727,8 @@ export class CopilotClient { const errors: Error[] = []; // Disconnect all active sessions with retry logic - for (const session of this.sessions.values()) { + const activeSessions = [...this.sessions.values()]; + for (const session of activeSessions) { const sessionId = session.sessionId; let lastError: Error | null = null; @@ -756,6 +757,9 @@ export class CopilotClient { ); } } + for (const session of activeSessions) { + session._markDisconnected(); + } this.sessions.clear(); // Ask SDK-owned runtimes to flush and clean up before we tear down @@ -916,6 +920,9 @@ export class CopilotClient { this.forceStopping = true; // Clear sessions immediately without trying to destroy them + for (const session of this.sessions.values()) { + session._markDisconnected(); + } this.sessions.clear(); // Force close connection diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts index 6303f9db2..b894228f5 100644 --- a/nodejs/src/generated/rpc.ts +++ b/nodejs/src/generated/rpc.ts @@ -7,6 +7,20 @@ 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"; +/** + * Initial authentication info for the session. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AuthInfo". + */ +export type AuthInfo = + | HMACAuthInfo + | EnvAuthInfo + | TokenAuthInfo + | CopilotApiTokenAuthInfo + | UserAuthInfo + | GhCliAuthInfo + | ApiKeyAuthInfo; /** * Which tier this directory belongs to * @@ -173,21 +187,6 @@ export type AgentRegistrySpawnValidationErrorField = | "model" /** The permissionMode parameter */ | "permissionMode"; -/** - * Initial authentication info for the session. - * - * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AuthInfo". - */ -/** @experimental */ -export type AuthInfo = - | HMACAuthInfo - | EnvAuthInfo - | TokenAuthInfo - | CopilotApiTokenAuthInfo - | UserAuthInfo - | GhCliAuthInfo - | ApiKeyAuthInfo; /** * Authentication type * @@ -1796,6 +1795,13 @@ export type WorkspacesWorkspaceDetailsHostType = | "github" /** Workspace repository is hosted on Azure DevOps. */ | "ado"; +/** + * List of all authenticated users + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AccountGetAllUsersResult". + */ +export type AccountGetAllUsersResult = AccountAllUsers[]; /** * Parameters for aborting the current turn @@ -1824,827 +1830,893 @@ export interface AbortResult { */ error?: string; } - -export interface AccountGetQuotaRequest { - /** - * GitHub token for per-user quota lookup. When provided, resolves this token to determine the user's quota instead of using the global auth. - */ - gitHubToken?: string; -} /** - * Quota usage snapshots for the resolved user, keyed by quota type. + * Schema for the `AccountAllUsers` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AccountGetQuotaResult". + * via the `definition` "AccountAllUsers". */ -export interface AccountGetQuotaResult { +export interface AccountAllUsers { + authInfo: AuthInfo; /** - * Quota snapshots keyed by type (e.g., chat, completions, premium_interactions) + * Associated token, if available */ - quotaSnapshots: { - [k: string]: AccountQuotaSnapshot | undefined; - }; + token?: string; } /** - * Schema for the `AccountQuotaSnapshot` type. + * Schema for the `HMACAuthInfo` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AccountQuotaSnapshot". + * via the `definition` "HMACAuthInfo". */ -export interface AccountQuotaSnapshot { - /** - * Whether the user has an unlimited usage entitlement - */ - isUnlimitedEntitlement: boolean; - /** - * Number of requests included in the entitlement, or -1 for unlimited entitlements - */ - entitlementRequests: number; - /** - * Number of requests used so far this period - */ - usedRequests: number; - /** - * Whether usage is still permitted after quota exhaustion - */ - usageAllowedWithExhaustedQuota: boolean; - /** - * Percentage of entitlement remaining - */ - remainingPercentage: number; +export interface HMACAuthInfo { /** - * Number of additional usage requests made this period + * HMAC-based authentication used by GitHub-internal services. */ - overage: number; + type: "hmac"; /** - * Whether additional usage is allowed when quota is exhausted + * Authentication host. HMAC auth always targets the public GitHub host. */ - overageAllowedWithExhaustedQuota: boolean; + host: "https://github.com"; /** - * Date when the quota resets (ISO 8601 string) + * HMAC secret used to sign requests. */ - resetDate?: string; + hmac: string; + copilotUser?: CopilotUserResponse; } /** - * Schema for the `AgentDiscoveryPath` type. + * Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentDiscoveryPath". + * via the `definition` "CopilotUserResponse". */ -/** @experimental */ -export interface AgentDiscoveryPath { - /** - * Absolute path of the search/create directory (may not exist on disk yet) - */ - path: string; - scope: AgentDiscoveryPathScope; - /** - * Whether this is the canonical directory to create a new agent in its tier. At most one entry per tier is preferred. - */ - preferredForCreation: boolean; - /** - * The input project path this directory was derived from (only for project scope) - */ - projectPath?: string; +export interface CopilotUserResponse { + login?: string; + access_type_sku?: string; + analytics_tracking_id?: string; + assigned_date?: + | ( + | { + [k: string]: unknown | undefined; + } + | string + ) + | null; + can_signup_for_limited?: boolean; + chat_enabled?: boolean; + copilot_plan?: string; + copilotignore_enabled?: boolean; + endpoints?: CopilotUserResponseEndpoints; + organization_login_list?: string[]; + organization_list?: + | ( + | { + [k: string]: unknown | undefined; + } + | ({ + login?: + | ( + | { + [k: string]: unknown | undefined; + } + | string + ) + | null; + name?: + | ( + | { + [k: string]: unknown | undefined; + } + | string + ) + | null; + } | null)[] + ) + | null; + codex_agent_enabled?: boolean; + is_mcp_enabled?: + | ( + | { + [k: string]: unknown | undefined; + } + | boolean + ) + | null; + quota_reset_date?: string; + quota_snapshots?: CopilotUserResponseQuotaSnapshots; + restricted_telemetry?: boolean; + is_staff?: boolean; + token_based_billing?: boolean; + can_upgrade_plan?: boolean; + quota_reset_date_utc?: string; + limited_user_quotas?: { + [k: string]: number | undefined; + }; + limited_user_reset_date?: string; + monthly_quotas?: { + [k: string]: number | undefined; + }; + cloud_session_storage_enabled?: boolean; + cli_remote_control_enabled?: boolean; } /** - * Canonical locations where custom agents can be created so the runtime will recognize them. + * Schema for the `CopilotUserResponseEndpoints` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentDiscoveryPathList". + * via the `definition` "CopilotUserResponseEndpoints". */ -/** @experimental */ -export interface AgentDiscoveryPathList { - /** - * Canonical agent create/discovery directories, in priority order - */ - paths: AgentDiscoveryPath[]; +export interface CopilotUserResponseEndpoints { + api?: string; + "origin-tracker"?: string; + proxy?: string; + telemetry?: string; } /** - * The currently selected custom agent, or null when using the default agent. + * Schema for the `CopilotUserResponseQuotaSnapshots` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentGetCurrentResult". + * via the `definition` "CopilotUserResponseQuotaSnapshots". */ -/** @experimental */ -export interface AgentGetCurrentResult { - /** - * Currently selected custom agent, or null if using the default agent - */ - agent?: AgentInfo | null; +export interface CopilotUserResponseQuotaSnapshots { + chat?: CopilotUserResponseQuotaSnapshotsChat; + completions?: CopilotUserResponseQuotaSnapshotsCompletions; + premium_interactions?: CopilotUserResponseQuotaSnapshotsPremiumInteractions; + [k: string]: + | ({ + entitlement?: number; + overage_count?: number; + overage_permitted?: boolean; + percent_remaining?: number; + quota_id?: string; + quota_remaining?: number; + remaining?: number; + unlimited?: boolean; + timestamp_utc?: string; + has_quota?: boolean; + quota_reset_at?: number; + token_based_billing?: boolean; + } | null) + | undefined; } /** - * Schema for the `AgentInfo` type. + * Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentInfo". + * via the `definition` "CopilotUserResponseQuotaSnapshotsChat". */ -/** @experimental */ -export interface AgentInfo { - /** - * Unique identifier of the custom agent - */ - name: string; - /** - * Human-readable display name - */ - displayName: string; - /** - * Description of the agent's purpose - */ - description: string; - /** - * Absolute local file path of the agent definition. Only set for file-based agents loaded from disk; remote agents do not have a path. - */ - path?: string; - /** - * Stable identifier for selection. For most agents this is the same as `name`; for plugin/builtin agents it may differ. Always populated; defaults to `name` when no distinct id was assigned. - */ - id: string; - source?: AgentInfoSource; - /** - * Whether the agent can be selected directly by the user. Agents marked `false` are subagent-only. - */ - userInvocable?: boolean; - /** - * Allowed tool names for this agent. Empty array means none; omitted means inherit defaults. - */ - tools?: string[]; - /** - * Preferred model id for this agent. When omitted, inherits the outer agent's model. - */ - model?: string; - /** - * MCP server configurations attached to this agent, keyed by server name. Server config shape mirrors the MCP `mcpServers` schema. - * - * @experimental - */ - mcpServers?: { - [k: string]: unknown | undefined; - }; - /** - * Skill names preloaded into this agent's context. Omitted means none. - */ - skills?: string[]; +export interface CopilotUserResponseQuotaSnapshotsChat { + entitlement?: number; + overage_count?: number; + overage_permitted?: boolean; + percent_remaining?: number; + quota_id?: string; + quota_remaining?: number; + remaining?: number; + unlimited?: boolean; + timestamp_utc?: string; + has_quota?: boolean; + quota_reset_at?: number; + token_based_billing?: boolean; } /** - * Custom agents available to the session. + * Schema for the `CopilotUserResponseQuotaSnapshotsCompletions` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentList". + * via the `definition` "CopilotUserResponseQuotaSnapshotsCompletions". */ -/** @experimental */ -export interface AgentList { - /** - * Available custom agents - */ - agents: AgentInfo[]; +export interface CopilotUserResponseQuotaSnapshotsCompletions { + entitlement?: number; + overage_count?: number; + overage_permitted?: boolean; + percent_remaining?: number; + quota_id?: string; + quota_remaining?: number; + remaining?: number; + unlimited?: boolean; + timestamp_utc?: string; + has_quota?: boolean; + quota_reset_at?: number; + token_based_billing?: boolean; } /** - * Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). + * Schema for the `CopilotUserResponseQuotaSnapshotsPremiumInteractions` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentRegistryLiveTargetEntry". + * via the `definition` "CopilotUserResponseQuotaSnapshotsPremiumInteractions". */ -/** @experimental */ -export interface AgentRegistryLiveTargetEntry { - /** - * Registry entry schema version (1 = ui-server, 2 = managed-server) - */ - schemaVersion: number; - kind: AgentRegistryLiveTargetEntryKind; +export interface CopilotUserResponseQuotaSnapshotsPremiumInteractions { + entitlement?: number; + overage_count?: number; + overage_permitted?: boolean; + percent_remaining?: number; + quota_id?: string; + quota_remaining?: number; + remaining?: number; + unlimited?: boolean; + timestamp_utc?: string; + has_quota?: boolean; + quota_reset_at?: number; + token_based_billing?: boolean; +} +/** + * Schema for the `EnvAuthInfo` type. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "EnvAuthInfo". + */ +export interface EnvAuthInfo { /** - * Operating-system pid of the process owning this entry + * Personal access token (PAT) or server-to-server token sourced from an environment variable. */ - pid: number; + type: "env"; /** - * Bind host for the entry's JSON-RPC server + * Authentication host (e.g. https://github.com or a GHES host). */ host: string; /** - * TCP port the entry's JSON-RPC server is listening on + * User login associated with the token. Undefined for server-to-server tokens (those starting with `ghs_`). */ - port: number; + login?: string; /** - * Connection token (null when the target is unauthenticated) - * - * @internal + * The token value itself. Treat as a secret. */ - token?: string | null; + token: string; /** - * Session ID of the foreground session for this entry + * Name of the environment variable the token was sourced from. */ - sessionId?: string; + envVar: string; + copilotUser?: CopilotUserResponse; +} +/** + * Schema for the `TokenAuthInfo` type. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "TokenAuthInfo". + */ +export interface TokenAuthInfo { /** - * Friendly session name (when set) + * SDK-side token authentication; the host configured the token directly via the SDK. */ - sessionName?: string; + type: "token"; /** - * Working directory of the session (when known) + * Authentication host. */ - cwd?: string; + host: string; /** - * Git branch of the session (when known) + * The token value itself. Treat as a secret. */ - branch?: string; + token: string; + copilotUser?: CopilotUserResponse; +} +/** + * Schema for the `CopilotApiTokenAuthInfo` type. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "CopilotApiTokenAuthInfo". + */ +export interface CopilotApiTokenAuthInfo { /** - * Model identifier currently selected for the session + * Direct Copilot API authentication via the `GITHUB_COPILOT_API_TOKEN` + `COPILOT_API_URL` environment-variable pair. The token itself is read from the environment by the runtime, not carried in this struct. */ - model?: string; - status?: AgentRegistryLiveTargetEntryStatus; - attentionKind?: AgentRegistryLiveTargetEntryAttentionKind; + type: "copilot-api-token"; /** - * Monotonic per-publisher revision counter incremented on every status update. Lets watchers detect transient flips. + * Authentication host (always the public GitHub host). */ - statusRevision?: number; - lastTerminalEvent?: AgentRegistryLiveTargetEntryLastTerminalEvent; + host: "https://github.com"; + copilotUser?: CopilotUserResponse; +} +/** + * Schema for the `UserAuthInfo` type. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "UserAuthInfo". + */ +export interface UserAuthInfo { /** - * ISO 8601 timestamp captured at registration + * OAuth user authentication. The token itself is held in the runtime's secret token store (keyed by host+login) and is NOT carried in this struct. */ - startedAt: string; + type: "user"; /** - * Copilot CLI version that wrote the entry + * Authentication host. */ - copilotVersion: string; + host: string; /** - * Wall-clock milliseconds since the watcher last observed this entry (heartbeat freshness) + * OAuth user login. */ - lastSeenMs: number; + login: string; + copilotUser?: CopilotUserResponse; } /** - * Per-spawn log-capture outcome; populated from spawnLiveTarget. + * Schema for the `GhCliAuthInfo` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentRegistryLogCapture". + * via the `definition` "GhCliAuthInfo". */ -/** @experimental */ -export interface AgentRegistryLogCapture { +export interface GhCliAuthInfo { /** - * Whether per-spawn log capture is on (false when env-disabled or open failed) + * Authentication via the `gh` CLI's saved credentials. */ - enabled: boolean; + type: "gh-cli"; /** - * Absolute path to the per-spawn log file (only set when enabled) + * Authentication host. */ - path?: string; + host: string; /** - * Human-readable open failure message (only set when enabled === false AND the env-disable opt-out was NOT used) + * User login as reported by `gh auth status`. */ - openError?: string; - openErrorReason?: AgentRegistryLogCaptureOpenErrorReason; + login: string; + /** + * The token returned by `gh auth token`. Treat as a secret. + */ + token: string; + copilotUser?: CopilotUserResponse; } /** - * `child_process.spawn` itself failed before the child entered the registry. + * Schema for the `ApiKeyAuthInfo` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentRegistrySpawnError". + * via the `definition` "ApiKeyAuthInfo". */ -/** @experimental */ -export interface AgentRegistrySpawnError { +export interface ApiKeyAuthInfo { /** - * Discriminator: child_process.spawn itself failed + * API-key authentication for non-GitHub LLM providers (e.g. when running BYOM-style). */ - kind: "spawn-error"; + type: "api-key"; /** - * Human-readable error message + * The API key. Treat as a secret. */ - message: string; + apiKey: string; /** - * Underlying errno code (e.g. ENOENT, EACCES) when available + * Authentication host. */ - code?: string; + host: string; + copilotUser?: CopilotUserResponse; } /** - * Spawn succeeded but the child did not publish a matching managed-server entry within the timeout. + * Current authentication state * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentRegistrySpawnRegistryTimeout". + * via the `definition` "AccountGetCurrentAuthResult". */ -/** @experimental */ -export interface AgentRegistrySpawnRegistryTimeout { +export interface AccountGetCurrentAuthResult { + authInfo?: AuthInfo; /** - * Discriminator: spawn succeeded but child never registered + * Authentication errors from the last auth attempt, if any */ - kind: "registry-timeout"; + authErrors?: string[]; +} + +export interface AccountGetQuotaRequest { /** - * Process ID of the orphaned child (so the caller can offer 'kill the pid' guidance) + * GitHub token for per-user quota lookup. When provided, resolves this token to determine the user's quota instead of using the global auth. */ - childPid: number; - logCapture?: AgentRegistryLogCapture; + gitHubToken?: string; } /** - * Inputs to spawn a managed-server child via the controller's spawn delegate. + * Quota usage snapshots for the resolved user, keyed by quota type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentRegistrySpawnRequest". + * via the `definition` "AccountGetQuotaResult". */ -/** @experimental */ -export interface AgentRegistrySpawnRequest { +export interface AccountGetQuotaResult { /** - * Working directory for the spawned child (must be an existing directory) + * Quota snapshots keyed by type (e.g., chat, completions, premium_interactions) */ - cwd: string; + quotaSnapshots: { + [k: string]: AccountQuotaSnapshot | undefined; + }; +} +/** + * Schema for the `AccountQuotaSnapshot` type. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AccountQuotaSnapshot". + */ +export interface AccountQuotaSnapshot { /** - * Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own default. + * Whether the user has an unlimited usage entitlement */ - agentName?: string; + isUnlimitedEntitlement: boolean; /** - * Model identifier to apply to the new session + * Number of requests included in the entitlement, or -1 for unlimited entitlements */ - model?: string; + entitlementRequests: number; /** - * Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing whitespace, <=100 chars, no control chars, no double quotes. + * Number of requests used so far this period */ - name?: string; - permissionMode?: AgentRegistrySpawnPermissionMode; + usedRequests: number; /** - * Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it post-attach via the standard LocalRpcSession.send path). + * Whether usage is still permitted after quota exhaustion */ - initialPrompt?: string; -} -/** - * Managed-server child was spawned and registered successfully. - * - * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentRegistrySpawnSpawned". - */ -/** @experimental */ -export interface AgentRegistrySpawnSpawned { + usageAllowedWithExhaustedQuota: boolean; /** - * Discriminator: managed-server child spawned successfully + * Percentage of entitlement remaining */ - kind: "spawned"; - entry: AgentRegistryLiveTargetEntry; + remainingPercentage: number; /** - * Whether the delegate already sent the initial prompt. Always omitted in the current wiring: the controller sends the prompt post-attach via the standard LocalRpcSession.send path. + * Number of additional usage requests made this period */ - initialPromptSent?: boolean; + overage: number; /** - * If the delegate attempted to send the initial prompt and failed, the categorized error message. + * Whether additional usage is allowed when quota is exhausted */ - initialPromptError?: string; - logCapture?: AgentRegistryLogCapture; + overageAllowedWithExhaustedQuota: boolean; + /** + * Date when the quota resets (ISO 8601 string) + */ + resetDate?: string; } /** - * Synchronous pre-validation rejected the spawn request. + * Credentials to store after successful authentication * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentRegistrySpawnValidationError". + * via the `definition` "AccountLoginRequest". */ -/** @experimental */ -export interface AgentRegistrySpawnValidationError { +export interface AccountLoginRequest { /** - * Discriminator: synchronous pre-validation rejected the request + * GitHub host URL */ - kind: "validation-error"; - reason: AgentRegistrySpawnValidationErrorReason; - field?: AgentRegistrySpawnValidationErrorField; + host: string; /** - * Human-readable explanation; safe to surface in the UI banner. Never logged to unrestricted telemetry. + * User login/username */ - message: string; -} -/** - * Custom agents available to the session after reloading definitions from disk. - * - * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentReloadResult". - */ -/** @experimental */ -export interface AgentReloadResult { + login: string; /** - * Reloaded custom agents + * GitHub authentication token */ - agents: AgentInfo[]; + token: string; } /** - * Optional project paths to include in agent discovery. + * Result of a successful login; throws on failure * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentsDiscoverRequest". + * via the `definition` "AccountLoginResult". */ -/** @experimental */ -export interface AgentsDiscoverRequest { - /** - * Optional list of project directory paths to scan for project-scoped agents. When omitted or empty, only user/plugin/remote-independent agents are returned (no project scan). - */ - projectPaths?: string[]; +export interface AccountLoginResult { /** - * When true, omit the host's agents (the user-level agent directory and all plugin agents), leaving only project and remote agents. For multitenant deployments. + * Whether the credential was persisted to a secure store (system keychain, or the config file when plaintext storage is enabled). False when no secure store was available and the token was not saved, so the consumer can decide how to proceed. */ - excludeHostAgents?: boolean; + storedInVault: boolean; } /** - * Name of the custom agent to select for subsequent turns. + * User to log out * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentSelectRequest". + * via the `definition` "AccountLogoutRequest". */ -/** @experimental */ -export interface AgentSelectRequest { - /** - * Name of the custom agent to select - */ - name: string; +export interface AccountLogoutRequest { + authInfo: AuthInfo; } /** - * The newly selected custom agent. + * Logout result indicating if more users remain * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentSelectResult". + * via the `definition` "AccountLogoutResult". */ -/** @experimental */ -export interface AgentSelectResult { - agent: AgentInfo; +export interface AccountLogoutResult { + /** + * Whether other authenticated users remain after logout + */ + hasMoreUsers: boolean; } /** - * Optional project paths to include when enumerating agent discovery directories. + * Schema for the `AgentDiscoveryPath` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AgentsGetDiscoveryPathsRequest". + * via the `definition` "AgentDiscoveryPath". */ /** @experimental */ -export interface AgentsGetDiscoveryPathsRequest { +export interface AgentDiscoveryPath { /** - * Optional list of project directory paths. When omitted or empty, only the user-level directory is returned. + * Absolute path of the search/create directory (may not exist on disk yet) */ - projectPaths?: string[]; + path: string; + scope: AgentDiscoveryPathScope; /** - * When true, omit the host's user-level agent directory, leaving only project directories. For multitenant deployments (mirrors `discover`'s `excludeHostAgents`). + * Whether this is the canonical directory to create a new agent in its tier. At most one entry per tier is preferred. */ - excludeHostAgents?: boolean; + preferredForCreation: boolean; + /** + * The input project path this directory was derived from (only for project scope) + */ + projectPath?: string; } /** - * Indicates whether the operation succeeded and reports the post-mutation state. + * Canonical locations where custom agents can be created so the runtime will recognize them. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AllowAllPermissionSetResult". + * via the `definition` "AgentDiscoveryPathList". */ /** @experimental */ -export interface AllowAllPermissionSetResult { - /** - * Whether the operation succeeded - */ - success: boolean; +export interface AgentDiscoveryPathList { /** - * Authoritative allow-all state after the mutation + * Canonical agent create/discovery directories, in priority order */ - enabled: boolean; + paths: AgentDiscoveryPath[]; } /** - * Current full allow-all permission state. + * The currently selected custom agent, or null when using the default agent. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "AllowAllPermissionState". + * via the `definition` "AgentGetCurrentResult". */ /** @experimental */ -export interface AllowAllPermissionState { +export interface AgentGetCurrentResult { /** - * Whether full allow-all permissions are currently active + * Currently selected custom agent, or null if using the default agent */ - enabled: boolean; + agent?: AgentInfo | null; } /** - * Schema for the `ApiKeyAuthInfo` type. + * Schema for the `AgentInfo` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "ApiKeyAuthInfo". + * via the `definition` "AgentInfo". */ /** @experimental */ -export interface ApiKeyAuthInfo { +export interface AgentInfo { /** - * API-key authentication for non-GitHub LLM providers (e.g. when running BYOM-style). + * Unique identifier of the custom agent */ - type: "api-key"; + name: string; /** - * The API key. Treat as a secret. + * Human-readable display name */ - apiKey: string; + displayName: string; /** - * Authentication host. + * Description of the agent's purpose */ - host: string; - copilotUser?: CopilotUserResponse; -} -/** - * Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. - * - * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "CopilotUserResponse". - */ -/** @experimental */ -export interface CopilotUserResponse { - login?: string; - access_type_sku?: string; - analytics_tracking_id?: string; - assigned_date?: - | ( - | { - [k: string]: unknown | undefined; - } - | string - ) - | null; - can_signup_for_limited?: boolean; - chat_enabled?: boolean; - copilot_plan?: string; - copilotignore_enabled?: boolean; - endpoints?: CopilotUserResponseEndpoints; - organization_login_list?: string[]; - organization_list?: - | ( - | { - [k: string]: unknown | undefined; - } - | ({ - login?: - | ( - | { - [k: string]: unknown | undefined; - } - | string - ) - | null; - name?: - | ( - | { - [k: string]: unknown | undefined; - } - | string - ) - | null; - } | null)[] - ) - | null; - codex_agent_enabled?: boolean; - is_mcp_enabled?: - | ( - | { - [k: string]: unknown | undefined; - } - | boolean - ) - | null; - quota_reset_date?: string; - quota_snapshots?: CopilotUserResponseQuotaSnapshots; - restricted_telemetry?: boolean; - is_staff?: boolean; - token_based_billing?: boolean; - can_upgrade_plan?: boolean; - quota_reset_date_utc?: string; - limited_user_quotas?: { - [k: string]: number | undefined; - }; - limited_user_reset_date?: string; - monthly_quotas?: { - [k: string]: number | undefined; + description: string; + /** + * Absolute local file path of the agent definition. Only set for file-based agents loaded from disk; remote agents do not have a path. + */ + path?: string; + /** + * Stable identifier for selection. For most agents this is the same as `name`; for plugin/builtin agents it may differ. Always populated; defaults to `name` when no distinct id was assigned. + */ + id: string; + source?: AgentInfoSource; + /** + * Whether the agent can be selected directly by the user. Agents marked `false` are subagent-only. + */ + userInvocable?: boolean; + /** + * Allowed tool names for this agent. Empty array means none; omitted means inherit defaults. + */ + tools?: string[]; + /** + * Preferred model id for this agent. When omitted, inherits the outer agent's model. + */ + model?: string; + /** + * MCP server configurations attached to this agent, keyed by server name. Server config shape mirrors the MCP `mcpServers` schema. + * + * @experimental + */ + mcpServers?: { + [k: string]: unknown | undefined; }; - cloud_session_storage_enabled?: boolean; - cli_remote_control_enabled?: boolean; + /** + * Skill names preloaded into this agent's context. Omitted means none. + */ + skills?: string[]; } /** - * Schema for the `CopilotUserResponseEndpoints` type. + * Custom agents available to the session. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "CopilotUserResponseEndpoints". + * via the `definition` "AgentList". */ /** @experimental */ -export interface CopilotUserResponseEndpoints { - api?: string; - "origin-tracker"?: string; - proxy?: string; - telemetry?: string; +export interface AgentList { + /** + * Available custom agents + */ + agents: AgentInfo[]; } /** - * Schema for the `CopilotUserResponseQuotaSnapshots` type. + * Full registry entry for the spawned child. Lets the controller call `handleLiveTargetSelected(entry)` directly without re-reading the registry (avoids a TOCTOU window). * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "CopilotUserResponseQuotaSnapshots". + * via the `definition` "AgentRegistryLiveTargetEntry". */ /** @experimental */ -export interface CopilotUserResponseQuotaSnapshots { - chat?: CopilotUserResponseQuotaSnapshotsChat; - completions?: CopilotUserResponseQuotaSnapshotsCompletions; - premium_interactions?: CopilotUserResponseQuotaSnapshotsPremiumInteractions; - [k: string]: - | ({ - entitlement?: number; - overage_count?: number; - overage_permitted?: boolean; - percent_remaining?: number; - quota_id?: string; - quota_remaining?: number; - remaining?: number; - unlimited?: boolean; - timestamp_utc?: string; - has_quota?: boolean; - quota_reset_at?: number; - token_based_billing?: boolean; - } | null) - | undefined; +export interface AgentRegistryLiveTargetEntry { + /** + * Registry entry schema version (1 = ui-server, 2 = managed-server) + */ + schemaVersion: number; + kind: AgentRegistryLiveTargetEntryKind; + /** + * Operating-system pid of the process owning this entry + */ + pid: number; + /** + * Bind host for the entry's JSON-RPC server + */ + host: string; + /** + * TCP port the entry's JSON-RPC server is listening on + */ + port: number; + /** + * Connection token (null when the target is unauthenticated) + * + * @internal + */ + token?: string | null; + /** + * Session ID of the foreground session for this entry + */ + sessionId?: string; + /** + * Friendly session name (when set) + */ + sessionName?: string; + /** + * Working directory of the session (when known) + */ + cwd?: string; + /** + * Git branch of the session (when known) + */ + branch?: string; + /** + * Model identifier currently selected for the session + */ + model?: string; + status?: AgentRegistryLiveTargetEntryStatus; + attentionKind?: AgentRegistryLiveTargetEntryAttentionKind; + /** + * Monotonic per-publisher revision counter incremented on every status update. Lets watchers detect transient flips. + */ + statusRevision?: number; + lastTerminalEvent?: AgentRegistryLiveTargetEntryLastTerminalEvent; + /** + * ISO 8601 timestamp captured at registration + */ + startedAt: string; + /** + * Copilot CLI version that wrote the entry + */ + copilotVersion: string; + /** + * Wall-clock milliseconds since the watcher last observed this entry (heartbeat freshness) + */ + lastSeenMs: number; } /** - * Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. + * Per-spawn log-capture outcome; populated from spawnLiveTarget. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "CopilotUserResponseQuotaSnapshotsChat". + * via the `definition` "AgentRegistryLogCapture". */ /** @experimental */ -export interface CopilotUserResponseQuotaSnapshotsChat { - entitlement?: number; - overage_count?: number; - overage_permitted?: boolean; - percent_remaining?: number; - quota_id?: string; - quota_remaining?: number; - remaining?: number; - unlimited?: boolean; - timestamp_utc?: string; - has_quota?: boolean; - quota_reset_at?: number; - token_based_billing?: boolean; +export interface AgentRegistryLogCapture { + /** + * Whether per-spawn log capture is on (false when env-disabled or open failed) + */ + enabled: boolean; + /** + * Absolute path to the per-spawn log file (only set when enabled) + */ + path?: string; + /** + * Human-readable open failure message (only set when enabled === false AND the env-disable opt-out was NOT used) + */ + openError?: string; + openErrorReason?: AgentRegistryLogCaptureOpenErrorReason; } /** - * Schema for the `CopilotUserResponseQuotaSnapshotsCompletions` type. + * `child_process.spawn` itself failed before the child entered the registry. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "CopilotUserResponseQuotaSnapshotsCompletions". + * via the `definition` "AgentRegistrySpawnError". */ /** @experimental */ -export interface CopilotUserResponseQuotaSnapshotsCompletions { - entitlement?: number; - overage_count?: number; - overage_permitted?: boolean; - percent_remaining?: number; - quota_id?: string; - quota_remaining?: number; - remaining?: number; - unlimited?: boolean; - timestamp_utc?: string; - has_quota?: boolean; - quota_reset_at?: number; - token_based_billing?: boolean; +export interface AgentRegistrySpawnError { + /** + * Discriminator: child_process.spawn itself failed + */ + kind: "spawn-error"; + /** + * Human-readable error message + */ + message: string; + /** + * Underlying errno code (e.g. ENOENT, EACCES) when available + */ + code?: string; } /** - * Schema for the `CopilotUserResponseQuotaSnapshotsPremiumInteractions` type. + * Spawn succeeded but the child did not publish a matching managed-server entry within the timeout. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "CopilotUserResponseQuotaSnapshotsPremiumInteractions". + * via the `definition` "AgentRegistrySpawnRegistryTimeout". */ /** @experimental */ -export interface CopilotUserResponseQuotaSnapshotsPremiumInteractions { - entitlement?: number; - overage_count?: number; - overage_permitted?: boolean; - percent_remaining?: number; - quota_id?: string; - quota_remaining?: number; - remaining?: number; - unlimited?: boolean; - timestamp_utc?: string; - has_quota?: boolean; - quota_reset_at?: number; - token_based_billing?: boolean; +export interface AgentRegistrySpawnRegistryTimeout { + /** + * Discriminator: spawn succeeded but child never registered + */ + kind: "registry-timeout"; + /** + * Process ID of the orphaned child (so the caller can offer 'kill the pid' guidance) + */ + childPid: number; + logCapture?: AgentRegistryLogCapture; } /** - * Schema for the `HMACAuthInfo` type. + * Inputs to spawn a managed-server child via the controller's spawn delegate. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "HMACAuthInfo". + * via the `definition` "AgentRegistrySpawnRequest". */ /** @experimental */ -export interface HMACAuthInfo { +export interface AgentRegistrySpawnRequest { /** - * HMAC-based authentication used by GitHub-internal services. + * Working directory for the spawned child (must be an existing directory) */ - type: "hmac"; + cwd: string; /** - * Authentication host. HMAC auth always targets the public GitHub host. + * Custom or built-in agent name (e.g. 'explore'). When omitted, the child uses its own default. */ - host: "https://github.com"; + agentName?: string; /** - * HMAC secret used to sign requests. + * Model identifier to apply to the new session */ - hmac: string; - copilotUser?: CopilotUserResponse; + model?: string; + /** + * Friendly session name. Must satisfy validateSessionName: non-empty, no leading/trailing whitespace, <=100 chars, no control chars, no double quotes. + */ + name?: string; + permissionMode?: AgentRegistrySpawnPermissionMode; + /** + * Optional first user message. Forwarded to the caller (the CLI's spawn wrapper sends it post-attach via the standard LocalRpcSession.send path). + */ + initialPrompt?: string; } /** - * Schema for the `EnvAuthInfo` type. + * Managed-server child was spawned and registered successfully. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "EnvAuthInfo". + * via the `definition` "AgentRegistrySpawnSpawned". */ /** @experimental */ -export interface EnvAuthInfo { - /** - * Personal access token (PAT) or server-to-server token sourced from an environment variable. - */ - type: "env"; - /** - * Authentication host (e.g. https://github.com or a GHES host). - */ - host: string; +export interface AgentRegistrySpawnSpawned { /** - * User login associated with the token. Undefined for server-to-server tokens (those starting with `ghs_`). + * Discriminator: managed-server child spawned successfully */ - login?: string; + kind: "spawned"; + entry: AgentRegistryLiveTargetEntry; /** - * The token value itself. Treat as a secret. + * Whether the delegate already sent the initial prompt. Always omitted in the current wiring: the controller sends the prompt post-attach via the standard LocalRpcSession.send path. */ - token: string; + initialPromptSent?: boolean; /** - * Name of the environment variable the token was sourced from. + * If the delegate attempted to send the initial prompt and failed, the categorized error message. */ - envVar: string; - copilotUser?: CopilotUserResponse; + initialPromptError?: string; + logCapture?: AgentRegistryLogCapture; } /** - * Schema for the `TokenAuthInfo` type. + * Synchronous pre-validation rejected the spawn request. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "TokenAuthInfo". + * via the `definition` "AgentRegistrySpawnValidationError". */ /** @experimental */ -export interface TokenAuthInfo { +export interface AgentRegistrySpawnValidationError { /** - * SDK-side token authentication; the host configured the token directly via the SDK. + * Discriminator: synchronous pre-validation rejected the request */ - type: "token"; + kind: "validation-error"; + reason: AgentRegistrySpawnValidationErrorReason; + field?: AgentRegistrySpawnValidationErrorField; /** - * Authentication host. + * Human-readable explanation; safe to surface in the UI banner. Never logged to unrestricted telemetry. */ - host: string; + message: string; +} +/** + * Custom agents available to the session after reloading definitions from disk. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentReloadResult". + */ +/** @experimental */ +export interface AgentReloadResult { /** - * The token value itself. Treat as a secret. + * Reloaded custom agents */ - token: string; - copilotUser?: CopilotUserResponse; + agents: AgentInfo[]; } /** - * Schema for the `CopilotApiTokenAuthInfo` type. + * Optional project paths to include in agent discovery. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "CopilotApiTokenAuthInfo". + * via the `definition` "AgentsDiscoverRequest". */ /** @experimental */ -export interface CopilotApiTokenAuthInfo { +export interface AgentsDiscoverRequest { /** - * Direct Copilot API authentication via the `GITHUB_COPILOT_API_TOKEN` + `COPILOT_API_URL` environment-variable pair. The token itself is read from the environment by the runtime, not carried in this struct. + * Optional list of project directory paths to scan for project-scoped agents. When omitted or empty, only user/plugin/remote-independent agents are returned (no project scan). */ - type: "copilot-api-token"; + projectPaths?: string[]; /** - * Authentication host (always the public GitHub host). + * When true, omit the host's agents (the user-level agent directory and all plugin agents), leaving only project and remote agents. For multitenant deployments. */ - host: "https://github.com"; - copilotUser?: CopilotUserResponse; + excludeHostAgents?: boolean; } /** - * Schema for the `UserAuthInfo` type. + * Name of the custom agent to select for subsequent turns. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "UserAuthInfo". + * via the `definition` "AgentSelectRequest". */ /** @experimental */ -export interface UserAuthInfo { +export interface AgentSelectRequest { /** - * OAuth user authentication. The token itself is held in the runtime's secret token store (keyed by host+login) and is NOT carried in this struct. + * Name of the custom agent to select */ - type: "user"; + name: string; +} +/** + * The newly selected custom agent. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentSelectResult". + */ +/** @experimental */ +export interface AgentSelectResult { + agent: AgentInfo; +} +/** + * Optional project paths to include when enumerating agent discovery directories. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentsGetDiscoveryPathsRequest". + */ +/** @experimental */ +export interface AgentsGetDiscoveryPathsRequest { /** - * Authentication host. + * Optional list of project directory paths. When omitted or empty, only the user-level directory is returned. */ - host: string; + projectPaths?: string[]; /** - * OAuth user login. + * When true, omit the host's user-level agent directory, leaving only project directories. For multitenant deployments (mirrors `discover`'s `excludeHostAgents`). */ - login: string; - copilotUser?: CopilotUserResponse; + excludeHostAgents?: boolean; } /** - * Schema for the `GhCliAuthInfo` type. + * Indicates whether the operation succeeded and reports the post-mutation state. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "GhCliAuthInfo". + * via the `definition` "AllowAllPermissionSetResult". */ /** @experimental */ -export interface GhCliAuthInfo { - /** - * Authentication via the `gh` CLI's saved credentials. - */ - type: "gh-cli"; +export interface AllowAllPermissionSetResult { /** - * Authentication host. + * Whether the operation succeeded */ - host: string; + success: boolean; /** - * User login as reported by `gh auth status`. + * Authoritative allow-all state after the mutation */ - login: string; + enabled: boolean; +} +/** + * Current full allow-all permission state. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AllowAllPermissionState". + */ +/** @experimental */ +export interface AllowAllPermissionState { /** - * The token returned by `gh auth token`. Treat as a secret. + * Whether full allow-all permissions are currently active */ - token: string; - copilotUser?: CopilotUserResponse; + enabled: boolean; } /** * Cancellation result for a user-requested shell command. @@ -6250,7 +6322,8 @@ export interface ModelBillingTokenPrices { */ outputPrice?: number; /** - * Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens + * @deprecated + * Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens */ cachePrice?: number; /** @@ -6266,7 +6339,8 @@ export interface ModelBillingTokenPrices { */ batchSize?: number; /** - * Deprecated: use maxPromptTokens. Prompt token budget for the default tier. The total context window is this value plus the model's max_output_tokens. + * @deprecated + * Use maxPromptTokens instead. Prompt token budget for the default tier. The total context window is this value plus the model's max_output_tokens. */ contextMax?: number; /** @@ -6291,7 +6365,8 @@ export interface ModelBillingTokenPricesLongContext { */ outputPrice?: number; /** - * Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens + * @deprecated + * Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens */ cachePrice?: number; /** @@ -6303,7 +6378,8 @@ export interface ModelBillingTokenPricesLongContext { */ cacheWritePrice?: number; /** - * Deprecated: use maxPromptTokens. Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. + * @deprecated + * Use maxPromptTokens instead. Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. */ contextMax?: number; /** @@ -8373,6 +8449,78 @@ export interface SessionsPollSpawnedSessionsEvent { */ sessionId: string; } +/** + * BYOK providers and/or models to add to the session's registry at runtime. Both fields are optional; provide providers, models, or both. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "ProviderAddRequest". + */ +/** @experimental */ +export interface ProviderAddRequest { + /** + * Named BYOK provider connections to register, additive to any providers already in the registry. Each name must be unique across the registry and must not contain '/'. + */ + providers?: NamedProviderConfig[]; + /** + * BYOK model definitions to register. Each must reference a provider that is already registered or included in this same call. Selection ids (`provider/id`) must be unique across the registry. + */ + models?: ProviderModelConfig[]; +} +/** + * A BYOK model definition referencing a named provider. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "ProviderModelConfig". + */ +/** @experimental */ +export interface ProviderModelConfig { + /** + * Provider-local model id, unique within its provider. The session-wide selection id (shown in the model list and passed to switchTo) is the provider-qualified `provider/id`. + */ + id: string; + /** + * Name of the NamedProviderConfig that serves this model. + */ + provider: string; + /** + * The model name sent to the provider API for inference. Defaults to `id`. + */ + wireModel?: string; + /** + * Well-known base model id used for behavior/capability/config lookup. Defaults to `id`. + */ + modelId?: string; + /** + * Display name for model pickers. Defaults to the provider-qualified selection id (`provider/id`). + */ + name?: string; + /** + * Maximum prompt/input tokens for the model. + */ + maxPromptTokens?: number; + /** + * Maximum context window tokens for the model. + */ + maxContextWindowTokens?: number; + /** + * Maximum output tokens for the model. + */ + maxOutputTokens?: number; + capabilities?: ModelCapabilitiesOverride; +} +/** + * The selectable model entries synthesized for the models added by this call. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "ProviderAddResult". + */ +/** @experimental */ +export interface ProviderAddResult { + /** + * Synthesized selectable model entries for the newly added BYOK models, each under its provider-qualified selection id (`provider/id`). Empty when only providers were added. + */ + models: unknown[]; +} /** * Custom model-provider configuration (BYOK). * @@ -8487,48 +8635,6 @@ export interface ProviderGetEndpointRequest { */ modelId?: string; } -/** - * A BYOK model definition referencing a named provider. - * - * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "ProviderModelConfig". - */ -/** @experimental */ -export interface ProviderModelConfig { - /** - * Provider-local model id, unique within its provider. The session-wide selection id (shown in the model list and passed to switchTo) is the provider-qualified `provider/id`. - */ - id: string; - /** - * Name of the NamedProviderConfig that serves this model. - */ - provider: string; - /** - * The model name sent to the provider API for inference. Defaults to `id`. - */ - wireModel?: string; - /** - * Well-known base model id used for behavior/capability/config lookup. Defaults to `id`. - */ - modelId?: string; - /** - * Display name for model pickers. Defaults to the provider-qualified selection id (`provider/id`). - */ - name?: string; - /** - * Maximum prompt/input tokens for the model. - */ - maxPromptTokens?: number; - /** - * Maximum context window tokens for the model. - */ - maxContextWindowTokens?: number; - /** - * Maximum output tokens for the model. - */ - maxOutputTokens?: number; - capabilities?: ModelCapabilitiesOverride; -} /** * File attachment * @@ -9550,6 +9656,10 @@ export interface ServerSkill { * The project path this skill belongs to (only for project/inherited skills) */ projectPath?: string; + /** + * Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field + */ + argumentHint?: string; } /** * Skills discovered across global and project sources. @@ -11630,6 +11740,10 @@ export interface Skill { * Name of the plugin that provides the skill, when source is 'plugin' */ pluginName?: string; + /** + * Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field + */ + argumentHint?: string; } /** * Schema for the `SkillDiscoveryPath` type. @@ -13576,6 +13690,38 @@ export function createServerRpc(connection: MessageConnection) { */ getQuota: async (params: AccountGetQuotaRequest): Promise => connection.sendRequest("account.getQuota", params), + /** + * Gets the currently active authentication credentials from the global auth manager. + * + * @returns Current authentication state + */ + getCurrentAuth: async (): Promise => + connection.sendRequest("account.getCurrentAuth", {}), + /** + * Gets all authenticated users available for account switching. + * + * @returns List of all authenticated users + */ + getAllUsers: async (): Promise => + connection.sendRequest("account.getAllUsers", {}), + /** + * Stores authentication credentials after successful login (e.g., device code flow). + * + * @param params Credentials to store after successful authentication + * + * @returns Result of a successful login; throws on failure + */ + login: async (params: AccountLoginRequest): Promise => + connection.sendRequest("account.login", params), + /** + * Removes user authentication from keychain and persisted state. + * + * @param params User to log out + * + * @returns Logout result indicating if more users remain + */ + logout: async (params: AccountLogoutRequest): Promise => + connection.sendRequest("account.logout", params), }, secrets: { /** @@ -14846,6 +14992,15 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin */ getEndpoint: async (params?: ProviderGetEndpointRequest): Promise => connection.sendRequest("session.provider.getEndpoint", { sessionId, ...params }), + /** + * Adds BYOK providers and/or models to the session's registry at runtime, extending the additive registry built from the session's `providers`/`models` options. Both fields are optional, so a call may add providers only, models only, or both. Within a single call providers are registered before models, so a model may reference a provider added in the same call; across calls a model may reference any provider already registered (from session creation or a prior add). A model whose referenced provider is not registered by the end of the call is rejected. Newly added models become selectable via `model.list` / `model.switchTo` and are inherited by sub-agents spawned afterwards. + * + * @param params BYOK providers and/or models to add to the session's registry at runtime. Both fields are optional; provide providers, models, or both. + * + * @returns The selectable model entries synthesized for the models added by this call. + */ + add: async (params: ProviderAddRequest): Promise => + connection.sendRequest("session.provider.add", { sessionId, ...params }), }, /** @experimental */ options: { diff --git a/nodejs/src/generated/session-events.ts b/nodejs/src/generated/session-events.ts index cd74a7b48..d4faf7d4b 100644 --- a/nodejs/src/generated/session-events.ts +++ b/nodejs/src/generated/session-events.ts @@ -3441,6 +3441,7 @@ export interface ModelCallFailureData { * GitHub request tracing ID (x-github-request-id header) for server-side log correlation */ providerCallId?: string; + requestFingerprint?: ModelCallFailureRequestFingerprint; /** * Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation */ @@ -3451,6 +3452,39 @@ export interface ModelCallFailureData { */ statusCode?: number; } +/** + * Content-free structural summary of the failing request for diagnosing malformed 4xx calls + */ +export interface ModelCallFailureRequestFingerprint { + /** + * Total number of image content parts + */ + imagePartCount: number; + /** + * Image parts whose media type cannot be determined (rejected by strict providers) + */ + imagePartsMissingMediaType: number; + /** + * Role of the final message in the request + */ + lastMessageRole?: string; + /** + * Total number of messages in the request + */ + messageCount: number; + /** + * Tool calls whose name is missing or empty (rejected by strict providers) + */ + namelessToolCallCount: number; + /** + * Total number of tool calls across assistant messages + */ + toolCallCount: number; + /** + * Number of "tool" result messages in the request + */ + toolResultMessageCount: number; +} /** * Session event "abort". Turn abort information including the reason for termination */ @@ -7091,6 +7125,10 @@ export interface SkillsLoadedData { * Schema for the `SkillsLoadedSkill` type. */ export interface SkillsLoadedSkill { + /** + * Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field + */ + argumentHint?: string; /** * Description of what the skill does */ diff --git a/nodejs/src/session.ts b/nodejs/src/session.ts index 8ae19755a..0ba42ab76 100644 --- a/nodejs/src/session.ts +++ b/nodejs/src/session.ts @@ -134,6 +134,7 @@ export class CopilotSession { private traceContextProvider?: TraceContextProvider; private _capabilities: SessionCapabilities = {}; private openCanvasInstances: OpenCanvasInstance[] = []; + private disconnected = false; /** @internal Client session API handlers, populated by CopilotClient during create/resume. */ clientSessionApis: ClientSessionApiHandlers = {}; @@ -326,6 +327,22 @@ export class CopilotSession { } } + /** @internal */ + _markDisconnected(): void { + this.disconnected = true; + this.eventHandlers.clear(); + this.typedEventHandlers.clear(); + this.toolHandlers.clear(); + this.permissionHandler = undefined; + this.userInputHandler = undefined; + this.elicitationHandler = undefined; + this.exitPlanModeHandler = undefined; + this.autoModeSwitchHandler = undefined; + this.commandHandlers.clear(); + this.canvases.clear(); + this.transformCallbacks?.clear(); + } + /** * Subscribes to events from this session. * @@ -443,6 +460,9 @@ export class CopilotSession { * @internal */ private _handleBroadcastEvent(event: SessionEvent): void { + if (this.disconnected) { + return; + } if (event.type === "external_tool.requested") { const { requestId, toolName } = event.data as { requestId: string; @@ -582,8 +602,14 @@ export class CopilotSession { } else { result = JSON.stringify(rawResult); } + if (this.disconnected) { + return; + } await this.rpc.tools.handlePendingToolCall({ requestId, result }); } catch (error) { + if (this.disconnected) { + return; + } const message = error instanceof Error ? error.message : String(error); try { await this.rpc.tools.handlePendingToolCall({ requestId, error: message }); @@ -611,8 +637,14 @@ export class CopilotSession { if (result.kind === "no-result") { return; } + if (this.disconnected) { + return; + } await this.rpc.permissions.handlePendingPermissionRequest({ requestId, result }); } catch (_error) { + if (this.disconnected) { + return; + } try { await this.rpc.permissions.handlePendingPermissionRequest({ requestId, @@ -656,8 +688,14 @@ export class CopilotSession { try { await handler({ sessionId: this.sessionId, command, commandName, args }); + if (this.disconnected) { + return; + } await this.rpc.commands.handlePendingCommand({ requestId }); } catch (error) { + if (this.disconnected) { + return; + } const message = error instanceof Error ? error.message : String(error); try { await this.rpc.commands.handlePendingCommand({ requestId, error: message }); @@ -1170,17 +1208,13 @@ export class CopilotSession { * ``` */ async disconnect(): Promise { + if (this.disconnected) { + return; + } await this.connection.sendRequest("session.destroy", { sessionId: this.sessionId, }); - this.eventHandlers.clear(); - this.typedEventHandlers.clear(); - this.toolHandlers.clear(); - this.permissionHandler = undefined; - this.userInputHandler = undefined; - this.elicitationHandler = undefined; - this.exitPlanModeHandler = undefined; - this.autoModeSwitchHandler = undefined; + this._markDisconnected(); } /** Enables `await using session = ...` syntax for automatic cleanup. */ diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py index de42808b4..38100f534 100644 --- a/python/copilot/generated/rpc.py +++ b/python/copilot/generated/rpc.py @@ -48,10 +48,6 @@ def from_bool(x: Any) -> bool: assert isinstance(x, bool) return x -def from_int(x: Any) -> int: - assert isinstance(x, int) and not isinstance(x, bool) - return x - def from_float(x: Any) -> float: assert isinstance(x, (float, int)) and not isinstance(x, bool) return float(x) @@ -64,13 +60,17 @@ def from_dict(f: Callable[[Any], T], x: Any) -> dict[str, T]: assert isinstance(x, dict) return { k: f(v) for (k, v) in x.items() } +def from_list(f: Callable[[Any], T], x: Any) -> list[T]: + assert isinstance(x, list) + return [f(y) for y in x] + def to_enum(c: type[EnumT], x: Any) -> EnumT: assert isinstance(x, c) return x.value -def from_list(f: Callable[[Any], T], x: Any) -> list[T]: - assert isinstance(x, list) - return [f(y) for y in x] +def from_int(x: Any) -> int: + assert isinstance(x, int) and not isinstance(x, bool) + return x def from_datetime(x: Any) -> datetime: return dateutil.parser.parse(x) @@ -120,6 +120,99 @@ def to_dict(self) -> dict: result["error"] = from_union([from_str, from_none], self.error) return result +@dataclass +class CopilotUserResponseEndpoints: + """Schema for the `CopilotUserResponseEndpoints` type.""" + + api: str | None = None + origin_tracker: str | None = None + proxy: str | None = None + telemetry: str | None = None + + @staticmethod + def from_dict(obj: Any) -> 'CopilotUserResponseEndpoints': + assert isinstance(obj, dict) + api = from_union([from_str, from_none], obj.get("api")) + origin_tracker = from_union([from_str, from_none], obj.get("origin-tracker")) + proxy = from_union([from_str, from_none], obj.get("proxy")) + telemetry = from_union([from_str, from_none], obj.get("telemetry")) + return CopilotUserResponseEndpoints(api, origin_tracker, proxy, telemetry) + + def to_dict(self) -> dict: + result: dict = {} + if self.api is not None: + result["api"] = from_union([from_str, from_none], self.api) + if self.origin_tracker is not None: + result["origin-tracker"] = from_union([from_str, from_none], self.origin_tracker) + if self.proxy is not None: + result["proxy"] = from_union([from_str, from_none], self.proxy) + if self.telemetry is not None: + result["telemetry"] = from_union([from_str, from_none], self.telemetry) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +class AuthInfoType(Enum): + """Authentication type""" + + API_KEY = "api-key" + COPILOT_API_TOKEN = "copilot-api-token" + ENV = "env" + GH_CLI = "gh-cli" + HMAC = "hmac" + TOKEN = "token" + USER = "user" + +@dataclass +class AccountAllUsers: + """Schema for the `AccountAllUsers` type. + + List of all authenticated users + """ + auth_info: AuthInfo + """Authentication information for this user""" + + token: str | None = None + """Associated token, if available""" + + @staticmethod + def from_dict(obj: Any) -> 'AccountAllUsers': + assert isinstance(obj, dict) + auth_info = _load_AuthInfo(obj.get("authInfo")) + token = from_union([from_str, from_none], obj.get("token")) + return AccountAllUsers(auth_info, token) + + def to_dict(self) -> dict: + result: dict = {} + result["authInfo"] = (self.auth_info).to_dict() + if self.token is not None: + result["token"] = from_union([from_str, from_none], self.token) + return result + +@dataclass +class AccountGetCurrentAuthResult: + """Current authentication state""" + + auth_errors: list[str] | None = None + """Authentication errors from the last auth attempt, if any""" + + auth_info: AuthInfo | None = None + """Current authentication information, if authenticated""" + + @staticmethod + def from_dict(obj: Any) -> 'AccountGetCurrentAuthResult': + assert isinstance(obj, dict) + auth_errors = from_union([lambda x: from_list(from_str, x), from_none], obj.get("authErrors")) + auth_info = from_union([_load_AuthInfo, from_none], obj.get("authInfo")) + return AccountGetCurrentAuthResult(auth_errors, auth_info) + + def to_dict(self) -> dict: + result: dict = {} + if self.auth_errors is not None: + result["authErrors"] = from_union([lambda x: from_list(from_str, x), from_none], self.auth_errors) + if self.auth_info is not None: + result["authInfo"] = from_union([lambda x: (x).to_dict(), from_none], self.auth_info) + return result + @dataclass class AccountGetQuotaRequest: git_hub_token: str | None = None @@ -193,6 +286,91 @@ def to_dict(self) -> dict: result["resetDate"] = from_union([from_str, from_none], self.reset_date) return result +@dataclass +class AccountLoginRequest: + """Credentials to store after successful authentication""" + + host: str + """GitHub host URL""" + + login: str + """User login/username""" + + token: str + """GitHub authentication token""" + + @staticmethod + def from_dict(obj: Any) -> 'AccountLoginRequest': + assert isinstance(obj, dict) + host = from_str(obj.get("host")) + login = from_str(obj.get("login")) + token = from_str(obj.get("token")) + return AccountLoginRequest(host, login, token) + + def to_dict(self) -> dict: + result: dict = {} + result["host"] = from_str(self.host) + result["login"] = from_str(self.login) + result["token"] = from_str(self.token) + return result + +@dataclass +class AccountLoginResult: + """Result of a successful login; throws on failure""" + + stored_in_vault: bool + """Whether the credential was persisted to a secure store (system keychain, or the config + file when plaintext storage is enabled). False when no secure store was available and the + token was not saved, so the consumer can decide how to proceed. + """ + + @staticmethod + def from_dict(obj: Any) -> 'AccountLoginResult': + assert isinstance(obj, dict) + stored_in_vault = from_bool(obj.get("storedInVault")) + return AccountLoginResult(stored_in_vault) + + def to_dict(self) -> dict: + result: dict = {} + result["storedInVault"] = from_bool(self.stored_in_vault) + return result + +@dataclass +class AccountLogoutRequest: + """User to log out""" + + auth_info: AuthInfo + """Authentication information for the user to log out""" + + @staticmethod + def from_dict(obj: Any) -> 'AccountLogoutRequest': + assert isinstance(obj, dict) + auth_info = _load_AuthInfo(obj.get("authInfo")) + return AccountLogoutRequest(auth_info) + + def to_dict(self) -> dict: + result: dict = {} + result["authInfo"] = (self.auth_info).to_dict() + return result + +@dataclass +class AccountLogoutResult: + """Logout result indicating if more users remain""" + + has_more_users: bool + """Whether other authenticated users remain after logout""" + + @staticmethod + def from_dict(obj: Any) -> 'AccountLogoutResult': + assert isinstance(obj, dict) + has_more_users = from_bool(obj.get("hasMoreUsers")) + return AccountLogoutResult(has_more_users) + + def to_dict(self) -> dict: + result: dict = {} + result["hasMoreUsers"] = from_bool(self.has_more_users) + return result + # Experimental: this type is part of an experimental API and may change or be removed. class AgentDiscoveryPathScope(Enum): """Which tier this directory belongs to""" @@ -422,52 +600,9 @@ def to_dict(self) -> dict: result["enabled"] = from_bool(self.enabled) return result -# Experimental: this type is part of an experimental API and may change or be removed. -@dataclass -class CopilotUserResponseEndpoints: - """Schema for the `CopilotUserResponseEndpoints` type.""" - - api: str | None = None - origin_tracker: str | None = None - proxy: str | None = None - telemetry: str | None = None - - @staticmethod - def from_dict(obj: Any) -> 'CopilotUserResponseEndpoints': - assert isinstance(obj, dict) - api = from_union([from_str, from_none], obj.get("api")) - origin_tracker = from_union([from_str, from_none], obj.get("origin-tracker")) - proxy = from_union([from_str, from_none], obj.get("proxy")) - telemetry = from_union([from_str, from_none], obj.get("telemetry")) - return CopilotUserResponseEndpoints(api, origin_tracker, proxy, telemetry) - - def to_dict(self) -> dict: - result: dict = {} - if self.api is not None: - result["api"] = from_union([from_str, from_none], self.api) - if self.origin_tracker is not None: - result["origin-tracker"] = from_union([from_str, from_none], self.origin_tracker) - if self.proxy is not None: - result["proxy"] = from_union([from_str, from_none], self.proxy) - if self.telemetry is not None: - result["telemetry"] = from_union([from_str, from_none], self.telemetry) - return result - class APIKeyAuthInfoType(Enum): API_KEY = "api-key" -# Experimental: this type is part of an experimental API and may change or be removed. -class AuthInfoType(Enum): - """Authentication type""" - - API_KEY = "api-key" - COPILOT_API_TOKEN = "copilot-api-token" - ENV = "env" - GH_CLI = "gh-cli" - HMAC = "hmac" - TOKEN = "token" - USER = "user" - # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CancelUserRequestedShellCommandResult: @@ -974,7 +1109,6 @@ class Host(Enum): class CopilotAPITokenAuthInfoType(Enum): COPILOT_API_TOKEN = "copilot-api-token" -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CopilotUserResponseQuotaSnapshotsChat: """Schema for the `CopilotUserResponseQuotaSnapshotsChat` type.""" @@ -1037,7 +1171,6 @@ def to_dict(self) -> dict: result["unlimited"] = from_union([from_bool, from_none], self.unlimited) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CopilotUserResponseQuotaSnapshotsCompletions: """Schema for the `CopilotUserResponseQuotaSnapshotsCompletions` type.""" @@ -1100,7 +1233,6 @@ def to_dict(self) -> dict: result["unlimited"] = from_union([from_bool, from_none], self.unlimited) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CopilotUserResponseQuotaSnapshotsPremiumInteractions: """Schema for the `CopilotUserResponseQuotaSnapshotsPremiumInteractions` type.""" @@ -3367,7 +3499,7 @@ class ModelBillingTokenPricesLongContext: """Long context tier pricing (available for models with extended context windows)""" cache_price: float | None = None - """Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens""" + """Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens""" cache_read_price: float | None = None """AI Credits cost per billing batch of cached (read) tokens""" @@ -3376,7 +3508,7 @@ class ModelBillingTokenPricesLongContext: """AI Credits cost per billing batch of cache-write (cache creation) tokens.""" context_max: int | None = None - """Deprecated: use maxPromptTokens. Prompt token budget for the long context tier. The total + """Use maxPromptTokens instead. Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. """ input_price: float | None = None @@ -4957,6 +5089,27 @@ def to_dict(self) -> dict: result["sessionId"] = from_str(self.session_id) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class ProviderAddResult: + """The selectable model entries synthesized for the models added by this call.""" + + models: list[Any] + """Synthesized selectable model entries for the newly added BYOK models, each under its + provider-qualified selection id (`provider/id`). Empty when only providers were added. + """ + + @staticmethod + def from_dict(obj: Any) -> 'ProviderAddResult': + assert isinstance(obj, dict) + models = from_list(lambda x: x, obj.get("models")) + return ProviderAddResult(models) + + def to_dict(self) -> dict: + result: dict = {} + result["models"] = from_list(lambda x: x, self.models) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class ProviderSessionToken: @@ -5818,6 +5971,10 @@ class ServerSkill: user_invocable: bool """Whether the skill can be invoked by the user as a slash command""" + argument_hint: str | None = None + """Optional freeform hint describing the skill's expected arguments, from the + `argument-hint` frontmatter field + """ path: str | None = None """Absolute path to the skill file""" @@ -5832,9 +5989,10 @@ def from_dict(obj: Any) -> 'ServerSkill': name = from_str(obj.get("name")) source = SkillSource(obj.get("source")) user_invocable = from_bool(obj.get("userInvocable")) + argument_hint = from_union([from_str, from_none], obj.get("argumentHint")) path = from_union([from_str, from_none], obj.get("path")) project_path = from_union([from_str, from_none], obj.get("projectPath")) - return ServerSkill(description, enabled, name, source, user_invocable, path, project_path) + return ServerSkill(description, enabled, name, source, user_invocable, argument_hint, path, project_path) def to_dict(self) -> dict: result: dict = {} @@ -5843,6 +6001,8 @@ def to_dict(self) -> dict: result["name"] = from_str(self.name) result["source"] = to_enum(SkillSource, self.source) result["userInvocable"] = from_bool(self.user_invocable) + if self.argument_hint is not None: + result["argumentHint"] = from_union([from_str, from_none], self.argument_hint) if self.path is not None: result["path"] = from_union([from_str, from_none], self.path) if self.project_path is not None: @@ -7492,6 +7652,10 @@ class Skill: user_invocable: bool """Whether the skill can be invoked by the user as a slash command""" + argument_hint: str | None = None + """Optional freeform hint describing the skill's expected arguments, from the + `argument-hint` frontmatter field + """ path: str | None = None """Absolute path to the skill file""" @@ -7506,9 +7670,10 @@ def from_dict(obj: Any) -> 'Skill': name = from_str(obj.get("name")) source = SkillSource(obj.get("source")) user_invocable = from_bool(obj.get("userInvocable")) + argument_hint = from_union([from_str, from_none], obj.get("argumentHint")) path = from_union([from_str, from_none], obj.get("path")) plugin_name = from_union([from_str, from_none], obj.get("pluginName")) - return Skill(description, enabled, name, source, user_invocable, path, plugin_name) + return Skill(description, enabled, name, source, user_invocable, argument_hint, path, plugin_name) def to_dict(self) -> dict: result: dict = {} @@ -7517,6 +7682,8 @@ def to_dict(self) -> dict: result["name"] = from_str(self.name) result["source"] = to_enum(SkillSource, self.source) result["userInvocable"] = from_bool(self.user_invocable) + if self.argument_hint is not None: + result["argumentHint"] = from_union([from_str, from_none], self.argument_hint) if self.path is not None: result["path"] = from_union([from_str, from_none], self.path) if self.plugin_name is not None: @@ -8918,6 +9085,55 @@ def to_dict(self) -> dict: result["sizeBytes"] = from_int(self.size_bytes) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class SessionAuthStatus: + """Authentication status and account metadata for the session.""" + + is_authenticated: bool + """Whether the session has resolved authentication""" + + auth_type: AuthInfoType | None = None + """Authentication type""" + + copilot_plan: str | None = None + """Copilot plan tier (e.g., individual_pro, business)""" + + host: str | None = None + """Authentication host URL""" + + login: str | None = None + """Authenticated login/username, if available""" + + status_message: str | None = None + """Human-readable authentication status description""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionAuthStatus': + assert isinstance(obj, dict) + is_authenticated = from_bool(obj.get("isAuthenticated")) + auth_type = from_union([AuthInfoType, from_none], obj.get("authType")) + copilot_plan = from_union([from_str, from_none], obj.get("copilotPlan")) + host = from_union([from_str, from_none], obj.get("host")) + login = from_union([from_str, from_none], obj.get("login")) + status_message = from_union([from_str, from_none], obj.get("statusMessage")) + return SessionAuthStatus(is_authenticated, auth_type, copilot_plan, host, login, status_message) + + def to_dict(self) -> dict: + result: dict = {} + result["isAuthenticated"] = from_bool(self.is_authenticated) + if self.auth_type is not None: + result["authType"] = from_union([lambda x: to_enum(AuthInfoType, x), from_none], self.auth_type) + if self.copilot_plan is not None: + result["copilotPlan"] = from_union([from_str, from_none], self.copilot_plan) + if self.host is not None: + result["host"] = from_union([from_str, from_none], self.host) + if self.login is not None: + result["login"] = from_union([from_str, from_none], self.login) + if self.status_message is not None: + result["statusMessage"] = from_union([from_str, from_none], self.status_message) + return result + @dataclass class AccountGetQuotaResult: """Quota usage snapshots for the resolved user, keyed by quota type.""" @@ -9075,55 +9291,6 @@ def to_dict(self) -> dict: result["field"] = from_union([lambda x: to_enum(AgentRegistrySpawnValidationErrorField, x), from_none], self.field) return result -# Experimental: this type is part of an experimental API and may change or be removed. -@dataclass -class SessionAuthStatus: - """Authentication status and account metadata for the session.""" - - is_authenticated: bool - """Whether the session has resolved authentication""" - - auth_type: AuthInfoType | None = None - """Authentication type""" - - copilot_plan: str | None = None - """Copilot plan tier (e.g., individual_pro, business)""" - - host: str | None = None - """Authentication host URL""" - - login: str | None = None - """Authenticated login/username, if available""" - - status_message: str | None = None - """Human-readable authentication status description""" - - @staticmethod - def from_dict(obj: Any) -> 'SessionAuthStatus': - assert isinstance(obj, dict) - is_authenticated = from_bool(obj.get("isAuthenticated")) - auth_type = from_union([AuthInfoType, from_none], obj.get("authType")) - copilot_plan = from_union([from_str, from_none], obj.get("copilotPlan")) - host = from_union([from_str, from_none], obj.get("host")) - login = from_union([from_str, from_none], obj.get("login")) - status_message = from_union([from_str, from_none], obj.get("statusMessage")) - return SessionAuthStatus(is_authenticated, auth_type, copilot_plan, host, login, status_message) - - def to_dict(self) -> dict: - result: dict = {} - result["isAuthenticated"] = from_bool(self.is_authenticated) - if self.auth_type is not None: - result["authType"] = from_union([lambda x: to_enum(AuthInfoType, x), from_none], self.auth_type) - if self.copilot_plan is not None: - result["copilotPlan"] = from_union([from_str, from_none], self.copilot_plan) - if self.host is not None: - result["host"] = from_union([from_str, from_none], self.host) - if self.login is not None: - result["login"] = from_union([from_str, from_none], self.login) - if self.status_message is not None: - result["statusMessage"] = from_union([from_str, from_none], self.status_message) - return result - # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class DiscoveredCanvas: @@ -9408,7 +9575,6 @@ def to_dict(self) -> dict: result["canvases"] = from_union([from_bool, from_none], self.canvases) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CopilotUserResponseQuotaSnapshots: """Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. @@ -11353,7 +11519,7 @@ class ModelBillingTokenPrices: """Number of tokens per standard billing batch""" cache_price: float | None = None - """Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens""" + """Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens""" cache_read_price: float | None = None """AI Credits cost per billing batch of cached (read) tokens""" @@ -11362,8 +11528,8 @@ class ModelBillingTokenPrices: """AI Credits cost per billing batch of cache-write (cache creation) tokens.""" context_max: int | None = None - """Deprecated: use maxPromptTokens. Prompt token budget for the default tier. The total - context window is this value plus the model's max_output_tokens. + """Use maxPromptTokens instead. Prompt token budget for the default tier. The total context + window is this value plus the model's max_output_tokens. """ input_price: float | None = None """AI Credits cost per billing batch of input tokens""" @@ -15468,7 +15634,6 @@ def to_dict(self) -> dict: result["capabilities"] = from_union([lambda x: to_class(CanvasHostContextCapabilities, x), from_none], self.capabilities) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CopilotUserResponse: """Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the @@ -17803,7 +17968,6 @@ def to_dict(self) -> dict: result["session"] = from_union([lambda x: to_class(CanvasSessionContext, x), from_none], self.session) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class APIKeyAuthInfo: """Schema for the `ApiKeyAuthInfo` type.""" @@ -17840,7 +18004,6 @@ def to_dict(self) -> dict: result["copilotUser"] = from_union([lambda x: to_class(CopilotUserResponse, x), from_none], self.copilot_user) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class CopilotAPITokenAuthInfo: """Schema for the `CopilotApiTokenAuthInfo` type.""" @@ -17874,7 +18037,6 @@ def to_dict(self) -> dict: result["copilotUser"] = from_union([lambda x: to_class(CopilotUserResponse, x), from_none], self.copilot_user) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class EnvAuthInfo: """Schema for the `EnvAuthInfo` type.""" @@ -17924,7 +18086,6 @@ def to_dict(self) -> dict: result["login"] = from_union([from_str, from_none], self.login) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class GhCLIAuthInfo: """Schema for the `GhCliAuthInfo` type.""" @@ -17966,7 +18127,6 @@ def to_dict(self) -> dict: result["copilotUser"] = from_union([lambda x: to_class(CopilotUserResponse, x), from_none], self.copilot_user) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class HMACAuthInfo: """Schema for the `HMACAuthInfo` type.""" @@ -18003,7 +18163,6 @@ def to_dict(self) -> dict: result["copilotUser"] = from_union([lambda x: to_class(CopilotUserResponse, x), from_none], self.copilot_user) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class TokenAuthInfo: """Schema for the `TokenAuthInfo` type.""" @@ -18040,7 +18199,6 @@ def to_dict(self) -> dict: result["copilotUser"] = from_union([lambda x: to_class(CopilotUserResponse, x), from_none], self.copilot_user) return result -# Experimental: this type is part of an experimental API and may change or be removed. @dataclass class UserAuthInfo: """Schema for the `UserAuthInfo` type.""" @@ -18775,6 +18933,37 @@ def to_dict(self) -> dict: result["plugins"] = from_list(lambda x: to_class(InstalledPlugin, x), self.plugins) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class ProviderAddRequest: + """BYOK providers and/or models to add to the session's registry at runtime. Both fields are + optional; provide providers, models, or both. + """ + models: list[ProviderModelConfig] | None = None + """BYOK model definitions to register. Each must reference a provider that is already + registered or included in this same call. Selection ids (`provider/id`) must be unique + across the registry. + """ + providers: list[NamedProviderConfig] | None = None + """Named BYOK provider connections to register, additive to any providers already in the + registry. Each name must be unique across the registry and must not contain '/'. + """ + + @staticmethod + def from_dict(obj: Any) -> 'ProviderAddRequest': + assert isinstance(obj, dict) + models = from_union([lambda x: from_list(ProviderModelConfig.from_dict, x), from_none], obj.get("models")) + providers = from_union([lambda x: from_list(NamedProviderConfig.from_dict, x), from_none], obj.get("providers")) + return ProviderAddRequest(models, providers) + + def to_dict(self) -> dict: + result: dict = {} + if self.models is not None: + result["models"] = from_union([lambda x: from_list(lambda x: to_class(ProviderModelConfig, x), x), from_none], self.models) + if self.providers is not None: + result["providers"] = from_union([lambda x: from_list(lambda x: to_class(NamedProviderConfig, x), x), from_none], self.providers) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class SessionOpenOptions: @@ -20560,8 +20749,15 @@ def to_dict(self) -> dict: class RPC: abort_request: AbortRequest abort_result: AbortResult + account_all_users: AccountAllUsers + account_get_all_users_result: list[AccountAllUsers] + account_get_current_auth_result: AccountGetCurrentAuthResult account_get_quota_request: AccountGetQuotaRequest account_get_quota_result: AccountGetQuotaResult + account_login_request: AccountLoginRequest + account_login_result: AccountLoginResult + account_logout_request: AccountLogoutRequest + account_logout_result: AccountLogoutResult account_quota_snapshot: AccountQuotaSnapshot agent_discovery_path: AgentDiscoveryPath agent_discovery_path_list: AgentDiscoveryPathList @@ -20983,6 +21179,8 @@ class RPC: plugin_update_all_result: PluginUpdateAllResult plugin_update_result: PluginUpdateResult poll_spawned_sessions_result: PollSpawnedSessionsResult + provider_add_request: ProviderAddRequest + provider_add_result: ProviderAddResult provider_config: ProviderConfig provider_config_azure: ProviderConfigAzure provider_config_type: ProviderType @@ -21317,8 +21515,15 @@ def from_dict(obj: Any) -> 'RPC': assert isinstance(obj, dict) abort_request = AbortRequest.from_dict(obj.get("AbortRequest")) abort_result = AbortResult.from_dict(obj.get("AbortResult")) + account_all_users = AccountAllUsers.from_dict(obj.get("AccountAllUsers")) + account_get_all_users_result = from_list(AccountAllUsers.from_dict, obj.get("AccountGetAllUsersResult")) + account_get_current_auth_result = AccountGetCurrentAuthResult.from_dict(obj.get("AccountGetCurrentAuthResult")) account_get_quota_request = AccountGetQuotaRequest.from_dict(obj.get("AccountGetQuotaRequest")) account_get_quota_result = AccountGetQuotaResult.from_dict(obj.get("AccountGetQuotaResult")) + account_login_request = AccountLoginRequest.from_dict(obj.get("AccountLoginRequest")) + account_login_result = AccountLoginResult.from_dict(obj.get("AccountLoginResult")) + account_logout_request = AccountLogoutRequest.from_dict(obj.get("AccountLogoutRequest")) + account_logout_result = AccountLogoutResult.from_dict(obj.get("AccountLogoutResult")) account_quota_snapshot = AccountQuotaSnapshot.from_dict(obj.get("AccountQuotaSnapshot")) agent_discovery_path = AgentDiscoveryPath.from_dict(obj.get("AgentDiscoveryPath")) agent_discovery_path_list = AgentDiscoveryPathList.from_dict(obj.get("AgentDiscoveryPathList")) @@ -21740,6 +21945,8 @@ def from_dict(obj: Any) -> 'RPC': plugin_update_all_result = PluginUpdateAllResult.from_dict(obj.get("PluginUpdateAllResult")) plugin_update_result = PluginUpdateResult.from_dict(obj.get("PluginUpdateResult")) poll_spawned_sessions_result = PollSpawnedSessionsResult.from_dict(obj.get("PollSpawnedSessionsResult")) + provider_add_request = ProviderAddRequest.from_dict(obj.get("ProviderAddRequest")) + provider_add_result = ProviderAddResult.from_dict(obj.get("ProviderAddResult")) provider_config = ProviderConfig.from_dict(obj.get("ProviderConfig")) provider_config_azure = ProviderConfigAzure.from_dict(obj.get("ProviderConfigAzure")) provider_config_type = ProviderType(obj.get("ProviderConfigType")) @@ -22068,14 +22275,21 @@ 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_get_quota_request, account_get_quota_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_instance_availability, canvas_json_schema, canvas_list, canvas_list_open_result, canvas_open_request, canvas_provider_close_request, canvas_provider_invoke_action_request, canvas_provider_open_request, canvas_provider_open_result, canvas_session_context, command_list, commands_handle_pending_command_request, commands_handle_pending_command_result, commands_invoke_request, commands_list_request, commands_respond_to_queued_command_request, commands_respond_to_queued_command_result, 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_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_config, provider_config_azure, provider_config_type, provider_config_wire_api, provider_endpoint, provider_endpoint_type, provider_endpoint_wire_api, provider_get_endpoint_request, provider_model_config, provider_session_token, 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, 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_instance_availability, canvas_json_schema, canvas_list, canvas_list_open_result, canvas_open_request, canvas_provider_close_request, canvas_provider_invoke_action_request, canvas_provider_open_request, canvas_provider_open_result, canvas_session_context, command_list, commands_handle_pending_command_request, commands_handle_pending_command_result, commands_invoke_request, commands_list_request, commands_respond_to_queued_command_request, commands_respond_to_queued_command_result, 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_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_type, provider_config_wire_api, provider_endpoint, provider_endpoint_type, provider_endpoint_wire_api, provider_get_endpoint_request, provider_model_config, provider_session_token, 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, 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 = {} result["AbortRequest"] = to_class(AbortRequest, self.abort_request) result["AbortResult"] = to_class(AbortResult, self.abort_result) + result["AccountAllUsers"] = to_class(AccountAllUsers, self.account_all_users) + result["AccountGetAllUsersResult"] = from_list(lambda x: to_class(AccountAllUsers, x), self.account_get_all_users_result) + result["AccountGetCurrentAuthResult"] = to_class(AccountGetCurrentAuthResult, self.account_get_current_auth_result) result["AccountGetQuotaRequest"] = to_class(AccountGetQuotaRequest, self.account_get_quota_request) result["AccountGetQuotaResult"] = to_class(AccountGetQuotaResult, self.account_get_quota_result) + result["AccountLoginRequest"] = to_class(AccountLoginRequest, self.account_login_request) + result["AccountLoginResult"] = to_class(AccountLoginResult, self.account_login_result) + result["AccountLogoutRequest"] = to_class(AccountLogoutRequest, self.account_logout_request) + result["AccountLogoutResult"] = to_class(AccountLogoutResult, self.account_logout_result) result["AccountQuotaSnapshot"] = to_class(AccountQuotaSnapshot, self.account_quota_snapshot) result["AgentDiscoveryPath"] = to_class(AgentDiscoveryPath, self.agent_discovery_path) result["AgentDiscoveryPathList"] = to_class(AgentDiscoveryPathList, self.agent_discovery_path_list) @@ -22497,6 +22711,8 @@ def to_dict(self) -> dict: result["PluginUpdateAllResult"] = to_class(PluginUpdateAllResult, self.plugin_update_all_result) result["PluginUpdateResult"] = to_class(PluginUpdateResult, self.plugin_update_result) result["PollSpawnedSessionsResult"] = to_class(PollSpawnedSessionsResult, self.poll_spawned_sessions_result) + result["ProviderAddRequest"] = to_class(ProviderAddRequest, self.provider_add_request) + result["ProviderAddResult"] = to_class(ProviderAddResult, self.provider_add_result) result["ProviderConfig"] = to_class(ProviderConfig, self.provider_config) result["ProviderConfigAzure"] = to_class(ProviderConfigAzure, self.provider_config_azure) result["ProviderConfigType"] = to_enum(ProviderType, self.provider_config_type) @@ -23046,6 +23262,7 @@ def _load_TaskInfo(obj: Any) -> "TaskInfo": case _: raise ValueError(f"Unknown TaskInfo type: {kind!r}") +AccountGetAllUsersResult = list CanvasActionInvokeResult = Any CanvasJsonSchema = Any ExternalToolResult = ExternalToolTextResultForLlm @@ -23146,6 +23363,24 @@ async def get_quota(self, params: AccountGetQuotaRequest, *, timeout: float | No params_dict = {k: v for k, v in params.to_dict().items() if v is not None} return AccountGetQuotaResult.from_dict(await self._client.request("account.getQuota", params_dict, **_timeout_kwargs(timeout))) + async def get_current_auth(self, *, timeout: float | None = None) -> AccountGetCurrentAuthResult: + "Gets the currently active authentication credentials from the global auth manager.\n\nReturns:\n Current authentication state" + return AccountGetCurrentAuthResult.from_dict(await self._client.request("account.getCurrentAuth", {}, **_timeout_kwargs(timeout))) + + async def get_all_users(self, *, timeout: float | None = None) -> list: + "Gets all authenticated users available for account switching.\n\nReturns:\n List of all authenticated users" + return list(await self._client.request("account.getAllUsers", {}, **_timeout_kwargs(timeout))) + + async def login(self, params: AccountLoginRequest, *, timeout: float | None = None) -> AccountLoginResult: + "Stores authentication credentials after successful login (e.g., device code flow).\n\nArgs:\n params: Credentials to store after successful authentication\n\nReturns:\n Result of a successful login; throws on failure" + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + return AccountLoginResult.from_dict(await self._client.request("account.login", params_dict, **_timeout_kwargs(timeout))) + + async def logout(self, params: AccountLogoutRequest, *, timeout: float | None = None) -> AccountLogoutResult: + "Removes user authentication from keychain and persisted state.\n\nArgs:\n params: User to log out\n\nReturns:\n Logout result indicating if more users remain" + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + return AccountLogoutResult.from_dict(await self._client.request("account.logout", params_dict, **_timeout_kwargs(timeout))) + class ServerSecretsApi: def __init__(self, client: "JsonRpcClient"): @@ -24106,6 +24341,12 @@ async def get_endpoint(self, params: ProviderGetEndpointRequest | None = None, * params_dict["sessionId"] = self._session_id return ProviderEndpoint.from_dict(await self._client.request("session.provider.getEndpoint", params_dict, **_timeout_kwargs(timeout))) + async def add(self, params: ProviderAddRequest, *, timeout: float | None = None) -> ProviderAddResult: + "Adds BYOK providers and/or models to the session's registry at runtime, extending the additive registry built from the session's `providers`/`models` options. Both fields are optional, so a call may add providers only, models only, or both. Within a single call providers are registered before models, so a model may reference a provider added in the same call; across calls a model may reference any provider already registered (from session creation or a prior add). A model whose referenced provider is not registered by the end of the call is rejected. Newly added models become selectable via `model.list` / `model.switchTo` and are inherited by sub-agents spawned afterwards.\n\nArgs:\n params: BYOK providers and/or models to add to the session's registry at runtime. Both fields are optional; provide providers, models, or both.\n\nReturns:\n The selectable model entries synthesized for the models added by this call." + 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 ProviderAddResult.from_dict(await self._client.request("session.provider.add", params_dict, **_timeout_kwargs(timeout))) + # Experimental: this API group is experimental and may change or be removed. class OptionsApi: @@ -24976,8 +25217,15 @@ async def handle_canvas_action_invoke(params: dict) -> dict | None: "APIKeyAuthInfoType", "AbortRequest", "AbortResult", + "AccountAllUsers", + "AccountGetAllUsersResult", + "AccountGetCurrentAuthResult", "AccountGetQuotaRequest", "AccountGetQuotaResult", + "AccountLoginRequest", + "AccountLoginResult", + "AccountLogoutRequest", + "AccountLogoutResult", "AccountQuotaSnapshot", "AdditionalContentExclusionPolicyScope", "AgentApi", @@ -25475,6 +25723,8 @@ async def handle_canvas_action_invoke(params: dict) -> dict | None: "PluginsUninstallRequest", "PluginsUpdateRequest", "PollSpawnedSessionsResult", + "ProviderAddRequest", + "ProviderAddResult", "ProviderApi", "ProviderConfig", "ProviderConfigAzure", diff --git a/python/copilot/generated/session_events.py b/python/copilot/generated/session_events.py index 14da3d634..cb4851ec3 100644 --- a/python/copilot/generated/session_events.py +++ b/python/copilot/generated/session_events.py @@ -2798,6 +2798,7 @@ class ModelCallFailureData: initiator: str | None = None model: str | None = None provider_call_id: str | None = None + request_fingerprint: ModelCallFailureRequestFingerprint | None = None service_request_id: str | None = None status_code: int | None = None @@ -2814,6 +2815,7 @@ def from_dict(obj: Any) -> "ModelCallFailureData": initiator = from_union([from_none, from_str], obj.get("initiator")) model = from_union([from_none, from_str], obj.get("model")) provider_call_id = from_union([from_none, from_str], obj.get("providerCallId")) + request_fingerprint = from_union([from_none, ModelCallFailureRequestFingerprint.from_dict], obj.get("requestFingerprint")) service_request_id = from_union([from_none, from_str], obj.get("serviceRequestId")) status_code = from_union([from_none, from_int], obj.get("statusCode")) return ModelCallFailureData( @@ -2827,6 +2829,7 @@ def from_dict(obj: Any) -> "ModelCallFailureData": initiator=initiator, model=model, provider_call_id=provider_call_id, + request_fingerprint=request_fingerprint, service_request_id=service_request_id, status_code=status_code, ) @@ -2852,6 +2855,8 @@ def to_dict(self) -> dict: result["model"] = from_union([from_none, from_str], self.model) if self.provider_call_id is not None: result["providerCallId"] = from_union([from_none, from_str], self.provider_call_id) + if self.request_fingerprint is not None: + result["requestFingerprint"] = from_union([from_none, lambda x: to_class(ModelCallFailureRequestFingerprint, x)], self.request_fingerprint) if self.service_request_id is not None: result["serviceRequestId"] = from_union([from_none, from_str], self.service_request_id) if self.status_code is not None: @@ -2859,6 +2864,50 @@ def to_dict(self) -> dict: return result +@dataclass +class ModelCallFailureRequestFingerprint: + "Content-free structural summary of the failing request for diagnosing malformed 4xx calls" + image_part_count: int + image_parts_missing_media_type: int + message_count: int + nameless_tool_call_count: int + tool_call_count: int + tool_result_message_count: int + last_message_role: str | None = None + + @staticmethod + def from_dict(obj: Any) -> "ModelCallFailureRequestFingerprint": + assert isinstance(obj, dict) + image_part_count = from_int(obj.get("imagePartCount")) + image_parts_missing_media_type = from_int(obj.get("imagePartsMissingMediaType")) + message_count = from_int(obj.get("messageCount")) + nameless_tool_call_count = from_int(obj.get("namelessToolCallCount")) + tool_call_count = from_int(obj.get("toolCallCount")) + tool_result_message_count = from_int(obj.get("toolResultMessageCount")) + last_message_role = from_union([from_none, from_str], obj.get("lastMessageRole")) + return ModelCallFailureRequestFingerprint( + image_part_count=image_part_count, + image_parts_missing_media_type=image_parts_missing_media_type, + message_count=message_count, + nameless_tool_call_count=nameless_tool_call_count, + tool_call_count=tool_call_count, + tool_result_message_count=tool_result_message_count, + last_message_role=last_message_role, + ) + + def to_dict(self) -> dict: + result: dict = {} + result["imagePartCount"] = to_int(self.image_part_count) + result["imagePartsMissingMediaType"] = to_int(self.image_parts_missing_media_type) + result["messageCount"] = to_int(self.message_count) + result["namelessToolCallCount"] = to_int(self.nameless_tool_call_count) + result["toolCallCount"] = to_int(self.tool_call_count) + result["toolResultMessageCount"] = to_int(self.tool_result_message_count) + if self.last_message_role is not None: + result["lastMessageRole"] = from_union([from_none, from_str], self.last_message_role) + return result + + @dataclass class PendingMessagesModifiedData: "Empty payload; the event signals that the pending message queue has changed" @@ -5681,6 +5730,7 @@ class SkillsLoadedSkill: name: str source: SkillSource user_invocable: bool + argument_hint: str | None = None path: str | None = None @staticmethod @@ -5691,6 +5741,7 @@ def from_dict(obj: Any) -> "SkillsLoadedSkill": name = from_str(obj.get("name")) source = parse_enum(SkillSource, obj.get("source")) user_invocable = from_bool(obj.get("userInvocable")) + argument_hint = from_union([from_none, from_str], obj.get("argumentHint")) path = from_union([from_none, from_str], obj.get("path")) return SkillsLoadedSkill( description=description, @@ -5698,6 +5749,7 @@ def from_dict(obj: Any) -> "SkillsLoadedSkill": name=name, source=source, user_invocable=user_invocable, + argument_hint=argument_hint, path=path, ) @@ -5708,6 +5760,8 @@ def to_dict(self) -> dict: result["name"] = from_str(self.name) result["source"] = to_enum(SkillSource, self.source) result["userInvocable"] = from_bool(self.user_invocable) + if self.argument_hint is not None: + result["argumentHint"] = from_union([from_none, from_str], self.argument_hint) if self.path is not None: result["path"] = from_union([from_none, from_str], self.path) return result @@ -8191,6 +8245,7 @@ def session_event_to_dict(x: SessionEvent) -> Any: "McpServersLoadedServer", "ModelCallFailureBadRequestKind", "ModelCallFailureData", + "ModelCallFailureRequestFingerprint", "ModelCallFailureSource", "OmittedBinaryOmittedReason", "OmittedBinaryResult", diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index e9bd5ed86..522222b32 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -27,6 +27,14 @@ pub mod rpc_methods { pub const TOOLS_LIST: &str = "tools.list"; /// `account.getQuota` pub const ACCOUNT_GETQUOTA: &str = "account.getQuota"; + /// `account.getCurrentAuth` + pub const ACCOUNT_GETCURRENTAUTH: &str = "account.getCurrentAuth"; + /// `account.getAllUsers` + pub const ACCOUNT_GETALLUSERS: &str = "account.getAllUsers"; + /// `account.login` + pub const ACCOUNT_LOGIN: &str = "account.login"; + /// `account.logout` + pub const ACCOUNT_LOGOUT: &str = "account.logout"; /// `secrets.addFilterValues` pub const SECRETS_ADDFILTERVALUES: &str = "secrets.addFilterValues"; /// `mcp.config.list` @@ -331,6 +339,8 @@ pub mod rpc_methods { pub const SESSION_PLUGINS_RELOAD: &str = "session.plugins.reload"; /// `session.provider.getEndpoint` pub const SESSION_PROVIDER_GETENDPOINT: &str = "session.provider.getEndpoint"; + /// `session.provider.add` + pub const SESSION_PROVIDER_ADD: &str = "session.provider.add"; /// `session.options.update` pub const SESSION_OPTIONS_UPDATE: &str = "session.options.update"; /// `session.lsp.initialize` @@ -571,6 +581,29 @@ pub struct AbortResult { pub success: bool, } +/// Schema for the `AccountAllUsers` type. +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AccountAllUsers { + /// Authentication information for this user + pub auth_info: serde_json::Value, + /// Associated token, if available + #[serde(skip_serializing_if = "Option::is_none")] + pub token: Option, +} + +/// Current authentication state +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AccountGetCurrentAuthResult { + /// Authentication errors from the last auth attempt, if any + #[serde(skip_serializing_if = "Option::is_none")] + pub auth_errors: Option>, + /// Current authentication information, if authenticated + #[serde(skip_serializing_if = "Option::is_none")] + pub auth_info: Option, +} + /// Optional GitHub token used to look up quota for a specific user instead of the global auth context. #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -611,6 +644,42 @@ pub struct AccountGetQuotaResult { pub quota_snapshots: HashMap, } +/// Credentials to store after successful authentication +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AccountLoginRequest { + /// GitHub host URL + pub host: String, + /// User login/username + pub login: String, + /// GitHub authentication token + pub token: String, +} + +/// Result of a successful login; throws on failure +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AccountLoginResult { + /// Whether the credential was persisted to a secure store (system keychain, or the config file when plaintext storage is enabled). False when no secure store was available and the token was not saved, so the consumer can decide how to proceed. + pub stored_in_vault: bool, +} + +/// User to log out +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AccountLogoutRequest { + /// Authentication information for the user to log out + pub auth_info: serde_json::Value, +} + +/// Logout result indicating if more users remain +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AccountLogoutResult { + /// Whether other authenticated users remain after logout + pub has_more_users: bool, +} + /// Schema for the `AgentDiscoveryPath` type. /// ///

@@ -1045,13 +1114,6 @@ pub struct AllowAllPermissionState { } /// Schema for the `CopilotUserResponseEndpoints` type. -/// -///
-/// -/// **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 CopilotUserResponseEndpoints { @@ -1066,13 +1128,6 @@ pub struct CopilotUserResponseEndpoints { } /// Schema for the `CopilotUserResponseQuotaSnapshotsChat` type. -/// -///
-/// -/// **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 CopilotUserResponseQuotaSnapshotsChat { @@ -1106,13 +1161,6 @@ pub struct CopilotUserResponseQuotaSnapshotsChat { } /// Schema for the `CopilotUserResponseQuotaSnapshotsCompletions` type. -/// -///
-/// -/// **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 CopilotUserResponseQuotaSnapshotsCompletions { @@ -1146,13 +1194,6 @@ pub struct CopilotUserResponseQuotaSnapshotsCompletions { } /// Schema for the `CopilotUserResponseQuotaSnapshotsPremiumInteractions` type. -/// -///
-/// -/// **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 CopilotUserResponseQuotaSnapshotsPremiumInteractions { @@ -1186,13 +1227,6 @@ pub struct CopilotUserResponseQuotaSnapshotsPremiumInteractions { } /// Schema for the `CopilotUserResponseQuotaSnapshots` type. -/// -///
-/// -/// **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 CopilotUserResponseQuotaSnapshots { @@ -1211,13 +1245,6 @@ pub struct CopilotUserResponseQuotaSnapshots { } /// Snapshot of the authenticated user's Copilot subscription info, if known. Mirrors the GitHub API `/copilot_internal/v2/token` user response shape — the runtime trusts this verbatim and does not re-fetch when set. -/// -///
-/// -/// **Experimental.** This type is part of an experimental wire-protocol surface -/// and may change or be removed in future SDK or CLI releases. -/// -///
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CopilotUserResponse { @@ -1312,13 +1339,6 @@ pub struct CopilotUserResponse { } /// Schema for the `ApiKeyAuthInfo` type. -/// -///
-/// -/// **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 ApiKeyAuthInfo { @@ -2224,13 +2244,6 @@ pub(crate) struct ConnectResult { } /// Schema for the `CopilotApiTokenAuthInfo` type. -/// -///
-/// -/// **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 CopilotApiTokenAuthInfo { @@ -2349,13 +2362,6 @@ pub struct EnqueueCommandResult { } /// Schema for the `EnvAuthInfo` type. -/// -///
-/// -/// **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 EnvAuthInfo { @@ -2863,13 +2869,6 @@ pub struct FolderTrustCheckResult { } /// Schema for the `GhCliAuthInfo` type. -/// -///
-/// -/// **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 GhCliAuthInfo { @@ -3067,13 +3066,6 @@ pub struct HistoryTruncateResult { } /// Schema for the `HMACAuthInfo` type. -/// -///
-/// -/// **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 HMACAuthInfo { @@ -5129,7 +5121,9 @@ pub struct MetadataSnapshotRemoteMetadata { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ModelBillingTokenPricesLongContext { - /// Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens + /// Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens + #[doc(hidden)] + #[deprecated] #[serde(skip_serializing_if = "Option::is_none")] pub cache_price: Option, /// AI Credits cost per billing batch of cached (read) tokens @@ -5138,7 +5132,9 @@ pub struct ModelBillingTokenPricesLongContext { /// AI Credits cost per billing batch of cache-write (cache creation) tokens. #[serde(skip_serializing_if = "Option::is_none")] pub cache_write_price: Option, - /// Deprecated: use maxPromptTokens. Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. + /// Use maxPromptTokens instead. Prompt token budget for the long context tier. The total context window is this value plus the model's max_output_tokens. + #[doc(hidden)] + #[deprecated] #[serde(skip_serializing_if = "Option::is_none")] pub context_max: Option, /// AI Credits cost per billing batch of input tokens @@ -5159,7 +5155,9 @@ pub struct ModelBillingTokenPrices { /// Number of tokens per standard billing batch #[serde(skip_serializing_if = "Option::is_none")] pub batch_size: Option, - /// Deprecated: use cacheReadPrice. AI Credits cost per billing batch of cached tokens + /// Use cacheReadPrice instead. AI Credits cost per billing batch of cached tokens + #[doc(hidden)] + #[deprecated] #[serde(skip_serializing_if = "Option::is_none")] pub cache_price: Option, /// AI Credits cost per billing batch of cached (read) tokens @@ -5168,7 +5166,9 @@ pub struct ModelBillingTokenPrices { /// AI Credits cost per billing batch of cache-write (cache creation) tokens. #[serde(skip_serializing_if = "Option::is_none")] pub cache_write_price: Option, - /// Deprecated: use maxPromptTokens. Prompt token budget for the default tier. The total context window is this value plus the model's max_output_tokens. + /// Use maxPromptTokens instead. Prompt token budget for the default tier. The total context window is this value plus the model's max_output_tokens. + #[doc(hidden)] + #[deprecated] #[serde(skip_serializing_if = "Option::is_none")] pub context_max: Option, /// AI Credits cost per billing batch of input tokens @@ -7588,6 +7588,78 @@ pub struct PollSpawnedSessionsResult { pub events: Vec, } +/// A BYOK model definition referencing a named provider. +/// +///
+/// +/// **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 ProviderModelConfig { + /// Optional capability overrides (vision, tool_calls, reasoning, etc.). + #[serde(skip_serializing_if = "Option::is_none")] + pub capabilities: Option, + /// Provider-local model id, unique within its provider. The session-wide selection id (shown in the model list and passed to switchTo) is the provider-qualified `provider/id`. + pub id: String, + /// Maximum context window tokens for the model. + #[serde(skip_serializing_if = "Option::is_none")] + pub max_context_window_tokens: Option, + /// Maximum output tokens for the model. + #[serde(skip_serializing_if = "Option::is_none")] + pub max_output_tokens: Option, + /// Maximum prompt/input tokens for the model. + #[serde(skip_serializing_if = "Option::is_none")] + pub max_prompt_tokens: Option, + /// Well-known base model id used for behavior/capability/config lookup. Defaults to `id`. + #[serde(skip_serializing_if = "Option::is_none")] + pub model_id: Option, + /// Display name for model pickers. Defaults to the provider-qualified selection id (`provider/id`). + #[serde(skip_serializing_if = "Option::is_none")] + pub name: Option, + /// Name of the NamedProviderConfig that serves this model. + pub provider: String, + /// The model name sent to the provider API for inference. Defaults to `id`. + #[serde(skip_serializing_if = "Option::is_none")] + pub wire_model: Option, +} + +/// BYOK providers and/or models to add to the session's registry at runtime. Both fields are optional; provide providers, models, or both. +/// +///
+/// +/// **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 ProviderAddRequest { + /// BYOK model definitions to register. Each must reference a provider that is already registered or included in this same call. Selection ids (`provider/id`) must be unique across the registry. + #[serde(skip_serializing_if = "Option::is_none")] + pub models: Option>, + /// Named BYOK provider connections to register, additive to any providers already in the registry. Each name must be unique across the registry and must not contain '/'. + #[serde(skip_serializing_if = "Option::is_none")] + pub providers: Option>, +} + +/// The selectable model entries synthesized for the models added by this call. +/// +///
+/// +/// **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 ProviderAddResult { + /// Synthesized selectable model entries for the newly added BYOK models, each under its provider-qualified selection id (`provider/id`). Empty when only providers were added. + pub models: Vec, +} + /// Custom model-provider configuration (BYOK). /// ///
@@ -7703,44 +7775,6 @@ pub struct ProviderGetEndpointRequest { pub model_id: Option, } -/// A BYOK model definition referencing a named provider. -/// -///
-/// -/// **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 ProviderModelConfig { - /// Optional capability overrides (vision, tool_calls, reasoning, etc.). - #[serde(skip_serializing_if = "Option::is_none")] - pub capabilities: Option, - /// Provider-local model id, unique within its provider. The session-wide selection id (shown in the model list and passed to switchTo) is the provider-qualified `provider/id`. - pub id: String, - /// Maximum context window tokens for the model. - #[serde(skip_serializing_if = "Option::is_none")] - pub max_context_window_tokens: Option, - /// Maximum output tokens for the model. - #[serde(skip_serializing_if = "Option::is_none")] - pub max_output_tokens: Option, - /// Maximum prompt/input tokens for the model. - #[serde(skip_serializing_if = "Option::is_none")] - pub max_prompt_tokens: Option, - /// Well-known base model id used for behavior/capability/config lookup. Defaults to `id`. - #[serde(skip_serializing_if = "Option::is_none")] - pub model_id: Option, - /// Display name for model pickers. Defaults to the provider-qualified selection id (`provider/id`). - #[serde(skip_serializing_if = "Option::is_none")] - pub name: Option, - /// Name of the NamedProviderConfig that serves this model. - pub provider: String, - /// The model name sent to the provider API for inference. Defaults to `id`. - #[serde(skip_serializing_if = "Option::is_none")] - pub wire_model: Option, -} - /// Blob attachment with inline base64-encoded data /// ///
@@ -8783,6 +8817,9 @@ pub struct ServerInstructionSourceList { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ServerSkill { + /// Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field + #[serde(skip_serializing_if = "Option::is_none")] + pub argument_hint: Option, /// Description of what the skill does pub description: String, /// Whether the skill is currently enabled (based on global config) @@ -11035,6 +11072,9 @@ pub struct ShutdownRequest { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct Skill { + /// Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field + #[serde(skip_serializing_if = "Option::is_none")] + pub argument_hint: Option, /// Description of what the skill does pub description: String, /// Whether the skill is currently enabled @@ -11836,13 +11876,6 @@ pub struct TelemetrySetFeatureOverridesRequest { } /// Schema for the `TokenAuthInfo` type. -/// -///
-/// -/// **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 TokenAuthInfo { @@ -12692,13 +12725,6 @@ pub struct UsageGetMetricsResult { } /// Schema for the `UserAuthInfo` type. -/// -///
-/// -/// **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 UserAuthInfo { @@ -15187,6 +15213,21 @@ pub struct SessionProviderGetEndpointResult { pub wire_api: Option, } +/// The selectable model entries synthesized for the models added by this call. +/// +///
+/// +/// **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 SessionProviderAddResult { + /// Synthesized selectable model entries for the newly added BYOK models, each under its provider-qualified selection id (`provider/id`). Empty when only providers were added. + pub models: Vec, +} + /// Indicates whether the session options patch was applied successfully. /// ///
@@ -16751,6 +16792,9 @@ pub type McpExecuteSamplingResult = HashMap; ///
pub type UIElicitationResponseContent = HashMap; +/// List of all authenticated users +pub type AccountGetAllUsersResult = Vec; + /// Standard MCP CallToolResult /// ///
diff --git a/rust/src/generated/rpc.rs b/rust/src/generated/rpc.rs index fc969c188..608dfa939 100644 --- a/rust/src/generated/rpc.rs +++ b/rust/src/generated/rpc.rs @@ -212,6 +212,78 @@ impl<'a> ClientRpcAccount<'a> { .await?; Ok(serde_json::from_value(_value)?) } + + /// Gets the currently active authentication credentials from the global auth manager. + /// + /// Wire method: `account.getCurrentAuth`. + /// + /// # Returns + /// + /// Current authentication state + pub async fn get_current_auth(&self) -> Result { + let wire_params = serde_json::json!({}); + let _value = self + .client + .call(rpc_methods::ACCOUNT_GETCURRENTAUTH, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Gets all authenticated users available for account switching. + /// + /// Wire method: `account.getAllUsers`. + /// + /// # Returns + /// + /// List of all authenticated users + pub async fn get_all_users(&self) -> Result { + let wire_params = serde_json::json!({}); + let _value = self + .client + .call(rpc_methods::ACCOUNT_GETALLUSERS, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Stores authentication credentials after successful login (e.g., device code flow). + /// + /// Wire method: `account.login`. + /// + /// # Parameters + /// + /// * `params` - Credentials to store after successful authentication + /// + /// # Returns + /// + /// Result of a successful login; throws on failure + pub async fn login(&self, params: AccountLoginRequest) -> Result { + let wire_params = serde_json::to_value(params)?; + let _value = self + .client + .call(rpc_methods::ACCOUNT_LOGIN, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } + + /// Removes user authentication from keychain and persisted state. + /// + /// Wire method: `account.logout`. + /// + /// # Parameters + /// + /// * `params` - User to log out + /// + /// # Returns + /// + /// Logout result indicating if more users remain + pub async fn logout(&self, params: AccountLogoutRequest) -> Result { + let wire_params = serde_json::to_value(params)?; + let _value = self + .client + .call(rpc_methods::ACCOUNT_LOGOUT, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } } /// `agentRegistry.*` RPCs. @@ -6284,6 +6356,36 @@ impl<'a> SessionRpcProvider<'a> { .await?; Ok(serde_json::from_value(_value)?) } + + /// Adds BYOK providers and/or models to the session's registry at runtime, extending the additive registry built from the session's `providers`/`models` options. Both fields are optional, so a call may add providers only, models only, or both. Within a single call providers are registered before models, so a model may reference a provider added in the same call; across calls a model may reference any provider already registered (from session creation or a prior add). A model whose referenced provider is not registered by the end of the call is rejected. Newly added models become selectable via `model.list` / `model.switchTo` and are inherited by sub-agents spawned afterwards. + /// + /// Wire method: `session.provider.add`. + /// + /// # Parameters + /// + /// * `params` - BYOK providers and/or models to add to the session's registry at runtime. Both fields are optional; provide providers, models, or both. + /// + /// # Returns + /// + /// The selectable model entries synthesized for the models added by this call. + /// + ///
+ /// + /// **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 add(&self, params: ProviderAddRequest) -> 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_PROVIDER_ADD, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } } /// `session.queue.*` RPCs. diff --git a/rust/src/generated/session_events.rs b/rust/src/generated/session_events.rs index 0fe47f263..78269cb6c 100644 --- a/rust/src/generated/session_events.rs +++ b/rust/src/generated/session_events.rs @@ -1602,6 +1602,27 @@ pub struct AssistantUsageData { pub time_to_first_token_ms: Option, } +/// Content-free structural summary of the failing request for diagnosing malformed 4xx calls +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ModelCallFailureRequestFingerprint { + /// Total number of image content parts + pub image_part_count: i64, + /// Image parts whose media type cannot be determined (rejected by strict providers) + pub image_parts_missing_media_type: i64, + /// Role of the final message in the request + #[serde(skip_serializing_if = "Option::is_none")] + pub last_message_role: Option, + /// Total number of messages in the request + pub message_count: i64, + /// Tool calls whose name is missing or empty (rejected by strict providers) + pub nameless_tool_call_count: i64, + /// Total number of tool calls across assistant messages + pub tool_call_count: i64, + /// Number of "tool" result messages in the request + pub tool_result_message_count: i64, +} + /// Session event "model.call_failure". Failed LLM API call metadata for telemetry #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -1633,6 +1654,9 @@ pub struct ModelCallFailureData { /// GitHub request tracing ID (x-github-request-id header) for server-side log correlation #[serde(skip_serializing_if = "Option::is_none")] pub provider_call_id: Option, + /// Content-free structural summary of the failing request. Contains only counts and shape flags (no prompt content), so it is safe for unrestricted telemetry. Populated only for client-error (4xx) failures. + #[serde(skip_serializing_if = "Option::is_none")] + pub request_fingerprint: Option, /// Copilot service request ID (x-copilot-service-request-id header) for CAPI log correlation #[serde(skip_serializing_if = "Option::is_none")] pub service_request_id: Option, @@ -3369,6 +3393,9 @@ pub struct SessionBackgroundTasksChangedData {} #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SkillsLoadedSkill { + /// Optional freeform hint describing the skill's expected arguments, from the `argument-hint` frontmatter field + #[serde(skip_serializing_if = "Option::is_none")] + pub argument_hint: Option, /// Description of what the skill does pub description: String, /// Whether the skill is currently enabled diff --git a/rust/tests/session_test.rs b/rust/tests/session_test.rs index 6677b3c98..99d8c1391 100644 --- a/rust/tests/session_test.rs +++ b/rust/tests/session_test.rs @@ -1213,12 +1213,12 @@ async fn list_models_returns_typed_model_info() { "outputPrice": 8.0, "cachePrice": 0.5, "batchSize": 1000000, - "contextMax": 128000, + "maxPromptTokens": 128000, "longContext": { "inputPrice": 4.0, "outputPrice": 16.0, "cachePrice": 1.0, - "contextMax": 1000000 + "maxPromptTokens": 1000000 } } } @@ -1244,11 +1244,11 @@ async fn list_models_returns_typed_model_info() { .expect("token prices"); assert_eq!(token_prices.input_price, Some(2.0)); assert_eq!(token_prices.batch_size, Some(1000000)); - assert_eq!(token_prices.context_max, Some(128000)); + assert_eq!(token_prices.max_prompt_tokens, Some(128000)); let long_context: &github_copilot_sdk::types::ModelBillingTokenPricesLongContext = token_prices.long_context.as_ref().expect("long context"); assert_eq!(long_context.output_price, Some(16.0)); - assert_eq!(long_context.context_max, Some(1000000)); + assert_eq!(long_context.max_prompt_tokens, Some(1000000)); } #[tokio::test] diff --git a/scripts/codegen/rust.ts b/scripts/codegen/rust.ts index e8543c5cf..b8a1c6d6d 100644 --- a/scripts/codegen/rust.ts +++ b/scripts/codegen/rust.ts @@ -474,6 +474,21 @@ function isRustMapSchema(schema: JSONSchema7): boolean { ); } +function isRustArraySchema(schema: JSONSchema7): boolean { + return schema.type === "array"; +} + +function rustArrayType( + schema: JSONSchema7, + parentTypeName: string, + ctx: RustCodegenCtx, +): string { + const items = schema.items as JSONSchema7 | undefined; + if (!items) return "Vec"; + + return `Vec<${resolveRustType(items, parentTypeName, "item", true, ctx)}>`; +} + function rustMapValueType( schema: JSONSchema7, parentTypeName: string, @@ -528,6 +543,22 @@ function emitRustTypeAlias( ctx.typeAliases.push(lines.join("\n")); } +function emitRustArrayAlias( + typeName: string, + schema: JSONSchema7, + ctx: RustCodegenCtx, + description?: string, +): void { + if (ctx.generatedNames.has(typeName)) return; + emitRustTypeAlias( + typeName, + schema, + rustArrayType(schema, typeName, ctx), + ctx, + description, + ); +} + function emitRustMapAlias( typeName: string, schema: JSONSchema7, @@ -1469,6 +1500,8 @@ function generateApiTypesCode( getEnumValueDescriptions(schema), isSchemaExperimental(schema), ); + } else if (isRustArraySchema(schema)) { + emitRustArrayAlias(name, schema, ctx, schema.description); } else if (isRustMapSchema(schema)) { emitRustMapAlias(name, schema, ctx, schema.description); } else if (asGeneratedObjectSchema(schema, defCollections)) { @@ -1531,6 +1564,8 @@ function generateApiTypesCode( if (resolved) { if (resolved.enum && Array.isArray(resolved.enum)) { // Already generated from definitions + } else if (isRustArraySchema(resolved)) { + emitRustArrayAlias(resultName, resolved, ctx, resolved.description); } else if (isRustMapSchema(resolved)) { emitRustMapAlias(resultName, resolved, ctx, resolved.description); } else if (isObjectSchema(resolved)) { diff --git a/test/harness/package-lock.json b/test/harness/package-lock.json index a71ef1835..865c67bc9 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.64-1", + "@github/copilot": "^1.0.64-3", "@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.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-1.tgz", - "integrity": "sha512-lojV4Cb7oT4VJnYPEKBRH8KI3W43Q4Lh0Pc+V6sej+xjPJkoqwm68sNKn73/p3wXPBSTVTzPeCm9WhIisgf1Jw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.64-3.tgz", + "integrity": "sha512-Q9nBMYEHX1bJLXzzJocQx2nZvORJ0E9gvK6ly/FCtmtA7ad96BWZvf4EHzkCNDsn56aI3zNaUSfKHUKcmIAzSg==", "dev": true, "license": "SEE LICENSE IN LICENSE.md", "dependencies": { @@ -513,20 +513,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.64-1", - "@github/copilot-darwin-x64": "1.0.64-1", - "@github/copilot-linux-arm64": "1.0.64-1", - "@github/copilot-linux-x64": "1.0.64-1", - "@github/copilot-linuxmusl-arm64": "1.0.64-1", - "@github/copilot-linuxmusl-x64": "1.0.64-1", - "@github/copilot-win32-arm64": "1.0.64-1", - "@github/copilot-win32-x64": "1.0.64-1" + "@github/copilot-darwin-arm64": "1.0.64-3", + "@github/copilot-darwin-x64": "1.0.64-3", + "@github/copilot-linux-arm64": "1.0.64-3", + "@github/copilot-linux-x64": "1.0.64-3", + "@github/copilot-linuxmusl-arm64": "1.0.64-3", + "@github/copilot-linuxmusl-x64": "1.0.64-3", + "@github/copilot-win32-arm64": "1.0.64-3", + "@github/copilot-win32-x64": "1.0.64-3" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-1.tgz", - "integrity": "sha512-MQHZT9LhmCiq+ogO1E8cPCWrurZ6x+r9lPJfYUSnOyMO+EHbREpiJwOOChxtLHgL2/tKJSZdId2pg3tDgUlcsw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.64-3.tgz", + "integrity": "sha512-wlV6mRoAd/wG2V08TG+BOJ0nyOjroya24FSyA5A49z7PnUUuQXYRpa/GljvI5j3PM8aUl0DyBkXuB/DcFU818g==", "cpu": [ "arm64" ], @@ -541,9 +541,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-1.tgz", - "integrity": "sha512-kOQY7CvI7He0eO3ObQAHePWdkNLWAOegCSzUqUmdcpa1SNVqbZ3GBMsQ7uAZQip2cQxnGZ7pS1v6tKQ0HJdkYw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.64-3.tgz", + "integrity": "sha512-mk48PIESL2keeemX7tLRmWRDxKwl0q3cFI1ORD2QcrieNK7pSqI3eVbfoB7MqoUUI27yzIkl67xqgl8Qq28IUQ==", "cpu": [ "x64" ], @@ -558,9 +558,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-1.tgz", - "integrity": "sha512-hIfuO7Q+pWs0SKfIRYqT+CjMaupudnhp4RMS6XoJ5s/e33rvpj2tkTkXYlHJo1PMDI823vvbqgpEdr+KeewMwg==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.64-3.tgz", + "integrity": "sha512-rCgtK3/rofQW5StSbeU0TwDUlOl2bvS2HGKyapVxow1Nvz3Q/TDB+eFRQc5ocBdv5tNSor+Caw2JGkRx5v508w==", "cpu": [ "arm64" ], @@ -575,9 +575,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-1.tgz", - "integrity": "sha512-VHaE62pha0rDDvuNN3bd97gf0EZ+EJebstM1ejHsMYoPT1IOUkYEXlNfGGHY+GfUGYxAiy/+Uew4xw5mJyy/Sw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.64-3.tgz", + "integrity": "sha512-FAiBMw1h07mURSBLi3ztj5yzbP+uTbo9mhxOym1Xysut5LDpO2kYUzTYk2DlIyLGZhmH/HDOZE+b6U7lOUQy0g==", "cpu": [ "x64" ], @@ -592,9 +592,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-1.tgz", - "integrity": "sha512-L/YrZPotRujAP0QERq+DlkR1SLr7abbTSz/56JqKKOqEdjKZPdQW1bUlhL/w1CZg1gXlTNUsNVyKz/fUfrEBgw==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.64-3.tgz", + "integrity": "sha512-vn8P6grPf0y2mNskkdVbAz0i46b1sP9uSXv7z6kgycjprl0CdIYPDf3WEkG60vpyopfQna+iCqCLMWRnNyCk3g==", "cpu": [ "arm64" ], @@ -609,9 +609,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-1.tgz", - "integrity": "sha512-AGMjXqR128oyjiJhoI6Gd7JP5ddWkib+P4YH/JoHm05iNn23ZYl4tSc0XihHzeyMI1ix7Aacn8UINYB7lGOGOA==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.64-3.tgz", + "integrity": "sha512-atdHimNd6nzRRwHybXUY6/84bYzXeKbDOeYN/N/DsX23+AQOPSu5BD8MD8166I/5kNHui0XOmeTSydVNBUwcJw==", "cpu": [ "x64" ], @@ -626,9 +626,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-1.tgz", - "integrity": "sha512-vvv+gnemi9WKaxF41zz7Xmq6a493n8Yjps5UFaOY6a3WR222kKXZXfOpeRvIYsDgnIPHGBHIj1TBOmnHQT4V4w==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.64-3.tgz", + "integrity": "sha512-jUTS9meoHEXQR8nMDOjwC0baqV273lYtLxY46W7TiOFszhsqhbhWxQMkNQBfT3GEfPp+40igzMPq3reaUTuvag==", "cpu": [ "arm64" ], @@ -643,9 +643,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.64-1", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-1.tgz", - "integrity": "sha512-mcHvD0fjGDuqr/YXzy8mKuDmah1F+qjPujxoFuGmabmTJZ33cSIJ3nq7RRvxZNIdp8YJ57NkbcW30WvIcOeJ3w==", + "version": "1.0.64-3", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.64-3.tgz", + "integrity": "sha512-gHUhS500Q91hjtH9fqKDblaIs0mO09G4ifpZ1woDPXbkdKe/W29uwB7g2fn0+KczNRyPxFSWlqjnOon4Fe8svA==", "cpu": [ "x64" ], diff --git a/test/harness/package.json b/test/harness/package.json index af588a91c..f1506e95d 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.64-1", + "@github/copilot": "^1.0.64-3", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "@types/node-forge": "^1.3.14",