From 46f86cb1edcef63a2bd75b6062fa9ae592ff1f5a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Jun 2026 22:17:48 +0000 Subject: [PATCH 1/4] Update @github/copilot to 1.0.61 - Updated nodejs and test harness dependencies - Re-ran code generators - Formatted generated code --- dotnet/src/Generated/Rpc.cs | 819 ++++++++++-------- dotnet/src/Generated/SessionEvents.cs | 35 +- go/rpc/zrpc.go | 551 +++++++----- go/rpc/zsession_events.go | 16 +- java/pom.xml | 2 +- java/scripts/codegen/package-lock.json | 72 +- java/scripts/codegen/package.json | 2 +- .../copilot/generated/HookProgressEvent.java | 4 +- .../copilot/generated/SessionResumeEvent.java | 2 + .../SessionScheduleCreatedEvent.java | 8 +- .../generated/SessionShutdownEvent.java | 2 + .../generated/rpc/AgentsDiscoverParams.java | 33 + .../generated/rpc/AgentsDiscoverResult.java | 31 + .../generated/rpc/InstructionSource.java | 46 + .../rpc/InstructionSourceLocation.java | 39 + .../generated/rpc/InstructionSourceType.java | 45 + .../rpc/InstructionsDiscoverParams.java | 33 + .../rpc/InstructionsDiscoverResult.java | 31 + .../copilot/generated/rpc/ScheduleEntry.java | 8 +- .../generated/rpc/ServerAgentsApi.java | 40 + .../generated/rpc/ServerInstructionsApi.java | 40 + .../copilot/generated/rpc/ServerRpc.java | 6 + .../SessionInstructionsGetSourcesResult.java | 2 +- nodejs/package-lock.json | 72 +- nodejs/package.json | 2 +- nodejs/samples/package-lock.json | 2 +- nodejs/src/generated/rpc.ts | 256 ++++-- nodejs/src/generated/session-events.ts | 28 +- python/copilot/generated/rpc.py | 580 +++++++++---- python/copilot/generated/session_events.py | 39 +- rust/src/generated/api_types.rs | 140 ++- rust/src/generated/rpc.rs | 89 ++ rust/src/generated/session_events.rs | 23 +- test/harness/package-lock.json | 72 +- test/harness/package.json | 2 +- 35 files changed, 2225 insertions(+), 947 deletions(-) create mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/AgentsDiscoverParams.java create mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/AgentsDiscoverResult.java create mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/InstructionSource.java create mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/InstructionSourceLocation.java create mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/InstructionSourceType.java create mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/InstructionsDiscoverParams.java create mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/InstructionsDiscoverResult.java create mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/ServerAgentsApi.java create mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/ServerInstructionsApi.java diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index b95ab82f1..4b6cdab93 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -821,6 +821,145 @@ internal sealed class SkillsConfigSetDisabledSkillsRequest public IList DisabledSkills { get => field ??= []; 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; + + /// 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; } + + /// Preferred model id for this agent. When omitted, inherits the outer agent's model. + [JsonPropertyName("model")] + public string? Model { get; set; } + + /// Unique identifier of the custom agent. + [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; } +} + +/// Optional project paths to include in agent discovery. +[Experimental(Diagnostics.Experimental)] +internal sealed class AgentsDiscoverRequest +{ + /// When true, omit the host's agents (the `<COPILOT_HOME>/agents` 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; } +} + +/// Schema for the `InstructionSource` type. +[Experimental(Diagnostics.Experimental)] +public sealed class InstructionSource +{ + /// Glob pattern(s) from frontmatter — when set, this instruction applies only to matching files. + [JsonPropertyName("applyTo")] + public IList? ApplyTo { get; set; } + + /// Raw content of the instruction file. + [JsonPropertyName("content")] + public string Content { get; set; } = string.Empty; + + /// When true, this source starts disabled and must be toggled on by the user. + [JsonPropertyName("defaultDisabled")] + public bool? DefaultDisabled { get; set; } + + /// Short description (body after frontmatter) for use in instruction tables. + [JsonPropertyName("description")] + public string? Description { get; set; } + + /// Unique identifier for this source (used for toggling). + [JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; + + /// Human-readable label. + [JsonPropertyName("label")] + public string Label { get; set; } = string.Empty; + + /// Where this source lives — used for UI grouping. + [JsonPropertyName("location")] + public InstructionSourceLocation Location { 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; } + + /// File path relative to repo or absolute for home. + [JsonPropertyName("sourcePath")] + public string SourcePath { get; set; } = string.Empty; + + /// Category of instruction source — used for merge logic. + [JsonPropertyName("type")] + public InstructionSourceType Type { 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; } +} + +/// 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 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; } +} + /// Indicates whether the calling client was registered as the session filesystem provider. public sealed class SessionFsSetProviderResult { @@ -3795,54 +3934,13 @@ internal sealed class WorkspacesDiffRequest public string SessionId { get; set; } = string.Empty; } -/// Schema for the `InstructionsSources` type. -[Experimental(Diagnostics.Experimental)] -public sealed class InstructionsSources -{ - /// Glob pattern(s) from frontmatter — when set, this instruction applies only to matching files. - [JsonPropertyName("applyTo")] - public IList? ApplyTo { get; set; } - - /// Raw content of the instruction file. - [JsonPropertyName("content")] - public string Content { get; set; } = string.Empty; - - /// When true, this source starts disabled and must be toggled on by the user. - [JsonPropertyName("defaultDisabled")] - public bool? DefaultDisabled { get; set; } - - /// Short description (body after frontmatter) for use in instruction tables. - [JsonPropertyName("description")] - public string? Description { get; set; } - - /// Unique identifier for this source (used for toggling). - [JsonPropertyName("id")] - public string Id { get; set; } = string.Empty; - - /// Human-readable label. - [JsonPropertyName("label")] - public string Label { get; set; } = string.Empty; - - /// Where this source lives — used for UI grouping. - [JsonPropertyName("location")] - public InstructionsSourcesLocation Location { get; set; } - - /// File path relative to repo or absolute for home. - [JsonPropertyName("sourcePath")] - public string SourcePath { get; set; } = string.Empty; - - /// Category of instruction source — used for merge logic. - [JsonPropertyName("type")] - public InstructionsSourcesType Type { get; set; } -} - /// Instruction sources loaded for the session, in merge order. [Experimental(Diagnostics.Experimental)] public sealed class InstructionsGetSourcesResult { /// Instruction sources for the session. [JsonPropertyName("sources")] - public IList Sources { get => field ??= []; set; } + public IList Sources { get => field ??= []; set; } } /// Identifies the target session. @@ -3876,56 +3974,6 @@ internal sealed class FleetStartRequest public string SessionId { get; set; } = string.Empty; } -/// 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; - - /// 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; } - - /// Preferred model id for this agent. When omitted, inherits the outer agent's model. - [JsonPropertyName("model")] - public string? Model { get; set; } - - /// Unique identifier of the custom agent. - [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; } -} - /// Custom agents available to the session. [Experimental(Diagnostics.Experimental)] public sealed class AgentList @@ -4127,7 +4175,7 @@ public partial class TaskInfoAgent : TaskInfo [JsonPropertyName("latestResponse")] public string? LatestResponse { get; set; } - /// Model used for the task when specified. + /// Requested model override for the task when specified. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("model")] public string? Model { get; set; } @@ -4136,6 +4184,11 @@ public partial class TaskInfoAgent : TaskInfo [JsonPropertyName("prompt")] public required string Prompt { get; set; } + /// Runtime model resolved for the task when available. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("resolvedModel")] + public string? ResolvedModel { get; set; } + /// Result text from the task when available. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("result")] @@ -4849,7 +4902,7 @@ public sealed class McpFilteredServer /// MCP server startup filtering result. [Experimental(Diagnostics.Experimental)] -public sealed class McpStartServersResult +internal sealed class McpStartServersResult { /// Non-default servers allowed by policy. [JsonPropertyName("allowedServers")] @@ -4992,7 +5045,7 @@ internal sealed class SessionMcpRemoveGitHubRequest /// Result of configuring GitHub MCP. [Experimental(Diagnostics.Experimental)] -public sealed class McpConfigureGitHubResult +internal sealed class McpConfigureGitHubResult { /// Whether GitHub MCP configuration changed. [JsonPropertyName("changed")] @@ -5127,7 +5180,7 @@ internal sealed class McpIsServerRunningRequest /// Empty result after recording the MCP OAuth response. [Experimental(Diagnostics.Experimental)] -public sealed class McpOauthRespondResult +internal sealed class McpOauthRespondResult { } @@ -9462,6 +9515,14 @@ internal sealed class RemoteNotifySteerableChangedRequest [Experimental(Diagnostics.Experimental)] public sealed class ScheduleEntry { + /// Absolute fire time (epoch milliseconds) for a one-shot calendar schedule. + [JsonPropertyName("at")] + public long? At { get; set; } + + /// 5-field cron expression for a recurring calendar schedule, evaluated in `tz`. + [JsonPropertyName("cron")] + public string? Cron { get; set; } + /// Display-only label for the prompt as shown in the UI (e.g. `/skill-name` for a skill-invocation schedule). The actual enqueued prompt is `prompt`. [JsonPropertyName("displayPrompt")] public string? DisplayPrompt { get; set; } @@ -9470,10 +9531,10 @@ public sealed class ScheduleEntry [JsonPropertyName("id")] public long Id { get; set; } - /// Interval between scheduled ticks, in milliseconds. + /// Interval between scheduled ticks, in milliseconds (relative-interval schedules). [JsonConverter(typeof(MillisecondsTimeSpanConverter))] [JsonPropertyName("intervalMs")] - public TimeSpan Interval { get; set; } + public TimeSpan? Interval { get; set; } /// ISO 8601 timestamp when the next tick is scheduled to fire. [JsonPropertyName("nextRunAt")] @@ -9486,6 +9547,10 @@ public sealed class ScheduleEntry /// Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`). [JsonPropertyName("recurring")] public bool Recurring { get; set; } + + /// IANA timezone the `cron` expression is evaluated in. + [JsonPropertyName("tz")] + public string? Tz { get; set; } } /// Snapshot of the currently active recurring prompts for this session. @@ -10255,42 +10320,55 @@ public override void Write(Utf8JsonWriter writer, DiscoveredMcpServerType value, } -/// Path conventions used by this filesystem. +/// Where the agent definition was loaded from. +[Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] [DebuggerDisplay("{Value,nq}")] -public readonly struct SessionFsSetProviderConventions : IEquatable +public readonly struct AgentInfoSource : 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 SessionFsSetProviderConventions(string value) + public AgentInfoSource(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; - /// Paths use Windows path conventions. - public static SessionFsSetProviderConventions Windows { get; } = new("windows"); + /// Agent loaded from the user's personal agent configuration. + public static AgentInfoSource User { get; } = new("user"); - /// Paths use POSIX path conventions. - public static SessionFsSetProviderConventions Posix { get; } = new("posix"); + /// Agent loaded from the current project's repository configuration. + public static AgentInfoSource Project { get; } = new("project"); - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(SessionFsSetProviderConventions left, SessionFsSetProviderConventions right) => left.Equals(right); + /// Agent inherited from a parent project or workspace. + public static AgentInfoSource Inherited { get; } = new("inherited"); - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(SessionFsSetProviderConventions left, SessionFsSetProviderConventions right) => !(left == right); + /// Agent provided by a remote runtime or service. + public static AgentInfoSource Remote { get; } = new("remote"); + + /// Agent contributed by an installed plugin. + public static AgentInfoSource Plugin { get; } = new("plugin"); + + /// Agent built into the Copilot runtime. + public static AgentInfoSource Builtin { get; } = new("builtin"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(AgentInfoSource left, AgentInfoSource right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(AgentInfoSource left, AgentInfoSource right) => !(left == right); /// - public override bool Equals(object? obj) => obj is SessionFsSetProviderConventions other && Equals(other); + public override bool Equals(object? obj) => obj is AgentInfoSource other && Equals(other); /// - public bool Equals(SessionFsSetProviderConventions other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + public bool Equals(AgentInfoSource other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); /// public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); @@ -10298,9 +10376,218 @@ public SessionFsSetProviderConventions(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 AgentInfoSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, AgentInfoSource value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentInfoSource)); + } + } +} + + +/// Where this source lives — used for UI grouping. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct InstructionSourceLocation : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public InstructionSourceLocation(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Instructions live in user-level configuration. + public static InstructionSourceLocation User { get; } = new("user"); + + /// Instructions live in repository-level configuration. + public static InstructionSourceLocation Repository { get; } = new("repository"); + + /// Instructions live under the current working directory. + public static InstructionSourceLocation WorkingDirectory { get; } = new("working-directory"); + + /// Instructions live in plugin-provided configuration. + public static InstructionSourceLocation Plugin { get; } = new("plugin"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(InstructionSourceLocation left, InstructionSourceLocation right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(InstructionSourceLocation left, InstructionSourceLocation right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is InstructionSourceLocation other && Equals(other); + + /// + public bool Equals(InstructionSourceLocation other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override InstructionSourceLocation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, InstructionSourceLocation value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(InstructionSourceLocation)); + } + } +} + + +/// Category of instruction source — used for merge logic. +[Experimental(Diagnostics.Experimental)] +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct InstructionSourceType : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public InstructionSourceType(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Instructions loaded from the user's home configuration. + public static InstructionSourceType Home { get; } = new("home"); + + /// Instructions loaded from repository-scoped files. + public static InstructionSourceType Repo { get; } = new("repo"); + + /// Instructions loaded from model-specific files. + public static InstructionSourceType Model { get; } = new("model"); + + /// Instructions loaded from VS Code instruction files. + public static InstructionSourceType Vscode { get; } = new("vscode"); + + /// Instructions discovered from nested agent files. + public static InstructionSourceType NestedAgents { get; } = new("nested-agents"); + + /// Instructions inherited from child instruction files. + public static InstructionSourceType ChildInstructions { get; } = new("child-instructions"); + + /// Instructions supplied by an installed plugin. + public static InstructionSourceType Plugin { get; } = new("plugin"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(InstructionSourceType left, InstructionSourceType right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(InstructionSourceType left, InstructionSourceType right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is InstructionSourceType other && Equals(other); + + /// + public bool Equals(InstructionSourceType other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter + { + /// + public override InstructionSourceType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); + } + + /// + public override void Write(Utf8JsonWriter writer, InstructionSourceType value, JsonSerializerOptions options) + { + GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(InstructionSourceType)); + } + } +} + + +/// Path conventions used by this filesystem. +[JsonConverter(typeof(Converter))] +[DebuggerDisplay("{Value,nq}")] +public readonly struct SessionFsSetProviderConventions : IEquatable +{ + private readonly string? _value; + + /// Initializes a new instance of the struct. + /// The value to associate with this . + [JsonConstructor] + public SessionFsSetProviderConventions(string value) + { + ArgumentException.ThrowIfNullOrWhiteSpace(value); + _value = value; + } + + /// Gets the value associated with this . + public string Value => _value ?? string.Empty; + + /// Paths use Windows path conventions. + public static SessionFsSetProviderConventions Windows { get; } = new("windows"); + + /// Paths use POSIX path conventions. + public static SessionFsSetProviderConventions Posix { get; } = new("posix"); + + /// Returns a value indicating whether two instances are equivalent. + public static bool operator ==(SessionFsSetProviderConventions left, SessionFsSetProviderConventions right) => left.Equals(right); + + /// Returns a value indicating whether two instances are not equivalent. + public static bool operator !=(SessionFsSetProviderConventions left, SessionFsSetProviderConventions right) => !(left == right); + + /// + public override bool Equals(object? obj) => obj is SessionFsSetProviderConventions other && Equals(other); + + /// + public bool Equals(SessionFsSetProviderConventions other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); + + /// + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + + /// + public override string ToString() => Value; + + /// Provides a for serializing instances. + [EditorBrowsable(EditorBrowsableState.Never)] + public sealed class Converter : JsonConverter { /// public override SessionFsSetProviderConventions Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) @@ -11859,228 +12146,6 @@ public override void Write(Utf8JsonWriter writer, WorkspaceDiffMode value, JsonS } -/// Where this source lives — used for UI grouping. -[Experimental(Diagnostics.Experimental)] -[JsonConverter(typeof(Converter))] -[DebuggerDisplay("{Value,nq}")] -public readonly struct InstructionsSourcesLocation : IEquatable -{ - private readonly string? _value; - - /// Initializes a new instance of the struct. - /// The value to associate with this . - [JsonConstructor] - public InstructionsSourcesLocation(string value) - { - ArgumentException.ThrowIfNullOrWhiteSpace(value); - _value = value; - } - - /// Gets the value associated with this . - public string Value => _value ?? string.Empty; - - /// Instructions live in user-level configuration. - public static InstructionsSourcesLocation User { get; } = new("user"); - - /// Instructions live in repository-level configuration. - public static InstructionsSourcesLocation Repository { get; } = new("repository"); - - /// Instructions live under the current working directory. - public static InstructionsSourcesLocation WorkingDirectory { get; } = new("working-directory"); - - /// Instructions live in plugin-provided configuration. - public static InstructionsSourcesLocation Plugin { get; } = new("plugin"); - - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(InstructionsSourcesLocation left, InstructionsSourcesLocation right) => left.Equals(right); - - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(InstructionsSourcesLocation left, InstructionsSourcesLocation right) => !(left == right); - - /// - public override bool Equals(object? obj) => obj is InstructionsSourcesLocation other && Equals(other); - - /// - public bool Equals(InstructionsSourcesLocation other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); - - /// - public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); - - /// - public override string ToString() => Value; - - /// Provides a for serializing instances. - [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter - { - /// - public override InstructionsSourcesLocation Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); - } - - /// - public override void Write(Utf8JsonWriter writer, InstructionsSourcesLocation value, JsonSerializerOptions options) - { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(InstructionsSourcesLocation)); - } - } -} - - -/// Category of instruction source — used for merge logic. -[Experimental(Diagnostics.Experimental)] -[JsonConverter(typeof(Converter))] -[DebuggerDisplay("{Value,nq}")] -public readonly struct InstructionsSourcesType : IEquatable -{ - private readonly string? _value; - - /// Initializes a new instance of the struct. - /// The value to associate with this . - [JsonConstructor] - public InstructionsSourcesType(string value) - { - ArgumentException.ThrowIfNullOrWhiteSpace(value); - _value = value; - } - - /// Gets the value associated with this . - public string Value => _value ?? string.Empty; - - /// Instructions loaded from the user's home configuration. - public static InstructionsSourcesType Home { get; } = new("home"); - - /// Instructions loaded from repository-scoped files. - public static InstructionsSourcesType Repo { get; } = new("repo"); - - /// Instructions loaded from model-specific files. - public static InstructionsSourcesType Model { get; } = new("model"); - - /// Instructions loaded from VS Code instruction files. - public static InstructionsSourcesType Vscode { get; } = new("vscode"); - - /// Instructions discovered from nested agent files. - public static InstructionsSourcesType NestedAgents { get; } = new("nested-agents"); - - /// Instructions inherited from child instruction files. - public static InstructionsSourcesType ChildInstructions { get; } = new("child-instructions"); - - /// Instructions supplied by an installed plugin. - public static InstructionsSourcesType Plugin { get; } = new("plugin"); - - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(InstructionsSourcesType left, InstructionsSourcesType right) => left.Equals(right); - - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(InstructionsSourcesType left, InstructionsSourcesType right) => !(left == right); - - /// - public override bool Equals(object? obj) => obj is InstructionsSourcesType other && Equals(other); - - /// - public bool Equals(InstructionsSourcesType other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); - - /// - public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); - - /// - public override string ToString() => Value; - - /// Provides a for serializing instances. - [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter - { - /// - public override InstructionsSourcesType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); - } - - /// - public override void Write(Utf8JsonWriter writer, InstructionsSourcesType value, JsonSerializerOptions options) - { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(InstructionsSourcesType)); - } - } -} - - -/// Where the agent definition was loaded from. -[Experimental(Diagnostics.Experimental)] -[JsonConverter(typeof(Converter))] -[DebuggerDisplay("{Value,nq}")] -public readonly struct AgentInfoSource : IEquatable -{ - private readonly string? _value; - - /// Initializes a new instance of the struct. - /// The value to associate with this . - [JsonConstructor] - public AgentInfoSource(string value) - { - ArgumentException.ThrowIfNullOrWhiteSpace(value); - _value = value; - } - - /// Gets the value associated with this . - public string Value => _value ?? string.Empty; - - /// Agent loaded from the user's personal agent configuration. - public static AgentInfoSource User { get; } = new("user"); - - /// Agent loaded from the current project's repository configuration. - public static AgentInfoSource Project { get; } = new("project"); - - /// Agent inherited from a parent project or workspace. - public static AgentInfoSource Inherited { get; } = new("inherited"); - - /// Agent provided by a remote runtime or service. - public static AgentInfoSource Remote { get; } = new("remote"); - - /// Agent contributed by an installed plugin. - public static AgentInfoSource Plugin { get; } = new("plugin"); - - /// Agent built into the Copilot runtime. - public static AgentInfoSource Builtin { get; } = new("builtin"); - - /// Returns a value indicating whether two instances are equivalent. - public static bool operator ==(AgentInfoSource left, AgentInfoSource right) => left.Equals(right); - - /// Returns a value indicating whether two instances are not equivalent. - public static bool operator !=(AgentInfoSource left, AgentInfoSource right) => !(left == right); - - /// - public override bool Equals(object? obj) => obj is AgentInfoSource other && Equals(other); - - /// - public bool Equals(AgentInfoSource other) => string.Equals(Value, other.Value, StringComparison.OrdinalIgnoreCase); - - /// - public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Value); - - /// - public override string ToString() => Value; - - /// Provides a for serializing instances. - [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class Converter : JsonConverter - { - /// - public override AgentInfoSource Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - return new(GeneratedStringEnumJson.ReadValue(ref reader, typeToConvert)); - } - - /// - public override void Write(Utf8JsonWriter writer, AgentInfoSource value, JsonSerializerOptions options) - { - GeneratedStringEnumJson.WriteValue(writer, value.Value, typeof(AgentInfoSource)); - } - } -} - - /// Whether task execution is synchronously awaited or managed in the background. [Experimental(Diagnostics.Experimental)] [JsonConverter(typeof(Converter))] @@ -15159,6 +15224,18 @@ internal async Task ConnectAsync(string? token = null, Cancellati Interlocked.CompareExchange(ref field, new(_rpc), null) ?? field; + /// Agents APIs. + public ServerAgentsApi Agents => + field ?? + Interlocked.CompareExchange(ref field, new(_rpc), null) ?? + field; + + /// Instructions APIs. + public ServerInstructionsApi Instructions => + field ?? + Interlocked.CompareExchange(ref field, new(_rpc), null) ?? + field; + /// User APIs. public ServerUserApi User => field ?? @@ -15597,6 +15674,52 @@ public async Task SetDisabledSkillsAsync(IList disabledSkills, Cancellat } } +/// Provides server-scoped Agents APIs. +[Experimental(Diagnostics.Experimental)] +public sealed class ServerAgentsApi +{ + private readonly JsonRpc _rpc; + + internal ServerAgentsApi(JsonRpc rpc) + { + _rpc = rpc; + } + + /// Discovers custom agents across user, project, plugin, and remote sources. + /// 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). + /// When true, omit the host's agents (the `<COPILOT_HOME>/agents` directory and all plugin agents), leaving only project and remote agents. For multitenant deployments. + /// The to monitor for cancellation requests. The default is . + /// Agents discovered across user, project, plugin, and remote sources. + public async Task DiscoverAsync(IList? projectPaths = null, bool? excludeHostAgents = null, CancellationToken cancellationToken = default) + { + var request = new AgentsDiscoverRequest { ProjectPaths = projectPaths, ExcludeHostAgents = excludeHostAgents }; + return await CopilotClient.InvokeRpcAsync(_rpc, "agents.discover", [request], cancellationToken); + } +} + +/// Provides server-scoped Instructions APIs. +[Experimental(Diagnostics.Experimental)] +public sealed class ServerInstructionsApi +{ + private readonly JsonRpc _rpc; + + internal ServerInstructionsApi(JsonRpc rpc) + { + _rpc = rpc; + } + + /// Discovers instruction sources across user, repository, and plugin sources. + /// 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). + /// 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. + /// The to monitor for cancellation requests. The default is . + /// Instruction sources discovered across user, repository, and plugin sources. + public async Task DiscoverAsync(IList? projectPaths = null, bool? excludeHostInstructions = null, CancellationToken cancellationToken = default) + { + var request = new InstructionsDiscoverRequest { ProjectPaths = projectPaths, ExcludeHostInstructions = excludeHostInstructions }; + return await CopilotClient.InvokeRpcAsync(_rpc, "instructions.discover", [request], cancellationToken); + } +} + /// Provides server-scoped User APIs. public sealed class ServerUserApi { @@ -17200,7 +17323,7 @@ public async Task ReloadAsync(CancellationToken cancellationToken = default) /// Opaque runtime MCP reload configuration. Marked internal: an in-process runtime shape (reloadMcpServers throws over the wire). /// The to monitor for cancellation requests. The default is . /// MCP server startup filtering result. - public async Task ReloadWithConfigAsync(object config, CancellationToken cancellationToken = default) + internal async Task ReloadWithConfigAsync(object config, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(config); _session.ThrowIfDisposed(); @@ -17268,7 +17391,7 @@ public async Task RemoveGitHubAsync(CancellationToken can /// Opaque runtime auth info for GitHub MCP configuration. Marked internal: an in-process runtime shape (configureGitHubMcp is a no-op over the wire). /// The to monitor for cancellation requests. The default is . /// Result of configuring GitHub MCP. - public async Task ConfigureGitHubAsync(object authInfo, CancellationToken cancellationToken = default) + internal async Task ConfigureGitHubAsync(object authInfo, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(authInfo); _session.ThrowIfDisposed(); @@ -17281,7 +17404,7 @@ public async Task ConfigureGitHubAsync(object authInfo /// Name of the MCP server to start. /// Opaque server configuration (MCPServerConfig). Marked internal: an in-process runtime shape supplied only by in-process CLI callers. /// The to monitor for cancellation requests. The default is . - public async Task StartServerAsync(string serverName, object config, CancellationToken cancellationToken = default) + internal async Task StartServerAsync(string serverName, object config, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(serverName); ArgumentNullException.ThrowIfNull(config); @@ -17295,7 +17418,7 @@ public async Task StartServerAsync(string serverName, object config, Cancellatio /// Name of the MCP server to restart. /// Opaque server configuration (MCPServerConfig). Marked internal: an in-process runtime shape supplied only by in-process CLI callers. /// The to monitor for cancellation requests. The default is . - public async Task RestartServerAsync(string serverName, object config, CancellationToken cancellationToken = default) + internal async Task RestartServerAsync(string serverName, object config, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(serverName); ArgumentNullException.ThrowIfNull(config); @@ -17323,7 +17446,7 @@ public async Task StopServerAsync(string serverName, CancellationToken cancellat /// In-process MCP Transport instance. Marked internal: cannot be serialized across the JSON-RPC boundary. /// In-process server config (MCPServerConfig) paired with the in-process client/transport. Marked internal alongside its companions. /// The to monitor for cancellation requests. The default is . - public async Task RegisterExternalClientAsync(string serverName, object client, object transport, object config, CancellationToken cancellationToken = default) + internal async Task RegisterExternalClientAsync(string serverName, object client, object transport, object config, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(serverName); ArgumentNullException.ThrowIfNull(client); @@ -17338,7 +17461,7 @@ public async Task RegisterExternalClientAsync(string serverName, object client, /// Unregisters a previously registered external MCP client by server name. Marked internal as the paired companion of `registerExternalClient`: only in-process callers that registered a client this way can meaningfully unregister it. Disappears alongside `registerExternalClient`: once external clients are described to the runtime as config rather than handed in as instances, lifecycle (including deregistration) is owned entirely by the runtime. /// Server name of the external client to unregister. /// The to monitor for cancellation requests. The default is . - public async Task UnregisterExternalClientAsync(string serverName, CancellationToken cancellationToken = default) + internal async Task UnregisterExternalClientAsync(string serverName, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(serverName); _session.ThrowIfDisposed(); @@ -17389,7 +17512,7 @@ internal McpOauthApi(CopilotSession session) /// In-process OAuthClientProvider instance, or omitted to deny. Marked internal: cannot be serialized across the JSON-RPC boundary. /// The to monitor for cancellation requests. The default is . /// Empty result after recording the MCP OAuth response. - public async Task RespondAsync(string requestId, object? provider = null, CancellationToken cancellationToken = default) + internal async Task RespondAsync(string requestId, object? provider = null, CancellationToken cancellationToken = default) { ArgumentNullException.ThrowIfNull(requestId); _session.ThrowIfDisposed(); @@ -19304,6 +19427,7 @@ public static void RegisterClientSessionApiHandlers(JsonRpc rpc, FuncOn-disk byte size of the session's persisted events.jsonl file at resume time; omitted when the file does not exist or cannot be stat'd. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("eventsFileSizeBytes")] + public long? EventsFileSizeBytes { get; set; } + /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max"). [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("reasoningEffort")] @@ -1508,6 +1513,16 @@ public sealed partial class SessionTitleChangedData /// Scheduled prompt registered via /every or /after. public sealed partial class SessionScheduleCreatedData { + /// Absolute fire time (epoch milliseconds) for a one-shot calendar schedule. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("at")] + public long? At { get; set; } + + /// 5-field cron expression for a recurring calendar schedule, evaluated in `tz`. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("cron")] + public string? Cron { get; set; } + /// Optional user-facing label shown in the timeline instead of the actual prompt (e.g. `/skill-name args` when the prompt is a skill invocation expansion). [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("displayPrompt")] @@ -1517,10 +1532,11 @@ public sealed partial class SessionScheduleCreatedData [JsonPropertyName("id")] public required long Id { get; set; } - /// Interval between ticks in milliseconds. + /// Interval between ticks in milliseconds (relative-interval schedules). [JsonConverter(typeof(MillisecondsTimeSpanConverter))] + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("intervalMs")] - public required TimeSpan Interval { get; set; } + public TimeSpan? Interval { get; set; } /// Prompt text that gets enqueued on every tick. [JsonPropertyName("prompt")] @@ -1530,6 +1546,11 @@ public sealed partial class SessionScheduleCreatedData [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("recurring")] public bool? Recurring { get; set; } + + /// IANA timezone the `cron` expression is evaluated in. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("tz")] + public string? Tz { get; set; } } /// Scheduled prompt cancelled from the schedule manager dialog. @@ -1796,6 +1817,11 @@ public sealed partial class SessionShutdownData [JsonPropertyName("errorReason")] public string? ErrorReason { get; set; } + /// On-disk byte size of the session's persisted events.jsonl file at shutdown time; omitted when the file does not exist or cannot be stat'd. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("eventsFileSizeBytes")] + public long? EventsFileSizeBytes { get; set; } + /// Per-model usage breakdown, keyed by model identifier. [JsonPropertyName("modelMetrics")] public required IDictionary ModelMetrics { get; set; } @@ -2819,6 +2845,11 @@ public sealed partial class HookProgressData /// Human-readable progress message from the hook process. [JsonPropertyName("message")] public required string Message { get; set; } + + /// When true, this status message replaces the previous temporary one instead of accumulating. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("temporary")] + public bool? Temporary { get; set; } } /// System/developer instruction content with role and optional template metadata. diff --git a/go/rpc/zrpc.go b/go/rpc/zrpc.go index 6c3252007..b1d9df103 100644 --- a/go/rpc/zrpc.go +++ b/go/rpc/zrpc.go @@ -294,6 +294,18 @@ type AgentReloadResult struct { Agents []AgentInfo `json:"agents"` } +// Optional project paths to include in agent discovery. +// Experimental: AgentsDiscoverRequest is part of an experimental API and may change or be +// removed. +type AgentsDiscoverRequest struct { + // When true, omit the host's agents (the `/agents` directory and all plugin + // agents), leaving only project and remote agents. For multitenant deployments. + ExcludeHostAgents *bool `json:"excludeHostAgents,omitempty"` + // 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 `json:"projectPaths,omitzero"` +} + // Name of the custom agent to select for subsequent turns. // Experimental: AgentSelectRequest is part of an experimental API and may change or be // removed. @@ -1772,18 +1784,31 @@ type InstalledPluginSourceURL struct { URL string `json:"url"` } +// Optional project paths to include in instruction discovery. +// Experimental: InstructionsDiscoverRequest is part of an experimental API and may change +// or be removed. +type InstructionsDiscoverRequest struct { + // 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. + ExcludeHostInstructions *bool `json:"excludeHostInstructions,omitempty"` + // 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). + ProjectPaths []string `json:"projectPaths,omitzero"` +} + // Instruction sources loaded for the session, in merge order. // Experimental: InstructionsGetSourcesResult is part of an experimental API and may change // or be removed. type InstructionsGetSourcesResult struct { // Instruction sources for the session - Sources []InstructionsSources `json:"sources"` + Sources []InstructionSource `json:"sources"` } -// Schema for the `InstructionsSources` type. -// Experimental: InstructionsSources is part of an experimental API and may change or be +// Schema for the `InstructionSource` type. +// Experimental: InstructionSource is part of an experimental API and may change or be // removed. -type InstructionsSources struct { +type InstructionSource struct { // Glob pattern(s) from frontmatter — when set, this instruction applies only to matching // files ApplyTo []string `json:"applyTo,omitzero"` @@ -1798,11 +1823,16 @@ type InstructionsSources struct { // Human-readable label Label string `json:"label"` // Where this source lives — used for UI grouping - Location InstructionsSourcesLocation `json:"location"` + Location InstructionSourceLocation `json:"location"` + // 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. + ProjectPath *string `json:"projectPath,omitempty"` // File path relative to repo or absolute for home SourcePath string `json:"sourcePath"` // Category of instruction source — used for merge logic - Type InstructionsSourcesType `json:"type"` + Type InstructionSourceType `json:"type"` } // Schema for the `LocalSessionMetadataValue` type. @@ -5106,20 +5136,26 @@ type SandboxConfigUserPolicyNetwork struct { // Schema for the `ScheduleEntry` type. // Experimental: ScheduleEntry is part of an experimental API and may change or be removed. type ScheduleEntry struct { + // Absolute fire time (epoch milliseconds) for a one-shot calendar schedule. + At *int64 `json:"at,omitempty"` + // 5-field cron expression for a recurring calendar schedule, evaluated in `tz`. + Cron *string `json:"cron,omitempty"` // Display-only label for the prompt as shown in the UI (e.g. `/skill-name` for a // skill-invocation schedule). The actual enqueued prompt is `prompt`. DisplayPrompt *string `json:"displayPrompt,omitempty"` // Sequential id assigned by the runtime within the session. Stable across resumes (rebuilt // from the event log). ID int64 `json:"id"` - // Interval between scheduled ticks, in milliseconds. - IntervalMs int64 `json:"intervalMs"` + // Interval between scheduled ticks, in milliseconds (relative-interval schedules). + IntervalMs *int64 `json:"intervalMs,omitempty"` // ISO 8601 timestamp when the next tick is scheduled to fire. NextRunAt time.Time `json:"nextRunAt"` // Prompt text that gets enqueued on every tick. Prompt string `json:"prompt"` // Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`). Recurring bool `json:"recurring"` + // IANA timezone the `cron` expression is evaluated in. + Tz *string `json:"tz,omitempty"` } // Snapshot of the currently active recurring prompts for this session. @@ -5223,6 +5259,21 @@ type SendResult struct { MessageID string `json:"messageId"` } +// Agents discovered across user, project, plugin, and remote sources. +// Experimental: ServerAgentList is part of an experimental API and may change or be removed. +type ServerAgentList struct { + // All discovered agents across all sources + Agents []AgentInfo `json:"agents"` +} + +// Instruction sources discovered across user, repository, and plugin sources. +// Experimental: ServerInstructionSourceList is part of an experimental API and may change +// or be removed. +type ServerInstructionSourceList struct { + // All discovered instruction sources + Sources []InstructionSource `json:"sources"` +} + // Schema for the `ServerSkill` type. type ServerSkill struct { // Description of what the skill does @@ -7204,11 +7255,13 @@ type TaskAgentInfo struct { IdleSince *time.Time `json:"idleSince,omitempty"` // Most recent response text from the agent LatestResponse *string `json:"latestResponse,omitempty"` - // Model used for the task when specified + // Requested model override for the task when specified Model *string `json:"model,omitempty"` // Most recent prompt delivered to the agent. Updated whenever the agent receives a // follow-up message. Prompt string `json:"prompt"` + // Runtime model resolved for the task when available + ResolvedModel *string `json:"resolvedModel,omitempty"` // Result text from the task when available Result *string `json:"result,omitempty"` // ISO 8601 timestamp when the task was started @@ -8797,41 +8850,41 @@ const ( ) // Where this source lives — used for UI grouping -// Experimental: InstructionsSourcesLocation is part of an experimental API and may change -// or be removed. -type InstructionsSourcesLocation string +// Experimental: InstructionSourceLocation is part of an experimental API and may change or +// be removed. +type InstructionSourceLocation string const ( // Instructions live in plugin-provided configuration. - InstructionsSourcesLocationPlugin InstructionsSourcesLocation = "plugin" + InstructionSourceLocationPlugin InstructionSourceLocation = "plugin" // Instructions live in repository-level configuration. - InstructionsSourcesLocationRepository InstructionsSourcesLocation = "repository" + InstructionSourceLocationRepository InstructionSourceLocation = "repository" // Instructions live in user-level configuration. - InstructionsSourcesLocationUser InstructionsSourcesLocation = "user" + InstructionSourceLocationUser InstructionSourceLocation = "user" // Instructions live under the current working directory. - InstructionsSourcesLocationWorkingDirectory InstructionsSourcesLocation = "working-directory" + InstructionSourceLocationWorkingDirectory InstructionSourceLocation = "working-directory" ) // Category of instruction source — used for merge logic -// Experimental: InstructionsSourcesType is part of an experimental API and may change or be +// Experimental: InstructionSourceType is part of an experimental API and may change or be // removed. -type InstructionsSourcesType string +type InstructionSourceType string const ( // Instructions inherited from child instruction files. - InstructionsSourcesTypeChildInstructions InstructionsSourcesType = "child-instructions" + InstructionSourceTypeChildInstructions InstructionSourceType = "child-instructions" // Instructions loaded from the user's home configuration. - InstructionsSourcesTypeHome InstructionsSourcesType = "home" + InstructionSourceTypeHome InstructionSourceType = "home" // Instructions loaded from model-specific files. - InstructionsSourcesTypeModel InstructionsSourcesType = "model" + InstructionSourceTypeModel InstructionSourceType = "model" // Instructions discovered from nested agent files. - InstructionsSourcesTypeNestedAgents InstructionsSourcesType = "nested-agents" + InstructionSourceTypeNestedAgents InstructionSourceType = "nested-agents" // Instructions supplied by an installed plugin. - InstructionsSourcesTypePlugin InstructionsSourcesType = "plugin" + InstructionSourceTypePlugin InstructionSourceType = "plugin" // Instructions loaded from repository-scoped files. - InstructionsSourcesTypeRepo InstructionsSourcesType = "repo" + InstructionSourceTypeRepo InstructionSourceType = "repo" // Instructions loaded from VS Code instruction files. - InstructionsSourcesTypeVscode InstructionsSourcesType = "vscode" + InstructionSourceTypeVscode InstructionSourceType = "vscode" ) // Allowed values for the `McpAppsHostContextDetailsAvailableDisplayMode` enumeration. @@ -10074,6 +10127,51 @@ func (a *ServerAgentRegistryAPI) Spawn(ctx context.Context, params *AgentRegistr return result, nil } +// Experimental: ServerAgentsAPI contains experimental APIs that may change or be removed. +type ServerAgentsAPI serverAPI + +// Discovers custom agents across user, project, plugin, and remote sources. +// +// RPC method: agents.discover. +// +// Parameters: Optional project paths to include in agent discovery. +// +// Returns: Agents discovered across user, project, plugin, and remote sources. +func (a *ServerAgentsAPI) Discover(ctx context.Context, params *AgentsDiscoverRequest) (*ServerAgentList, error) { + raw, err := a.client.Request("agents.discover", params) + if err != nil { + return nil, err + } + var result ServerAgentList + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Experimental: ServerInstructionsAPI contains experimental APIs that may change or be +// removed. +type ServerInstructionsAPI serverAPI + +// Discovers instruction sources across user, repository, and plugin sources. +// +// RPC method: instructions.discover. +// +// Parameters: Optional project paths to include in instruction discovery. +// +// Returns: Instruction sources discovered across user, repository, and plugin sources. +func (a *ServerInstructionsAPI) Discover(ctx context.Context, params *InstructionsDiscoverRequest) (*ServerInstructionSourceList, error) { + raw, err := a.client.Request("instructions.discover", params) + if err != nil { + return nil, err + } + var result ServerInstructionSourceList + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + type ServerMCPAPI serverAPI // Discovers MCP servers from user, workspace, plugin, and builtin sources. @@ -11114,6 +11212,8 @@ type ServerRPC struct { Account *ServerAccountAPI AgentRegistry *ServerAgentRegistryAPI + Agents *ServerAgentsAPI + Instructions *ServerInstructionsAPI MCP *ServerMCPAPI Models *ServerModelsAPI Plugins *ServerPluginsAPI @@ -11151,6 +11251,8 @@ func NewServerRPC(client *jsonrpc2.Client) *ServerRPC { r.common = serverAPI{client: client} r.Account = (*ServerAccountAPI)(&r.common) r.AgentRegistry = (*ServerAgentRegistryAPI)(&r.common) + r.Agents = (*ServerAgentsAPI)(&r.common) + r.Instructions = (*ServerInstructionsAPI)(&r.common) r.MCP = (*ServerMCPAPI)(&r.common) r.Models = (*ServerModelsAPI)(&r.common) r.Plugins = (*ServerPluginsAPI)(&r.common) @@ -12245,30 +12347,6 @@ func (a *MCPAPI) CancelSamplingExecution(ctx context.Context, params *MCPCancelS return &result, nil } -// ConfigureGitHub configures the built-in GitHub MCP server for the session's current auth -// context. -// -// RPC method: session.mcp.configureGitHub. -// -// Parameters: Opaque auth info used to configure GitHub MCP. -// -// Returns: Result of configuring GitHub MCP. -func (a *MCPAPI) ConfigureGitHub(ctx context.Context, params *MCPConfigureGitHubRequest) (*MCPConfigureGitHubResult, error) { - req := map[string]any{"sessionId": a.sessionID} - if params != nil { - req["authInfo"] = params.AuthInfo - } - raw, err := a.client.Request("session.mcp.configureGitHub", req) - if err != nil { - return nil, err - } - var result MCPConfigureGitHubResult - if err := json.Unmarshal(raw, &result); err != nil { - return nil, err - } - return &result, nil -} - // Disables an MCP server for the session. // // RPC method: session.mcp.disable. @@ -12409,35 +12487,6 @@ func (a *MCPAPI) ListTools(ctx context.Context, params *MCPListToolsRequest) (*M return &result, nil } -// RegisterExternalClient registers a pre-connected external MCP client (e.g. IDE) on the -// session's host. The caller retains lifecycle ownership of the client and transport. -// Marked internal because the `client` and `transport` arguments are in-process MCP SDK -// instances that cannot be serialized across the JSON-RPC boundary; once the CLI moves on -// top of the SDK, external clients will be expressed as transport configs the runtime can -// construct itself. -// -// RPC method: session.mcp.registerExternalClient. -// -// Parameters: Registration parameters for an external MCP client. -func (a *MCPAPI) RegisterExternalClient(ctx context.Context, params *MCPRegisterExternalClientRequest) (*SessionMCPRegisterExternalClientResult, error) { - req := map[string]any{"sessionId": a.sessionID} - if params != nil { - req["client"] = params.Client - req["config"] = params.Config - req["serverName"] = params.ServerName - req["transport"] = params.Transport - } - raw, err := a.client.Request("session.mcp.registerExternalClient", req) - if err != nil { - return nil, err - } - var result SessionMCPRegisterExternalClientResult - if err := json.Unmarshal(raw, &result); err != nil { - return nil, err - } - return &result, nil -} - // Reloads MCP server connections for the session. // // RPC method: session.mcp.reload. @@ -12454,30 +12503,6 @@ func (a *MCPAPI) Reload(ctx context.Context) (*SessionMCPReloadResult, error) { return &result, nil } -// ReloadWithConfig reloads MCP server connections for the session with an explicit -// host-provided configuration. -// -// RPC method: session.mcp.reloadWithConfig. -// -// Parameters: Opaque MCP reload configuration. -// -// Returns: MCP server startup filtering result. -func (a *MCPAPI) ReloadWithConfig(ctx context.Context, params *MCPReloadWithConfigRequest) (*MCPStartServersResult, error) { - req := map[string]any{"sessionId": a.sessionID} - if params != nil { - req["config"] = params.Config - } - raw, err := a.client.Request("session.mcp.reloadWithConfig", req) - if err != nil { - return nil, err - } - var result MCPStartServersResult - if err := json.Unmarshal(raw, &result); err != nil { - return nil, err - } - return &result, nil -} - // RemoveGitHub removes the auto-managed `github` MCP server when present. // // RPC method: session.mcp.removeGitHub. @@ -12497,28 +12522,6 @@ func (a *MCPAPI) RemoveGitHub(ctx context.Context) (*MCPRemoveGitHubResult, erro return &result, nil } -// RestartServer restarts an individual MCP server on the session's host (stops then starts). -// -// RPC method: session.mcp.restartServer. -// -// Parameters: Server name and opaque configuration for an individual MCP server restart. -func (a *MCPAPI) RestartServer(ctx context.Context, params *MCPRestartServerRequest) (*SessionMCPRestartServerResult, error) { - req := map[string]any{"sessionId": a.sessionID} - if params != nil { - req["config"] = params.Config - req["serverName"] = params.ServerName - } - raw, err := a.client.Request("session.mcp.restartServer", req) - if err != nil { - return nil, err - } - var result SessionMCPRestartServerResult - if err := json.Unmarshal(raw, &result); err != nil { - return nil, err - } - return &result, nil -} - // SetEnvValueMode sets how environment-variable values supplied to MCP servers are resolved // (direct or indirect). // @@ -12544,28 +12547,6 @@ func (a *MCPAPI) SetEnvValueMode(ctx context.Context, params *MCPSetEnvValueMode return &result, nil } -// StartServer starts an individual MCP server on the session's host. -// -// RPC method: session.mcp.startServer. -// -// Parameters: Server name and opaque configuration for an individual MCP server start. -func (a *MCPAPI) StartServer(ctx context.Context, params *MCPStartServerRequest) (*SessionMCPStartServerResult, error) { - req := map[string]any{"sessionId": a.sessionID} - if params != nil { - req["config"] = params.Config - req["serverName"] = params.ServerName - } - raw, err := a.client.Request("session.mcp.startServer", req) - if err != nil { - return nil, err - } - var result SessionMCPStartServerResult - if err := json.Unmarshal(raw, &result); err != nil { - return nil, err - } - return &result, nil -} - // StopServer stops an individual MCP server on the session's host. // // RPC method: session.mcp.stopServer. @@ -12587,32 +12568,6 @@ func (a *MCPAPI) StopServer(ctx context.Context, params *MCPStopServerRequest) ( return &result, nil } -// UnregisterExternalClient unregisters a previously registered external MCP client by -// server name. Marked internal as the paired companion of `registerExternalClient`: only -// in-process callers that registered a client this way can meaningfully unregister it. -// Disappears alongside `registerExternalClient`: once external clients are described to the -// runtime as config rather than handed in as instances, lifecycle (including -// deregistration) is owned entirely by the runtime. -// -// RPC method: session.mcp.unregisterExternalClient. -// -// Parameters: Server name identifying the external client to remove. -func (a *MCPAPI) UnregisterExternalClient(ctx context.Context, params *MCPUnregisterExternalClientRequest) (*SessionMCPUnregisterExternalClientResult, error) { - req := map[string]any{"sessionId": a.sessionID} - if params != nil { - req["serverName"] = params.ServerName - } - raw, err := a.client.Request("session.mcp.unregisterExternalClient", req) - if err != nil { - return nil, err - } - var result SessionMCPUnregisterExternalClientResult - if err := json.Unmarshal(raw, &result); err != nil { - return nil, err - } - return &result, nil -} - // Experimental: MCPAppsAPI contains experimental APIs that may change or be removed. type MCPAppsAPI sessionAPI @@ -12803,35 +12758,6 @@ func (a *MCPOauthAPI) Login(ctx context.Context, params *MCPOauthLoginRequest) ( return &result, nil } -// Responds to a pending MCP OAuth provider request. Marked internal because the `provider` -// argument is an in-process OAuthClientProvider instance that cannot be carried over the -// wire; the public OAuth surface will route the response through a wire-clean handshake -// once the CLI moves on top of the SDK. -// -// RPC method: session.mcp.oauth.respond. -// -// Parameters: MCP OAuth request id and optional provider response. -// -// Returns: Empty result after recording the MCP OAuth response. -func (a *MCPOauthAPI) Respond(ctx context.Context, params *MCPOauthRespondRequest) (*MCPOauthRespondResult, error) { - req := map[string]any{"sessionId": a.sessionID} - if params != nil { - if params.Provider != nil { - req["provider"] = params.Provider - } - req["requestId"] = params.RequestID - } - raw, err := a.client.Request("session.mcp.oauth.respond", req) - if err != nil { - return nil, err - } - var result MCPOauthRespondResult - if err := json.Unmarshal(raw, &result); err != nil { - return nil, err - } - return &result, nil -} - // Experimental: Oauth returns experimental APIs that may change or be removed. func (s *MCPAPI) Oauth() *MCPOauthAPI { return (*MCPOauthAPI)(s) @@ -15549,6 +15475,229 @@ func NewSessionRPC(client *jsonrpc2.Client, sessionID string) *SessionRPC { return r } +type internalSessionAPI struct { + client *jsonrpc2.Client + sessionID string +} + +// Experimental: InternalMCPAPI contains experimental APIs that may change or be removed. +type InternalMCPAPI internalSessionAPI + +// ConfigureGitHub configures the built-in GitHub MCP server for the session's current auth +// context. +// +// RPC method: session.mcp.configureGitHub. +// +// Parameters: Opaque auth info used to configure GitHub MCP. +// +// Returns: Result of configuring GitHub MCP. +// Internal: ConfigureGitHub is part of the SDK's internal handshake/plumbing; external +// callers should not use it. +func (a *InternalMCPAPI) ConfigureGitHub(ctx context.Context, params *MCPConfigureGitHubRequest) (*MCPConfigureGitHubResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["authInfo"] = params.AuthInfo + } + raw, err := a.client.Request("session.mcp.configureGitHub", req) + if err != nil { + return nil, err + } + var result MCPConfigureGitHubResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// RegisterExternalClient registers a pre-connected external MCP client (e.g. IDE) on the +// session's host. The caller retains lifecycle ownership of the client and transport. +// Marked internal because the `client` and `transport` arguments are in-process MCP SDK +// instances that cannot be serialized across the JSON-RPC boundary; once the CLI moves on +// top of the SDK, external clients will be expressed as transport configs the runtime can +// construct itself. +// +// RPC method: session.mcp.registerExternalClient. +// +// Parameters: Registration parameters for an external MCP client. +// Internal: RegisterExternalClient is part of the SDK's internal handshake/plumbing; +// external callers should not use it. +func (a *InternalMCPAPI) RegisterExternalClient(ctx context.Context, params *MCPRegisterExternalClientRequest) (*SessionMCPRegisterExternalClientResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["client"] = params.Client + req["config"] = params.Config + req["serverName"] = params.ServerName + req["transport"] = params.Transport + } + raw, err := a.client.Request("session.mcp.registerExternalClient", req) + if err != nil { + return nil, err + } + var result SessionMCPRegisterExternalClientResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// ReloadWithConfig reloads MCP server connections for the session with an explicit +// host-provided configuration. +// +// RPC method: session.mcp.reloadWithConfig. +// +// Parameters: Opaque MCP reload configuration. +// +// Returns: MCP server startup filtering result. +// Internal: ReloadWithConfig is part of the SDK's internal handshake/plumbing; external +// callers should not use it. +func (a *InternalMCPAPI) ReloadWithConfig(ctx context.Context, params *MCPReloadWithConfigRequest) (*MCPStartServersResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["config"] = params.Config + } + raw, err := a.client.Request("session.mcp.reloadWithConfig", req) + if err != nil { + return nil, err + } + var result MCPStartServersResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// RestartServer restarts an individual MCP server on the session's host (stops then starts). +// +// RPC method: session.mcp.restartServer. +// +// Parameters: Server name and opaque configuration for an individual MCP server restart. +// Internal: RestartServer is part of the SDK's internal handshake/plumbing; external +// callers should not use it. +func (a *InternalMCPAPI) RestartServer(ctx context.Context, params *MCPRestartServerRequest) (*SessionMCPRestartServerResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["config"] = params.Config + req["serverName"] = params.ServerName + } + raw, err := a.client.Request("session.mcp.restartServer", req) + if err != nil { + return nil, err + } + var result SessionMCPRestartServerResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// StartServer starts an individual MCP server on the session's host. +// +// RPC method: session.mcp.startServer. +// +// Parameters: Server name and opaque configuration for an individual MCP server start. +// Internal: StartServer is part of the SDK's internal handshake/plumbing; external callers +// should not use it. +func (a *InternalMCPAPI) StartServer(ctx context.Context, params *MCPStartServerRequest) (*SessionMCPStartServerResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["config"] = params.Config + req["serverName"] = params.ServerName + } + raw, err := a.client.Request("session.mcp.startServer", req) + if err != nil { + return nil, err + } + var result SessionMCPStartServerResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// UnregisterExternalClient unregisters a previously registered external MCP client by +// server name. Marked internal as the paired companion of `registerExternalClient`: only +// in-process callers that registered a client this way can meaningfully unregister it. +// Disappears alongside `registerExternalClient`: once external clients are described to the +// runtime as config rather than handed in as instances, lifecycle (including +// deregistration) is owned entirely by the runtime. +// +// RPC method: session.mcp.unregisterExternalClient. +// +// Parameters: Server name identifying the external client to remove. +// Internal: UnregisterExternalClient is part of the SDK's internal handshake/plumbing; +// external callers should not use it. +func (a *InternalMCPAPI) UnregisterExternalClient(ctx context.Context, params *MCPUnregisterExternalClientRequest) (*SessionMCPUnregisterExternalClientResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + req["serverName"] = params.ServerName + } + raw, err := a.client.Request("session.mcp.unregisterExternalClient", req) + if err != nil { + return nil, err + } + var result SessionMCPUnregisterExternalClientResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Experimental: InternalMCPOauthAPI contains experimental APIs that may change or be +// removed. +type InternalMCPOauthAPI internalSessionAPI + +// Responds to a pending MCP OAuth provider request. Marked internal because the `provider` +// argument is an in-process OAuthClientProvider instance that cannot be carried over the +// wire; the public OAuth surface will route the response through a wire-clean handshake +// once the CLI moves on top of the SDK. +// +// RPC method: session.mcp.oauth.respond. +// +// Parameters: MCP OAuth request id and optional provider response. +// +// Returns: Empty result after recording the MCP OAuth response. +// Internal: Respond is part of the SDK's internal handshake/plumbing; external callers +// should not use it. +func (a *InternalMCPOauthAPI) Respond(ctx context.Context, params *MCPOauthRespondRequest) (*MCPOauthRespondResult, error) { + req := map[string]any{"sessionId": a.sessionID} + if params != nil { + if params.Provider != nil { + req["provider"] = params.Provider + } + req["requestId"] = params.RequestID + } + raw, err := a.client.Request("session.mcp.oauth.respond", req) + if err != nil { + return nil, err + } + var result MCPOauthRespondResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +// Experimental: Oauth returns experimental APIs that may change or be removed. +func (s *InternalMCPAPI) Oauth() *InternalMCPOauthAPI { + return (*InternalMCPOauthAPI)(s) +} + +// InternalSessionRPC provides internal SDK session-scoped RPC methods (handshake helpers +// etc.). Not part of the public API. +type InternalSessionRPC struct { + // Reuse a single struct instead of allocating one for each service on the heap. + common internalSessionAPI + + MCP *InternalMCPAPI +} + +func NewInternalSessionRPC(client *jsonrpc2.Client, sessionID string) *InternalSessionRPC { + r := &InternalSessionRPC{} + r.common = internalSessionAPI{client: client, sessionID: sessionID} + r.MCP = (*InternalMCPAPI)(&r.common) + return r +} + // Experimental: CanvasHandler contains experimental APIs that may change or be removed. type CanvasHandler interface { // Closes a canvas instance on the provider. diff --git a/go/rpc/zsession_events.go b/go/rpc/zsession_events.go index 5148d46c3..98d008256 100644 --- a/go/rpc/zsession_events.go +++ b/go/rpc/zsession_events.go @@ -431,6 +431,8 @@ func (*PendingMessagesModifiedData) Type() SessionEventType { type HookProgressData struct { // Human-readable progress message from the hook process Message string `json:"message"` + // When true, this status message replaces the previous temporary one instead of accumulating + Temporary *bool `json:"temporary,omitempty"` } func (*HookProgressData) sessionEventData() {} @@ -894,16 +896,22 @@ func (*SessionScheduleCancelledData) Type() SessionEventType { // Scheduled prompt registered via /every or /after type SessionScheduleCreatedData struct { + // Absolute fire time (epoch milliseconds) for a one-shot calendar schedule + At *int64 `json:"at,omitempty"` + // 5-field cron expression for a recurring calendar schedule, evaluated in `tz` + Cron *string `json:"cron,omitempty"` // Optional user-facing label shown in the timeline instead of the actual prompt (e.g. `/skill-name args` when the prompt is a skill invocation expansion) DisplayPrompt *string `json:"displayPrompt,omitempty"` // Sequential id assigned to the scheduled prompt within the session ID int64 `json:"id"` - // Interval between ticks in milliseconds - IntervalMs int64 `json:"intervalMs"` + // Interval between ticks in milliseconds (relative-interval schedules) + IntervalMs *int64 `json:"intervalMs,omitempty"` // Prompt text that gets enqueued on every tick Prompt string `json:"prompt"` // Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`) Recurring *bool `json:"recurring,omitempty"` + // IANA timezone the `cron` expression is evaluated in + Tz *string `json:"tz,omitempty"` } func (*SessionScheduleCreatedData) sessionEventData() {} @@ -1154,6 +1162,8 @@ type SessionResumeData struct { ContinuePendingWork *bool `json:"continuePendingWork,omitempty"` // Total number of persisted events in the session at the time of resume EventCount int64 `json:"eventCount"` + // On-disk byte size of the session's persisted events.jsonl file at resume time; omitted when the file does not exist or cannot be stat'd + EventsFileSizeBytes *int64 `json:"eventsFileSizeBytes,omitempty"` // Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max") ReasoningEffort *string `json:"reasoningEffort,omitempty"` // Reasoning summary mode used for model calls, if applicable (e.g. "none", "concise", "detailed") @@ -1196,6 +1206,8 @@ type SessionShutdownData struct { CurrentTokens *int64 `json:"currentTokens,omitempty"` // Error description when shutdownType is "error" ErrorReason *string `json:"errorReason,omitempty"` + // On-disk byte size of the session's persisted events.jsonl file at shutdown time; omitted when the file does not exist or cannot be stat'd + EventsFileSizeBytes *int64 `json:"eventsFileSizeBytes,omitempty"` // Per-model usage breakdown, keyed by model identifier ModelMetrics map[string]ShutdownModelMetric `json:"modelMetrics"` // Unix timestamp (milliseconds) when the session started diff --git a/java/pom.xml b/java/pom.xml index 125b9afe0..0281e4e92 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.60 + ^1.0.61 diff --git a/java/scripts/codegen/package-lock.json b/java/scripts/codegen/package-lock.json index e58973859..85f8d5745 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.60", + "@github/copilot": "^1.0.61", "json-schema": "^0.4.0", "tsx": "^4.20.6" } @@ -428,9 +428,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.60.tgz", - "integrity": "sha512-+GjW+GJNo55nwJwt48o9szWcyhuY0u682cBKQI1ay9jVBX8DCCXC6HB6Tyv5/MaM4N7CxTiEgp48aVMkye8K+g==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.61.tgz", + "integrity": "sha512-E4f7YXTL2uUZY/ypnfsUruAeSgrHx3AGYEbm5N0DrpzPqoNAZqV6kHEWM4vu+W/nGvydIfPxmOTqaMEhM8r0Uw==", "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.60", - "@github/copilot-darwin-x64": "1.0.60", - "@github/copilot-linux-arm64": "1.0.60", - "@github/copilot-linux-x64": "1.0.60", - "@github/copilot-linuxmusl-arm64": "1.0.60", - "@github/copilot-linuxmusl-x64": "1.0.60", - "@github/copilot-win32-arm64": "1.0.60", - "@github/copilot-win32-x64": "1.0.60" + "@github/copilot-darwin-arm64": "1.0.61", + "@github/copilot-darwin-x64": "1.0.61", + "@github/copilot-linux-arm64": "1.0.61", + "@github/copilot-linux-x64": "1.0.61", + "@github/copilot-linuxmusl-arm64": "1.0.61", + "@github/copilot-linuxmusl-x64": "1.0.61", + "@github/copilot-win32-arm64": "1.0.61", + "@github/copilot-win32-x64": "1.0.61" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.60.tgz", - "integrity": "sha512-TErNaVxsv+uB3bdHwdoKorCd1rhiRh7HkX48vnS7jwqa8EtGgAkzNrHKC7mruL2rnYOOsNIdPfhzQk+2Y6PSxQ==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.61.tgz", + "integrity": "sha512-10prvjHRXB0SD28NsIpzdNDgLquQYUwaH5Ev9KVdIWdBPAvlQsHmQ4JSCyD/UILc/nrrr02CKUgum+mZRKUKIg==", "cpu": [ "arm64" ], @@ -466,9 +466,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.60.tgz", - "integrity": "sha512-PthhcR6PqbQlT04xQKTElpPSJOrJd65nK/l9Sjmpwtk21RrDKs13DCY/19ubP17updYUWBxp3VNfyfN3DAQKOA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.61.tgz", + "integrity": "sha512-NXUjageJ3mxDfHtXGYu//XhJ+dhJFYObT4R3jeWgIHhd+4lX7FlC754nwlBP/ZuVhJ3ND22JK9sua9d2F3Cbwg==", "cpu": [ "x64" ], @@ -482,9 +482,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.60.tgz", - "integrity": "sha512-AVahkDVQTiGmHvDjlb4CHO8CFEGqmCEipxi0qTA60oH3Y3W2C4aYBwEBtP/85pN3wUUKZJVrWTCcxdufUBuK2Q==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.61.tgz", + "integrity": "sha512-dwB2+QSMr622JkePeK56M7YWXsTT/DQzKfpDq8Lk2kmGU052RZAarRmt8gcNm4anofN7pMSrqc3YHj1TM84MFw==", "cpu": [ "arm64" ], @@ -498,9 +498,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.60.tgz", - "integrity": "sha512-NwQjV2ZyUdJVAO4t7wiT+eR3uNWYP57xaLUIhf6JTMGpsTyN+mAFXW63xpwM/K+Pug62uRDQDBjEeOQRB7qZrA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.61.tgz", + "integrity": "sha512-q6n8R8oybvuCmmkP+43w809Wpud/wwRi/fFSZEYJagiNGmYJ00SDkrfJxHbZsAFMpaJC+oTswqzJHjRoZbO74w==", "cpu": [ "x64" ], @@ -514,9 +514,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.60.tgz", - "integrity": "sha512-AYGPc9vq2k248bVwUbiVJ65kIYYMQQ7ci+S3oefWBIyYtYwAH0n+Q/IGAj49IPrelBarYABAsX+EQZJJC8rhxw==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.61.tgz", + "integrity": "sha512-yWo7JXnZS11eJpm68E1RWKMR47EwzPKj3V7GX0EMTd8Fw0T2Aurk9wt9p3c9w0v02nTO1DqJhi68KVWJPdVqvA==", "cpu": [ "arm64" ], @@ -530,9 +530,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.60.tgz", - "integrity": "sha512-9/F7yl0/9FpGvYR/TCQtbhu0vIaUVem6U7em85QYaEjkS45nK500pByCMWY0bXv2eSS8U2g+8FOAjfkyLlxwPw==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.61.tgz", + "integrity": "sha512-nHzx27Ac4B0fpD9CcmvyrGOBEMJ01CPRgVRP0yAl4wpU4cM2I6+9TPyfYThlWDqZqiUKGXC1ZRQ+B8cJREVGmA==", "cpu": [ "x64" ], @@ -546,9 +546,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.60.tgz", - "integrity": "sha512-ZxxS+Ua1+7Puz80yTOpQ4WS+s32NjrxIsqo8gE0FpuZId16BGOGbWkzWQvR/k2AVBCqpLZ7SK3LfDVKuKJRbpA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.61.tgz", + "integrity": "sha512-k6knzI+K5HlZeJDS/yeJAfoYD4xcURWfuqunpTCyk1pDbIFxmrLSqR/TDi7KNlpsf883n5WqpnB06K5kysdHHQ==", "cpu": [ "arm64" ], @@ -562,9 +562,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.60.tgz", - "integrity": "sha512-e91ZlFz9J1lkadExLg36oN8Ms/xIa03vAEir3DmyCeYebZ+Y48vdS+BwhQEma+GLoxJUOhzHndCckGnMRfNIbA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.61.tgz", + "integrity": "sha512-L6NZ6o73VZFHd7OoRaztV3Prh1PbW9HXqYsAx+XywNALQvE1u489WBUC1ggfYBW5MTBCf8mxSkYQdb3Am2omsw==", "cpu": [ "x64" ], diff --git a/java/scripts/codegen/package.json b/java/scripts/codegen/package.json index 4040da3c7..a932d0a3b 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.60", + "@github/copilot": "^1.0.61", "json-schema": "^0.4.0", "tsx": "^4.20.6" } diff --git a/java/src/generated/java/com/github/copilot/generated/HookProgressEvent.java b/java/src/generated/java/com/github/copilot/generated/HookProgressEvent.java index c3c4c64e0..b4d96764f 100644 --- a/java/src/generated/java/com/github/copilot/generated/HookProgressEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/HookProgressEvent.java @@ -35,7 +35,9 @@ public final class HookProgressEvent extends SessionEvent { @JsonInclude(JsonInclude.Include.NON_NULL) public record HookProgressEventData( /** Human-readable progress message from the hook process */ - @JsonProperty("message") String message + @JsonProperty("message") String message, + /** When true, this status message replaces the previous temporary one instead of accumulating */ + @JsonProperty("temporary") Boolean temporary ) { } } diff --git a/java/src/generated/java/com/github/copilot/generated/SessionResumeEvent.java b/java/src/generated/java/com/github/copilot/generated/SessionResumeEvent.java index e06451b3f..b1cfda933 100644 --- a/java/src/generated/java/com/github/copilot/generated/SessionResumeEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/SessionResumeEvent.java @@ -39,6 +39,8 @@ public record SessionResumeEventData( @JsonProperty("resumeTime") OffsetDateTime resumeTime, /** Total number of persisted events in the session at the time of resume */ @JsonProperty("eventCount") Long eventCount, + /** On-disk byte size of the session's persisted events.jsonl file at resume time; omitted when the file does not exist or cannot be stat'd */ + @JsonProperty("eventsFileSizeBytes") Long eventsFileSizeBytes, /** Model currently selected at resume time */ @JsonProperty("selectedModel") String selectedModel, /** Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max") */ diff --git a/java/src/generated/java/com/github/copilot/generated/SessionScheduleCreatedEvent.java b/java/src/generated/java/com/github/copilot/generated/SessionScheduleCreatedEvent.java index 653622e5f..a7a934949 100644 --- a/java/src/generated/java/com/github/copilot/generated/SessionScheduleCreatedEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/SessionScheduleCreatedEvent.java @@ -36,8 +36,14 @@ public final class SessionScheduleCreatedEvent extends SessionEvent { public record SessionScheduleCreatedEventData( /** Sequential id assigned to the scheduled prompt within the session */ @JsonProperty("id") Long id, - /** Interval between ticks in milliseconds */ + /** Interval between ticks in milliseconds (relative-interval schedules) */ @JsonProperty("intervalMs") Long intervalMs, + /** 5-field cron expression for a recurring calendar schedule, evaluated in `tz` */ + @JsonProperty("cron") String cron, + /** IANA timezone the `cron` expression is evaluated in */ + @JsonProperty("tz") String tz, + /** Absolute fire time (epoch milliseconds) for a one-shot calendar schedule */ + @JsonProperty("at") Long at, /** Prompt text that gets enqueued on every tick */ @JsonProperty("prompt") String prompt, /** Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`) */ diff --git a/java/src/generated/java/com/github/copilot/generated/SessionShutdownEvent.java b/java/src/generated/java/com/github/copilot/generated/SessionShutdownEvent.java index e1609588c..84c302306 100644 --- a/java/src/generated/java/com/github/copilot/generated/SessionShutdownEvent.java +++ b/java/src/generated/java/com/github/copilot/generated/SessionShutdownEvent.java @@ -49,6 +49,8 @@ public record SessionShutdownEventData( @JsonProperty("totalApiDurationMs") Long totalApiDurationMs, /** Unix timestamp (milliseconds) when the session started */ @JsonProperty("sessionStartTime") Long sessionStartTime, + /** On-disk byte size of the session's persisted events.jsonl file at shutdown time; omitted when the file does not exist or cannot be stat'd */ + @JsonProperty("eventsFileSizeBytes") Long eventsFileSizeBytes, /** Aggregate code change metrics for the session */ @JsonProperty("codeChanges") ShutdownCodeChanges codeChanges, /** Per-model usage breakdown, keyed by model identifier */ diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/AgentsDiscoverParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/AgentsDiscoverParams.java new file mode 100644 index 000000000..39cee86de --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/AgentsDiscoverParams.java @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * 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; + +/** + * Optional project paths to include in agent discovery. + * + * @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 AgentsDiscoverParams( + /** 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). */ + @JsonProperty("projectPaths") List projectPaths, + /** When true, omit the host's agents (the `/agents` directory and all plugin agents), leaving only project and remote agents. For multitenant deployments. */ + @JsonProperty("excludeHostAgents") Boolean excludeHostAgents +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/AgentsDiscoverResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/AgentsDiscoverResult.java new file mode 100644 index 000000000..50791127e --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/AgentsDiscoverResult.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; + +/** + * Agents discovered across user, project, plugin, and remote sources. + * + * @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 AgentsDiscoverResult( + /** All discovered agents across all sources */ + @JsonProperty("agents") List agents +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionSource.java b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionSource.java new file mode 100644 index 000000000..37d1ead1c --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionSource.java @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------------------------- + * 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; + +/** + * Schema for the `InstructionSource` type. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public record InstructionSource( + /** Unique identifier for this source (used for toggling) */ + @JsonProperty("id") String id, + /** Human-readable label */ + @JsonProperty("label") String label, + /** File path relative to repo or absolute for home */ + @JsonProperty("sourcePath") String sourcePath, + /** Raw content of the instruction file */ + @JsonProperty("content") String content, + /** Category of instruction source — used for merge logic */ + @JsonProperty("type") InstructionSourceType type, + /** Where this source lives — used for UI grouping */ + @JsonProperty("location") InstructionSourceLocation location, + /** Glob pattern(s) from frontmatter — when set, this instruction applies only to matching files */ + @JsonProperty("applyTo") List applyTo, + /** Short description (body after frontmatter) for use in instruction tables */ + @JsonProperty("description") String description, + /** When true, this source starts disabled and must be toggled on by the user */ + @JsonProperty("defaultDisabled") Boolean defaultDisabled, + /** 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. */ + @JsonProperty("projectPath") String projectPath +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionSourceLocation.java b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionSourceLocation.java new file mode 100644 index 000000000..261327cfb --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionSourceLocation.java @@ -0,0 +1,39 @@ +/*--------------------------------------------------------------------------------------------- + * 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 javax.annotation.processing.Generated; + +/** + * Where this source lives — used for UI grouping + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum InstructionSourceLocation { + /** The {@code user} variant. */ + USER("user"), + /** The {@code repository} variant. */ + REPOSITORY("repository"), + /** The {@code working-directory} variant. */ + WORKING_DIRECTORY("working-directory"), + /** The {@code plugin} variant. */ + PLUGIN("plugin"); + + private final String value; + InstructionSourceLocation(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static InstructionSourceLocation fromValue(String value) { + for (InstructionSourceLocation v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown InstructionSourceLocation value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionSourceType.java b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionSourceType.java new file mode 100644 index 000000000..d267e249f --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionSourceType.java @@ -0,0 +1,45 @@ +/*--------------------------------------------------------------------------------------------- + * 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 javax.annotation.processing.Generated; + +/** + * Category of instruction source — used for merge logic + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public enum InstructionSourceType { + /** The {@code home} variant. */ + HOME("home"), + /** The {@code repo} variant. */ + REPO("repo"), + /** The {@code model} variant. */ + MODEL("model"), + /** The {@code vscode} variant. */ + VSCODE("vscode"), + /** The {@code nested-agents} variant. */ + NESTED_AGENTS("nested-agents"), + /** The {@code child-instructions} variant. */ + CHILD_INSTRUCTIONS("child-instructions"), + /** The {@code plugin} variant. */ + PLUGIN("plugin"); + + private final String value; + InstructionSourceType(String value) { this.value = value; } + @com.fasterxml.jackson.annotation.JsonValue + public String getValue() { return value; } + @com.fasterxml.jackson.annotation.JsonCreator + public static InstructionSourceType fromValue(String value) { + for (InstructionSourceType v : values()) { + if (v.value.equals(value)) return v; + } + throw new IllegalArgumentException("Unknown InstructionSourceType value: " + value); + } +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsDiscoverParams.java b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsDiscoverParams.java new file mode 100644 index 000000000..1a0b84051 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsDiscoverParams.java @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * 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; + +/** + * Optional project paths to include in instruction discovery. + * + * @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 InstructionsDiscoverParams( + /** 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). */ + @JsonProperty("projectPaths") List projectPaths, + /** 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. */ + @JsonProperty("excludeHostInstructions") Boolean excludeHostInstructions +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsDiscoverResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsDiscoverResult.java new file mode 100644 index 000000000..e8cdee9e0 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsDiscoverResult.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; + +/** + * Instruction sources discovered across user, repository, and plugin sources. + * + * @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 InstructionsDiscoverResult( + /** All discovered instruction sources */ + @JsonProperty("sources") List sources +) { +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ScheduleEntry.java b/java/src/generated/java/com/github/copilot/generated/rpc/ScheduleEntry.java index fb41975bd..f8d58ad77 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/ScheduleEntry.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ScheduleEntry.java @@ -24,8 +24,14 @@ public record ScheduleEntry( /** Sequential id assigned by the runtime within the session. Stable across resumes (rebuilt from the event log). */ @JsonProperty("id") Long id, - /** Interval between scheduled ticks, in milliseconds. */ + /** Interval between scheduled ticks, in milliseconds (relative-interval schedules). */ @JsonProperty("intervalMs") Long intervalMs, + /** 5-field cron expression for a recurring calendar schedule, evaluated in `tz`. */ + @JsonProperty("cron") String cron, + /** IANA timezone the `cron` expression is evaluated in. */ + @JsonProperty("tz") String tz, + /** Absolute fire time (epoch milliseconds) for a one-shot calendar schedule. */ + @JsonProperty("at") Long at, /** Prompt text that gets enqueued on every tick. */ @JsonProperty("prompt") String prompt, /** Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`). */ diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ServerAgentsApi.java b/java/src/generated/java/com/github/copilot/generated/rpc/ServerAgentsApi.java new file mode 100644 index 000000000..6a73f4cbc --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ServerAgentsApi.java @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.github.copilot.CopilotExperimental; +import java.util.concurrent.CompletableFuture; +import javax.annotation.processing.Generated; + +/** + * API methods for the {@code agents} namespace. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class ServerAgentsApi { + + private final RpcCaller caller; + + /** @param caller the RPC transport function */ + ServerAgentsApi(RpcCaller caller) { + this.caller = caller; + } + + /** + * Optional project paths to include in agent discovery. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture discover(AgentsDiscoverParams params) { + return caller.invoke("agents.discover", params, AgentsDiscoverResult.class); + } + +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ServerInstructionsApi.java b/java/src/generated/java/com/github/copilot/generated/rpc/ServerInstructionsApi.java new file mode 100644 index 000000000..af5ac2719 --- /dev/null +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ServerInstructionsApi.java @@ -0,0 +1,40 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +// AUTO-GENERATED FILE - DO NOT EDIT +// Generated from: api.schema.json + +package com.github.copilot.generated.rpc; + +import com.github.copilot.CopilotExperimental; +import java.util.concurrent.CompletableFuture; +import javax.annotation.processing.Generated; + +/** + * API methods for the {@code instructions} namespace. + * + * @since 1.0.0 + */ +@javax.annotation.processing.Generated("copilot-sdk-codegen") +public final class ServerInstructionsApi { + + private final RpcCaller caller; + + /** @param caller the RPC transport function */ + ServerInstructionsApi(RpcCaller caller) { + this.caller = caller; + } + + /** + * Optional project paths to include in instruction discovery. + * + * @apiNote This method is experimental and may change in a future version. + * @since 1.0.0 + */ + @CopilotExperimental + public CompletableFuture discover(InstructionsDiscoverParams params) { + return caller.invoke("instructions.discover", params, InstructionsDiscoverResult.class); + } + +} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/ServerRpc.java b/java/src/generated/java/com/github/copilot/generated/rpc/ServerRpc.java index 435de1054..f96c87386 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/ServerRpc.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/ServerRpc.java @@ -38,6 +38,10 @@ public final class ServerRpc { public final ServerPluginsApi plugins; /** API methods for the {@code skills} namespace. */ public final ServerSkillsApi skills; + /** API methods for the {@code agents} namespace. */ + public final ServerAgentsApi agents; + /** API methods for the {@code instructions} namespace. */ + public final ServerInstructionsApi instructions; /** API methods for the {@code user} namespace. */ public final ServerUserApi user; /** API methods for the {@code runtime} namespace. */ @@ -63,6 +67,8 @@ public ServerRpc(RpcCaller caller) { this.mcp = new ServerMcpApi(caller); this.plugins = new ServerPluginsApi(caller); this.skills = new ServerSkillsApi(caller); + this.agents = new ServerAgentsApi(caller); + this.instructions = new ServerInstructionsApi(caller); this.user = new ServerUserApi(caller); this.runtime = new ServerRuntimeApi(caller); this.sessionFs = new ServerSessionFsApi(caller); diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/SessionInstructionsGetSourcesResult.java b/java/src/generated/java/com/github/copilot/generated/rpc/SessionInstructionsGetSourcesResult.java index f5275aa54..b798c1d65 100644 --- a/java/src/generated/java/com/github/copilot/generated/rpc/SessionInstructionsGetSourcesResult.java +++ b/java/src/generated/java/com/github/copilot/generated/rpc/SessionInstructionsGetSourcesResult.java @@ -26,6 +26,6 @@ @JsonIgnoreProperties(ignoreUnknown = true) public record SessionInstructionsGetSourcesResult( /** Instruction sources for the session */ - @JsonProperty("sources") List sources + @JsonProperty("sources") List sources ) { } diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json index fa7e47207..2c9823233 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.60", + "@github/copilot": "^1.0.61", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, @@ -697,9 +697,9 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.60.tgz", - "integrity": "sha512-+GjW+GJNo55nwJwt48o9szWcyhuY0u682cBKQI1ay9jVBX8DCCXC6HB6Tyv5/MaM4N7CxTiEgp48aVMkye8K+g==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.61.tgz", + "integrity": "sha512-E4f7YXTL2uUZY/ypnfsUruAeSgrHx3AGYEbm5N0DrpzPqoNAZqV6kHEWM4vu+W/nGvydIfPxmOTqaMEhM8r0Uw==", "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.60", - "@github/copilot-darwin-x64": "1.0.60", - "@github/copilot-linux-arm64": "1.0.60", - "@github/copilot-linux-x64": "1.0.60", - "@github/copilot-linuxmusl-arm64": "1.0.60", - "@github/copilot-linuxmusl-x64": "1.0.60", - "@github/copilot-win32-arm64": "1.0.60", - "@github/copilot-win32-x64": "1.0.60" + "@github/copilot-darwin-arm64": "1.0.61", + "@github/copilot-darwin-x64": "1.0.61", + "@github/copilot-linux-arm64": "1.0.61", + "@github/copilot-linux-x64": "1.0.61", + "@github/copilot-linuxmusl-arm64": "1.0.61", + "@github/copilot-linuxmusl-x64": "1.0.61", + "@github/copilot-win32-arm64": "1.0.61", + "@github/copilot-win32-x64": "1.0.61" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.60.tgz", - "integrity": "sha512-TErNaVxsv+uB3bdHwdoKorCd1rhiRh7HkX48vnS7jwqa8EtGgAkzNrHKC7mruL2rnYOOsNIdPfhzQk+2Y6PSxQ==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.61.tgz", + "integrity": "sha512-10prvjHRXB0SD28NsIpzdNDgLquQYUwaH5Ev9KVdIWdBPAvlQsHmQ4JSCyD/UILc/nrrr02CKUgum+mZRKUKIg==", "cpu": [ "arm64" ], @@ -735,9 +735,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.60.tgz", - "integrity": "sha512-PthhcR6PqbQlT04xQKTElpPSJOrJd65nK/l9Sjmpwtk21RrDKs13DCY/19ubP17updYUWBxp3VNfyfN3DAQKOA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.61.tgz", + "integrity": "sha512-NXUjageJ3mxDfHtXGYu//XhJ+dhJFYObT4R3jeWgIHhd+4lX7FlC754nwlBP/ZuVhJ3ND22JK9sua9d2F3Cbwg==", "cpu": [ "x64" ], @@ -751,9 +751,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.60.tgz", - "integrity": "sha512-AVahkDVQTiGmHvDjlb4CHO8CFEGqmCEipxi0qTA60oH3Y3W2C4aYBwEBtP/85pN3wUUKZJVrWTCcxdufUBuK2Q==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.61.tgz", + "integrity": "sha512-dwB2+QSMr622JkePeK56M7YWXsTT/DQzKfpDq8Lk2kmGU052RZAarRmt8gcNm4anofN7pMSrqc3YHj1TM84MFw==", "cpu": [ "arm64" ], @@ -767,9 +767,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.60.tgz", - "integrity": "sha512-NwQjV2ZyUdJVAO4t7wiT+eR3uNWYP57xaLUIhf6JTMGpsTyN+mAFXW63xpwM/K+Pug62uRDQDBjEeOQRB7qZrA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.61.tgz", + "integrity": "sha512-q6n8R8oybvuCmmkP+43w809Wpud/wwRi/fFSZEYJagiNGmYJ00SDkrfJxHbZsAFMpaJC+oTswqzJHjRoZbO74w==", "cpu": [ "x64" ], @@ -783,9 +783,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.60.tgz", - "integrity": "sha512-AYGPc9vq2k248bVwUbiVJ65kIYYMQQ7ci+S3oefWBIyYtYwAH0n+Q/IGAj49IPrelBarYABAsX+EQZJJC8rhxw==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.61.tgz", + "integrity": "sha512-yWo7JXnZS11eJpm68E1RWKMR47EwzPKj3V7GX0EMTd8Fw0T2Aurk9wt9p3c9w0v02nTO1DqJhi68KVWJPdVqvA==", "cpu": [ "arm64" ], @@ -799,9 +799,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.60.tgz", - "integrity": "sha512-9/F7yl0/9FpGvYR/TCQtbhu0vIaUVem6U7em85QYaEjkS45nK500pByCMWY0bXv2eSS8U2g+8FOAjfkyLlxwPw==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.61.tgz", + "integrity": "sha512-nHzx27Ac4B0fpD9CcmvyrGOBEMJ01CPRgVRP0yAl4wpU4cM2I6+9TPyfYThlWDqZqiUKGXC1ZRQ+B8cJREVGmA==", "cpu": [ "x64" ], @@ -815,9 +815,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.60.tgz", - "integrity": "sha512-ZxxS+Ua1+7Puz80yTOpQ4WS+s32NjrxIsqo8gE0FpuZId16BGOGbWkzWQvR/k2AVBCqpLZ7SK3LfDVKuKJRbpA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.61.tgz", + "integrity": "sha512-k6knzI+K5HlZeJDS/yeJAfoYD4xcURWfuqunpTCyk1pDbIFxmrLSqR/TDi7KNlpsf883n5WqpnB06K5kysdHHQ==", "cpu": [ "arm64" ], @@ -831,9 +831,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.60.tgz", - "integrity": "sha512-e91ZlFz9J1lkadExLg36oN8Ms/xIa03vAEir3DmyCeYebZ+Y48vdS+BwhQEma+GLoxJUOhzHndCckGnMRfNIbA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.61.tgz", + "integrity": "sha512-L6NZ6o73VZFHd7OoRaztV3Prh1PbW9HXqYsAx+XywNALQvE1u489WBUC1ggfYBW5MTBCf8mxSkYQdb3Am2omsw==", "cpu": [ "x64" ], diff --git a/nodejs/package.json b/nodejs/package.json index 95e626d35..df34b9df7 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -56,7 +56,7 @@ "author": "GitHub", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.60", + "@github/copilot": "^1.0.61", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/samples/package-lock.json b/nodejs/samples/package-lock.json index e82d971ad..d80779f81 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.60", + "@github/copilot": "^1.0.61", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts index 53aa71fd2..c17a21d21 100644 --- a/nodejs/src/generated/rpc.ts +++ b/nodejs/src/generated/rpc.ts @@ -423,10 +423,10 @@ export type InstalledPluginSource = * Category of instruction source — used for merge logic * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "InstructionsSourcesType". + * via the `definition` "InstructionSourceType". */ /** @experimental */ -export type InstructionsSourcesType = +export type InstructionSourceType = /** Instructions loaded from the user's home configuration. */ | "home" /** Instructions loaded from repository-scoped files. */ @@ -445,10 +445,10 @@ export type InstructionsSourcesType = * Where this source lives — used for UI grouping * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "InstructionsSourcesLocation". + * via the `definition` "InstructionSourceLocation". */ /** @experimental */ -export type InstructionsSourcesLocation = +export type InstructionSourceLocation = /** Instructions live in user-level configuration. */ | "user" /** Instructions live in repository-level configuration. */ @@ -2011,6 +2011,23 @@ export interface AgentReloadResult { */ agents: AgentInfo[]; } +/** + * Optional project paths to include in agent discovery. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "AgentsDiscoverRequest". + */ +/** @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[]; + /** + * When true, omit the host's agents (the `/agents` directory and all plugin agents), leaving only project and remote agents. For multitenant deployments. + */ + excludeHostAgents?: boolean; +} /** * Name of the custom agent to select for subsequent turns. * @@ -3964,6 +3981,23 @@ export interface InstalledPluginInfo { */ enabled: boolean; } +/** + * Optional project paths to include in instruction discovery. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "InstructionsDiscoverRequest". + */ +/** @experimental */ +export interface InstructionsDiscoverRequest { + /** + * 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). + */ + projectPaths?: string[]; + /** + * 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. + */ + excludeHostInstructions?: boolean; +} /** * Instruction sources loaded for the session, in merge order. * @@ -3975,16 +4009,16 @@ export interface InstructionsGetSourcesResult { /** * Instruction sources for the session */ - sources: InstructionsSources[]; + sources: InstructionSource[]; } /** - * Schema for the `InstructionsSources` type. + * Schema for the `InstructionSource` type. * * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema - * via the `definition` "InstructionsSources". + * via the `definition` "InstructionSource". */ /** @experimental */ -export interface InstructionsSources { +export interface InstructionSource { /** * Unique identifier for this source (used for toggling) */ @@ -4001,8 +4035,8 @@ export interface InstructionsSources { * Raw content of the instruction file */ content: string; - type: InstructionsSourcesType; - location: InstructionsSourcesLocation; + type: InstructionSourceType; + location: InstructionSourceLocation; /** * Glob pattern(s) from frontmatter — when set, this instruction applies only to matching files */ @@ -4015,6 +4049,10 @@ export interface InstructionsSources { * When true, this source starts disabled and must be toggled on by the user */ defaultDisabled?: boolean; + /** + * 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. + */ + projectPath?: string; } /** * Schema for the `LocalSessionMetadataValue` type. @@ -8553,9 +8591,21 @@ export interface ScheduleEntry { */ id: number; /** - * Interval between scheduled ticks, in milliseconds. + * Interval between scheduled ticks, in milliseconds (relative-interval schedules). + */ + intervalMs?: number; + /** + * 5-field cron expression for a recurring calendar schedule, evaluated in `tz`. + */ + cron?: string; + /** + * IANA timezone the `cron` expression is evaluated in. + */ + tz?: string; + /** + * Absolute fire time (epoch milliseconds) for a one-shot calendar schedule. */ - intervalMs: number; + at?: number; /** * Prompt text that gets enqueued on every tick. */ @@ -8722,6 +8772,32 @@ export interface SendResult { */ messageId: string; } +/** + * Agents discovered across user, project, plugin, and remote sources. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "ServerAgentList". + */ +/** @experimental */ +export interface ServerAgentList { + /** + * All discovered agents across all sources + */ + agents: AgentInfo[]; +} +/** + * Instruction sources discovered across user, repository, and plugin sources. + * + * This interface was referenced by `_RpcSchemaRoot`'s JSON-Schema + * via the `definition` "ServerInstructionSourceList". + */ +/** @experimental */ +export interface ServerInstructionSourceList { + /** + * All discovered instruction sources + */ + sources: InstructionSource[]; +} /** * Schema for the `ServerSkill` type. * @@ -11112,9 +11188,13 @@ export interface TaskAgentInfo { */ result?: string; /** - * Model used for the task when specified + * Requested model override for the task when specified */ model?: string; + /** + * Runtime model resolved for the task when available + */ + resolvedModel?: string; executionMode?: TaskExecutionMode; /** * Whether the task is currently in the original sync wait and can be moved to background mode. False once it is already backgrounded, idle, finished, or no longer has a promotable sync waiter. @@ -12838,6 +12918,30 @@ export function createServerRpc(connection: MessageConnection) { discover: async (params: SkillsDiscoverRequest): Promise => connection.sendRequest("skills.discover", params), }, + /** @experimental */ + agents: { + /** + * Discovers custom agents across user, project, plugin, and remote sources. + * + * @param params Optional project paths to include in agent discovery. + * + * @returns Agents discovered across user, project, plugin, and remote sources. + */ + discover: async (params: AgentsDiscoverRequest): Promise => + connection.sendRequest("agents.discover", params), + }, + /** @experimental */ + instructions: { + /** + * Discovers instruction sources across user, repository, and plugin sources. + * + * @param params Optional project paths to include in instruction discovery. + * + * @returns Instruction sources discovered across user, repository, and plugin sources. + */ + discover: async (params: InstructionsDiscoverRequest): Promise => + connection.sendRequest("instructions.discover", params), + }, user: { settings: { /** @@ -13673,15 +13777,6 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin */ reload: async (): Promise => connection.sendRequest("session.mcp.reload", { sessionId }), - /** - * Reloads MCP server connections for the session with an explicit host-provided configuration. - * - * @param params Opaque MCP reload configuration. - * - * @returns MCP server startup filtering result. - */ - reloadWithConfig: async (params: McpReloadWithConfigRequest): Promise => - connection.sendRequest("session.mcp.reloadWithConfig", { sessionId, ...params }), /** * Runs an MCP sampling inference on behalf of an MCP server. * @@ -13716,29 +13811,6 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin */ removeGitHub: async (): Promise => connection.sendRequest("session.mcp.removeGitHub", { sessionId }), - /** - * Configures the built-in GitHub MCP server for the session's current auth context. - * - * @param params Opaque auth info used to configure GitHub MCP. - * - * @returns Result of configuring GitHub MCP. - */ - configureGitHub: async (params: McpConfigureGitHubRequest): Promise => - connection.sendRequest("session.mcp.configureGitHub", { sessionId, ...params }), - /** - * Starts an individual MCP server on the session's host. - * - * @param params Server name and opaque configuration for an individual MCP server start. - */ - startServer: async (params: McpStartServerRequest): Promise => - connection.sendRequest("session.mcp.startServer", { sessionId, ...params }), - /** - * Restarts an individual MCP server on the session's host (stops then starts). - * - * @param params Server name and opaque configuration for an individual MCP server restart. - */ - restartServer: async (params: McpRestartServerRequest): Promise => - connection.sendRequest("session.mcp.restartServer", { sessionId, ...params }), /** * Stops an individual MCP server on the session's host. * @@ -13746,20 +13818,6 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin */ stopServer: async (params: McpStopServerRequest): Promise => connection.sendRequest("session.mcp.stopServer", { sessionId, ...params }), - /** - * Registers a pre-connected external MCP client (e.g. IDE) on the session's host. The caller retains lifecycle ownership of the client and transport. Marked internal because the `client` and `transport` arguments are in-process MCP SDK instances that cannot be serialized across the JSON-RPC boundary; once the CLI moves on top of the SDK, external clients will be expressed as transport configs the runtime can construct itself. - * - * @param params Registration parameters for an external MCP client. - */ - registerExternalClient: async (params: McpRegisterExternalClientRequest): Promise => - connection.sendRequest("session.mcp.registerExternalClient", { sessionId, ...params }), - /** - * Unregisters a previously registered external MCP client by server name. Marked internal as the paired companion of `registerExternalClient`: only in-process callers that registered a client this way can meaningfully unregister it. Disappears alongside `registerExternalClient`: once external clients are described to the runtime as config rather than handed in as instances, lifecycle (including deregistration) is owned entirely by the runtime. - * - * @param params Server name identifying the external client to remove. - */ - unregisterExternalClient: async (params: McpUnregisterExternalClientRequest): Promise => - connection.sendRequest("session.mcp.unregisterExternalClient", { sessionId, ...params }), /** * Checks whether a named MCP server is currently running on the session's host. * @@ -13771,15 +13829,6 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin connection.sendRequest("session.mcp.isServerRunning", { sessionId, ...params }), /** @experimental */ oauth: { - /** - * Responds to a pending MCP OAuth provider request. Marked internal because the `provider` argument is an in-process OAuthClientProvider instance that cannot be carried over the wire; the public OAuth surface will route the response through a wire-clean handshake once the CLI moves on top of the SDK. - * - * @param params MCP OAuth request id and optional provider response. - * - * @returns Empty result after recording the MCP OAuth response. - */ - respond: async (params: McpOauthRespondRequest): Promise => - connection.sendRequest("session.mcp.oauth.respond", { sessionId, ...params }), /** * Starts OAuth authentication for a remote MCP server. * @@ -14566,6 +14615,77 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin }; } +/** + * Create typed session-scoped RPC methods that are part of the SDK's internal + * surface. Not exported on the public client API. + * @internal + */ +export function createInternalSessionRpc(connection: MessageConnection, sessionId: string) { + return { + /** @experimental */ + mcp: { + /** + * Reloads MCP server connections for the session with an explicit host-provided configuration. + * + * @param params Opaque MCP reload configuration. + * + * @returns MCP server startup filtering result. + */ + reloadWithConfig: async (params: McpReloadWithConfigRequest): Promise => + connection.sendRequest("session.mcp.reloadWithConfig", { sessionId, ...params }), + /** + * Configures the built-in GitHub MCP server for the session's current auth context. + * + * @param params Opaque auth info used to configure GitHub MCP. + * + * @returns Result of configuring GitHub MCP. + */ + configureGitHub: async (params: McpConfigureGitHubRequest): Promise => + connection.sendRequest("session.mcp.configureGitHub", { sessionId, ...params }), + /** + * Starts an individual MCP server on the session's host. + * + * @param params Server name and opaque configuration for an individual MCP server start. + */ + startServer: async (params: McpStartServerRequest): Promise => + connection.sendRequest("session.mcp.startServer", { sessionId, ...params }), + /** + * Restarts an individual MCP server on the session's host (stops then starts). + * + * @param params Server name and opaque configuration for an individual MCP server restart. + */ + restartServer: async (params: McpRestartServerRequest): Promise => + connection.sendRequest("session.mcp.restartServer", { sessionId, ...params }), + /** + * Registers a pre-connected external MCP client (e.g. IDE) on the session's host. The caller retains lifecycle ownership of the client and transport. Marked internal because the `client` and `transport` arguments are in-process MCP SDK instances that cannot be serialized across the JSON-RPC boundary; once the CLI moves on top of the SDK, external clients will be expressed as transport configs the runtime can construct itself. + * + * @param params Registration parameters for an external MCP client. + */ + registerExternalClient: async (params: McpRegisterExternalClientRequest): Promise => + connection.sendRequest("session.mcp.registerExternalClient", { sessionId, ...params }), + /** + * Unregisters a previously registered external MCP client by server name. Marked internal as the paired companion of `registerExternalClient`: only in-process callers that registered a client this way can meaningfully unregister it. Disappears alongside `registerExternalClient`: once external clients are described to the runtime as config rather than handed in as instances, lifecycle (including deregistration) is owned entirely by the runtime. + * + * @param params Server name identifying the external client to remove. + */ + unregisterExternalClient: async (params: McpUnregisterExternalClientRequest): Promise => + connection.sendRequest("session.mcp.unregisterExternalClient", { sessionId, ...params }), + /** @experimental */ + oauth: { + /** + * Responds to a pending MCP OAuth provider request. Marked internal because the `provider` argument is an in-process OAuthClientProvider instance that cannot be carried over the wire; the public OAuth surface will route the response through a wire-clean handshake once the CLI moves on top of the SDK. + * + * @param params MCP OAuth request id and optional provider response. + * + * @returns Empty result after recording the MCP OAuth response. + */ + respond: async (params: McpOauthRespondRequest): Promise => + connection.sendRequest("session.mcp.oauth.respond", { sessionId, ...params }), + }, + }, + }; +} + /** Handler for `sessionFs` client session API methods. */ /** @experimental */ export interface SessionFsHandler { diff --git a/nodejs/src/generated/session-events.ts b/nodejs/src/generated/session-events.ts index 77a354cb6..a4fba8f33 100644 --- a/nodejs/src/generated/session-events.ts +++ b/nodejs/src/generated/session-events.ts @@ -715,6 +715,10 @@ export interface ResumeData { * Total number of persisted events in the session at the time of resume */ eventCount: number; + /** + * On-disk byte size of the session's persisted events.jsonl file at resume time; omitted when the file does not exist or cannot be stat'd + */ + eventsFileSizeBytes?: number; /** * Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max") */ @@ -959,6 +963,14 @@ export interface ScheduleCreatedEvent { * Scheduled prompt registered via /every or /after */ export interface ScheduleCreatedData { + /** + * Absolute fire time (epoch milliseconds) for a one-shot calendar schedule + */ + at?: number; + /** + * 5-field cron expression for a recurring calendar schedule, evaluated in `tz` + */ + cron?: string; /** * Optional user-facing label shown in the timeline instead of the actual prompt (e.g. `/skill-name args` when the prompt is a skill invocation expansion) */ @@ -968,9 +980,9 @@ export interface ScheduleCreatedData { */ id: number; /** - * Interval between ticks in milliseconds + * Interval between ticks in milliseconds (relative-interval schedules) */ - intervalMs: number; + intervalMs?: number; /** * Prompt text that gets enqueued on every tick */ @@ -979,6 +991,10 @@ export interface ScheduleCreatedData { * Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`) */ recurring?: boolean; + /** + * IANA timezone the `cron` expression is evaluated in + */ + tz?: string; } /** * Session event "session.schedule_cancelled". Scheduled prompt cancelled from the schedule manager dialog @@ -1610,6 +1626,10 @@ export interface ShutdownData { * Error description when shutdownType is "error" */ errorReason?: string; + /** + * On-disk byte size of the session's persisted events.jsonl file at shutdown time; omitted when the file does not exist or cannot be stat'd + */ + eventsFileSizeBytes?: number; /** * Per-model usage breakdown, keyed by model identifier */ @@ -4271,6 +4291,10 @@ export interface HookProgressData { * Human-readable progress message from the hook process */ message: string; + /** + * When true, this status message replaces the previous temporary one instead of accumulating + */ + temporary?: boolean; } /** * Session event "system.message". System/developer instruction content with role and optional template metadata diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py index 0f2a57069..69bf16007 100644 --- a/python/copilot/generated/rpc.py +++ b/python/copilot/generated/rpc.py @@ -314,6 +314,35 @@ def to_dict(self) -> dict: result["name"] = from_str(self.name) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class AgentsDiscoverRequest: + """Optional project paths to include in agent discovery.""" + + exclude_host_agents: bool | None = None + """When true, omit the host's agents (the `/agents` directory and all plugin + agents), leaving only project and remote agents. For multitenant deployments. + """ + project_paths: list[str] | None = None + """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). + """ + + @staticmethod + def from_dict(obj: Any) -> 'AgentsDiscoverRequest': + assert isinstance(obj, dict) + exclude_host_agents = from_union([from_bool, from_none], obj.get("excludeHostAgents")) + project_paths = from_union([lambda x: from_list(from_str, x), from_none], obj.get("projectPaths")) + return AgentsDiscoverRequest(exclude_host_agents, project_paths) + + def to_dict(self) -> dict: + result: dict = {} + if self.exclude_host_agents is not None: + result["excludeHostAgents"] = from_union([from_bool, from_none], self.exclude_host_agents) + if self.project_paths is not None: + result["projectPaths"] = from_union([lambda x: from_list(from_str, x), from_none], self.project_paths) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class AllowAllPermissionSetResult: @@ -1706,7 +1735,7 @@ class StickySource(Enum): URL = "url" # Experimental: this type is part of an experimental API and may change or be removed. -class InstructionsSourcesLocation(Enum): +class InstructionSourceLocation(Enum): """Where this source lives — used for UI grouping""" PLUGIN = "plugin" @@ -1715,7 +1744,7 @@ class InstructionsSourcesLocation(Enum): WORKING_DIRECTORY = "working-directory" # Experimental: this type is part of an experimental API and may change or be removed. -class InstructionsSourcesType(Enum): +class InstructionSourceType(Enum): """Category of instruction source — used for merge logic""" CHILD_INSTRUCTIONS = "child-instructions" @@ -1726,6 +1755,36 @@ class InstructionsSourcesType(Enum): REPO = "repo" VSCODE = "vscode" +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class InstructionsDiscoverRequest: + """Optional project paths to include in instruction discovery.""" + + exclude_host_instructions: bool | None = None + """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. + """ + project_paths: list[str] | None = None + """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). + """ + + @staticmethod + def from_dict(obj: Any) -> 'InstructionsDiscoverRequest': + assert isinstance(obj, dict) + exclude_host_instructions = from_union([from_bool, from_none], obj.get("excludeHostInstructions")) + project_paths = from_union([lambda x: from_list(from_str, x), from_none], obj.get("projectPaths")) + return InstructionsDiscoverRequest(exclude_host_instructions, project_paths) + + def to_dict(self) -> dict: + result: dict = {} + if self.exclude_host_instructions is not None: + result["excludeHostInstructions"] = from_union([from_bool, from_none], self.exclude_host_instructions) + if self.project_paths is not None: + result["projectPaths"] = from_union([lambda x: from_list(from_str, x), from_none], self.project_paths) + return result + # Experimental: this type is part of an experimental API and may change or be removed. class HostType(Enum): """Repository host type @@ -5172,9 +5231,6 @@ class ScheduleEntry: """Sequential id assigned by the runtime within the session. Stable across resumes (rebuilt from the event log). """ - interval_ms: int - """Interval between scheduled ticks, in milliseconds.""" - next_run_at: datetime """ISO 8601 timestamp when the next tick is scheduled to fire.""" @@ -5184,31 +5240,52 @@ class ScheduleEntry: recurring: bool """Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`).""" + at: int | None = None + """Absolute fire time (epoch milliseconds) for a one-shot calendar schedule.""" + + cron: str | None = None + """5-field cron expression for a recurring calendar schedule, evaluated in `tz`.""" + display_prompt: str | None = None """Display-only label for the prompt as shown in the UI (e.g. `/skill-name` for a skill-invocation schedule). The actual enqueued prompt is `prompt`. """ + interval_ms: int | None = None + """Interval between scheduled ticks, in milliseconds (relative-interval schedules).""" + + tz: str | None = None + """IANA timezone the `cron` expression is evaluated in.""" @staticmethod def from_dict(obj: Any) -> 'ScheduleEntry': assert isinstance(obj, dict) id = from_int(obj.get("id")) - interval_ms = from_int(obj.get("intervalMs")) next_run_at = from_datetime(obj.get("nextRunAt")) prompt = from_str(obj.get("prompt")) recurring = from_bool(obj.get("recurring")) + at = from_union([from_int, from_none], obj.get("at")) + cron = from_union([from_str, from_none], obj.get("cron")) display_prompt = from_union([from_str, from_none], obj.get("displayPrompt")) - return ScheduleEntry(id, interval_ms, next_run_at, prompt, recurring, display_prompt) + interval_ms = from_union([from_int, from_none], obj.get("intervalMs")) + tz = from_union([from_str, from_none], obj.get("tz")) + return ScheduleEntry(id, next_run_at, prompt, recurring, at, cron, display_prompt, interval_ms, tz) def to_dict(self) -> dict: result: dict = {} result["id"] = from_int(self.id) - result["intervalMs"] = from_int(self.interval_ms) result["nextRunAt"] = self.next_run_at.isoformat() result["prompt"] = from_str(self.prompt) result["recurring"] = from_bool(self.recurring) + if self.at is not None: + result["at"] = from_union([from_int, from_none], self.at) + if self.cron is not None: + result["cron"] = from_union([from_str, from_none], self.cron) if self.display_prompt is not None: result["displayPrompt"] = from_union([from_str, from_none], self.display_prompt) + if self.interval_ms is not None: + result["intervalMs"] = from_union([from_int, from_none], self.interval_ms) + if self.tz is not None: + result["tz"] = from_union([from_str, from_none], self.tz) return result # Experimental: this type is part of an experimental API and may change or be removed. @@ -9585,8 +9662,8 @@ def to_dict(self) -> dict: # Experimental: this type is part of an experimental API and may change or be removed. @dataclass -class InstructionsSources: - """Schema for the `InstructionsSources` type.""" +class InstructionSource: + """Schema for the `InstructionSource` type.""" content: str """Raw content of the instruction file""" @@ -9597,13 +9674,13 @@ class InstructionsSources: label: str """Human-readable label""" - location: InstructionsSourcesLocation + location: InstructionSourceLocation """Where this source lives — used for UI grouping""" source_path: str """File path relative to repo or absolute for home""" - type: InstructionsSourcesType + type: InstructionSourceType """Category of instruction source — used for merge logic""" apply_to: list[str] | None = None @@ -9616,34 +9693,44 @@ class InstructionsSources: description: str | None = None """Short description (body after frontmatter) for use in instruction tables""" + project_path: str | None = None + """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. + """ + @staticmethod - def from_dict(obj: Any) -> 'InstructionsSources': + def from_dict(obj: Any) -> 'InstructionSource': assert isinstance(obj, dict) content = from_str(obj.get("content")) id = from_str(obj.get("id")) label = from_str(obj.get("label")) - location = InstructionsSourcesLocation(obj.get("location")) + location = InstructionSourceLocation(obj.get("location")) source_path = from_str(obj.get("sourcePath")) - type = InstructionsSourcesType(obj.get("type")) + type = InstructionSourceType(obj.get("type")) apply_to = from_union([lambda x: from_list(from_str, x), from_none], obj.get("applyTo")) default_disabled = from_union([from_bool, from_none], obj.get("defaultDisabled")) description = from_union([from_str, from_none], obj.get("description")) - return InstructionsSources(content, id, label, location, source_path, type, apply_to, default_disabled, description) + project_path = from_union([from_str, from_none], obj.get("projectPath")) + return InstructionSource(content, id, label, location, source_path, type, apply_to, default_disabled, description, project_path) def to_dict(self) -> dict: result: dict = {} result["content"] = from_str(self.content) result["id"] = from_str(self.id) result["label"] = from_str(self.label) - result["location"] = to_enum(InstructionsSourcesLocation, self.location) + result["location"] = to_enum(InstructionSourceLocation, self.location) result["sourcePath"] = from_str(self.source_path) - result["type"] = to_enum(InstructionsSourcesType, self.type) + result["type"] = to_enum(InstructionSourceType, self.type) if self.apply_to is not None: result["applyTo"] = from_union([lambda x: from_list(from_str, x), from_none], self.apply_to) if self.default_disabled is not None: result["defaultDisabled"] = from_union([from_bool, from_none], self.default_disabled) if self.description is not None: result["description"] = from_union([from_str, from_none], self.description) + if self.project_path is not None: + result["projectPath"] = from_union([from_str, from_none], self.project_path) return result # Experimental: this type is part of an experimental API and may change or be removed. @@ -13519,6 +13606,128 @@ def to_dict(self) -> dict: result["locationKey"] = from_str(self.location_key) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class TaskAgentInfo: + """Schema for the `TaskAgentInfo` type.""" + + agent_type: str + """Type of agent running this task""" + + description: str + """Short description of the task""" + + id: str + """Unique task identifier""" + + prompt: str + """Most recent prompt delivered to the agent. Updated whenever the agent receives a + follow-up message. + """ + started_at: datetime + """ISO 8601 timestamp when the task was started""" + + status: TaskStatus + """Current lifecycle status of the task""" + + tool_call_id: str + """Tool call ID associated with this agent task""" + + type: ClassVar[str] = "agent" + """Task kind""" + + active_started_at: datetime | None = None + """ISO 8601 timestamp when the current active period began""" + + active_time_ms: int | None = None + """Accumulated active execution time in milliseconds""" + + can_promote_to_background: bool | None = None + """Whether the task is currently in the original sync wait and can be moved to background + mode. False once it is already backgrounded, idle, finished, or no longer has a + promotable sync waiter. + """ + completed_at: datetime | None = None + """ISO 8601 timestamp when the task finished""" + + error: str | None = None + """Error message when the task failed""" + + execution_mode: TaskExecutionMode | None = None + """Whether task execution is synchronously awaited or managed in the background""" + + idle_since: datetime | None = None + """ISO 8601 timestamp when the agent entered idle state""" + + latest_response: str | None = None + """Most recent response text from the agent""" + + model: str | None = None + """Requested model override for the task when specified""" + + resolved_model: str | None = None + """Runtime model resolved for the task when available""" + + result: str | None = None + """Result text from the task when available""" + + @staticmethod + def from_dict(obj: Any) -> 'TaskAgentInfo': + assert isinstance(obj, dict) + agent_type = from_str(obj.get("agentType")) + description = from_str(obj.get("description")) + id = from_str(obj.get("id")) + prompt = from_str(obj.get("prompt")) + started_at = from_datetime(obj.get("startedAt")) + status = TaskStatus(obj.get("status")) + tool_call_id = from_str(obj.get("toolCallId")) + active_started_at = from_union([from_datetime, from_none], obj.get("activeStartedAt")) + active_time_ms = from_union([from_int, from_none], obj.get("activeTimeMs")) + can_promote_to_background = from_union([from_bool, from_none], obj.get("canPromoteToBackground")) + completed_at = from_union([from_datetime, from_none], obj.get("completedAt")) + error = from_union([from_str, from_none], obj.get("error")) + execution_mode = from_union([TaskExecutionMode, from_none], obj.get("executionMode")) + idle_since = from_union([from_datetime, from_none], obj.get("idleSince")) + latest_response = from_union([from_str, from_none], obj.get("latestResponse")) + model = from_union([from_str, from_none], obj.get("model")) + resolved_model = from_union([from_str, from_none], obj.get("resolvedModel")) + result = from_union([from_str, from_none], obj.get("result")) + return TaskAgentInfo(agent_type, description, id, prompt, started_at, status, tool_call_id, active_started_at, active_time_ms, can_promote_to_background, completed_at, error, execution_mode, idle_since, latest_response, model, resolved_model, result) + + def to_dict(self) -> dict: + result: dict = {} + result["agentType"] = from_str(self.agent_type) + result["description"] = from_str(self.description) + result["id"] = from_str(self.id) + result["prompt"] = from_str(self.prompt) + result["startedAt"] = self.started_at.isoformat() + result["status"] = to_enum(TaskStatus, self.status) + result["toolCallId"] = from_str(self.tool_call_id) + result["type"] = self.type + if self.active_started_at is not None: + result["activeStartedAt"] = from_union([lambda x: x.isoformat(), from_none], self.active_started_at) + if self.active_time_ms is not None: + result["activeTimeMs"] = from_union([from_int, from_none], self.active_time_ms) + if self.can_promote_to_background is not None: + result["canPromoteToBackground"] = from_union([from_bool, from_none], self.can_promote_to_background) + if self.completed_at is not None: + result["completedAt"] = from_union([lambda x: x.isoformat(), from_none], self.completed_at) + if self.error is not None: + result["error"] = from_union([from_str, from_none], self.error) + if self.execution_mode is not None: + result["executionMode"] = from_union([lambda x: to_enum(TaskExecutionMode, x), from_none], self.execution_mode) + if self.idle_since is not None: + result["idleSince"] = from_union([lambda x: x.isoformat(), from_none], self.idle_since) + if self.latest_response is not None: + result["latestResponse"] = from_union([from_str, from_none], self.latest_response) + if self.model is not None: + result["model"] = from_union([from_str, from_none], self.model) + if self.resolved_model is not None: + result["resolvedModel"] = from_union([from_str, from_none], self.resolved_model) + if self.result is not None: + result["result"] = from_union([from_str, from_none], self.result) + return result + @dataclass class ToolList: """Built-in tools available for the requested model, with their parameters and instructions.""" @@ -14707,18 +14916,37 @@ def to_dict(self) -> dict: class InstructionsGetSourcesResult: """Instruction sources loaded for the session, in merge order.""" - sources: list[InstructionsSources] + sources: list[InstructionSource] """Instruction sources for the session""" @staticmethod def from_dict(obj: Any) -> 'InstructionsGetSourcesResult': assert isinstance(obj, dict) - sources = from_list(InstructionsSources.from_dict, obj.get("sources")) + sources = from_list(InstructionSource.from_dict, obj.get("sources")) return InstructionsGetSourcesResult(sources) def to_dict(self) -> dict: result: dict = {} - result["sources"] = from_list(lambda x: to_class(InstructionsSources, x), self.sources) + result["sources"] = from_list(lambda x: to_class(InstructionSource, x), self.sources) + return result + +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class ServerInstructionSourceList: + """Instruction sources discovered across user, repository, and plugin sources.""" + + sources: list[InstructionSource] + """All discovered instruction sources""" + + @staticmethod + def from_dict(obj: Any) -> 'ServerInstructionSourceList': + assert isinstance(obj, dict) + sources = from_list(InstructionSource.from_dict, obj.get("sources")) + return ServerInstructionSourceList(sources) + + def to_dict(self) -> dict: + result: dict = {} + result["sources"] = from_list(lambda x: to_class(InstructionSource, x), self.sources) return result # Experimental: this type is part of an experimental API and may change or be removed. @@ -15867,6 +16095,25 @@ def to_dict(self) -> dict: result["agent"] = to_class(AgentInfo, self.agent) return result +# Experimental: this type is part of an experimental API and may change or be removed. +@dataclass +class ServerAgentList: + """Agents discovered across user, project, plugin, and remote sources.""" + + agents: list[AgentInfo] + """All discovered agents across all sources""" + + @staticmethod + def from_dict(obj: Any) -> 'ServerAgentList': + assert isinstance(obj, dict) + agents = from_list(AgentInfo.from_dict, obj.get("agents")) + return ServerAgentList(agents) + + def to_dict(self) -> dict: + result: dict = {} + result["agents"] = from_list(lambda x: to_class(AgentInfo, x), self.agents) + return result + # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class TaskProgress: @@ -18975,122 +19222,6 @@ def to_dict(self) -> dict: result["taskType"] = from_union([lambda x: to_enum(TaskType, x), from_none], self.task_type) return result -# Experimental: this type is part of an experimental API and may change or be removed. -@dataclass -class TaskAgentInfo: - """Schema for the `TaskAgentInfo` type.""" - - agent_type: str - """Type of agent running this task""" - - description: str - """Short description of the task""" - - id: str - """Unique task identifier""" - - prompt: str - """Most recent prompt delivered to the agent. Updated whenever the agent receives a - follow-up message. - """ - started_at: datetime - """ISO 8601 timestamp when the task was started""" - - status: TaskStatus - """Current lifecycle status of the task""" - - tool_call_id: str - """Tool call ID associated with this agent task""" - - type: ClassVar[str] = "agent" - """Task kind""" - - active_started_at: datetime | None = None - """ISO 8601 timestamp when the current active period began""" - - active_time_ms: int | None = None - """Accumulated active execution time in milliseconds""" - - can_promote_to_background: bool | None = None - """Whether the task is currently in the original sync wait and can be moved to background - mode. False once it is already backgrounded, idle, finished, or no longer has a - promotable sync waiter. - """ - completed_at: datetime | None = None - """ISO 8601 timestamp when the task finished""" - - error: str | None = None - """Error message when the task failed""" - - execution_mode: TaskExecutionMode | None = None - """Whether task execution is synchronously awaited or managed in the background""" - - idle_since: datetime | None = None - """ISO 8601 timestamp when the agent entered idle state""" - - latest_response: str | None = None - """Most recent response text from the agent""" - - model: str | None = None - """Model used for the task when specified""" - - result: str | None = None - """Result text from the task when available""" - - @staticmethod - def from_dict(obj: Any) -> 'TaskAgentInfo': - assert isinstance(obj, dict) - agent_type = from_str(obj.get("agentType")) - description = from_str(obj.get("description")) - id = from_str(obj.get("id")) - prompt = from_str(obj.get("prompt")) - started_at = from_datetime(obj.get("startedAt")) - status = TaskStatus(obj.get("status")) - tool_call_id = from_str(obj.get("toolCallId")) - active_started_at = from_union([from_datetime, from_none], obj.get("activeStartedAt")) - active_time_ms = from_union([from_int, from_none], obj.get("activeTimeMs")) - can_promote_to_background = from_union([from_bool, from_none], obj.get("canPromoteToBackground")) - completed_at = from_union([from_datetime, from_none], obj.get("completedAt")) - error = from_union([from_str, from_none], obj.get("error")) - execution_mode = from_union([TaskExecutionMode, from_none], obj.get("executionMode")) - idle_since = from_union([from_datetime, from_none], obj.get("idleSince")) - latest_response = from_union([from_str, from_none], obj.get("latestResponse")) - model = from_union([from_str, from_none], obj.get("model")) - result = from_union([from_str, from_none], obj.get("result")) - return TaskAgentInfo(agent_type, description, id, prompt, started_at, status, tool_call_id, active_started_at, active_time_ms, can_promote_to_background, completed_at, error, execution_mode, idle_since, latest_response, model, result) - - def to_dict(self) -> dict: - result: dict = {} - result["agentType"] = from_str(self.agent_type) - result["description"] = from_str(self.description) - result["id"] = from_str(self.id) - result["prompt"] = from_str(self.prompt) - result["startedAt"] = self.started_at.isoformat() - result["status"] = to_enum(TaskStatus, self.status) - result["toolCallId"] = from_str(self.tool_call_id) - result["type"] = self.type - if self.active_started_at is not None: - result["activeStartedAt"] = from_union([lambda x: x.isoformat(), from_none], self.active_started_at) - if self.active_time_ms is not None: - result["activeTimeMs"] = from_union([from_int, from_none], self.active_time_ms) - if self.can_promote_to_background is not None: - result["canPromoteToBackground"] = from_union([from_bool, from_none], self.can_promote_to_background) - if self.completed_at is not None: - result["completedAt"] = from_union([lambda x: x.isoformat(), from_none], self.completed_at) - if self.error is not None: - result["error"] = from_union([from_str, from_none], self.error) - if self.execution_mode is not None: - result["executionMode"] = from_union([lambda x: to_enum(TaskExecutionMode, x), from_none], self.execution_mode) - if self.idle_since is not None: - result["idleSince"] = from_union([lambda x: x.isoformat(), from_none], self.idle_since) - if self.latest_response is not None: - result["latestResponse"] = from_union([from_str, from_none], self.latest_response) - if self.model is not None: - result["model"] = from_union([from_str, from_none], self.model) - if self.result is not None: - result["result"] = from_union([from_str, from_none], self.result) - return result - # Experimental: this type is part of an experimental API and may change or be removed. @dataclass class ToolsGetCurrentMetadataResult: @@ -19176,6 +19307,7 @@ class RPC: agent_registry_spawn_validation_error_field: AgentRegistrySpawnValidationErrorField agent_registry_spawn_validation_error_reason: AgentRegistrySpawnValidationErrorReason agent_reload_result: AgentReloadResult + agents_discover_request: AgentsDiscoverRequest agent_select_request: AgentSelectRequest agent_select_result: AgentSelectResult allow_all_permission_set_result: AllowAllPermissionSetResult @@ -19284,10 +19416,11 @@ class RPC: installed_plugin_source_git_hub: InstalledPluginSourceGitHub installed_plugin_source_local: InstalledPluginSourceLocal installed_plugin_source_url: InstalledPluginSourceURL + instructions_discover_request: InstructionsDiscoverRequest instructions_get_sources_result: InstructionsGetSourcesResult - instructions_sources: InstructionsSources - instructions_sources_location: InstructionsSourcesLocation - instructions_sources_type: InstructionsSourcesType + instruction_source: InstructionSource + instruction_source_location: InstructionSourceLocation + instruction_source_type: InstructionSourceType local_session_metadata_value: LocalSessionMetadataValue log_request: LogRequest log_result: LogResult @@ -19608,6 +19741,8 @@ class RPC: send_mode: SendMode send_request: SendRequest send_result: SendResult + server_agent_list: ServerAgentList + server_instruction_source_list: ServerInstructionSourceList server_skill: ServerSkill server_skill_list: ServerSkillList session_activity: SessionActivity @@ -19885,6 +20020,7 @@ def from_dict(obj: Any) -> 'RPC': agent_registry_spawn_validation_error_field = AgentRegistrySpawnValidationErrorField(obj.get("AgentRegistrySpawnValidationErrorField")) agent_registry_spawn_validation_error_reason = AgentRegistrySpawnValidationErrorReason(obj.get("AgentRegistrySpawnValidationErrorReason")) agent_reload_result = AgentReloadResult.from_dict(obj.get("AgentReloadResult")) + agents_discover_request = AgentsDiscoverRequest.from_dict(obj.get("AgentsDiscoverRequest")) agent_select_request = AgentSelectRequest.from_dict(obj.get("AgentSelectRequest")) agent_select_result = AgentSelectResult.from_dict(obj.get("AgentSelectResult")) allow_all_permission_set_result = AllowAllPermissionSetResult.from_dict(obj.get("AllowAllPermissionSetResult")) @@ -19993,10 +20129,11 @@ def from_dict(obj: Any) -> 'RPC': installed_plugin_source_git_hub = InstalledPluginSourceGitHub.from_dict(obj.get("InstalledPluginSourceGitHub")) installed_plugin_source_local = InstalledPluginSourceLocal.from_dict(obj.get("InstalledPluginSourceLocal")) installed_plugin_source_url = InstalledPluginSourceURL.from_dict(obj.get("InstalledPluginSourceUrl")) + instructions_discover_request = InstructionsDiscoverRequest.from_dict(obj.get("InstructionsDiscoverRequest")) instructions_get_sources_result = InstructionsGetSourcesResult.from_dict(obj.get("InstructionsGetSourcesResult")) - instructions_sources = InstructionsSources.from_dict(obj.get("InstructionsSources")) - instructions_sources_location = InstructionsSourcesLocation(obj.get("InstructionsSourcesLocation")) - instructions_sources_type = InstructionsSourcesType(obj.get("InstructionsSourcesType")) + instruction_source = InstructionSource.from_dict(obj.get("InstructionSource")) + instruction_source_location = InstructionSourceLocation(obj.get("InstructionSourceLocation")) + instruction_source_type = InstructionSourceType(obj.get("InstructionSourceType")) local_session_metadata_value = LocalSessionMetadataValue.from_dict(obj.get("LocalSessionMetadataValue")) log_request = LogRequest.from_dict(obj.get("LogRequest")) log_result = LogResult.from_dict(obj.get("LogResult")) @@ -20317,6 +20454,8 @@ def from_dict(obj: Any) -> 'RPC': send_mode = SendMode(obj.get("SendMode")) send_request = SendRequest.from_dict(obj.get("SendRequest")) send_result = SendResult.from_dict(obj.get("SendResult")) + server_agent_list = ServerAgentList.from_dict(obj.get("ServerAgentList")) + server_instruction_source_list = ServerInstructionSourceList.from_dict(obj.get("ServerInstructionSourceList")) server_skill = ServerSkill.from_dict(obj.get("ServerSkill")) server_skill_list = ServerSkillList.from_dict(obj.get("ServerSkillList")) session_activity = SessionActivity.from_dict(obj.get("SessionActivity")) @@ -20564,7 +20703,7 @@ def from_dict(obj: Any) -> 'RPC': session_context_info = from_union([SessionContextInfo.from_dict, from_none], obj.get("SessionContextInfo")) task_progress = from_union([TaskProgress.from_dict, from_none], obj.get("TaskProgress")) workspace_summary = from_union([WorkspaceSummary.from_dict, from_none], obj.get("WorkspaceSummary")) - return RPC(abort_request, abort_result, account_get_quota_request, account_get_quota_result, account_quota_snapshot, agent_get_current_result, agent_info, agent_info_source, agent_list, agent_registry_live_target_entry, agent_registry_live_target_entry_attention_kind, agent_registry_live_target_entry_kind, agent_registry_live_target_entry_last_terminal_event, agent_registry_live_target_entry_status, agent_registry_log_capture, agent_registry_log_capture_open_error_reason, agent_registry_spawn_error, agent_registry_spawn_permission_mode, agent_registry_spawn_registry_timeout, agent_registry_spawn_request, agent_registry_spawn_result, agent_registry_spawn_spawned, agent_registry_spawn_validation_error, agent_registry_spawn_validation_error_field, agent_registry_spawn_validation_error_reason, agent_reload_result, agent_select_request, agent_select_result, allow_all_permission_set_result, allow_all_permission_state, api_key_auth_info, auth_info, auth_info_type, 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, instructions_get_sources_result, instructions_sources, instructions_sources_location, instructions_sources_type, 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_login_request, mcp_oauth_login_result, 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_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, 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, 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_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, 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_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_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_invoked_result, skills_invoked_skill, skills_load_diagnostics, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_select_subcommand_option, slash_command_select_subcommand_result, slash_command_text_result, task_agent_info, task_agent_progress, task_execution_mode, task_info, task_list, task_progress_line, tasks_cancel_request, tasks_cancel_result, tasks_get_current_promotable_result, tasks_get_progress_request, tasks_get_progress_result, task_shell_info, task_shell_info_attachment_mode, task_shell_progress, tasks_promote_current_to_background_result, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_refresh_result, tasks_remove_request, tasks_remove_result, tasks_send_message_request, tasks_send_message_result, tasks_start_agent_request, tasks_start_agent_result, task_status, tasks_wait_for_pending_result, telemetry_set_feature_overrides_request, token_auth_info, tool, tool_list, tools_get_current_metadata_result, tools_initialize_and_validate_result, tools_list_request, ui_auto_mode_switch_response, ui_elicitation_array_any_of_field, ui_elicitation_array_any_of_field_items, ui_elicitation_array_any_of_field_items_any_of, ui_elicitation_array_enum_field, ui_elicitation_array_enum_field_items, ui_elicitation_field_value, ui_elicitation_request, ui_elicitation_response, ui_elicitation_response_action, ui_elicitation_response_content, ui_elicitation_result, ui_elicitation_schema, ui_elicitation_schema_property, ui_elicitation_schema_property_boolean, ui_elicitation_schema_property_number, ui_elicitation_schema_property_number_type, ui_elicitation_schema_property_string, ui_elicitation_schema_property_string_format, ui_elicitation_string_enum_field, ui_elicitation_string_one_of_field, ui_elicitation_string_one_of_field_one_of, ui_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, 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, task_progress, workspace_summary) + return RPC(abort_request, abort_result, account_get_quota_request, account_get_quota_result, account_quota_snapshot, agent_get_current_result, agent_info, agent_info_source, agent_list, agent_registry_live_target_entry, agent_registry_live_target_entry_attention_kind, agent_registry_live_target_entry_kind, agent_registry_live_target_entry_last_terminal_event, agent_registry_live_target_entry_status, agent_registry_log_capture, agent_registry_log_capture_open_error_reason, agent_registry_spawn_error, agent_registry_spawn_permission_mode, agent_registry_spawn_registry_timeout, agent_registry_spawn_request, agent_registry_spawn_result, agent_registry_spawn_spawned, agent_registry_spawn_validation_error, agent_registry_spawn_validation_error_field, agent_registry_spawn_validation_error_reason, agent_reload_result, agents_discover_request, agent_select_request, agent_select_result, 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, instructions_discover_request, instructions_get_sources_result, instruction_source, instruction_source_location, instruction_source_type, 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_login_request, mcp_oauth_login_result, 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_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, 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, 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_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, 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_list, skills_config_set_disabled_skills_request, skills_disable_request, skills_discover_request, skills_enable_request, skills_get_invoked_result, skills_invoked_skill, skills_load_diagnostics, slash_command_agent_prompt_result, slash_command_completed_result, slash_command_info, slash_command_input, slash_command_input_completion, slash_command_invocation_result, slash_command_kind, slash_command_select_subcommand_option, slash_command_select_subcommand_result, slash_command_text_result, task_agent_info, task_agent_progress, task_execution_mode, task_info, task_list, task_progress_line, tasks_cancel_request, tasks_cancel_result, tasks_get_current_promotable_result, tasks_get_progress_request, tasks_get_progress_result, task_shell_info, task_shell_info_attachment_mode, task_shell_progress, tasks_promote_current_to_background_result, tasks_promote_to_background_request, tasks_promote_to_background_result, tasks_refresh_result, tasks_remove_request, tasks_remove_result, tasks_send_message_request, tasks_send_message_result, tasks_start_agent_request, tasks_start_agent_result, task_status, tasks_wait_for_pending_result, telemetry_set_feature_overrides_request, token_auth_info, tool, tool_list, tools_get_current_metadata_result, tools_initialize_and_validate_result, tools_list_request, ui_auto_mode_switch_response, ui_elicitation_array_any_of_field, ui_elicitation_array_any_of_field_items, ui_elicitation_array_any_of_field_items_any_of, ui_elicitation_array_enum_field, ui_elicitation_array_enum_field_items, ui_elicitation_field_value, ui_elicitation_request, ui_elicitation_response, ui_elicitation_response_action, ui_elicitation_response_content, ui_elicitation_result, ui_elicitation_schema, ui_elicitation_schema_property, ui_elicitation_schema_property_boolean, ui_elicitation_schema_property_number, ui_elicitation_schema_property_number_type, ui_elicitation_schema_property_string, ui_elicitation_schema_property_string_format, ui_elicitation_string_enum_field, ui_elicitation_string_one_of_field, ui_elicitation_string_one_of_field_one_of, ui_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, 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, task_progress, workspace_summary) def to_dict(self) -> dict: result: dict = {} @@ -20594,6 +20733,7 @@ def to_dict(self) -> dict: result["AgentRegistrySpawnValidationErrorField"] = to_enum(AgentRegistrySpawnValidationErrorField, self.agent_registry_spawn_validation_error_field) result["AgentRegistrySpawnValidationErrorReason"] = to_enum(AgentRegistrySpawnValidationErrorReason, self.agent_registry_spawn_validation_error_reason) result["AgentReloadResult"] = to_class(AgentReloadResult, self.agent_reload_result) + result["AgentsDiscoverRequest"] = to_class(AgentsDiscoverRequest, self.agents_discover_request) result["AgentSelectRequest"] = to_class(AgentSelectRequest, self.agent_select_request) result["AgentSelectResult"] = to_class(AgentSelectResult, self.agent_select_result) result["AllowAllPermissionSetResult"] = to_class(AllowAllPermissionSetResult, self.allow_all_permission_set_result) @@ -20702,10 +20842,11 @@ def to_dict(self) -> dict: result["InstalledPluginSourceGitHub"] = to_class(InstalledPluginSourceGitHub, self.installed_plugin_source_git_hub) result["InstalledPluginSourceLocal"] = to_class(InstalledPluginSourceLocal, self.installed_plugin_source_local) result["InstalledPluginSourceUrl"] = to_class(InstalledPluginSourceURL, self.installed_plugin_source_url) + result["InstructionsDiscoverRequest"] = to_class(InstructionsDiscoverRequest, self.instructions_discover_request) result["InstructionsGetSourcesResult"] = to_class(InstructionsGetSourcesResult, self.instructions_get_sources_result) - result["InstructionsSources"] = to_class(InstructionsSources, self.instructions_sources) - result["InstructionsSourcesLocation"] = to_enum(InstructionsSourcesLocation, self.instructions_sources_location) - result["InstructionsSourcesType"] = to_enum(InstructionsSourcesType, self.instructions_sources_type) + result["InstructionSource"] = to_class(InstructionSource, self.instruction_source) + result["InstructionSourceLocation"] = to_enum(InstructionSourceLocation, self.instruction_source_location) + result["InstructionSourceType"] = to_enum(InstructionSourceType, self.instruction_source_type) result["LocalSessionMetadataValue"] = to_class(LocalSessionMetadataValue, self.local_session_metadata_value) result["LogRequest"] = to_class(LogRequest, self.log_request) result["LogResult"] = to_class(LogResult, self.log_result) @@ -21026,6 +21167,8 @@ def to_dict(self) -> dict: result["SendMode"] = to_enum(SendMode, self.send_mode) result["SendRequest"] = to_class(SendRequest, self.send_request) result["SendResult"] = to_class(SendResult, self.send_result) + result["ServerAgentList"] = to_class(ServerAgentList, self.server_agent_list) + result["ServerInstructionSourceList"] = to_class(ServerInstructionSourceList, self.server_instruction_source_list) result["ServerSkill"] = to_class(ServerSkill, self.server_skill) result["ServerSkillList"] = to_class(ServerSkillList, self.server_skill_list) result["SessionActivity"] = to_class(SessionActivity, self.session_activity) @@ -21737,6 +21880,28 @@ async def discover(self, params: SkillsDiscoverRequest, *, timeout: float | None return ServerSkillList.from_dict(await self._client.request("skills.discover", params_dict, **_timeout_kwargs(timeout))) +# Experimental: this API group is experimental and may change or be removed. +class ServerAgentsApi: + def __init__(self, client: "JsonRpcClient"): + self._client = client + + async def discover(self, params: AgentsDiscoverRequest, *, timeout: float | None = None) -> ServerAgentList: + "Discovers custom agents across user, project, plugin, and remote sources.\n\nArgs:\n params: Optional project paths to include in agent discovery.\n\nReturns:\n Agents discovered across user, project, plugin, and remote sources." + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + return ServerAgentList.from_dict(await self._client.request("agents.discover", params_dict, **_timeout_kwargs(timeout))) + + +# Experimental: this API group is experimental and may change or be removed. +class ServerInstructionsApi: + def __init__(self, client: "JsonRpcClient"): + self._client = client + + async def discover(self, params: InstructionsDiscoverRequest, *, timeout: float | None = None) -> ServerInstructionSourceList: + "Discovers instruction sources across user, repository, and plugin sources.\n\nArgs:\n params: Optional project paths to include in instruction discovery.\n\nReturns:\n Instruction sources discovered across user, repository, and plugin sources." + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + return ServerInstructionSourceList.from_dict(await self._client.request("instructions.discover", params_dict, **_timeout_kwargs(timeout))) + + class ServerUserSettingsApi: def __init__(self, client: "JsonRpcClient"): self._client = client @@ -21912,6 +22077,8 @@ def __init__(self, client: "JsonRpcClient"): self.mcp = ServerMcpApi(client) self.plugins = ServerPluginsApi(client) self.skills = ServerSkillsApi(client) + self.agents = ServerAgentsApi(client) + self.instructions = ServerInstructionsApi(client) self.user = ServerUserApi(client) self.runtime = ServerRuntimeApi(client) self.session_fs = ServerSessionFsApi(client) @@ -22330,12 +22497,6 @@ def __init__(self, client: "JsonRpcClient", session_id: str): self._client = client self._session_id = session_id - async def respond(self, params: MCPOauthRespondRequest, *, timeout: float | None = None) -> MCPOauthRespondResult: - "Responds to a pending MCP OAuth provider request. Marked internal because the `provider` argument is an in-process OAuthClientProvider instance that cannot be carried over the wire; the public OAuth surface will route the response through a wire-clean handshake once the CLI moves on top of the SDK.\n\nArgs:\n params: MCP OAuth request id and optional provider response.\n\nReturns:\n Empty result after recording the MCP OAuth response." - 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 MCPOauthRespondResult.from_dict(await self._client.request("session.mcp.oauth.respond", params_dict, **_timeout_kwargs(timeout))) - async def login(self, params: MCPOauthLoginRequest, *, timeout: float | None = None) -> MCPOauthLoginResult: "Starts OAuth authentication for a remote MCP server.\n\nArgs:\n params: Remote MCP server name and optional overrides controlling reauthentication, OAuth client display name, and the callback success-page copy.\n\nReturns:\n OAuth authorization URL the caller should open, or empty when cached tokens already authenticated the server." params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} @@ -22418,12 +22579,6 @@ async def reload(self, *, timeout: float | None = None) -> None: "Reloads MCP server connections for the session." await self._client.request("session.mcp.reload", {"sessionId": self._session_id}, **_timeout_kwargs(timeout)) - async def reload_with_config(self, params: MCPReloadWithConfigRequest, *, timeout: float | None = None) -> MCPStartServersResult: - "Reloads MCP server connections for the session with an explicit host-provided configuration.\n\nArgs:\n params: Opaque MCP reload configuration.\n\nReturns:\n MCP server startup filtering result." - 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 MCPStartServersResult.from_dict(await self._client.request("session.mcp.reloadWithConfig", params_dict, **_timeout_kwargs(timeout))) - async def execute_sampling(self, params: MCPExecuteSamplingParams, *, timeout: float | None = None) -> MCPSamplingExecutionResult: "Runs an MCP sampling inference on behalf of an MCP server.\n\nArgs:\n params: Identifiers and raw MCP CreateMessageRequest params used to run a sampling inference.\n\nReturns:\n Outcome of an MCP sampling execution: success result, failure error, or cancellation." params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} @@ -22446,42 +22601,12 @@ async def remove_git_hub(self, *, timeout: float | None = None) -> MCPRemoveGitH "Removes the auto-managed `github` MCP server when present.\n\nReturns:\n Indicates whether the auto-managed `github` MCP server was removed (false when nothing to remove)." return MCPRemoveGitHubResult.from_dict(await self._client.request("session.mcp.removeGitHub", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) - async def configure_git_hub(self, params: MCPConfigureGitHubRequest, *, timeout: float | None = None) -> MCPConfigureGitHubResult: - "Configures the built-in GitHub MCP server for the session's current auth context.\n\nArgs:\n params: Opaque auth info used to configure GitHub MCP.\n\nReturns:\n Result of configuring GitHub MCP." - 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 MCPConfigureGitHubResult.from_dict(await self._client.request("session.mcp.configureGitHub", params_dict, **_timeout_kwargs(timeout))) - - async def start_server(self, params: MCPStartServerRequest, *, timeout: float | None = None) -> None: - "Starts an individual MCP server on the session's host.\n\nArgs:\n params: Server name and opaque configuration for an individual MCP server start." - 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 - await self._client.request("session.mcp.startServer", params_dict, **_timeout_kwargs(timeout)) - - async def restart_server(self, params: MCPRestartServerRequest, *, timeout: float | None = None) -> None: - "Restarts an individual MCP server on the session's host (stops then starts).\n\nArgs:\n params: Server name and opaque configuration for an individual MCP server restart." - 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 - await self._client.request("session.mcp.restartServer", params_dict, **_timeout_kwargs(timeout)) - async def stop_server(self, params: MCPStopServerRequest, *, timeout: float | None = None) -> None: "Stops an individual MCP server on the session's host.\n\nArgs:\n params: Server name for an individual MCP server stop." 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 await self._client.request("session.mcp.stopServer", params_dict, **_timeout_kwargs(timeout)) - async def register_external_client(self, params: MCPRegisterExternalClientRequest, *, timeout: float | None = None) -> None: - "Registers a pre-connected external MCP client (e.g. IDE) on the session's host. The caller retains lifecycle ownership of the client and transport. Marked internal because the `client` and `transport` arguments are in-process MCP SDK instances that cannot be serialized across the JSON-RPC boundary; once the CLI moves on top of the SDK, external clients will be expressed as transport configs the runtime can construct itself.\n\nArgs:\n params: Registration parameters for an external MCP client." - 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 - await self._client.request("session.mcp.registerExternalClient", params_dict, **_timeout_kwargs(timeout)) - - async def unregister_external_client(self, params: MCPUnregisterExternalClientRequest, *, timeout: float | None = None) -> None: - "Unregisters a previously registered external MCP client by server name. Marked internal as the paired companion of `registerExternalClient`: only in-process callers that registered a client this way can meaningfully unregister it. Disappears alongside `registerExternalClient`: once external clients are described to the runtime as config rather than handed in as instances, lifecycle (including deregistration) is owned entirely by the runtime.\n\nArgs:\n params: Server name identifying the external client to remove." - 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 - await self._client.request("session.mcp.unregisterExternalClient", params_dict, **_timeout_kwargs(timeout)) - async def is_server_running(self, params: MCPIsServerRunningRequest, *, timeout: float | None = None) -> MCPIsServerRunningResult: "Checks whether a named MCP server is currently running on the session's host.\n\nArgs:\n params: Server name to check running status for.\n\nReturns:\n Whether the named MCP server is running." params_dict: dict[str, Any] = {k: v for k, v in params.to_dict().items() if v is not None} @@ -23131,6 +23256,71 @@ async def log(self, params: LogRequest, *, timeout: float | None = None) -> LogR return LogResult.from_dict(await self._client.request("session.log", params_dict, **_timeout_kwargs(timeout))) +# Experimental: this API group is experimental and may change or be removed. +class _InternalMcpOauthApi: + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + + async def _respond(self, params: MCPOauthRespondRequest, *, timeout: float | None = None) -> MCPOauthRespondResult: + "Responds to a pending MCP OAuth provider request. Marked internal because the `provider` argument is an in-process OAuthClientProvider instance that cannot be carried over the wire; the public OAuth surface will route the response through a wire-clean handshake once the CLI moves on top of the SDK.\n\nArgs:\n params: MCP OAuth request id and optional provider response.\n\nReturns:\n Empty result after recording the MCP OAuth response.\n\n:meta private:\n\nInternal SDK API; not part of the public surface." + 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 MCPOauthRespondResult.from_dict(await self._client.request("session.mcp.oauth.respond", params_dict, **_timeout_kwargs(timeout))) + + +# Experimental: this API group is experimental and may change or be removed. +class _InternalMcpApi: + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + self.oauth = _InternalMcpOauthApi(client, session_id) + + async def _reload_with_config(self, params: MCPReloadWithConfigRequest, *, timeout: float | None = None) -> MCPStartServersResult: + "Reloads MCP server connections for the session with an explicit host-provided configuration.\n\nArgs:\n params: Opaque MCP reload configuration.\n\nReturns:\n MCP server startup filtering result.\n\n:meta private:\n\nInternal SDK API; not part of the public surface." + 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 MCPStartServersResult.from_dict(await self._client.request("session.mcp.reloadWithConfig", params_dict, **_timeout_kwargs(timeout))) + + async def _configure_git_hub(self, params: MCPConfigureGitHubRequest, *, timeout: float | None = None) -> MCPConfigureGitHubResult: + "Configures the built-in GitHub MCP server for the session's current auth context.\n\nArgs:\n params: Opaque auth info used to configure GitHub MCP.\n\nReturns:\n Result of configuring GitHub MCP.\n\n:meta private:\n\nInternal SDK API; not part of the public surface." + 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 MCPConfigureGitHubResult.from_dict(await self._client.request("session.mcp.configureGitHub", params_dict, **_timeout_kwargs(timeout))) + + async def _start_server(self, params: MCPStartServerRequest, *, timeout: float | None = None) -> None: + "Starts an individual MCP server on the session's host.\n\nArgs:\n params: Server name and opaque configuration for an individual MCP server start.\n\n:meta private:\n\nInternal SDK API; not part of the public surface." + 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 + await self._client.request("session.mcp.startServer", params_dict, **_timeout_kwargs(timeout)) + + async def _restart_server(self, params: MCPRestartServerRequest, *, timeout: float | None = None) -> None: + "Restarts an individual MCP server on the session's host (stops then starts).\n\nArgs:\n params: Server name and opaque configuration for an individual MCP server restart.\n\n:meta private:\n\nInternal SDK API; not part of the public surface." + 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 + await self._client.request("session.mcp.restartServer", params_dict, **_timeout_kwargs(timeout)) + + async def _register_external_client(self, params: MCPRegisterExternalClientRequest, *, timeout: float | None = None) -> None: + "Registers a pre-connected external MCP client (e.g. IDE) on the session's host. The caller retains lifecycle ownership of the client and transport. Marked internal because the `client` and `transport` arguments are in-process MCP SDK instances that cannot be serialized across the JSON-RPC boundary; once the CLI moves on top of the SDK, external clients will be expressed as transport configs the runtime can construct itself.\n\nArgs:\n params: Registration parameters for an external MCP client.\n\n:meta private:\n\nInternal SDK API; not part of the public surface." + 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 + await self._client.request("session.mcp.registerExternalClient", params_dict, **_timeout_kwargs(timeout)) + + async def _unregister_external_client(self, params: MCPUnregisterExternalClientRequest, *, timeout: float | None = None) -> None: + "Unregisters a previously registered external MCP client by server name. Marked internal as the paired companion of `registerExternalClient`: only in-process callers that registered a client this way can meaningfully unregister it. Disappears alongside `registerExternalClient`: once external clients are described to the runtime as config rather than handed in as instances, lifecycle (including deregistration) is owned entirely by the runtime.\n\nArgs:\n params: Server name identifying the external client to remove.\n\n:meta private:\n\nInternal SDK API; not part of the public surface." + 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 + await self._client.request("session.mcp.unregisterExternalClient", params_dict, **_timeout_kwargs(timeout)) + + +class _InternalSessionRpc: + """Internal SDK session-scoped RPC methods. Not part of the public API.""" + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + self.mcp = _InternalMcpApi(client, session_id) + + # Experimental: this API group is experimental and may change or be removed. class SessionFsHandler(Protocol): async def read_file(self, params: SessionFSReadFileRequest) -> SessionFSReadFileResult: @@ -23336,6 +23526,7 @@ async def handle_canvas_action_invoke(params: dict) -> dict | None: "AgentReloadResult", "AgentSelectRequest", "AgentSelectResult", + "AgentsDiscoverRequest", "AllowAllPermissionSetResult", "AllowAllPermissionState", "ApprovalKind", @@ -23463,11 +23654,12 @@ async def handle_canvas_action_invoke(params: dict) -> dict | None: "InstalledPluginSourceGitHub", "InstalledPluginSourceLocal", "InstalledPluginSourceURL", + "InstructionSource", + "InstructionSourceLocation", + "InstructionSourceType", "InstructionsApi", + "InstructionsDiscoverRequest", "InstructionsGetSourcesResult", - "InstructionsSources", - "InstructionsSourcesLocation", - "InstructionsSourcesType", "KindEnum", "LocalSessionMetadataValue", "LogRequest", @@ -23848,7 +24040,11 @@ async def handle_canvas_action_invoke(params: dict) -> dict | None: "SendRequest", "SendResult", "ServerAccountApi", + "ServerAgentList", "ServerAgentRegistryApi", + "ServerAgentsApi", + "ServerInstructionSourceList", + "ServerInstructionsApi", "ServerMcpApi", "ServerMcpConfigApi", "ServerModelsApi", diff --git a/python/copilot/generated/session_events.py b/python/copilot/generated/session_events.py index 332ac3769..f2e155f49 100644 --- a/python/copilot/generated/session_events.py +++ b/python/copilot/generated/session_events.py @@ -2032,18 +2032,23 @@ def to_dict(self) -> dict: class HookProgressData: "Ephemeral progress update from a running hook process" message: str + temporary: bool | None = None @staticmethod def from_dict(obj: Any) -> "HookProgressData": assert isinstance(obj, dict) message = from_str(obj.get("message")) + temporary = from_union([from_none, from_bool], obj.get("temporary")) return HookProgressData( message=message, + temporary=temporary, ) def to_dict(self) -> dict: result: dict = {} result["message"] = from_str(self.message) + if self.temporary is not None: + result["temporary"] = from_union([from_none, from_bool], self.temporary) return result @@ -4330,6 +4335,7 @@ class SessionResumeData: context: WorkingDirectoryContext | None = None context_tier: ContextTier | None = None continue_pending_work: bool | None = None + events_file_size_bytes: int | None = None reasoning_effort: str | None = None reasoning_summary: ReasoningSummary | None = None remote_steerable: bool | None = None @@ -4345,6 +4351,7 @@ def from_dict(obj: Any) -> "SessionResumeData": context = from_union([from_none, WorkingDirectoryContext.from_dict], obj.get("context")) context_tier = from_union([from_none, lambda x: parse_enum(ContextTier, x)], obj.get("contextTier")) continue_pending_work = from_union([from_none, from_bool], obj.get("continuePendingWork")) + events_file_size_bytes = from_union([from_none, from_int], obj.get("eventsFileSizeBytes")) reasoning_effort = from_union([from_none, from_str], obj.get("reasoningEffort")) reasoning_summary = from_union([from_none, lambda x: parse_enum(ReasoningSummary, x)], obj.get("reasoningSummary")) remote_steerable = from_union([from_none, from_bool], obj.get("remoteSteerable")) @@ -4357,6 +4364,7 @@ def from_dict(obj: Any) -> "SessionResumeData": context=context, context_tier=context_tier, continue_pending_work=continue_pending_work, + events_file_size_bytes=events_file_size_bytes, reasoning_effort=reasoning_effort, reasoning_summary=reasoning_summary, remote_steerable=remote_steerable, @@ -4376,6 +4384,8 @@ def to_dict(self) -> dict: result["contextTier"] = from_union([from_none, lambda x: to_enum(ContextTier, x)], self.context_tier) if self.continue_pending_work is not None: result["continuePendingWork"] = from_union([from_none, from_bool], self.continue_pending_work) + if self.events_file_size_bytes is not None: + result["eventsFileSizeBytes"] = from_union([from_none, to_int], self.events_file_size_bytes) if self.reasoning_effort is not None: result["reasoningEffort"] = from_union([from_none, from_str], self.reasoning_effort) if self.reasoning_summary is not None: @@ -4412,36 +4422,52 @@ def to_dict(self) -> dict: class SessionScheduleCreatedData: "Scheduled prompt registered via /every or /after" id: int - interval: timedelta prompt: str + at: int | None = None + cron: str | None = None display_prompt: str | None = None + interval: timedelta | None = None recurring: bool | None = None + tz: str | None = None @staticmethod def from_dict(obj: Any) -> "SessionScheduleCreatedData": assert isinstance(obj, dict) id = from_int(obj.get("id")) - interval = from_timedelta(obj.get("intervalMs")) prompt = from_str(obj.get("prompt")) + at = from_union([from_none, from_int], obj.get("at")) + cron = from_union([from_none, from_str], obj.get("cron")) display_prompt = from_union([from_none, from_str], obj.get("displayPrompt")) + interval = from_union([from_none, from_timedelta], obj.get("intervalMs")) recurring = from_union([from_none, from_bool], obj.get("recurring")) + tz = from_union([from_none, from_str], obj.get("tz")) return SessionScheduleCreatedData( id=id, - interval=interval, prompt=prompt, + at=at, + cron=cron, display_prompt=display_prompt, + interval=interval, recurring=recurring, + tz=tz, ) def to_dict(self) -> dict: result: dict = {} result["id"] = to_int(self.id) - result["intervalMs"] = to_timedelta_int(self.interval) result["prompt"] = from_str(self.prompt) + if self.at is not None: + result["at"] = from_union([from_none, to_int], self.at) + if self.cron is not None: + result["cron"] = from_union([from_none, from_str], self.cron) if self.display_prompt is not None: result["displayPrompt"] = from_union([from_none, from_str], self.display_prompt) + if self.interval is not None: + result["intervalMs"] = from_union([from_none, to_timedelta_int], self.interval) if self.recurring is not None: result["recurring"] = from_union([from_none, from_bool], self.recurring) + if self.tz is not None: + result["tz"] = from_union([from_none, from_str], self.tz) return result @@ -4457,6 +4483,7 @@ class SessionShutdownData: current_model: str | None = None current_tokens: int | None = None error_reason: str | None = None + events_file_size_bytes: int | None = None system_tokens: int | None = None token_details: dict[str, ShutdownTokenDetail] | None = None tool_definitions_tokens: int | None = None @@ -4477,6 +4504,7 @@ def from_dict(obj: Any) -> "SessionShutdownData": current_model = from_union([from_none, from_str], obj.get("currentModel")) current_tokens = from_union([from_none, from_int], obj.get("currentTokens")) error_reason = from_union([from_none, from_str], obj.get("errorReason")) + events_file_size_bytes = from_union([from_none, from_int], obj.get("eventsFileSizeBytes")) system_tokens = from_union([from_none, from_int], obj.get("systemTokens")) token_details = from_union([from_none, lambda x: from_dict(ShutdownTokenDetail.from_dict, x)], obj.get("tokenDetails")) tool_definitions_tokens = from_union([from_none, from_int], obj.get("toolDefinitionsTokens")) @@ -4492,6 +4520,7 @@ def from_dict(obj: Any) -> "SessionShutdownData": current_model=current_model, current_tokens=current_tokens, error_reason=error_reason, + events_file_size_bytes=events_file_size_bytes, system_tokens=system_tokens, token_details=token_details, tool_definitions_tokens=tool_definitions_tokens, @@ -4514,6 +4543,8 @@ def to_dict(self) -> dict: result["currentTokens"] = from_union([from_none, to_int], self.current_tokens) if self.error_reason is not None: result["errorReason"] = from_union([from_none, from_str], self.error_reason) + if self.events_file_size_bytes is not None: + result["eventsFileSizeBytes"] = from_union([from_none, to_int], self.events_file_size_bytes) if self.system_tokens is not None: result["systemTokens"] = from_union([from_none, to_int], self.system_tokens) if self.token_details is not None: diff --git a/rust/src/generated/api_types.rs b/rust/src/generated/api_types.rs index 57aa9fcbd..f52c06651 100644 --- a/rust/src/generated/api_types.rs +++ b/rust/src/generated/api_types.rs @@ -72,6 +72,10 @@ pub mod rpc_methods { pub const SKILLS_CONFIG_SETDISABLEDSKILLS: &str = "skills.config.setDisabledSkills"; /// `skills.discover` pub const SKILLS_DISCOVER: &str = "skills.discover"; + /// `agents.discover` + pub const AGENTS_DISCOVER: &str = "agents.discover"; + /// `instructions.discover` + pub const INSTRUCTIONS_DISCOVER: &str = "instructions.discover"; /// `user.settings.reload` pub const USER_SETTINGS_RELOAD: &str = "user.settings.reload"; /// `runtime.shutdown` @@ -880,6 +884,25 @@ pub struct AgentReloadResult { pub agents: Vec, } +/// Optional project paths to include in agent discovery. +/// +///
+/// +/// **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 AgentsDiscoverRequest { + /// When true, omit the host's agents (the `/agents` directory and all plugin agents), leaving only project and remote agents. For multitenant deployments. + #[serde(skip_serializing_if = "Option::is_none")] + pub exclude_host_agents: Option, + /// 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). + #[serde(skip_serializing_if = "Option::is_none")] + pub project_paths: Option>, +} + /// Name of the custom agent to select for subsequent turns. /// ///
@@ -3060,7 +3083,7 @@ pub struct InstalledPluginSourceUrl { pub url: String, } -/// Schema for the `InstructionsSources` type. +/// Optional project paths to include in instruction discovery. /// ///
/// @@ -3070,7 +3093,26 @@ pub struct InstalledPluginSourceUrl { ///
#[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct InstructionsSources { +pub struct 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. + #[serde(skip_serializing_if = "Option::is_none")] + pub exclude_host_instructions: Option, + /// 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). + #[serde(skip_serializing_if = "Option::is_none")] + pub project_paths: Option>, +} + +/// Schema for the `InstructionSource` 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 InstructionSource { /// Glob pattern(s) from frontmatter — when set, this instruction applies only to matching files #[serde(skip_serializing_if = "Option::is_none")] pub apply_to: Option>, @@ -3087,11 +3129,14 @@ pub struct InstructionsSources { /// Human-readable label pub label: String, /// Where this source lives — used for UI grouping - pub location: InstructionsSourcesLocation, + pub location: InstructionSourceLocation, + /// 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. + #[serde(skip_serializing_if = "Option::is_none")] + pub project_path: Option, /// File path relative to repo or absolute for home pub source_path: String, /// Category of instruction source — used for merge logic - pub r#type: InstructionsSourcesType, + pub r#type: InstructionSourceType, } /// Instruction sources loaded for the session, in merge order. @@ -3106,7 +3151,7 @@ pub struct InstructionsSources { #[serde(rename_all = "camelCase")] pub struct InstructionsGetSourcesResult { /// Instruction sources for the session - pub sources: Vec, + pub sources: Vec, } /// Pre-resolved working-directory context for session startup. @@ -7925,19 +7970,29 @@ pub struct SandboxConfig { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ScheduleEntry { + /// Absolute fire time (epoch milliseconds) for a one-shot calendar schedule. + #[serde(skip_serializing_if = "Option::is_none")] + pub at: Option, + /// 5-field cron expression for a recurring calendar schedule, evaluated in `tz`. + #[serde(skip_serializing_if = "Option::is_none")] + pub cron: Option, /// Display-only label for the prompt as shown in the UI (e.g. `/skill-name` for a skill-invocation schedule). The actual enqueued prompt is `prompt`. #[serde(skip_serializing_if = "Option::is_none")] pub display_prompt: Option, /// Sequential id assigned by the runtime within the session. Stable across resumes (rebuilt from the event log). pub id: i64, - /// Interval between scheduled ticks, in milliseconds. - pub interval_ms: i64, + /// Interval between scheduled ticks, in milliseconds (relative-interval schedules). + #[serde(skip_serializing_if = "Option::is_none")] + pub interval_ms: Option, /// ISO 8601 timestamp when the next tick is scheduled to fire. pub next_run_at: String, /// Prompt text that gets enqueued on every tick. pub prompt: String, /// Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`). pub recurring: bool, + /// IANA timezone the `cron` expression is evaluated in. + #[serde(skip_serializing_if = "Option::is_none")] + pub tz: Option, } /// Snapshot of the currently active recurring prompts for this session. @@ -8087,6 +8142,36 @@ pub struct SendResult { pub message_id: String, } +/// Agents discovered across user, project, plugin, and remote sources. +/// +///
+/// +/// **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 ServerAgentList { + /// All discovered agents across all sources + pub agents: Vec, +} + +/// Instruction sources discovered across user, repository, and plugin sources. +/// +///
+/// +/// **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 ServerInstructionSourceList { + /// All discovered instruction sources + pub sources: Vec, +} + /// Schema for the `ServerSkill` type. #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -10596,11 +10681,14 @@ pub struct TaskAgentInfo { /// Most recent response text from the agent #[serde(skip_serializing_if = "Option::is_none")] pub latest_response: Option, - /// Model used for the task when specified + /// Requested model override for the task when specified #[serde(skip_serializing_if = "Option::is_none")] pub model: Option, /// Most recent prompt delivered to the agent. Updated whenever the agent receives a follow-up message. pub prompt: String, + /// Runtime model resolved for the task when available + #[serde(skip_serializing_if = "Option::is_none")] + pub resolved_model: Option, /// Result text from the task when available #[serde(skip_serializing_if = "Option::is_none")] pub result: Option, @@ -12378,6 +12466,36 @@ pub struct SkillsDiscoverResult { pub skills: Vec, } +/// Agents discovered across user, project, plugin, and remote sources. +/// +///
+/// +/// **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 AgentsDiscoverResult { + /// All discovered agents across all sources + pub agents: Vec, +} + +/// Instruction sources discovered across user, repository, and plugin sources. +/// +///
+/// +/// **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 InstructionsDiscoverResult { + /// All discovered instruction sources + pub sources: Vec, +} + /// Result of opening a session. /// ///
@@ -13346,7 +13464,7 @@ pub struct SessionInstructionsGetSourcesParams { #[serde(rename_all = "camelCase")] pub struct SessionInstructionsGetSourcesResult { /// Instruction sources for the session - pub sources: Vec, + pub sources: Vec, } /// Indicates whether fleet mode was successfully activated. @@ -16519,7 +16637,7 @@ pub enum InstalledPluginSourceUrlSource { /// ///
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] -pub enum InstructionsSourcesLocation { +pub enum InstructionSourceLocation { /// Instructions live in user-level configuration. #[serde(rename = "user")] User, @@ -16547,7 +16665,7 @@ pub enum InstructionsSourcesLocation { /// ///
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] -pub enum InstructionsSourcesType { +pub enum InstructionSourceType { /// Instructions loaded from the user's home configuration. #[serde(rename = "home")] Home, diff --git a/rust/src/generated/rpc.rs b/rust/src/generated/rpc.rs index e42dde5fa..cd5132f48 100644 --- a/rust/src/generated/rpc.rs +++ b/rust/src/generated/rpc.rs @@ -35,6 +35,20 @@ impl<'a> ClientRpc<'a> { } } + /// `agents.*` sub-namespace. + pub fn agents(&self) -> ClientRpcAgents<'a> { + ClientRpcAgents { + client: self.client, + } + } + + /// `instructions.*` sub-namespace. + pub fn instructions(&self) -> ClientRpcInstructions<'a> { + ClientRpcInstructions { + client: self.client, + } + } + /// `mcp.*` sub-namespace. pub fn mcp(&self) -> ClientRpcMcp<'a> { ClientRpcMcp { @@ -232,6 +246,81 @@ impl<'a> ClientRpcAgentRegistry<'a> { } } +/// `agents.*` RPCs. +#[derive(Clone, Copy)] +pub struct ClientRpcAgents<'a> { + pub(crate) client: &'a Client, +} + +impl<'a> ClientRpcAgents<'a> { + /// Discovers custom agents across user, project, plugin, and remote sources. + /// + /// Wire method: `agents.discover`. + /// + /// # Parameters + /// + /// * `params` - Optional project paths to include in agent discovery. + /// + /// # Returns + /// + /// Agents discovered across user, project, plugin, and remote sources. + /// + ///
+ /// + /// **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 discover(&self, params: AgentsDiscoverRequest) -> Result { + let wire_params = serde_json::to_value(params)?; + let _value = self + .client + .call(rpc_methods::AGENTS_DISCOVER, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } +} + +/// `instructions.*` RPCs. +#[derive(Clone, Copy)] +pub struct ClientRpcInstructions<'a> { + pub(crate) client: &'a Client, +} + +impl<'a> ClientRpcInstructions<'a> { + /// Discovers instruction sources across user, repository, and plugin sources. + /// + /// Wire method: `instructions.discover`. + /// + /// # Parameters + /// + /// * `params` - Optional project paths to include in instruction discovery. + /// + /// # Returns + /// + /// Instruction sources discovered across user, repository, and plugin sources. + /// + ///
+ /// + /// **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 discover( + &self, + params: InstructionsDiscoverRequest, + ) -> Result { + let wire_params = serde_json::to_value(params)?; + let _value = self + .client + .call(rpc_methods::INSTRUCTIONS_DISCOVER, Some(wire_params)) + .await?; + Ok(serde_json::from_value(_value)?) + } +} + /// `mcp.*` RPCs. #[derive(Clone, Copy)] pub struct ClientRpcMcp<'a> { diff --git a/rust/src/generated/session_events.rs b/rust/src/generated/session_events.rs index 7fb8fe0e0..e20d7d6ef 100644 --- a/rust/src/generated/session_events.rs +++ b/rust/src/generated/session_events.rs @@ -493,6 +493,9 @@ pub struct SessionResumeData { pub continue_pending_work: Option, /// Total number of persisted events in the session at the time of resume pub event_count: i64, + /// On-disk byte size of the session's persisted events.jsonl file at resume time; omitted when the file does not exist or cannot be stat'd + #[serde(skip_serializing_if = "Option::is_none")] + pub events_file_size_bytes: Option, /// Reasoning effort level used for model calls, if applicable (e.g. "none", "low", "medium", "high", "xhigh", "max") #[serde(skip_serializing_if = "Option::is_none")] pub reasoning_effort: Option, @@ -572,18 +575,28 @@ pub struct SessionTitleChangedData { #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SessionScheduleCreatedData { + /// Absolute fire time (epoch milliseconds) for a one-shot calendar schedule + #[serde(skip_serializing_if = "Option::is_none")] + pub at: Option, + /// 5-field cron expression for a recurring calendar schedule, evaluated in `tz` + #[serde(skip_serializing_if = "Option::is_none")] + pub cron: Option, /// Optional user-facing label shown in the timeline instead of the actual prompt (e.g. `/skill-name args` when the prompt is a skill invocation expansion) #[serde(skip_serializing_if = "Option::is_none")] pub display_prompt: Option, /// Sequential id assigned to the scheduled prompt within the session pub id: i64, - /// Interval between ticks in milliseconds - pub interval_ms: i64, + /// Interval between ticks in milliseconds (relative-interval schedules) + #[serde(skip_serializing_if = "Option::is_none")] + pub interval_ms: Option, /// Prompt text that gets enqueued on every tick pub prompt: String, /// Whether the schedule re-arms after each tick (`/every`) or fires once (`/after`) #[serde(skip_serializing_if = "Option::is_none")] pub recurring: Option, + /// IANA timezone the `cron` expression is evaluated in + #[serde(skip_serializing_if = "Option::is_none")] + pub tz: Option, } /// Session event "session.schedule_cancelled". Scheduled prompt cancelled from the schedule manager dialog @@ -886,6 +899,9 @@ pub struct SessionShutdownData { /// Error description when shutdownType is "error" #[serde(skip_serializing_if = "Option::is_none")] pub error_reason: Option, + /// On-disk byte size of the session's persisted events.jsonl file at shutdown time; omitted when the file does not exist or cannot be stat'd + #[serde(skip_serializing_if = "Option::is_none")] + pub events_file_size_bytes: Option, /// Per-model usage breakdown, keyed by model identifier pub model_metrics: HashMap, /// Unix timestamp (milliseconds) when the session started @@ -2057,6 +2073,9 @@ pub struct HookEndData { pub struct HookProgressData { /// Human-readable progress message from the hook process pub message: String, + /// When true, this status message replaces the previous temporary one instead of accumulating + #[serde(skip_serializing_if = "Option::is_none")] + pub temporary: Option, } /// Metadata about the prompt template and its construction diff --git a/test/harness/package-lock.json b/test/harness/package-lock.json index 6e15842e3..e67890d98 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.60", + "@github/copilot": "^1.0.61", "@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.60", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.60.tgz", - "integrity": "sha512-+GjW+GJNo55nwJwt48o9szWcyhuY0u682cBKQI1ay9jVBX8DCCXC6HB6Tyv5/MaM4N7CxTiEgp48aVMkye8K+g==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.61.tgz", + "integrity": "sha512-E4f7YXTL2uUZY/ypnfsUruAeSgrHx3AGYEbm5N0DrpzPqoNAZqV6kHEWM4vu+W/nGvydIfPxmOTqaMEhM8r0Uw==", "dev": true, "license": "SEE LICENSE IN LICENSE.md", "dependencies": { @@ -513,20 +513,20 @@ "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.60", - "@github/copilot-darwin-x64": "1.0.60", - "@github/copilot-linux-arm64": "1.0.60", - "@github/copilot-linux-x64": "1.0.60", - "@github/copilot-linuxmusl-arm64": "1.0.60", - "@github/copilot-linuxmusl-x64": "1.0.60", - "@github/copilot-win32-arm64": "1.0.60", - "@github/copilot-win32-x64": "1.0.60" + "@github/copilot-darwin-arm64": "1.0.61", + "@github/copilot-darwin-x64": "1.0.61", + "@github/copilot-linux-arm64": "1.0.61", + "@github/copilot-linux-x64": "1.0.61", + "@github/copilot-linuxmusl-arm64": "1.0.61", + "@github/copilot-linuxmusl-x64": "1.0.61", + "@github/copilot-win32-arm64": "1.0.61", + "@github/copilot-win32-x64": "1.0.61" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.60.tgz", - "integrity": "sha512-TErNaVxsv+uB3bdHwdoKorCd1rhiRh7HkX48vnS7jwqa8EtGgAkzNrHKC7mruL2rnYOOsNIdPfhzQk+2Y6PSxQ==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.61.tgz", + "integrity": "sha512-10prvjHRXB0SD28NsIpzdNDgLquQYUwaH5Ev9KVdIWdBPAvlQsHmQ4JSCyD/UILc/nrrr02CKUgum+mZRKUKIg==", "cpu": [ "arm64" ], @@ -541,9 +541,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.60.tgz", - "integrity": "sha512-PthhcR6PqbQlT04xQKTElpPSJOrJd65nK/l9Sjmpwtk21RrDKs13DCY/19ubP17updYUWBxp3VNfyfN3DAQKOA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.61.tgz", + "integrity": "sha512-NXUjageJ3mxDfHtXGYu//XhJ+dhJFYObT4R3jeWgIHhd+4lX7FlC754nwlBP/ZuVhJ3ND22JK9sua9d2F3Cbwg==", "cpu": [ "x64" ], @@ -558,9 +558,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.60.tgz", - "integrity": "sha512-AVahkDVQTiGmHvDjlb4CHO8CFEGqmCEipxi0qTA60oH3Y3W2C4aYBwEBtP/85pN3wUUKZJVrWTCcxdufUBuK2Q==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.61.tgz", + "integrity": "sha512-dwB2+QSMr622JkePeK56M7YWXsTT/DQzKfpDq8Lk2kmGU052RZAarRmt8gcNm4anofN7pMSrqc3YHj1TM84MFw==", "cpu": [ "arm64" ], @@ -575,9 +575,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.60.tgz", - "integrity": "sha512-NwQjV2ZyUdJVAO4t7wiT+eR3uNWYP57xaLUIhf6JTMGpsTyN+mAFXW63xpwM/K+Pug62uRDQDBjEeOQRB7qZrA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.61.tgz", + "integrity": "sha512-q6n8R8oybvuCmmkP+43w809Wpud/wwRi/fFSZEYJagiNGmYJ00SDkrfJxHbZsAFMpaJC+oTswqzJHjRoZbO74w==", "cpu": [ "x64" ], @@ -592,9 +592,9 @@ } }, "node_modules/@github/copilot-linuxmusl-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.60.tgz", - "integrity": "sha512-AYGPc9vq2k248bVwUbiVJ65kIYYMQQ7ci+S3oefWBIyYtYwAH0n+Q/IGAj49IPrelBarYABAsX+EQZJJC8rhxw==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-arm64/-/copilot-linuxmusl-arm64-1.0.61.tgz", + "integrity": "sha512-yWo7JXnZS11eJpm68E1RWKMR47EwzPKj3V7GX0EMTd8Fw0T2Aurk9wt9p3c9w0v02nTO1DqJhi68KVWJPdVqvA==", "cpu": [ "arm64" ], @@ -609,9 +609,9 @@ } }, "node_modules/@github/copilot-linuxmusl-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.60.tgz", - "integrity": "sha512-9/F7yl0/9FpGvYR/TCQtbhu0vIaUVem6U7em85QYaEjkS45nK500pByCMWY0bXv2eSS8U2g+8FOAjfkyLlxwPw==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-linuxmusl-x64/-/copilot-linuxmusl-x64-1.0.61.tgz", + "integrity": "sha512-nHzx27Ac4B0fpD9CcmvyrGOBEMJ01CPRgVRP0yAl4wpU4cM2I6+9TPyfYThlWDqZqiUKGXC1ZRQ+B8cJREVGmA==", "cpu": [ "x64" ], @@ -626,9 +626,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.60.tgz", - "integrity": "sha512-ZxxS+Ua1+7Puz80yTOpQ4WS+s32NjrxIsqo8gE0FpuZId16BGOGbWkzWQvR/k2AVBCqpLZ7SK3LfDVKuKJRbpA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.61.tgz", + "integrity": "sha512-k6knzI+K5HlZeJDS/yeJAfoYD4xcURWfuqunpTCyk1pDbIFxmrLSqR/TDi7KNlpsf883n5WqpnB06K5kysdHHQ==", "cpu": [ "arm64" ], @@ -643,9 +643,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.60", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.60.tgz", - "integrity": "sha512-e91ZlFz9J1lkadExLg36oN8Ms/xIa03vAEir3DmyCeYebZ+Y48vdS+BwhQEma+GLoxJUOhzHndCckGnMRfNIbA==", + "version": "1.0.61", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.61.tgz", + "integrity": "sha512-L6NZ6o73VZFHd7OoRaztV3Prh1PbW9HXqYsAx+XywNALQvE1u489WBUC1ggfYBW5MTBCf8mxSkYQdb3Am2omsw==", "cpu": [ "x64" ], diff --git a/test/harness/package.json b/test/harness/package.json index 99a7583d3..8b7016592 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.60", + "@github/copilot": "^1.0.61", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "@types/node-forge": "^1.3.14", From a98944a79607adfc8daa8f76dfe2eb524d585dfa Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 10 Jun 2026 00:20:42 -0400 Subject: [PATCH 2/4] Fix E2E CI for @github/copilot 1.0.61 1.0.61 marks several session MCP lifecycle RPC methods as internal (startServer, restartServer, registerExternalClient, unregisterExternalClient, reloadWithConfig, configureGitHub, mcp.oauth.respond). Remove the E2E cases that exercised those methods on the public client surface across the Node, Python, Go, and .NET MCP lifecycle suites; the public list-tools/status/stop cases are retained. Also make the abort-streaming snapshot tolerant of a transport timing change. Routing fetch through Rust reqwest in the runtime can land the abort before the in-flight assistant turn is finalized, so the recovery request's history omits the aborted assistant message. Add a second conversation covering that dropped-turn path so the replay proxy matches regardless of which side of the race wins. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- dotnet/test/E2E/RpcMcpLifecycleE2ETests.cs | 120 +--------------- go/internal/e2e/rpc_mcp_lifecycle_e2e_test.go | 120 ---------------- nodejs/test/e2e/rpc_mcp_lifecycle.e2e.test.ts | 111 --------------- python/e2e/test_rpc_mcp_lifecycle_e2e.py | 128 ------------------ .../should_abort_during_active_streaming.yaml | 10 ++ 5 files changed, 12 insertions(+), 477 deletions(-) diff --git a/dotnet/test/E2E/RpcMcpLifecycleE2ETests.cs b/dotnet/test/E2E/RpcMcpLifecycleE2ETests.cs index b87f7a478..60c4bde3f 100644 --- a/dotnet/test/E2E/RpcMcpLifecycleE2ETests.cs +++ b/dotnet/test/E2E/RpcMcpLifecycleE2ETests.cs @@ -9,9 +9,8 @@ namespace GitHub.Copilot.Test.E2E; /// -/// E2E coverage for the session-scoped MCP lifecycle RPC methods that were previously untested: -/// listTools, isServerRunning, stopServer, startServer, restartServer, registerExternalClient, -/// unregisterExternalClient, reloadWithConfig, configureGitHub, and oauth.respond. +/// E2E coverage for the public session-scoped MCP lifecycle RPC methods: +/// listTools, isServerRunning, and stopServer. /// public class RpcMcpLifecycleE2ETests(E2ETestFixture fixture, ITestOutputHelper output) : E2ETestBase(fixture, "rpc_mcp_lifecycle", output) @@ -71,121 +70,6 @@ public async Task Should_Stop_Running_Mcp_Server() await WaitForMcpRunningAsync(session, serverName, expectedRunning: false); } - [Fact] - public async Task Should_Start_And_Restart_Mcp_Server() - { - const string hostServer = "rpc-lifecycle-host-server"; - await using var session = await CreateSessionAsync(new SessionConfig - { - McpServers = CreateTestMcpServers(hostServer), - }); - await WaitForMcpServerStatusAsync(session, hostServer, McpServerStatus.Connected); - - // Start a brand-new server through the lifecycle API, reusing the exact stdio config shape - // the bulk session-config path uses so the runtime accepts and connects it. - const string startedServer = "rpc-lifecycle-started-server"; - var config = CreateTestMcpServers(startedServer)[startedServer]; - - await session.Rpc.Mcp.StartServerAsync(startedServer, config); - await WaitForMcpRunningAsync(session, startedServer, expectedRunning: true); - - // The freshly started server exposes its tools just like a config-provided server. - var tools = await session.Rpc.Mcp.ListToolsAsync(startedServer); - Assert.NotEmpty(tools.Tools); - - // Restart stops then starts the same server; it must end up running again. - await session.Rpc.Mcp.RestartServerAsync(startedServer, config); - await WaitForMcpRunningAsync(session, startedServer, expectedRunning: true); - } - - [Fact] - public async Task Should_Register_And_Unregister_External_Mcp_Client() - { - const string hostServer = "rpc-lifecycle-extclient-host"; - await using var session = await CreateSessionAsync(new SessionConfig - { - McpServers = CreateTestMcpServers(hostServer), - }); - await WaitForMcpServerStatusAsync(session, hostServer, McpServerStatus.Connected); - - const string externalName = "rpc-lifecycle-external-client"; - Assert.False((await session.Rpc.Mcp.IsServerRunningAsync(externalName)).Running); - - // The runtime stores the supplied client/transport handles on the host registry, so the - // registered name immediately reports as running until it is unregistered again. - await session.Rpc.Mcp.RegisterExternalClientAsync( - externalName, - client: new Dictionary { ["id"] = externalName }, - transport: new Dictionary { ["kind"] = "in-process" }, - config: new Dictionary { ["command"] = "noop" }); - Assert.True((await session.Rpc.Mcp.IsServerRunningAsync(externalName)).Running); - - await session.Rpc.Mcp.UnregisterExternalClientAsync(externalName); - Assert.False((await session.Rpc.Mcp.IsServerRunningAsync(externalName)).Running); - } - - [Fact] - public async Task Should_Reload_Mcp_Servers_With_Config() - { - const string hostServer = "rpc-lifecycle-reload-host"; - await using var session = await CreateSessionAsync(new SessionConfig - { - McpServers = CreateTestMcpServers(hostServer), - }); - await WaitForMcpServerStatusAsync(session, hostServer, McpServerStatus.Connected); - - // reloadWithConfig drives the runtime's reloadMcpServers with an explicit host config and - // returns the startup filtering result. Reloading an empty server set is a valid no-op. - var result = await session.Rpc.Mcp.ReloadWithConfigAsync(new Dictionary - { - ["mcpServers"] = new Dictionary(), - ["disabledServers"] = new List(), - }); - - Assert.NotNull(result); - Assert.NotNull(result.FilteredServers); - Assert.Empty(result.FilteredServers); - } - - [Fact] - public async Task Should_Configure_GitHub_Mcp_Server() - { - const string hostServer = "rpc-lifecycle-configure-host"; - await using var session = await CreateSessionAsync(new SessionConfig - { - McpServers = CreateTestMcpServers(hostServer), - }); - await WaitForMcpServerStatusAsync(session, hostServer, McpServerStatus.Connected); - - // configureGitHub forwards a typed auth-info union to the runtime. An "api-key" auth info is - // a recognized type that the runtime declines to act on, so configuration is left unchanged - // (changed=false) while still proving the method is wired through to the handler. - var result = await session.Rpc.Mcp.ConfigureGitHubAsync(new Dictionary - { - ["type"] = "api-key", - }); - - Assert.NotNull(result); - Assert.False(result.Changed); - } - - [Fact] - public async Task Should_Respond_To_Mcp_Oauth_Request_Without_Pending_Request() - { - const string hostServer = "rpc-lifecycle-oauth-host"; - await using var session = await CreateSessionAsync(new SessionConfig - { - McpServers = CreateTestMcpServers(hostServer), - }); - await WaitForMcpServerStatusAsync(session, hostServer, McpServerStatus.Connected); - - // With no pending OAuth request, the runtime's respondToMcpOAuth is a tolerant no-op: it - // looks up the request id, finds nothing, and returns an empty result without throwing. The - // call must reach the runtime and complete successfully, proving the method is wired. - var result = await session.Rpc.Mcp.Oauth.RespondAsync($"missing-{Guid.NewGuid():N}"); - Assert.NotNull(result); - } - private static Task WaitForMcpRunningAsync(CopilotSession session, string serverName, bool expectedRunning) => Harness.TestHelper.WaitForConditionAsync( async () => (await session.Rpc.Mcp.IsServerRunningAsync(serverName)).Running == expectedRunning, diff --git a/go/internal/e2e/rpc_mcp_lifecycle_e2e_test.go b/go/internal/e2e/rpc_mcp_lifecycle_e2e_test.go index 36bd5f5c3..cfe1123fd 100644 --- a/go/internal/e2e/rpc_mcp_lifecycle_e2e_test.go +++ b/go/internal/e2e/rpc_mcp_lifecycle_e2e_test.go @@ -80,126 +80,6 @@ func TestRpcMcpLifecycle(t *testing.T) { } waitForPortedMCPRunning(t, session, serverName, false) }) - - t.Run("should_start_and_restart_mcp_server", func(t *testing.T) { - ctx.ConfigureForTest(t) - const hostServer = "rpc-lifecycle-host-server" - session := createPortedSession(t, client, &copilot.SessionConfig{MCPServers: testMCPServers(t, hostServer)}) - defer session.Disconnect() - waitForPortedMCPServerStatus(t, session, hostServer, rpc.MCPServerStatusConnected) - - const startedServer = "rpc-lifecycle-started-server" - config := testMCPServers(t, startedServer)[startedServer] - if _, err := session.RPC.MCP.StartServer(t.Context(), &rpc.MCPStartServerRequest{ServerName: startedServer, Config: config}); err != nil { - t.Fatalf("MCP.StartServer failed: %v", err) - } - waitForPortedMCPRunning(t, session, startedServer, true) - - tools, err := session.RPC.MCP.ListTools(t.Context(), &rpc.MCPListToolsRequest{ServerName: startedServer}) - if err != nil { - t.Fatalf("MCP.ListTools(started) failed: %v", err) - } - if len(tools.Tools) == 0 { - t.Fatal("Expected started MCP server to expose tools") - } - - if _, err := session.RPC.MCP.RestartServer(t.Context(), &rpc.MCPRestartServerRequest{ServerName: startedServer, Config: config}); err != nil { - t.Fatalf("MCP.RestartServer failed: %v", err) - } - waitForPortedMCPRunning(t, session, startedServer, true) - }) - - t.Run("should_register_and_unregister_external_mcp_client", func(t *testing.T) { - ctx.ConfigureForTest(t) - const hostServer = "rpc-lifecycle-extclient-host" - session := createPortedSession(t, client, &copilot.SessionConfig{MCPServers: testMCPServers(t, hostServer)}) - defer session.Disconnect() - waitForPortedMCPServerStatus(t, session, hostServer, rpc.MCPServerStatusConnected) - - const externalName = "rpc-lifecycle-external-client" - initial, err := session.RPC.MCP.IsServerRunning(t.Context(), &rpc.MCPIsServerRunningRequest{ServerName: externalName}) - if err != nil { - t.Fatalf("MCP.IsServerRunning(initial external) failed: %v", err) - } - if initial.Running { - t.Fatal("Expected external client to start as not running") - } - - if _, err := session.RPC.MCP.RegisterExternalClient(t.Context(), &rpc.MCPRegisterExternalClientRequest{ - ServerName: externalName, - Client: map[string]any{"id": externalName}, - Transport: map[string]any{"kind": "in-process"}, - Config: map[string]any{"command": "noop"}, - }); err != nil { - t.Fatalf("MCP.RegisterExternalClient failed: %v", err) - } - waitForPortedMCPRunning(t, session, externalName, true) - - if _, err := session.RPC.MCP.UnregisterExternalClient(t.Context(), &rpc.MCPUnregisterExternalClientRequest{ServerName: externalName}); err != nil { - t.Fatalf("MCP.UnregisterExternalClient failed: %v", err) - } - waitForPortedMCPRunning(t, session, externalName, false) - }) - - t.Run("should_reload_mcp_servers_with_config", func(t *testing.T) { - ctx.ConfigureForTest(t) - const hostServer = "rpc-lifecycle-reload-host" - session := createPortedSession(t, client, &copilot.SessionConfig{MCPServers: testMCPServers(t, hostServer)}) - defer session.Disconnect() - waitForPortedMCPServerStatus(t, session, hostServer, rpc.MCPServerStatusConnected) - - result, err := session.RPC.MCP.ReloadWithConfig(t.Context(), &rpc.MCPReloadWithConfigRequest{Config: map[string]any{ - "mcpServers": map[string]any{}, - "disabledServers": []string{}, - }}) - if err != nil { - t.Fatalf("MCP.ReloadWithConfig failed: %v", err) - } - if result == nil { - t.Fatal("Expected non-nil reload result") - } - if result.FilteredServers == nil { - t.Fatal("Expected non-nil FilteredServers") - } - if len(result.FilteredServers) != 0 { - t.Fatalf("Expected no filtered servers, got %+v", result.FilteredServers) - } - }) - - t.Run("should_configure_github_mcp_server", func(t *testing.T) { - ctx.ConfigureForTest(t) - const hostServer = "rpc-lifecycle-configure-host" - session := createPortedSession(t, client, &copilot.SessionConfig{MCPServers: testMCPServers(t, hostServer)}) - defer session.Disconnect() - waitForPortedMCPServerStatus(t, session, hostServer, rpc.MCPServerStatusConnected) - - result, err := session.RPC.MCP.ConfigureGitHub(t.Context(), &rpc.MCPConfigureGitHubRequest{AuthInfo: map[string]any{"type": "api-key"}}) - if err != nil { - t.Fatalf("MCP.ConfigureGitHub failed: %v", err) - } - if result == nil { - t.Fatal("Expected non-nil configure result") - } - if result.Changed { - t.Fatal("Expected Changed=false") - } - }) - - t.Run("should_respond_to_mcp_oauth_request_without_pending_request", func(t *testing.T) { - ctx.ConfigureForTest(t) - const hostServer = "rpc-lifecycle-oauth-host" - session := createPortedSession(t, client, &copilot.SessionConfig{MCPServers: testMCPServers(t, hostServer)}) - defer session.Disconnect() - waitForPortedMCPServerStatus(t, session, hostServer, rpc.MCPServerStatusConnected) - - result, err := session.RPC.MCP.Oauth().Respond(t.Context(), &rpc.MCPOauthRespondRequest{RequestID: "missing-" + randomHex(t)}) - if err != nil { - t.Fatalf("MCP.Oauth.Respond failed: %v", err) - } - if result == nil { - t.Fatal("Expected non-nil OAuth respond result") - } - }) } func waitForPortedMCPServerStatus(t *testing.T, session *copilot.Session, serverName string, expectedStatus rpc.MCPServerStatus) { diff --git a/nodejs/test/e2e/rpc_mcp_lifecycle.e2e.test.ts b/nodejs/test/e2e/rpc_mcp_lifecycle.e2e.test.ts index 22db56d9b..40f837434 100644 --- a/nodejs/test/e2e/rpc_mcp_lifecycle.e2e.test.ts +++ b/nodejs/test/e2e/rpc_mcp_lifecycle.e2e.test.ts @@ -148,115 +148,4 @@ describe("Session-scoped MCP lifecycle RPC", async () => { await session.disconnect(); } }); - - it("should start and restart mcp server", { timeout: 180_000 }, async () => { - const hostServer = "rpc-lifecycle-host-server"; - const session = await createSessionWithMcp(hostServer); - try { - await waitForMcpServerStatus(session, hostServer); - - const startedServer = "rpc-lifecycle-started-server"; - const config = createTestMcpServers(startedServer)[startedServer] as unknown as Record< - string, - unknown - >; - - await session.rpc.mcp.startServer({ serverName: startedServer, config }); - await waitForMcpRunning(session, startedServer, true); - - const tools = await session.rpc.mcp.listTools({ serverName: startedServer }); - expect(tools.tools.length).toBeGreaterThan(0); - - await session.rpc.mcp.restartServer({ serverName: startedServer, config }); - await waitForMcpRunning(session, startedServer, true); - } finally { - await session.disconnect(); - } - }); - - it("should register and unregister external mcp client", { timeout: 120_000 }, async () => { - const hostServer = "rpc-lifecycle-extclient-host"; - const session = await createSessionWithMcp(hostServer); - try { - await waitForMcpServerStatus(session, hostServer); - - const externalName = "rpc-lifecycle-external-client"; - expect( - (await session.rpc.mcp.isServerRunning({ serverName: externalName })).running - ).toBe(false); - - await session.rpc.mcp.registerExternalClient({ - serverName: externalName, - client: { id: externalName }, - transport: { kind: "in-process" }, - config: { command: "noop" }, - }); - expect( - (await session.rpc.mcp.isServerRunning({ serverName: externalName })).running - ).toBe(true); - - await session.rpc.mcp.unregisterExternalClient({ serverName: externalName }); - expect( - (await session.rpc.mcp.isServerRunning({ serverName: externalName })).running - ).toBe(false); - } finally { - await session.disconnect(); - } - }); - - it("should reload mcp servers with config", { timeout: 120_000 }, async () => { - const hostServer = "rpc-lifecycle-reload-host"; - const session = await createSessionWithMcp(hostServer); - try { - await waitForMcpServerStatus(session, hostServer); - - const result = await session.rpc.mcp.reloadWithConfig({ - config: { - mcpServers: {}, - disabledServers: [], - }, - }); - - expect(result).toBeDefined(); - expect(result.filteredServers).toEqual([]); - } finally { - await session.disconnect(); - } - }); - - it("should configure github mcp server", { timeout: 120_000 }, async () => { - const hostServer = "rpc-lifecycle-configure-host"; - const session = await createSessionWithMcp(hostServer); - try { - await waitForMcpServerStatus(session, hostServer); - - const result = await session.rpc.mcp.configureGitHub({ - authInfo: { type: "api-key" }, - }); - - expect(result).toBeDefined(); - expect(result.changed).toBe(false); - } finally { - await session.disconnect(); - } - }); - - it( - "should respond to mcp oauth request without pending request", - { timeout: 120_000 }, - async () => { - const hostServer = "rpc-lifecycle-oauth-host"; - const session = await createSessionWithMcp(hostServer); - try { - await waitForMcpServerStatus(session, hostServer); - - const result = await session.rpc.mcp.oauth.respond({ - requestId: missingName("missing"), - }); - expect(result).toBeDefined(); - } finally { - await session.disconnect(); - } - } - ); }); diff --git a/python/e2e/test_rpc_mcp_lifecycle_e2e.py b/python/e2e/test_rpc_mcp_lifecycle_e2e.py index 090a3b07c..a16603706 100644 --- a/python/e2e/test_rpc_mcp_lifecycle_e2e.py +++ b/python/e2e/test_rpc_mcp_lifecycle_e2e.py @@ -13,16 +13,9 @@ import pytest from copilot.rpc import ( - MCPConfigureGitHubRequest, MCPIsServerRunningRequest, MCPListToolsRequest, - MCPOauthRespondRequest, - MCPRegisterExternalClientRequest, - MCPReloadWithConfigRequest, - MCPRestartServerRequest, - MCPStartServerRequest, MCPStopServerRequest, - MCPUnregisterExternalClientRequest, ) from copilot.session import PermissionHandler from copilot.session_events import McpServerStatus @@ -49,15 +42,6 @@ def _test_mcp_servers(*server_names: str) -> dict[str, dict]: } -def _wire_mcp_server_config() -> dict: - return { - "command": "node", - "args": [TEST_MCP_SERVER], - "tools": ["*"], - "cwd": TEST_HARNESS_DIR, - } - - async def _wait_for_mcp_server_status( session, server_name: str, @@ -165,115 +149,3 @@ async def test_should_stop_running_mcp_server(self, ctx: E2ETestContext): await session.rpc.mcp.stop_server(MCPStopServerRequest(server_name=server_name)) await _wait_for_mcp_running(session, server_name, expected_running=False) - - async def test_should_start_and_restart_mcp_server(self, ctx: E2ETestContext): - host_server = "rpc-lifecycle-host-server" - async with await ctx.client.create_session( - on_permission_request=PermissionHandler.approve_all, - mcp_servers=_test_mcp_servers(host_server), - ) as session: - await _wait_for_mcp_server_status(session, host_server) - - started_server = "rpc-lifecycle-started-server" - config = _wire_mcp_server_config() - - await session.rpc.mcp.start_server( - MCPStartServerRequest(server_name=started_server, config=config) - ) - await _wait_for_mcp_running(session, started_server, expected_running=True) - - tools = await session.rpc.mcp.list_tools( - MCPListToolsRequest(server_name=started_server) - ) - assert len(tools.tools) > 0 - - await session.rpc.mcp.restart_server( - MCPRestartServerRequest(server_name=started_server, config=config) - ) - await _wait_for_mcp_running(session, started_server, expected_running=True) - - async def test_should_register_and_unregister_external_mcp_client(self, ctx: E2ETestContext): - host_server = "rpc-lifecycle-extclient-host" - async with await ctx.client.create_session( - on_permission_request=PermissionHandler.approve_all, - mcp_servers=_test_mcp_servers(host_server), - ) as session: - await _wait_for_mcp_server_status(session, host_server) - - external_name = "rpc-lifecycle-external-client" - assert ( - await session.rpc.mcp.is_server_running( - MCPIsServerRunningRequest(server_name=external_name) - ) - ).running is False - - await session.rpc.mcp.register_external_client( - MCPRegisterExternalClientRequest( - server_name=external_name, - client={"id": external_name}, - transport={"kind": "in-process"}, - config={"command": "noop"}, - ) - ) - assert ( - await session.rpc.mcp.is_server_running( - MCPIsServerRunningRequest(server_name=external_name) - ) - ).running is True - - await session.rpc.mcp.unregister_external_client( - MCPUnregisterExternalClientRequest(server_name=external_name) - ) - assert ( - await session.rpc.mcp.is_server_running( - MCPIsServerRunningRequest(server_name=external_name) - ) - ).running is False - - async def test_should_reload_mcp_servers_with_config(self, ctx: E2ETestContext): - host_server = "rpc-lifecycle-reload-host" - async with await ctx.client.create_session( - on_permission_request=PermissionHandler.approve_all, - mcp_servers=_test_mcp_servers(host_server), - ) as session: - await _wait_for_mcp_server_status(session, host_server) - - result = await session.rpc.mcp.reload_with_config( - MCPReloadWithConfigRequest( - config={"mcpServers": {}, "disabledServers": []}, - ) - ) - - assert result is not None - assert result.filtered_servers is not None - assert result.filtered_servers == [] - - async def test_should_configure_github_mcp_server(self, ctx: E2ETestContext): - host_server = "rpc-lifecycle-configure-host" - async with await ctx.client.create_session( - on_permission_request=PermissionHandler.approve_all, - mcp_servers=_test_mcp_servers(host_server), - ) as session: - await _wait_for_mcp_server_status(session, host_server) - - result = await session.rpc.mcp.configure_git_hub( - MCPConfigureGitHubRequest(auth_info={"type": "api-key"}) - ) - - assert result is not None - assert result.changed is False - - async def test_should_respond_to_mcp_oauth_request_without_pending_request( - self, ctx: E2ETestContext - ): - host_server = "rpc-lifecycle-oauth-host" - async with await ctx.client.create_session( - on_permission_request=PermissionHandler.approve_all, - mcp_servers=_test_mcp_servers(host_server), - ) as session: - await _wait_for_mcp_server_status(session, host_server) - - result = await session.rpc.mcp.oauth.respond( - MCPOauthRespondRequest(request_id=f"missing-{uuid.uuid4().hex}") - ) - assert result is not None diff --git a/test/snapshots/abort/should_abort_during_active_streaming.yaml b/test/snapshots/abort/should_abort_during_active_streaming.yaml index bd18eab2f..0fa912159 100644 --- a/test/snapshots/abort/should_abort_during_active_streaming.yaml +++ b/test/snapshots/abort/should_abort_during_active_streaming.yaml @@ -28,3 +28,13 @@ conversations: content: Say 'abort_recovery_ok'. - role: assistant content: abort_recovery_ok + - messages: + - role: system + content: ${system} + - role: user + content: Write a very long essay about the history of computing, covering every decade from the 1940s to the 2020s in + great detail. + - role: user + content: Say 'abort_recovery_ok'. + - role: assistant + content: abort_recovery_ok From 372d1a5fd10d6d3e7fac3e5c7759fb649a248133 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 10 Jun 2026 07:05:38 -0400 Subject: [PATCH 3/4] Fix abort streaming E2E race in Node, Rust, and Python The should_abort_during_active_streaming E2E test used sendAndWait/ send_and_wait for the post-abort recovery turn, which resolves on the first session.idle it sees. After session.abort() (which resolves on the abort RPC ack, not on idle), the aborted turn's trailing session.idle can land inside the recovery wait window and resolve it early with no assistant message. The CLI 1.0.61 transport change (fetch via Rust reqwest) compressed the timing enough to make this fail consistently. Convert the Node, Rust, and Python streaming-abort tests to the event-listener pattern already used by the Go and .NET equivalents (and by the tool-execution abort tests): register a listener for the assistant.message containing abort_recovery_ok, send the recovery, and await that specific message. Also document the two legal post-abort histories captured by the snapshot's two stored conversations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- nodejs/test/e2e/abort.e2e.test.ts | 29 ++++++++++++++++--- python/e2e/test_abort_e2e.py | 23 ++++++++++++--- rust/tests/e2e/abort.rs | 21 +++++++++++--- .../should_abort_during_active_streaming.yaml | 11 +++++++ 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/nodejs/test/e2e/abort.e2e.test.ts b/nodejs/test/e2e/abort.e2e.test.ts index 87d91fc5e..89877387c 100644 --- a/nodejs/test/e2e/abort.e2e.test.ts +++ b/nodejs/test/e2e/abort.e2e.test.ts @@ -58,11 +58,32 @@ describe("Abort", async () => { // Abort mid-stream await session.abort(); - // Session should be usable after abort — send a follow-up and get a response - const followUp = await session.sendAndWait({ - prompt: "Say 'abort_recovery_ok'.", + // Session should be usable after abort. Wait for the specific recovery + // message rather than racing against a late idle from the aborted turn. + let recoveryResolve!: (content: string) => void; + const recoveryReceived = new Promise((resolve) => { + recoveryResolve = resolve; + }); + const unsubscribeRecovery = session.on((event) => { + if (event.type === "assistant.message") { + const content = event.data.content ?? ""; + if (content.toLowerCase().includes("abort_recovery_ok")) { + recoveryResolve(content); + } + } }); - expect(followUp?.data.content?.toLowerCase()).toContain("abort_recovery_ok"); + + try { + await session.send({ prompt: "Say 'abort_recovery_ok'." }); + const recoveryContent = await withTimeout( + recoveryReceived, + 60_000, + "assistant.message containing abort_recovery_ok" + ); + expect(recoveryContent.toLowerCase()).toContain("abort_recovery_ok"); + } finally { + unsubscribeRecovery(); + } await session.disconnect(); }); diff --git a/python/e2e/test_abort_e2e.py b/python/e2e/test_abort_e2e.py index 6711fb114..ce3a497f4 100644 --- a/python/e2e/test_abort_e2e.py +++ b/python/e2e/test_abort_e2e.py @@ -57,10 +57,25 @@ def on_event(event): types = [e.type.value for e in events] assert "assistant.message_delta" in types - # Session should be in a usable state after abort - follow_up = await session.send_and_wait("Say 'abort_recovery_ok'.", timeout=60.0) - assert follow_up is not None - assert "abort_recovery_ok" in (follow_up.data.content or "").lower() + # Session should be usable after abort. Wait for the specific recovery + # message rather than racing against a late idle from the aborted turn. + recovery_received: asyncio.Future = asyncio.get_event_loop().create_future() + + def check_recovery(event): + if ( + event.type.value == "assistant.message" + and "abort_recovery_ok" in (event.data.content or "").lower() + and not recovery_received.done() + ): + recovery_received.set_result(event) + + unsubscribe_recovery = session.on(check_recovery) + try: + await session.send("Say 'abort_recovery_ok'.") + recovery_message = await asyncio.wait_for(recovery_received, timeout=60.0) + assert "abort_recovery_ok" in (recovery_message.data.content or "").lower() + finally: + unsubscribe_recovery() finally: unsubscribe() await session.disconnect() diff --git a/rust/tests/e2e/abort.rs b/rust/tests/e2e/abort.rs index 8d4ab5499..d4e79452b 100644 --- a/rust/tests/e2e/abort.rs +++ b/rust/tests/e2e/abort.rs @@ -47,11 +47,24 @@ async fn should_abort_during_active_streaming() { session.abort().await.expect("abort session"); - let recovery = session - .send_and_wait("Say 'abort_recovery_ok'.") + // Session should be usable after abort. Wait for the specific recovery + // message rather than racing against a late idle from the aborted turn. + let recovery_events = session.subscribe(); + session + .send("Say 'abort_recovery_ok'.") .await - .expect("send recovery") - .expect("assistant message"); + .expect("send recovery"); + let recovery = wait_for_event( + recovery_events, + "assistant.message containing abort_recovery_ok", + |event| { + event.parsed_type() == SessionEventType::AssistantMessage + && assistant_message_content(event) + .to_lowercase() + .contains("abort_recovery_ok") + }, + ) + .await; assert!( assistant_message_content(&recovery) .to_lowercase() diff --git a/test/snapshots/abort/should_abort_during_active_streaming.yaml b/test/snapshots/abort/should_abort_during_active_streaming.yaml index 0fa912159..1f5c085eb 100644 --- a/test/snapshots/abort/should_abort_during_active_streaming.yaml +++ b/test/snapshots/abort/should_abort_during_active_streaming.yaml @@ -1,5 +1,16 @@ models: - claude-sonnet-4.5 +# Two stored conversations cover the two legal histories after aborting an +# in-flight streaming turn: +# conv0 (race-win): the essay assistant turn finalized before the abort, so +# it remains in history -> [system, user(essay), +# assistant(essay), user(recovery)]. +# conv1 (race-lose): the abort dropped the in-flight essay assistant turn, so +# it is absent from history -> [system, user(essay), +# user(recovery)]. This is the common outcome with the +# Rust-reqwest transport in CLI 1.0.61+. +# The replay proxy matches a request as a strict prefix of a stored conversation +# and returns the next assistant message, so both histories resolve correctly. conversations: - messages: - role: system From 76fac9604dd1ab0a639bead874b15a01330cab95 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 10 Jun 2026 09:09:11 -0400 Subject: [PATCH 4/4] Delete stale Java generated files orphaned by InstructionsSources->InstructionSource rename These three generated files were left behind by the codegen rename from InstructionsSources to InstructionSource. They are dead code: InstructionsSources is referenced only within these three files, and the current InstructionSource* types are used instead. Java codegen does not delete orphaned files, so they require manual removal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../generated/rpc/InstructionsSources.java | 44 ------------------ .../rpc/InstructionsSourcesLocation.java | 39 ---------------- .../rpc/InstructionsSourcesType.java | 45 ------------------- 3 files changed, 128 deletions(-) delete mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSources.java delete mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSourcesLocation.java delete mode 100644 java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSourcesType.java diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSources.java b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSources.java deleted file mode 100644 index 9e6a458d4..000000000 --- a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSources.java +++ /dev/null @@ -1,44 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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; - -/** - * Schema for the `InstructionsSources` type. - * - * @since 1.0.0 - */ -@javax.annotation.processing.Generated("copilot-sdk-codegen") -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public record InstructionsSources( - /** Unique identifier for this source (used for toggling) */ - @JsonProperty("id") String id, - /** Human-readable label */ - @JsonProperty("label") String label, - /** File path relative to repo or absolute for home */ - @JsonProperty("sourcePath") String sourcePath, - /** Raw content of the instruction file */ - @JsonProperty("content") String content, - /** Category of instruction source — used for merge logic */ - @JsonProperty("type") InstructionsSourcesType type, - /** Where this source lives — used for UI grouping */ - @JsonProperty("location") InstructionsSourcesLocation location, - /** Glob pattern(s) from frontmatter — when set, this instruction applies only to matching files */ - @JsonProperty("applyTo") List applyTo, - /** Short description (body after frontmatter) for use in instruction tables */ - @JsonProperty("description") String description, - /** When true, this source starts disabled and must be toggled on by the user */ - @JsonProperty("defaultDisabled") Boolean defaultDisabled -) { -} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSourcesLocation.java b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSourcesLocation.java deleted file mode 100644 index 23db5a367..000000000 --- a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSourcesLocation.java +++ /dev/null @@ -1,39 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 javax.annotation.processing.Generated; - -/** - * Where this source lives — used for UI grouping - * - * @since 1.0.0 - */ -@javax.annotation.processing.Generated("copilot-sdk-codegen") -public enum InstructionsSourcesLocation { - /** The {@code user} variant. */ - USER("user"), - /** The {@code repository} variant. */ - REPOSITORY("repository"), - /** The {@code working-directory} variant. */ - WORKING_DIRECTORY("working-directory"), - /** The {@code plugin} variant. */ - PLUGIN("plugin"); - - private final String value; - InstructionsSourcesLocation(String value) { this.value = value; } - @com.fasterxml.jackson.annotation.JsonValue - public String getValue() { return value; } - @com.fasterxml.jackson.annotation.JsonCreator - public static InstructionsSourcesLocation fromValue(String value) { - for (InstructionsSourcesLocation v : values()) { - if (v.value.equals(value)) return v; - } - throw new IllegalArgumentException("Unknown InstructionsSourcesLocation value: " + value); - } -} diff --git a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSourcesType.java b/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSourcesType.java deleted file mode 100644 index 6fed6c4bf..000000000 --- a/java/src/generated/java/com/github/copilot/generated/rpc/InstructionsSourcesType.java +++ /dev/null @@ -1,45 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 javax.annotation.processing.Generated; - -/** - * Category of instruction source — used for merge logic - * - * @since 1.0.0 - */ -@javax.annotation.processing.Generated("copilot-sdk-codegen") -public enum InstructionsSourcesType { - /** The {@code home} variant. */ - HOME("home"), - /** The {@code repo} variant. */ - REPO("repo"), - /** The {@code model} variant. */ - MODEL("model"), - /** The {@code vscode} variant. */ - VSCODE("vscode"), - /** The {@code nested-agents} variant. */ - NESTED_AGENTS("nested-agents"), - /** The {@code child-instructions} variant. */ - CHILD_INSTRUCTIONS("child-instructions"), - /** The {@code plugin} variant. */ - PLUGIN("plugin"); - - private final String value; - InstructionsSourcesType(String value) { this.value = value; } - @com.fasterxml.jackson.annotation.JsonValue - public String getValue() { return value; } - @com.fasterxml.jackson.annotation.JsonCreator - public static InstructionsSourcesType fromValue(String value) { - for (InstructionsSourcesType v : values()) { - if (v.value.equals(value)) return v; - } - throw new IllegalArgumentException("Unknown InstructionsSourcesType value: " + value); - } -}