diff --git a/dotnet/src/Generated/Rpc.cs b/dotnet/src/Generated/Rpc.cs index f6ca0382f..4f2a6fa58 100644 --- a/dotnet/src/Generated/Rpc.cs +++ b/dotnet/src/Generated/Rpc.cs @@ -237,6 +237,10 @@ internal class SessionLogRequest /// When true, the message is transient and not persisted to the session event log on disk. [JsonPropertyName("ephemeral")] public bool? Ephemeral { get; set; } + + /// Optional URL the user can open in their browser for more details. + [JsonPropertyName("url")] + public string? Url { get; set; } } /// RPC data type for SessionModelGetCurrent operations. @@ -559,6 +563,319 @@ internal class SessionAgentDeselectRequest public string SessionId { get; set; } = string.Empty; } +/// RPC data type for SessionAgentReload operations. +public class SessionAgentReloadResult +{ + /// Reloaded custom agents. + [JsonPropertyName("agents")] + public List Agents { get => field ??= []; set; } +} + +/// RPC data type for SessionAgentReload operations. +internal class SessionAgentReloadRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// RPC data type for Skill operations. +public class Skill +{ + /// Unique identifier for the skill. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// Description of what the skill does. + [JsonPropertyName("description")] + public string Description { get; set; } = string.Empty; + + /// Source location type (e.g., project, personal, plugin). + [JsonPropertyName("source")] + public string Source { get; set; } = string.Empty; + + /// Whether the skill can be invoked by the user as a slash command. + [JsonPropertyName("userInvocable")] + public bool UserInvocable { get; set; } + + /// Whether the skill is currently enabled. + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } + + /// Absolute path to the skill file. + [JsonPropertyName("path")] + public string? Path { get; set; } +} + +/// RPC data type for SessionSkillsList operations. +public class SessionSkillsListResult +{ + /// Available skills. + [JsonPropertyName("skills")] + public List Skills { get => field ??= []; set; } +} + +/// RPC data type for SessionSkillsList operations. +internal class SessionSkillsListRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// RPC data type for SessionSkillsEnable operations. +public class SessionSkillsEnableResult +{ +} + +/// RPC data type for SessionSkillsEnable operations. +internal class SessionSkillsEnableRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; + + /// Name of the skill to enable. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; +} + +/// RPC data type for SessionSkillsDisable operations. +public class SessionSkillsDisableResult +{ +} + +/// RPC data type for SessionSkillsDisable operations. +internal class SessionSkillsDisableRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; + + /// Name of the skill to disable. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; +} + +/// RPC data type for SessionSkillsReload operations. +public class SessionSkillsReloadResult +{ +} + +/// RPC data type for SessionSkillsReload operations. +internal class SessionSkillsReloadRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// RPC data type for Server operations. +public class Server +{ + /// Server name (config key). + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// Connection status: connected, failed, pending, disabled, or not_configured. + [JsonPropertyName("status")] + public ServerStatus Status { get; set; } + + /// Configuration source: user, workspace, plugin, or builtin. + [JsonPropertyName("source")] + public string? Source { get; set; } + + /// Error message if the server failed to connect. + [JsonPropertyName("error")] + public string? Error { get; set; } +} + +/// RPC data type for SessionMcpList operations. +public class SessionMcpListResult +{ + /// Configured MCP servers. + [JsonPropertyName("servers")] + public List Servers { get => field ??= []; set; } +} + +/// RPC data type for SessionMcpList operations. +internal class SessionMcpListRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// RPC data type for SessionMcpEnable operations. +public class SessionMcpEnableResult +{ +} + +/// RPC data type for SessionMcpEnable operations. +internal class SessionMcpEnableRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; + + /// Name of the MCP server to enable. + [JsonPropertyName("serverName")] + public string ServerName { get; set; } = string.Empty; +} + +/// RPC data type for SessionMcpDisable operations. +public class SessionMcpDisableResult +{ +} + +/// RPC data type for SessionMcpDisable operations. +internal class SessionMcpDisableRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; + + /// Name of the MCP server to disable. + [JsonPropertyName("serverName")] + public string ServerName { get; set; } = string.Empty; +} + +/// RPC data type for SessionMcpReload operations. +public class SessionMcpReloadResult +{ +} + +/// RPC data type for SessionMcpReload operations. +internal class SessionMcpReloadRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// RPC data type for Plugin operations. +public class Plugin +{ + /// Plugin name. + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// Marketplace the plugin came from. + [JsonPropertyName("marketplace")] + public string Marketplace { get; set; } = string.Empty; + + /// Installed version. + [JsonPropertyName("version")] + public string? Version { get; set; } + + /// Whether the plugin is currently enabled. + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } +} + +/// RPC data type for SessionPluginsList operations. +public class SessionPluginsListResult +{ + /// Installed plugins. + [JsonPropertyName("plugins")] + public List Plugins { get => field ??= []; set; } +} + +/// RPC data type for SessionPluginsList operations. +internal class SessionPluginsListRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// RPC data type for Extension operations. +public class Extension +{ + /// Source-qualified ID (e.g., 'project:my-ext', 'user:auth-helper'). + [JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; + + /// Extension name (directory name). + [JsonPropertyName("name")] + public string Name { get; set; } = string.Empty; + + /// Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/). + [JsonPropertyName("source")] + public ExtensionSource Source { get; set; } + + /// Current status: running, disabled, failed, or starting. + [JsonPropertyName("status")] + public ExtensionStatus Status { get; set; } + + /// Process ID if the extension is running. + [JsonPropertyName("pid")] + public double? Pid { get; set; } +} + +/// RPC data type for SessionExtensionsList operations. +public class SessionExtensionsListResult +{ + /// Discovered extensions and their current status. + [JsonPropertyName("extensions")] + public List Extensions { get => field ??= []; set; } +} + +/// RPC data type for SessionExtensionsList operations. +internal class SessionExtensionsListRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + +/// RPC data type for SessionExtensionsEnable operations. +public class SessionExtensionsEnableResult +{ +} + +/// RPC data type for SessionExtensionsEnable operations. +internal class SessionExtensionsEnableRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; + + /// Source-qualified extension ID to enable. + [JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; +} + +/// RPC data type for SessionExtensionsDisable operations. +public class SessionExtensionsDisableResult +{ +} + +/// RPC data type for SessionExtensionsDisable operations. +internal class SessionExtensionsDisableRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; + + /// Source-qualified extension ID to disable. + [JsonPropertyName("id")] + public string Id { get; set; } = string.Empty; +} + +/// RPC data type for SessionExtensionsReload operations. +public class SessionExtensionsReloadResult +{ +} + +/// RPC data type for SessionExtensionsReload operations. +internal class SessionExtensionsReloadRequest +{ + /// Target session identifier. + [JsonPropertyName("sessionId")] + public string SessionId { get; set; } = string.Empty; +} + /// RPC data type for SessionCompactionCompact operations. public class SessionCompactionCompactResult { @@ -719,6 +1036,60 @@ public enum SessionModeGetResultMode } +/// Connection status: connected, failed, pending, disabled, or not_configured. +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum ServerStatus +{ + /// The connected variant. + [JsonStringEnumMemberName("connected")] + Connected, + /// The failed variant. + [JsonStringEnumMemberName("failed")] + Failed, + /// The pending variant. + [JsonStringEnumMemberName("pending")] + Pending, + /// The disabled variant. + [JsonStringEnumMemberName("disabled")] + Disabled, + /// The not_configured variant. + [JsonStringEnumMemberName("not_configured")] + NotConfigured, +} + + +/// Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/). +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum ExtensionSource +{ + /// The project variant. + [JsonStringEnumMemberName("project")] + Project, + /// The user variant. + [JsonStringEnumMemberName("user")] + User, +} + + +/// Current status: running, disabled, failed, or starting. +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum ExtensionStatus +{ + /// The running variant. + [JsonStringEnumMemberName("running")] + Running, + /// The disabled variant. + [JsonStringEnumMemberName("disabled")] + Disabled, + /// The failed variant. + [JsonStringEnumMemberName("failed")] + Failed, + /// The starting variant. + [JsonStringEnumMemberName("starting")] + Starting, +} + + /// Signal to send (default: SIGTERM). [JsonConverter(typeof(JsonStringEnumConverter))] public enum SessionShellKillRequestSignal @@ -833,6 +1204,10 @@ internal SessionRpc(JsonRpc rpc, string sessionId) Workspace = new WorkspaceApi(rpc, sessionId); Fleet = new FleetApi(rpc, sessionId); Agent = new AgentApi(rpc, sessionId); + Skills = new SkillsApi(rpc, sessionId); + Mcp = new McpApi(rpc, sessionId); + Plugins = new PluginsApi(rpc, sessionId); + Extensions = new ExtensionsApi(rpc, sessionId); Compaction = new CompactionApi(rpc, sessionId); Tools = new ToolsApi(rpc, sessionId); Permissions = new PermissionsApi(rpc, sessionId); @@ -857,6 +1232,18 @@ internal SessionRpc(JsonRpc rpc, string sessionId) /// Agent APIs. public AgentApi Agent { get; } + /// Skills APIs. + public SkillsApi Skills { get; } + + /// Mcp APIs. + public McpApi Mcp { get; } + + /// Plugins APIs. + public PluginsApi Plugins { get; } + + /// Extensions APIs. + public ExtensionsApi Extensions { get; } + /// Compaction APIs. public CompactionApi Compaction { get; } @@ -870,9 +1257,9 @@ internal SessionRpc(JsonRpc rpc, string sessionId) public ShellApi Shell { get; } /// Calls "session.log". - public async Task LogAsync(string message, SessionLogRequestLevel? level = null, bool? ephemeral = null, CancellationToken cancellationToken = default) + public async Task LogAsync(string message, SessionLogRequestLevel? level = null, bool? ephemeral = null, string? url = null, CancellationToken cancellationToken = default) { - var request = new SessionLogRequest { SessionId = _sessionId, Message = message, Level = level, Ephemeral = ephemeral }; + var request = new SessionLogRequest { SessionId = _sessionId, Message = message, Level = level, Ephemeral = ephemeral, Url = url }; return await CopilotClient.InvokeRpcAsync(_rpc, "session.log", [request], cancellationToken); } } @@ -1058,6 +1445,156 @@ public async Task DeselectAsync(CancellationToken ca var request = new SessionAgentDeselectRequest { SessionId = _sessionId }; return await CopilotClient.InvokeRpcAsync(_rpc, "session.agent.deselect", [request], cancellationToken); } + + /// Calls "session.agent.reload". + public async Task ReloadAsync(CancellationToken cancellationToken = default) + { + var request = new SessionAgentReloadRequest { SessionId = _sessionId }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.agent.reload", [request], cancellationToken); + } +} + +/// Provides session-scoped Skills APIs. +public class SkillsApi +{ + private readonly JsonRpc _rpc; + private readonly string _sessionId; + + internal SkillsApi(JsonRpc rpc, string sessionId) + { + _rpc = rpc; + _sessionId = sessionId; + } + + /// Calls "session.skills.list". + public async Task ListAsync(CancellationToken cancellationToken = default) + { + var request = new SessionSkillsListRequest { SessionId = _sessionId }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.skills.list", [request], cancellationToken); + } + + /// Calls "session.skills.enable". + public async Task EnableAsync(string name, CancellationToken cancellationToken = default) + { + var request = new SessionSkillsEnableRequest { SessionId = _sessionId, Name = name }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.skills.enable", [request], cancellationToken); + } + + /// Calls "session.skills.disable". + public async Task DisableAsync(string name, CancellationToken cancellationToken = default) + { + var request = new SessionSkillsDisableRequest { SessionId = _sessionId, Name = name }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.skills.disable", [request], cancellationToken); + } + + /// Calls "session.skills.reload". + public async Task ReloadAsync(CancellationToken cancellationToken = default) + { + var request = new SessionSkillsReloadRequest { SessionId = _sessionId }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.skills.reload", [request], cancellationToken); + } +} + +/// Provides session-scoped Mcp APIs. +public class McpApi +{ + private readonly JsonRpc _rpc; + private readonly string _sessionId; + + internal McpApi(JsonRpc rpc, string sessionId) + { + _rpc = rpc; + _sessionId = sessionId; + } + + /// Calls "session.mcp.list". + public async Task ListAsync(CancellationToken cancellationToken = default) + { + var request = new SessionMcpListRequest { SessionId = _sessionId }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.mcp.list", [request], cancellationToken); + } + + /// Calls "session.mcp.enable". + public async Task EnableAsync(string serverName, CancellationToken cancellationToken = default) + { + var request = new SessionMcpEnableRequest { SessionId = _sessionId, ServerName = serverName }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.mcp.enable", [request], cancellationToken); + } + + /// Calls "session.mcp.disable". + public async Task DisableAsync(string serverName, CancellationToken cancellationToken = default) + { + var request = new SessionMcpDisableRequest { SessionId = _sessionId, ServerName = serverName }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.mcp.disable", [request], cancellationToken); + } + + /// Calls "session.mcp.reload". + public async Task ReloadAsync(CancellationToken cancellationToken = default) + { + var request = new SessionMcpReloadRequest { SessionId = _sessionId }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.mcp.reload", [request], cancellationToken); + } +} + +/// Provides session-scoped Plugins APIs. +public class PluginsApi +{ + private readonly JsonRpc _rpc; + private readonly string _sessionId; + + internal PluginsApi(JsonRpc rpc, string sessionId) + { + _rpc = rpc; + _sessionId = sessionId; + } + + /// Calls "session.plugins.list". + public async Task ListAsync(CancellationToken cancellationToken = default) + { + var request = new SessionPluginsListRequest { SessionId = _sessionId }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.plugins.list", [request], cancellationToken); + } +} + +/// Provides session-scoped Extensions APIs. +public class ExtensionsApi +{ + private readonly JsonRpc _rpc; + private readonly string _sessionId; + + internal ExtensionsApi(JsonRpc rpc, string sessionId) + { + _rpc = rpc; + _sessionId = sessionId; + } + + /// Calls "session.extensions.list". + public async Task ListAsync(CancellationToken cancellationToken = default) + { + var request = new SessionExtensionsListRequest { SessionId = _sessionId }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.extensions.list", [request], cancellationToken); + } + + /// Calls "session.extensions.enable". + public async Task EnableAsync(string id, CancellationToken cancellationToken = default) + { + var request = new SessionExtensionsEnableRequest { SessionId = _sessionId, Id = id }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.extensions.enable", [request], cancellationToken); + } + + /// Calls "session.extensions.disable". + public async Task DisableAsync(string id, CancellationToken cancellationToken = default) + { + var request = new SessionExtensionsDisableRequest { SessionId = _sessionId, Id = id }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.extensions.disable", [request], cancellationToken); + } + + /// Calls "session.extensions.reload". + public async Task ReloadAsync(CancellationToken cancellationToken = default) + { + var request = new SessionExtensionsReloadRequest { SessionId = _sessionId }; + return await CopilotClient.InvokeRpcAsync(_rpc, "session.extensions.reload", [request], cancellationToken); + } } /// Provides session-scoped Compaction APIs. @@ -1154,6 +1691,7 @@ public async Task KillAsync(string processId, SessionShe [JsonSerializable(typeof(AccountGetQuotaResult))] [JsonSerializable(typeof(AccountGetQuotaResultQuotaSnapshotsValue))] [JsonSerializable(typeof(Agent))] +[JsonSerializable(typeof(Extension))] [JsonSerializable(typeof(Model))] [JsonSerializable(typeof(ModelBilling))] [JsonSerializable(typeof(ModelCapabilities))] @@ -1163,6 +1701,8 @@ public async Task KillAsync(string processId, SessionShe [JsonSerializable(typeof(ModelsListResult))] [JsonSerializable(typeof(PingRequest))] [JsonSerializable(typeof(PingResult))] +[JsonSerializable(typeof(Plugin))] +[JsonSerializable(typeof(Server))] [JsonSerializable(typeof(SessionAgentDeselectRequest))] [JsonSerializable(typeof(SessionAgentDeselectResult))] [JsonSerializable(typeof(SessionAgentGetCurrentRequest))] @@ -1170,15 +1710,33 @@ public async Task KillAsync(string processId, SessionShe [JsonSerializable(typeof(SessionAgentGetCurrentResultAgent))] [JsonSerializable(typeof(SessionAgentListRequest))] [JsonSerializable(typeof(SessionAgentListResult))] +[JsonSerializable(typeof(SessionAgentReloadRequest))] +[JsonSerializable(typeof(SessionAgentReloadResult))] [JsonSerializable(typeof(SessionAgentSelectRequest))] [JsonSerializable(typeof(SessionAgentSelectResult))] [JsonSerializable(typeof(SessionAgentSelectResultAgent))] [JsonSerializable(typeof(SessionCompactionCompactRequest))] [JsonSerializable(typeof(SessionCompactionCompactResult))] +[JsonSerializable(typeof(SessionExtensionsDisableRequest))] +[JsonSerializable(typeof(SessionExtensionsDisableResult))] +[JsonSerializable(typeof(SessionExtensionsEnableRequest))] +[JsonSerializable(typeof(SessionExtensionsEnableResult))] +[JsonSerializable(typeof(SessionExtensionsListRequest))] +[JsonSerializable(typeof(SessionExtensionsListResult))] +[JsonSerializable(typeof(SessionExtensionsReloadRequest))] +[JsonSerializable(typeof(SessionExtensionsReloadResult))] [JsonSerializable(typeof(SessionFleetStartRequest))] [JsonSerializable(typeof(SessionFleetStartResult))] [JsonSerializable(typeof(SessionLogRequest))] [JsonSerializable(typeof(SessionLogResult))] +[JsonSerializable(typeof(SessionMcpDisableRequest))] +[JsonSerializable(typeof(SessionMcpDisableResult))] +[JsonSerializable(typeof(SessionMcpEnableRequest))] +[JsonSerializable(typeof(SessionMcpEnableResult))] +[JsonSerializable(typeof(SessionMcpListRequest))] +[JsonSerializable(typeof(SessionMcpListResult))] +[JsonSerializable(typeof(SessionMcpReloadRequest))] +[JsonSerializable(typeof(SessionMcpReloadResult))] [JsonSerializable(typeof(SessionModeGetRequest))] [JsonSerializable(typeof(SessionModeGetResult))] [JsonSerializable(typeof(SessionModeSetRequest))] @@ -1195,10 +1753,20 @@ public async Task KillAsync(string processId, SessionShe [JsonSerializable(typeof(SessionPlanReadResult))] [JsonSerializable(typeof(SessionPlanUpdateRequest))] [JsonSerializable(typeof(SessionPlanUpdateResult))] +[JsonSerializable(typeof(SessionPluginsListRequest))] +[JsonSerializable(typeof(SessionPluginsListResult))] [JsonSerializable(typeof(SessionShellExecRequest))] [JsonSerializable(typeof(SessionShellExecResult))] [JsonSerializable(typeof(SessionShellKillRequest))] [JsonSerializable(typeof(SessionShellKillResult))] +[JsonSerializable(typeof(SessionSkillsDisableRequest))] +[JsonSerializable(typeof(SessionSkillsDisableResult))] +[JsonSerializable(typeof(SessionSkillsEnableRequest))] +[JsonSerializable(typeof(SessionSkillsEnableResult))] +[JsonSerializable(typeof(SessionSkillsListRequest))] +[JsonSerializable(typeof(SessionSkillsListResult))] +[JsonSerializable(typeof(SessionSkillsReloadRequest))] +[JsonSerializable(typeof(SessionSkillsReloadResult))] [JsonSerializable(typeof(SessionToolsHandlePendingToolCallRequest))] [JsonSerializable(typeof(SessionToolsHandlePendingToolCallResult))] [JsonSerializable(typeof(SessionWorkspaceCreateFileRequest))] @@ -1207,6 +1775,7 @@ public async Task KillAsync(string processId, SessionShe [JsonSerializable(typeof(SessionWorkspaceListFilesResult))] [JsonSerializable(typeof(SessionWorkspaceReadFileRequest))] [JsonSerializable(typeof(SessionWorkspaceReadFileResult))] +[JsonSerializable(typeof(Skill))] [JsonSerializable(typeof(Tool))] [JsonSerializable(typeof(ToolsListRequest))] [JsonSerializable(typeof(ToolsListResult))] diff --git a/dotnet/src/Generated/SessionEvents.cs b/dotnet/src/Generated/SessionEvents.cs index 5ef1be352..02866f4fb 100644 --- a/dotnet/src/Generated/SessionEvents.cs +++ b/dotnet/src/Generated/SessionEvents.cs @@ -46,14 +46,18 @@ namespace GitHub.Copilot.SDK; [JsonDerivedType(typeof(SessionCompactionStartEvent), "session.compaction_start")] [JsonDerivedType(typeof(SessionContextChangedEvent), "session.context_changed")] [JsonDerivedType(typeof(SessionErrorEvent), "session.error")] +[JsonDerivedType(typeof(SessionExtensionsLoadedEvent), "session.extensions_loaded")] [JsonDerivedType(typeof(SessionHandoffEvent), "session.handoff")] [JsonDerivedType(typeof(SessionIdleEvent), "session.idle")] [JsonDerivedType(typeof(SessionInfoEvent), "session.info")] +[JsonDerivedType(typeof(SessionMcpServerStatusChangedEvent), "session.mcp_server_status_changed")] +[JsonDerivedType(typeof(SessionMcpServersLoadedEvent), "session.mcp_servers_loaded")] [JsonDerivedType(typeof(SessionModeChangedEvent), "session.mode_changed")] [JsonDerivedType(typeof(SessionModelChangeEvent), "session.model_change")] [JsonDerivedType(typeof(SessionPlanChangedEvent), "session.plan_changed")] [JsonDerivedType(typeof(SessionResumeEvent), "session.resume")] [JsonDerivedType(typeof(SessionShutdownEvent), "session.shutdown")] +[JsonDerivedType(typeof(SessionSkillsLoadedEvent), "session.skills_loaded")] [JsonDerivedType(typeof(SessionSnapshotRewindEvent), "session.snapshot_rewind")] [JsonDerivedType(typeof(SessionStartEvent), "session.start")] [JsonDerivedType(typeof(SessionTaskCompleteEvent), "session.task_complete")] @@ -363,7 +367,7 @@ public partial class SessionCompactionCompleteEvent : SessionEvent public required SessionCompactionCompleteData Data { get; set; } } -/// Task completion notification with optional summary from the agent. +/// Task completion notification with summary from the agent. /// Represents the session.task_complete event. public partial class SessionTaskCompleteEvent : SessionEvent { @@ -376,8 +380,7 @@ public partial class SessionTaskCompleteEvent : SessionEvent public required SessionTaskCompleteData Data { get; set; } } -/// User message content with optional attachments, source information, and interaction metadata. -/// Represents the user.message event. +/// Represents the user.message event. public partial class UserMessageEvent : SessionEvent { /// @@ -907,6 +910,54 @@ public partial class SessionBackgroundTasksChangedEvent : SessionEvent public required SessionBackgroundTasksChangedData Data { get; set; } } +/// Represents the session.skills_loaded event. +public partial class SessionSkillsLoadedEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "session.skills_loaded"; + + /// The session.skills_loaded event payload. + [JsonPropertyName("data")] + public required SessionSkillsLoadedData Data { get; set; } +} + +/// Represents the session.mcp_servers_loaded event. +public partial class SessionMcpServersLoadedEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "session.mcp_servers_loaded"; + + /// The session.mcp_servers_loaded event payload. + [JsonPropertyName("data")] + public required SessionMcpServersLoadedData Data { get; set; } +} + +/// Represents the session.mcp_server_status_changed event. +public partial class SessionMcpServerStatusChangedEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "session.mcp_server_status_changed"; + + /// The session.mcp_server_status_changed event payload. + [JsonPropertyName("data")] + public required SessionMcpServerStatusChangedData Data { get; set; } +} + +/// Represents the session.extensions_loaded event. +public partial class SessionExtensionsLoadedEvent : SessionEvent +{ + /// + [JsonIgnore] + public override string Type => "session.extensions_loaded"; + + /// The session.extensions_loaded event payload. + [JsonPropertyName("data")] + public required SessionExtensionsLoadedData Data { get; set; } +} + /// Session initialization metadata including context and configuration. public partial class SessionStartData { @@ -1008,6 +1059,11 @@ public partial class SessionErrorData [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("providerCallId")] public string? ProviderCallId { get; set; } + + /// Optional URL associated with this error that the user can open in a browser. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("url")] + public string? Url { get; set; } } /// Payload indicating the agent is idle; includes any background tasks still in flight. @@ -1037,6 +1093,11 @@ public partial class SessionInfoData /// Human-readable informational message for display in the timeline. [JsonPropertyName("message")] public required string Message { get; set; } + + /// Optional URL associated with this message that the user can open in a browser. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("url")] + public string? Url { get; set; } } /// Warning message for timeline display with categorization. @@ -1049,6 +1110,11 @@ public partial class SessionWarningData /// Human-readable warning message for display in the timeline. [JsonPropertyName("message")] public required string Message { get; set; } + + /// Optional URL associated with this warning that the user can open in a browser. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("url")] + public string? Url { get; set; } } /// Model change details including previous and new model identifiers. @@ -1346,16 +1412,16 @@ public partial class SessionCompactionCompleteData public string? RequestId { get; set; } } -/// Task completion notification with optional summary from the agent. +/// Task completion notification with summary from the agent. public partial class SessionTaskCompleteData { - /// Optional summary of the completed task, provided by the agent. + /// Summary of the completed task, provided by the agent. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("summary")] public string? Summary { get; set; } } -/// User message content with optional attachments, source information, and interaction metadata. +/// Event payload for . public partial class UserMessageData { /// The user's message text as displayed in the timeline. @@ -1372,10 +1438,10 @@ public partial class UserMessageData [JsonPropertyName("attachments")] public UserMessageDataAttachmentsItem[]? Attachments { get; set; } - /// Origin of this message, used for timeline filtering and telemetry (e.g., "user", "autopilot", "skill", or "command"). + /// Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected messages that should be hidden from the user). [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("source")] - public UserMessageDataSource? Source { get; set; } + public string? Source { get; set; } /// The agent mode that was active when this message was sent. [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -1953,6 +2019,11 @@ public partial class UserInputRequestedData [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonPropertyName("allowFreeform")] public bool? AllowFreeform { get; set; } + + /// The LLM-assigned tool call ID that triggered this request; used by remote UIs to correlate responses. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("toolCallId")] + public string? ToolCallId { get; set; } } /// User input request completion notification signaling UI dismissal. @@ -2100,6 +2171,42 @@ public partial class SessionBackgroundTasksChangedData { } +/// Event payload for . +public partial class SessionSkillsLoadedData +{ + /// Array of resolved skill metadata. + [JsonPropertyName("skills")] + public required SessionSkillsLoadedDataSkillsItem[] Skills { get; set; } +} + +/// Event payload for . +public partial class SessionMcpServersLoadedData +{ + /// Array of MCP server status summaries. + [JsonPropertyName("servers")] + public required SessionMcpServersLoadedDataServersItem[] Servers { get; set; } +} + +/// Event payload for . +public partial class SessionMcpServerStatusChangedData +{ + /// Name of the MCP server whose status changed. + [JsonPropertyName("serverName")] + public required string ServerName { get; set; } + + /// New connection status: connected, failed, pending, disabled, or not_configured. + [JsonPropertyName("status")] + public required SessionMcpServersLoadedDataServersItemStatus Status { get; set; } +} + +/// Event payload for . +public partial class SessionExtensionsLoadedData +{ + /// Array of discovered extensions and their status. + [JsonPropertyName("extensions")] + public required SessionExtensionsLoadedDataExtensionsItem[] Extensions { get; set; } +} + /// Working directory and git context at session start. /// Nested data type for SessionStartDataContext. public partial class SessionStartDataContext @@ -2787,6 +2894,27 @@ public partial class SystemNotificationDataKindAgentCompleted : SystemNotificati public string? Prompt { get; set; } } +/// The agent_idle variant of . +public partial class SystemNotificationDataKindAgentIdle : SystemNotificationDataKind +{ + /// + [JsonIgnore] + public override string Type => "agent_idle"; + + /// Unique identifier of the background agent. + [JsonPropertyName("agentId")] + public required string AgentId { get; set; } + + /// Type of the agent (e.g., explore, task, general-purpose). + [JsonPropertyName("agentType")] + public required string AgentType { get; set; } + + /// Human-readable description of the agent task. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("description")] + public string? Description { get; set; } +} + /// The shell_completed variant of . public partial class SystemNotificationDataKindShellCompleted : SystemNotificationDataKind { @@ -2832,6 +2960,7 @@ public partial class SystemNotificationDataKindShellDetachedCompleted : SystemNo TypeDiscriminatorPropertyName = "type", UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)] [JsonDerivedType(typeof(SystemNotificationDataKindAgentCompleted), "agent_completed")] +[JsonDerivedType(typeof(SystemNotificationDataKindAgentIdle), "agent_idle")] [JsonDerivedType(typeof(SystemNotificationDataKindShellCompleted), "shell_completed")] [JsonDerivedType(typeof(SystemNotificationDataKindShellDetachedCompleted), "shell_detached_completed")] public partial class SystemNotificationDataKind @@ -3148,6 +3277,77 @@ public partial class ElicitationRequestedDataRequestedSchema public string[]? Required { get; set; } } +/// Nested data type for SessionSkillsLoadedDataSkillsItem. +public partial class SessionSkillsLoadedDataSkillsItem +{ + /// Unique identifier for the skill. + [JsonPropertyName("name")] + public required string Name { get; set; } + + /// Description of what the skill does. + [JsonPropertyName("description")] + public required string Description { get; set; } + + /// Source location type of the skill (e.g., project, personal, plugin). + [JsonPropertyName("source")] + public required string Source { get; set; } + + /// Whether the skill can be invoked by the user as a slash command. + [JsonPropertyName("userInvocable")] + public required bool UserInvocable { get; set; } + + /// Whether the skill is currently enabled. + [JsonPropertyName("enabled")] + public required bool Enabled { get; set; } + + /// Absolute path to the skill file, if available. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("path")] + public string? Path { get; set; } +} + +/// Nested data type for SessionMcpServersLoadedDataServersItem. +public partial class SessionMcpServersLoadedDataServersItem +{ + /// Server name (config key). + [JsonPropertyName("name")] + public required string Name { get; set; } + + /// Connection status: connected, failed, pending, disabled, or not_configured. + [JsonPropertyName("status")] + public required SessionMcpServersLoadedDataServersItemStatus Status { get; set; } + + /// Configuration source: user, workspace, plugin, or builtin. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("source")] + public string? Source { get; set; } + + /// Error message if the server failed to connect. + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + [JsonPropertyName("error")] + public string? Error { get; set; } +} + +/// Nested data type for SessionExtensionsLoadedDataExtensionsItem. +public partial class SessionExtensionsLoadedDataExtensionsItem +{ + /// Source-qualified extension ID (e.g., 'project:my-ext', 'user:auth-helper'). + [JsonPropertyName("id")] + public required string Id { get; set; } + + /// Extension name (directory name). + [JsonPropertyName("name")] + public required string Name { get; set; } + + /// Discovery source. + [JsonPropertyName("source")] + public required SessionExtensionsLoadedDataExtensionsItemSource Source { get; set; } + + /// Current status: running, disabled, failed, or starting. + [JsonPropertyName("status")] + public required SessionExtensionsLoadedDataExtensionsItemStatus Status { get; set; } +} + /// Hosting platform type of the repository (github or ado). [JsonConverter(typeof(JsonStringEnumConverter))] public enum SessionStartDataContextHostType @@ -3226,42 +3426,6 @@ public enum UserMessageDataAttachmentsItemGithubReferenceReferenceType Discussion, } -/// Origin of this message, used for timeline filtering and telemetry (e.g., "user", "autopilot", "skill", or "command"). -[JsonConverter(typeof(JsonStringEnumConverter))] -public enum UserMessageDataSource -{ - /// The user variant. - [JsonStringEnumMemberName("user")] - User, - /// The autopilot variant. - [JsonStringEnumMemberName("autopilot")] - Autopilot, - /// The skill variant. - [JsonStringEnumMemberName("skill")] - Skill, - /// The system variant. - [JsonStringEnumMemberName("system")] - System, - /// The command variant. - [JsonStringEnumMemberName("command")] - Command, - /// The immediate-prompt variant. - [JsonStringEnumMemberName("immediate-prompt")] - ImmediatePrompt, - /// The jit-instruction variant. - [JsonStringEnumMemberName("jit-instruction")] - JitInstruction, - /// The snippy-blocking variant. - [JsonStringEnumMemberName("snippy-blocking")] - SnippyBlocking, - /// The thinking-exhausted-continuation variant. - [JsonStringEnumMemberName("thinking-exhausted-continuation")] - ThinkingExhaustedContinuation, - /// The other variant. - [JsonStringEnumMemberName("other")] - Other, -} - /// The agent mode that was active when this message was sent. [JsonConverter(typeof(JsonStringEnumConverter))] public enum UserMessageDataAgentMode @@ -3349,6 +3513,57 @@ public enum PermissionCompletedDataResultKind DeniedByContentExclusionPolicy, } +/// Connection status: connected, failed, pending, disabled, or not_configured. +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum SessionMcpServersLoadedDataServersItemStatus +{ + /// The connected variant. + [JsonStringEnumMemberName("connected")] + Connected, + /// The failed variant. + [JsonStringEnumMemberName("failed")] + Failed, + /// The pending variant. + [JsonStringEnumMemberName("pending")] + Pending, + /// The disabled variant. + [JsonStringEnumMemberName("disabled")] + Disabled, + /// The not_configured variant. + [JsonStringEnumMemberName("not_configured")] + NotConfigured, +} + +/// Discovery source. +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum SessionExtensionsLoadedDataExtensionsItemSource +{ + /// The project variant. + [JsonStringEnumMemberName("project")] + Project, + /// The user variant. + [JsonStringEnumMemberName("user")] + User, +} + +/// Current status: running, disabled, failed, or starting. +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum SessionExtensionsLoadedDataExtensionsItemStatus +{ + /// The running variant. + [JsonStringEnumMemberName("running")] + Running, + /// The disabled variant. + [JsonStringEnumMemberName("disabled")] + Disabled, + /// The failed variant. + [JsonStringEnumMemberName("failed")] + Failed, + /// The starting variant. + [JsonStringEnumMemberName("starting")] + Starting, +} + [JsonSourceGenerationOptions( JsonSerializerDefaults.Web, AllowOutOfOrderMetadataProperties = true, @@ -3429,6 +3644,9 @@ public enum PermissionCompletedDataResultKind [JsonSerializable(typeof(SessionErrorData))] [JsonSerializable(typeof(SessionErrorEvent))] [JsonSerializable(typeof(SessionEvent))] +[JsonSerializable(typeof(SessionExtensionsLoadedData))] +[JsonSerializable(typeof(SessionExtensionsLoadedDataExtensionsItem))] +[JsonSerializable(typeof(SessionExtensionsLoadedEvent))] [JsonSerializable(typeof(SessionHandoffData))] [JsonSerializable(typeof(SessionHandoffDataRepository))] [JsonSerializable(typeof(SessionHandoffEvent))] @@ -3439,6 +3657,11 @@ public enum PermissionCompletedDataResultKind [JsonSerializable(typeof(SessionIdleEvent))] [JsonSerializable(typeof(SessionInfoData))] [JsonSerializable(typeof(SessionInfoEvent))] +[JsonSerializable(typeof(SessionMcpServerStatusChangedData))] +[JsonSerializable(typeof(SessionMcpServerStatusChangedEvent))] +[JsonSerializable(typeof(SessionMcpServersLoadedData))] +[JsonSerializable(typeof(SessionMcpServersLoadedDataServersItem))] +[JsonSerializable(typeof(SessionMcpServersLoadedEvent))] [JsonSerializable(typeof(SessionModeChangedData))] [JsonSerializable(typeof(SessionModeChangedEvent))] [JsonSerializable(typeof(SessionModelChangeData))] @@ -3451,6 +3674,9 @@ public enum PermissionCompletedDataResultKind [JsonSerializable(typeof(SessionShutdownData))] [JsonSerializable(typeof(SessionShutdownDataCodeChanges))] [JsonSerializable(typeof(SessionShutdownEvent))] +[JsonSerializable(typeof(SessionSkillsLoadedData))] +[JsonSerializable(typeof(SessionSkillsLoadedDataSkillsItem))] +[JsonSerializable(typeof(SessionSkillsLoadedEvent))] [JsonSerializable(typeof(SessionSnapshotRewindData))] [JsonSerializable(typeof(SessionSnapshotRewindEvent))] [JsonSerializable(typeof(SessionStartData))] @@ -3488,6 +3714,7 @@ public enum PermissionCompletedDataResultKind [JsonSerializable(typeof(SystemNotificationData))] [JsonSerializable(typeof(SystemNotificationDataKind))] [JsonSerializable(typeof(SystemNotificationDataKindAgentCompleted))] +[JsonSerializable(typeof(SystemNotificationDataKindAgentIdle))] [JsonSerializable(typeof(SystemNotificationDataKindShellCompleted))] [JsonSerializable(typeof(SystemNotificationDataKindShellDetachedCompleted))] [JsonSerializable(typeof(SystemNotificationEvent))] diff --git a/go/generated_session_events.go b/go/generated_session_events.go index 55eea011e..9c28c07f3 100644 --- a/go/generated_session_events.go +++ b/go/generated_session_events.go @@ -66,10 +66,7 @@ type SessionEvent struct { // Conversation compaction results including success status, metrics, and optional error // details // - // Task completion notification with optional summary from the agent - // - // User message content with optional attachments, source information, and interaction - // metadata + // Task completion notification with summary from the agent // // Empty payload; the event signals that the pending message queue has changed // @@ -203,10 +200,7 @@ type SessionEvent struct { // Conversation compaction results including success status, metrics, and optional error // details // -// # Task completion notification with optional summary from the agent -// -// User message content with optional attachments, source information, and interaction -// metadata +// # Task completion notification with summary from the agent // // Empty payload; the event signals that the pending message queue has changed // @@ -343,6 +337,12 @@ type Data struct { Stack *string `json:"stack,omitempty"` // HTTP status code from the upstream request, if applicable StatusCode *int64 `json:"statusCode,omitempty"` + // Optional URL associated with this error that the user can open in a browser + // + // Optional URL associated with this message that the user can open in a browser + // + // Optional URL associated with this warning that the user can open in a browser + URL *string `json:"url,omitempty"` // Background tasks still running when the agent became idle BackgroundTasks *BackgroundTasks `json:"backgroundTasks,omitempty"` // The new display title for the session @@ -383,7 +383,7 @@ type Data struct { SourceType *SourceType `json:"sourceType,omitempty"` // Summary of the work done in the source session // - // Optional summary of the completed task, provided by the agent + // Summary of the completed task, provided by the agent // // Summary of the plan that was created Summary *string `json:"summary,omitempty"` @@ -530,9 +530,9 @@ type Data struct { // // CAPI interaction ID for correlating this tool execution with upstream telemetry InteractionID *string `json:"interactionId,omitempty"` - // Origin of this message, used for timeline filtering and telemetry (e.g., "user", - // "autopilot", "skill", or "command") - Source *Source `json:"source,omitempty"` + // Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected + // messages that should be hidden from the user) + Source *string `json:"source,omitempty"` // Transformed version of the message sent to the model, with XML wrapping, timestamps, and // other augmentations for prompt caching TransformedContent *string `json:"transformedContent,omitempty"` @@ -618,6 +618,9 @@ type Data struct { // // Tool call ID of the parent tool invocation that spawned this sub-agent // + // The LLM-assigned tool call ID that triggered this request; used by remote UIs to + // correlate responses + // // Tool call ID assigned to this external tool invocation ToolCallID *string `json:"toolCallId,omitempty"` // Name of the tool the user wants to invoke @@ -706,6 +709,16 @@ type Data struct { PlanContent *string `json:"planContent,omitempty"` // The recommended action for the user to take RecommendedAction *string `json:"recommendedAction,omitempty"` + // Array of resolved skill metadata + Skills []Skill `json:"skills,omitempty"` + // Array of MCP server status summaries + Servers []Server `json:"servers,omitempty"` + // Name of the MCP server whose status changed + ServerName *string `json:"serverName,omitempty"` + // New connection status: connected, failed, pending, disabled, or not_configured + Status *ServerStatus `json:"status,omitempty"` + // Array of discovered extensions and their status + Extensions []Extension `json:"extensions,omitempty"` } // A user message attachment — a file, directory, code selection, blob, or GitHub reference @@ -885,6 +898,17 @@ type ErrorClass struct { Stack *string `json:"stack,omitempty"` } +type Extension struct { + // Source-qualified extension ID (e.g., 'project:my-ext', 'user:auth-helper') + ID string `json:"id"` + // Extension name (directory name) + Name string `json:"name"` + // Discovery source + Source Source `json:"source"` + // Current status: running, disabled, failed, or starting + Status ExtensionStatus `json:"status"` +} + // Structured metadata identifying what triggered this notification type KindClass struct { // Unique identifier of the background agent @@ -898,8 +922,8 @@ type KindClass struct { // The full prompt given to the background agent Prompt *string `json:"prompt,omitempty"` // Whether the agent completed successfully or failed - Status *Status `json:"status,omitempty"` - Type KindType `json:"type"` + Status *KindStatus `json:"status,omitempty"` + Type KindType `json:"type"` // Exit code of the shell command, if available ExitCode *float64 `json:"exitCode,omitempty"` // Unique identifier of the shell session @@ -964,7 +988,7 @@ type PermissionRequest struct { // Whether the UI can offer session-wide approval for this command pattern CanOfferSessionApproval *bool `json:"canOfferSessionApproval,omitempty"` // Parsed command identifiers found in the command text - Commands []CommandElement `json:"commands,omitempty"` + Commands []Command `json:"commands,omitempty"` // The complete shell command text to be executed FullCommandText *string `json:"fullCommandText,omitempty"` // Whether the command includes a file write redirection (e.g., > or >>) @@ -1027,7 +1051,7 @@ type PermissionRequest struct { ToolArgs interface{} `json:"toolArgs"` } -type CommandElement struct { +type Command struct { // Command identifier (e.g., executable name) Identifier string `json:"identifier"` // Whether this command is read-only (no side effects) @@ -1172,6 +1196,32 @@ type ResourceClass struct { Blob *string `json:"blob,omitempty"` } +type Server struct { + // Error message if the server failed to connect + Error *string `json:"error,omitempty"` + // Server name (config key) + Name string `json:"name"` + // Configuration source: user, workspace, plugin, or builtin + Source *string `json:"source,omitempty"` + // Connection status: connected, failed, pending, disabled, or not_configured + Status ServerStatus `json:"status"` +} + +type Skill struct { + // Description of what the skill does + Description string `json:"description"` + // Whether the skill is currently enabled + Enabled bool `json:"enabled"` + // Unique identifier for the skill + Name string `json:"name"` + // Absolute path to the skill file, if available + Path *string `json:"path,omitempty"` + // Source location type of the skill (e.g., project, personal, plugin) + Source string `json:"source"` + // Whether the skill can be invoked by the user as a slash command + UserInvocable bool `json:"userInvocable"` +} + // A tool invocation request from the assistant type ToolRequest struct { // Arguments to pass to the tool, format depends on the tool @@ -1193,10 +1243,10 @@ type ToolRequest struct { type AgentMode string const ( - AgentModeAutopilot AgentMode = "autopilot" - AgentModeShell AgentMode = "shell" - Interactive AgentMode = "interactive" - Plan AgentMode = "plan" + AgentModeShell AgentMode = "shell" + Autopilot AgentMode = "autopilot" + Interactive AgentMode = "interactive" + Plan AgentMode = "plan" ) // Type of GitHub reference @@ -1226,18 +1276,37 @@ const ( Github HostType = "github" ) +// Discovery source +type Source string + +const ( + Project Source = "project" + User Source = "user" +) + +// Current status: running, disabled, failed, or starting +type ExtensionStatus string + +const ( + PurpleDisabled ExtensionStatus = "disabled" + PurpleFailed ExtensionStatus = "failed" + Running ExtensionStatus = "running" + Starting ExtensionStatus = "starting" +) + // Whether the agent completed successfully or failed -type Status string +type KindStatus string const ( - Completed Status = "completed" - Failed Status = "failed" + Completed KindStatus = "completed" + FluffyFailed KindStatus = "failed" ) type KindType string const ( AgentCompleted KindType = "agent_completed" + AgentIdle KindType = "agent_idle" ShellCompleted KindType = "shell_completed" ShellDetachedCompleted KindType = "shell_detached_completed" ) @@ -1312,33 +1381,29 @@ const ( type Role string const ( - Developer Role = "developer" - RoleSystem Role = "system" + Developer Role = "developer" + System Role = "system" ) -// Whether the session ended normally ("routine") or due to a crash/fatal error ("error") -type ShutdownType string +// Connection status: connected, failed, pending, disabled, or not_configured +// +// New connection status: connected, failed, pending, disabled, or not_configured +type ServerStatus string const ( - Error ShutdownType = "error" - Routine ShutdownType = "routine" + Connected ServerStatus = "connected" + FluffyDisabled ServerStatus = "disabled" + NotConfigured ServerStatus = "not_configured" + Pending ServerStatus = "pending" + TentacledFailed ServerStatus = "failed" ) -// Origin of this message, used for timeline filtering and telemetry (e.g., "user", -// "autopilot", "skill", or "command") -type Source string +// Whether the session ended normally ("routine") or due to a crash/fatal error ("error") +type ShutdownType string const ( - Command Source = "command" - ImmediatePrompt Source = "immediate-prompt" - JITInstruction Source = "jit-instruction" - Other Source = "other" - Skill Source = "skill" - SnippyBlocking Source = "snippy-blocking" - SourceAutopilot Source = "autopilot" - SourceSystem Source = "system" - ThinkingExhaustedContinuation Source = "thinking-exhausted-continuation" - User Source = "user" + Error ShutdownType = "error" + Routine ShutdownType = "routine" ) // Origin type of the session being handed off @@ -1389,14 +1454,18 @@ const ( SessionCompactionStart SessionEventType = "session.compaction_start" SessionContextChanged SessionEventType = "session.context_changed" SessionError SessionEventType = "session.error" + SessionExtensionsLoaded SessionEventType = "session.extensions_loaded" SessionHandoff SessionEventType = "session.handoff" SessionIdle SessionEventType = "session.idle" SessionInfo SessionEventType = "session.info" + SessionMCPServerStatusChanged SessionEventType = "session.mcp_server_status_changed" + SessionMCPServersLoaded SessionEventType = "session.mcp_servers_loaded" SessionModeChanged SessionEventType = "session.mode_changed" SessionModelChange SessionEventType = "session.model_change" SessionPlanChanged SessionEventType = "session.plan_changed" SessionResume SessionEventType = "session.resume" SessionShutdown SessionEventType = "session.shutdown" + SessionSkillsLoaded SessionEventType = "session.skills_loaded" SessionSnapshotRewind SessionEventType = "session.snapshot_rewind" SessionStart SessionEventType = "session.start" SessionTaskComplete SessionEventType = "session.task_complete" diff --git a/go/rpc/generated_rpc.go b/go/rpc/generated_rpc.go index ffe87455e..7929994cf 100644 --- a/go/rpc/generated_rpc.go +++ b/go/rpc/generated_rpc.go @@ -220,10 +220,10 @@ type SessionFleetStartParams struct { type SessionAgentListResult struct { // Available custom agents - Agents []AgentElement `json:"agents"` + Agents []SessionAgentListResultAgent `json:"agents"` } -type AgentElement struct { +type SessionAgentListResultAgent struct { // Description of the agent's purpose Description string `json:"description"` // Human-readable display name @@ -269,6 +269,147 @@ type SessionAgentSelectParams struct { type SessionAgentDeselectResult struct { } +type SessionAgentReloadResult struct { + // Reloaded custom agents + Agents []SessionAgentReloadResultAgent `json:"agents"` +} + +type SessionAgentReloadResultAgent struct { + // Description of the agent's purpose + Description string `json:"description"` + // Human-readable display name + DisplayName string `json:"displayName"` + // Unique identifier of the custom agent + Name string `json:"name"` +} + +type SessionSkillsListResult struct { + // Available skills + Skills []Skill `json:"skills"` +} + +type Skill struct { + // Description of what the skill does + Description string `json:"description"` + // Whether the skill is currently enabled + Enabled bool `json:"enabled"` + // Unique identifier for the skill + Name string `json:"name"` + // Absolute path to the skill file + Path *string `json:"path,omitempty"` + // Source location type (e.g., project, personal, plugin) + Source string `json:"source"` + // Whether the skill can be invoked by the user as a slash command + UserInvocable bool `json:"userInvocable"` +} + +type SessionSkillsEnableResult struct { +} + +type SessionSkillsEnableParams struct { + // Name of the skill to enable + Name string `json:"name"` +} + +type SessionSkillsDisableResult struct { +} + +type SessionSkillsDisableParams struct { + // Name of the skill to disable + Name string `json:"name"` +} + +type SessionSkillsReloadResult struct { +} + +type SessionMCPListResult struct { + // Configured MCP servers + Servers []Server `json:"servers"` +} + +type Server struct { + // Error message if the server failed to connect + Error *string `json:"error,omitempty"` + // Server name (config key) + Name string `json:"name"` + // Configuration source: user, workspace, plugin, or builtin + Source *string `json:"source,omitempty"` + // Connection status: connected, failed, pending, disabled, or not_configured + Status ServerStatus `json:"status"` +} + +type SessionMCPEnableResult struct { +} + +type SessionMCPEnableParams struct { + // Name of the MCP server to enable + ServerName string `json:"serverName"` +} + +type SessionMCPDisableResult struct { +} + +type SessionMCPDisableParams struct { + // Name of the MCP server to disable + ServerName string `json:"serverName"` +} + +type SessionMCPReloadResult struct { +} + +type SessionPluginsListResult struct { + // Installed plugins + Plugins []Plugin `json:"plugins"` +} + +type Plugin struct { + // Whether the plugin is currently enabled + Enabled bool `json:"enabled"` + // Marketplace the plugin came from + Marketplace string `json:"marketplace"` + // Plugin name + Name string `json:"name"` + // Installed version + Version *string `json:"version,omitempty"` +} + +type SessionExtensionsListResult struct { + // Discovered extensions and their current status + Extensions []Extension `json:"extensions"` +} + +type Extension struct { + // Source-qualified ID (e.g., 'project:my-ext', 'user:auth-helper') + ID string `json:"id"` + // Extension name (directory name) + Name string `json:"name"` + // Process ID if the extension is running + PID *int64 `json:"pid,omitempty"` + // Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/) + Source Source `json:"source"` + // Current status: running, disabled, failed, or starting + Status ExtensionStatus `json:"status"` +} + +type SessionExtensionsEnableResult struct { +} + +type SessionExtensionsEnableParams struct { + // Source-qualified extension ID to enable + ID string `json:"id"` +} + +type SessionExtensionsDisableResult struct { +} + +type SessionExtensionsDisableParams struct { + // Source-qualified extension ID to disable + ID string `json:"id"` +} + +type SessionExtensionsReloadResult struct { +} + type SessionCompactionCompactResult struct { // Number of messages removed during compaction MessagesRemoved float64 `json:"messagesRemoved"` @@ -327,6 +468,8 @@ type SessionLogParams struct { Level *Level `json:"level,omitempty"` // Human-readable message Message string `json:"message"` + // Optional URL the user can open in their browser for more details + URL *string `json:"url,omitempty"` } type SessionShellExecResult struct { @@ -368,6 +511,35 @@ const ( Plan Mode = "plan" ) +// Connection status: connected, failed, pending, disabled, or not_configured +type ServerStatus string + +const ( + Connected ServerStatus = "connected" + NotConfigured ServerStatus = "not_configured" + Pending ServerStatus = "pending" + PurpleDisabled ServerStatus = "disabled" + PurpleFailed ServerStatus = "failed" +) + +// Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/) +type Source string + +const ( + Project Source = "project" + User Source = "user" +) + +// Current status: running, disabled, failed, or starting +type ExtensionStatus string + +const ( + FluffyDisabled ExtensionStatus = "disabled" + FluffyFailed ExtensionStatus = "failed" + Running ExtensionStatus = "running" + Starting ExtensionStatus = "starting" +) + type Kind string const ( @@ -724,6 +896,226 @@ func (a *AgentRpcApi) Deselect(ctx context.Context) (*SessionAgentDeselectResult return &result, nil } +func (a *AgentRpcApi) Reload(ctx context.Context) (*SessionAgentReloadResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + raw, err := a.client.Request("session.agent.reload", req) + if err != nil { + return nil, err + } + var result SessionAgentReloadResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +type SkillsRpcApi struct { + client *jsonrpc2.Client + sessionID string +} + +func (a *SkillsRpcApi) List(ctx context.Context) (*SessionSkillsListResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + raw, err := a.client.Request("session.skills.list", req) + if err != nil { + return nil, err + } + var result SessionSkillsListResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *SkillsRpcApi) Enable(ctx context.Context, params *SessionSkillsEnableParams) (*SessionSkillsEnableResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + if params != nil { + req["name"] = params.Name + } + raw, err := a.client.Request("session.skills.enable", req) + if err != nil { + return nil, err + } + var result SessionSkillsEnableResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *SkillsRpcApi) Disable(ctx context.Context, params *SessionSkillsDisableParams) (*SessionSkillsDisableResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + if params != nil { + req["name"] = params.Name + } + raw, err := a.client.Request("session.skills.disable", req) + if err != nil { + return nil, err + } + var result SessionSkillsDisableResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *SkillsRpcApi) Reload(ctx context.Context) (*SessionSkillsReloadResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + raw, err := a.client.Request("session.skills.reload", req) + if err != nil { + return nil, err + } + var result SessionSkillsReloadResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +type McpRpcApi struct { + client *jsonrpc2.Client + sessionID string +} + +func (a *McpRpcApi) List(ctx context.Context) (*SessionMcpListResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + raw, err := a.client.Request("session.mcp.list", req) + if err != nil { + return nil, err + } + var result SessionMcpListResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *McpRpcApi) Enable(ctx context.Context, params *SessionMcpEnableParams) (*SessionMcpEnableResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + if params != nil { + req["serverName"] = params.ServerName + } + raw, err := a.client.Request("session.mcp.enable", req) + if err != nil { + return nil, err + } + var result SessionMcpEnableResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *McpRpcApi) Disable(ctx context.Context, params *SessionMcpDisableParams) (*SessionMcpDisableResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + if params != nil { + req["serverName"] = params.ServerName + } + raw, err := a.client.Request("session.mcp.disable", req) + if err != nil { + return nil, err + } + var result SessionMcpDisableResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *McpRpcApi) Reload(ctx context.Context) (*SessionMcpReloadResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + raw, err := a.client.Request("session.mcp.reload", req) + if err != nil { + return nil, err + } + var result SessionMcpReloadResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +type PluginsRpcApi struct { + client *jsonrpc2.Client + sessionID string +} + +func (a *PluginsRpcApi) List(ctx context.Context) (*SessionPluginsListResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + raw, err := a.client.Request("session.plugins.list", req) + if err != nil { + return nil, err + } + var result SessionPluginsListResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +type ExtensionsRpcApi struct { + client *jsonrpc2.Client + sessionID string +} + +func (a *ExtensionsRpcApi) List(ctx context.Context) (*SessionExtensionsListResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + raw, err := a.client.Request("session.extensions.list", req) + if err != nil { + return nil, err + } + var result SessionExtensionsListResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *ExtensionsRpcApi) Enable(ctx context.Context, params *SessionExtensionsEnableParams) (*SessionExtensionsEnableResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + if params != nil { + req["id"] = params.ID + } + raw, err := a.client.Request("session.extensions.enable", req) + if err != nil { + return nil, err + } + var result SessionExtensionsEnableResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *ExtensionsRpcApi) Disable(ctx context.Context, params *SessionExtensionsDisableParams) (*SessionExtensionsDisableResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + if params != nil { + req["id"] = params.ID + } + raw, err := a.client.Request("session.extensions.disable", req) + if err != nil { + return nil, err + } + var result SessionExtensionsDisableResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + +func (a *ExtensionsRpcApi) Reload(ctx context.Context) (*SessionExtensionsReloadResult, error) { + req := map[string]interface{}{"sessionId": a.sessionID} + raw, err := a.client.Request("session.extensions.reload", req) + if err != nil { + return nil, err + } + var result SessionExtensionsReloadResult + if err := json.Unmarshal(raw, &result); err != nil { + return nil, err + } + return &result, nil +} + type CompactionRpcApi struct { client *jsonrpc2.Client sessionID string @@ -847,6 +1239,10 @@ type SessionRpc struct { Workspace *WorkspaceRpcApi Fleet *FleetRpcApi Agent *AgentRpcApi + Skills *SkillsRpcApi + Mcp *McpRpcApi + Plugins *PluginsRpcApi + Extensions *ExtensionsRpcApi Compaction *CompactionRpcApi Tools *ToolsRpcApi Permissions *PermissionsRpcApi @@ -863,6 +1259,9 @@ func (a *SessionRpc) Log(ctx context.Context, params *SessionLogParams) (*Sessio if params.Ephemeral != nil { req["ephemeral"] = *params.Ephemeral } + if params.URL != nil { + req["url"] = *params.URL + } } raw, err := a.client.Request("session.log", req) if err != nil { @@ -883,6 +1282,10 @@ func NewSessionRpc(client *jsonrpc2.Client, sessionID string) *SessionRpc { Workspace: &WorkspaceRpcApi{client: client, sessionID: sessionID}, Fleet: &FleetRpcApi{client: client, sessionID: sessionID}, Agent: &AgentRpcApi{client: client, sessionID: sessionID}, + Skills: &SkillsRpcApi{client: client, sessionID: sessionID}, + Mcp: &McpRpcApi{client: client, sessionID: sessionID}, + Plugins: &PluginsRpcApi{client: client, sessionID: sessionID}, + Extensions: &ExtensionsRpcApi{client: client, sessionID: sessionID}, Compaction: &CompactionRpcApi{client: client, sessionID: sessionID}, Tools: &ToolsRpcApi{client: client, sessionID: sessionID}, Permissions: &PermissionsRpcApi{client: client, sessionID: sessionID}, diff --git a/nodejs/package-lock.json b/nodejs/package-lock.json index 0952122f0..867a5d5ef 100644 --- a/nodejs/package-lock.json +++ b/nodejs/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.8", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.4", + "@github/copilot": "^1.0.7", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, @@ -662,26 +662,26 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.4.tgz", - "integrity": "sha512-IpPg+zYplLu4F4lmatEDdR/1Y/jJ9cGWt89m3K3H4YSfYrZ5Go4UlM28llulYCG7sVdQeIGauQN1/KiBI/Rocg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.7.tgz", + "integrity": "sha512-KHBaJ1kbc19pqUMnB9LubPtwWVOaDCzWbzwsJss+DvHyCpr8wP8jR3GEZUnhq3rsuXI96ZKEeEozXM0NqxCAiw==", "license": "SEE LICENSE IN LICENSE.md", "bin": { "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.4", - "@github/copilot-darwin-x64": "1.0.4", - "@github/copilot-linux-arm64": "1.0.4", - "@github/copilot-linux-x64": "1.0.4", - "@github/copilot-win32-arm64": "1.0.4", - "@github/copilot-win32-x64": "1.0.4" + "@github/copilot-darwin-arm64": "1.0.7", + "@github/copilot-darwin-x64": "1.0.7", + "@github/copilot-linux-arm64": "1.0.7", + "@github/copilot-linux-x64": "1.0.7", + "@github/copilot-win32-arm64": "1.0.7", + "@github/copilot-win32-x64": "1.0.7" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.4.tgz", - "integrity": "sha512-/YGGhv6cp0ItolsF0HsLq2KmesA4atn0IEYApBs770fzJ8OP2pkOEzrxo3gWU3wc7fHF2uDB1RrJEZ7QSFLdEQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.7.tgz", + "integrity": "sha512-yQITowpkQYamww59CwcG5JTWV9ahj7nMH6oqObMJaeqXnG7j7dqE/YhLkujQZ3XR8VXAoIa1rZ3TahdMu94gOA==", "cpu": [ "arm64" ], @@ -695,9 +695,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.4.tgz", - "integrity": "sha512-gwn2QjZbc1SqPVSAtDMesU1NopyHZT8Qsn37xPfznpV9s94KVyX4TTiDZaUwfnI0wr8kVHBL46RPLNz6I8kR9A==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.7.tgz", + "integrity": "sha512-23vP5bHaFA030nB3tr+dUUdRm2SqmQbs2fZUQ4F7JeYy59jp9hi8lBdaZp/TeQnjEirAUU9H2HZxsGRIIUWp7g==", "cpu": [ "x64" ], @@ -711,9 +711,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.4.tgz", - "integrity": "sha512-92vzHKxN55BpI76sP/5fXIXfat1gzAhsq4bNLqLENGfZyMP/25OiVihCZuQHnvxzXaHBITFGUvtxfdll2kbcng==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.7.tgz", + "integrity": "sha512-g0mB98oyXKcpd4sMNBc5n1h3UhLy9AGRlT//VL8BXPSzvlTH/dJP3fdx74pbLSgvz105to/YUMmEAFfv25VNaw==", "cpu": [ "arm64" ], @@ -727,9 +727,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.4.tgz", - "integrity": "sha512-wQvpwf4/VMTnSmWyYzq07Xg18Vxg7aZ5NVkkXqlLTuXRASW0kvCCb5USEtXHHzR7E6rJztkhCjFRE1bZW8jAGw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.7.tgz", + "integrity": "sha512-TRxzvTo9I4ehYJLFHTCJSJYQ4QnO/V9zebqwszxHpJRxuBd7FV4cxLmfOBqZcUpEpZgBH+VJ4OG98BPW7YEtJQ==", "cpu": [ "x64" ], @@ -743,9 +743,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.4.tgz", - "integrity": "sha512-zOvD/5GVxDf0ZdlTkK+m55Vs55xuHNmACX50ZO2N23ZGG2dmkdS4mkruL59XB5ISgrOfeqvnqrwTFHbmPZtLfw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.7.tgz", + "integrity": "sha512-4yFgW1K0MlKBrK5BwMIj4nMu5KSFfytNXrs8iOpVgp7erEvKVyN7VXb6SWkoU3M9TfeNlqP6Uje2rxDvgR1u5w==", "cpu": [ "arm64" ], @@ -759,9 +759,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.4.tgz", - "integrity": "sha512-yQenHMdkV0b77mF6aLM60TuwtNZ592TluptVDF+80Sj2zPfCpLyvrRh2FCIHRtuwTy4BfxETh2hCFHef8E6IOw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.7.tgz", + "integrity": "sha512-RDZlvPf/q6B54wLXJRmI39fc9+pwfcAjSwUqw0FeQruCTQgoUl8eo9NqeVWDFlr3RdzgVSMUiJHc3aiifVG6lA==", "cpu": [ "x64" ], diff --git a/nodejs/package.json b/nodejs/package.json index 214ef3466..214216e63 100644 --- a/nodejs/package.json +++ b/nodejs/package.json @@ -44,7 +44,7 @@ "author": "GitHub", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.4", + "@github/copilot": "^1.0.7", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/samples/package-lock.json b/nodejs/samples/package-lock.json index 4f93a271c..6a76cc4bd 100644 --- a/nodejs/samples/package-lock.json +++ b/nodejs/samples/package-lock.json @@ -18,7 +18,7 @@ "version": "0.1.8", "license": "MIT", "dependencies": { - "@github/copilot": "^1.0.4", + "@github/copilot": "^1.0.7", "vscode-jsonrpc": "^8.2.1", "zod": "^4.3.6" }, diff --git a/nodejs/src/generated/rpc.ts b/nodejs/src/generated/rpc.ts index e5ba9ad4c..341baed0c 100644 --- a/nodejs/src/generated/rpc.ts +++ b/nodejs/src/generated/rpc.ts @@ -452,6 +452,274 @@ export interface SessionAgentDeselectParams { sessionId: string; } +export interface SessionAgentReloadResult { + /** + * Reloaded custom agents + */ + agents: { + /** + * Unique identifier of the custom agent + */ + name: string; + /** + * Human-readable display name + */ + displayName: string; + /** + * Description of the agent's purpose + */ + description: string; + }[]; +} + +export interface SessionAgentReloadParams { + /** + * Target session identifier + */ + sessionId: string; +} + +export interface SessionSkillsListResult { + /** + * Available skills + */ + skills: { + /** + * Unique identifier for the skill + */ + name: string; + /** + * Description of what the skill does + */ + description: string; + /** + * Source location type (e.g., project, personal, plugin) + */ + source: string; + /** + * Whether the skill can be invoked by the user as a slash command + */ + userInvocable: boolean; + /** + * Whether the skill is currently enabled + */ + enabled: boolean; + /** + * Absolute path to the skill file + */ + path?: string; + }[]; +} + +export interface SessionSkillsListParams { + /** + * Target session identifier + */ + sessionId: string; +} + +export interface SessionSkillsEnableResult {} + +export interface SessionSkillsEnableParams { + /** + * Target session identifier + */ + sessionId: string; + /** + * Name of the skill to enable + */ + name: string; +} + +export interface SessionSkillsDisableResult {} + +export interface SessionSkillsDisableParams { + /** + * Target session identifier + */ + sessionId: string; + /** + * Name of the skill to disable + */ + name: string; +} + +export interface SessionSkillsReloadResult {} + +export interface SessionSkillsReloadParams { + /** + * Target session identifier + */ + sessionId: string; +} + +export interface SessionMcpListResult { + /** + * Configured MCP servers + */ + servers: { + /** + * Server name (config key) + */ + name: string; + /** + * Connection status: connected, failed, pending, disabled, or not_configured + */ + status: "connected" | "failed" | "pending" | "disabled" | "not_configured"; + /** + * Configuration source: user, workspace, plugin, or builtin + */ + source?: string; + /** + * Error message if the server failed to connect + */ + error?: string; + }[]; +} + +export interface SessionMcpListParams { + /** + * Target session identifier + */ + sessionId: string; +} + +export interface SessionMcpEnableResult {} + +export interface SessionMcpEnableParams { + /** + * Target session identifier + */ + sessionId: string; + /** + * Name of the MCP server to enable + */ + serverName: string; +} + +export interface SessionMcpDisableResult {} + +export interface SessionMcpDisableParams { + /** + * Target session identifier + */ + sessionId: string; + /** + * Name of the MCP server to disable + */ + serverName: string; +} + +export interface SessionMcpReloadResult {} + +export interface SessionMcpReloadParams { + /** + * Target session identifier + */ + sessionId: string; +} + +export interface SessionPluginsListResult { + /** + * Installed plugins + */ + plugins: { + /** + * Plugin name + */ + name: string; + /** + * Marketplace the plugin came from + */ + marketplace: string; + /** + * Installed version + */ + version?: string; + /** + * Whether the plugin is currently enabled + */ + enabled: boolean; + }[]; +} + +export interface SessionPluginsListParams { + /** + * Target session identifier + */ + sessionId: string; +} + +export interface SessionExtensionsListResult { + /** + * Discovered extensions and their current status + */ + extensions: { + /** + * Source-qualified ID (e.g., 'project:my-ext', 'user:auth-helper') + */ + id: string; + /** + * Extension name (directory name) + */ + name: string; + /** + * Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/) + */ + source: "project" | "user"; + /** + * Current status: running, disabled, failed, or starting + */ + status: "running" | "disabled" | "failed" | "starting"; + /** + * Process ID if the extension is running + */ + pid?: number; + }[]; +} + +export interface SessionExtensionsListParams { + /** + * Target session identifier + */ + sessionId: string; +} + +export interface SessionExtensionsEnableResult {} + +export interface SessionExtensionsEnableParams { + /** + * Target session identifier + */ + sessionId: string; + /** + * Source-qualified extension ID to enable + */ + id: string; +} + +export interface SessionExtensionsDisableResult {} + +export interface SessionExtensionsDisableParams { + /** + * Target session identifier + */ + sessionId: string; + /** + * Source-qualified extension ID to disable + */ + id: string; +} + +export interface SessionExtensionsReloadResult {} + +export interface SessionExtensionsReloadParams { + /** + * Target session identifier + */ + sessionId: string; +} + export interface SessionCompactionCompactResult { /** * Whether compaction completed successfully @@ -559,6 +827,10 @@ export interface SessionLogParams { * When true, the message is transient and not persisted to the session event log on disk */ ephemeral?: boolean; + /** + * Optional URL the user can open in their browser for more details + */ + url?: string; } export interface SessionShellExecResult { @@ -673,6 +945,42 @@ export function createSessionRpc(connection: MessageConnection, sessionId: strin connection.sendRequest("session.agent.select", { sessionId, ...params }), deselect: async (): Promise => connection.sendRequest("session.agent.deselect", { sessionId }), + reload: async (): Promise => + connection.sendRequest("session.agent.reload", { sessionId }), + }, + skills: { + list: async (): Promise => + connection.sendRequest("session.skills.list", { sessionId }), + enable: async (params: Omit): Promise => + connection.sendRequest("session.skills.enable", { sessionId, ...params }), + disable: async (params: Omit): Promise => + connection.sendRequest("session.skills.disable", { sessionId, ...params }), + reload: async (): Promise => + connection.sendRequest("session.skills.reload", { sessionId }), + }, + mcp: { + list: async (): Promise => + connection.sendRequest("session.mcp.list", { sessionId }), + enable: async (params: Omit): Promise => + connection.sendRequest("session.mcp.enable", { sessionId, ...params }), + disable: async (params: Omit): Promise => + connection.sendRequest("session.mcp.disable", { sessionId, ...params }), + reload: async (): Promise => + connection.sendRequest("session.mcp.reload", { sessionId }), + }, + plugins: { + list: async (): Promise => + connection.sendRequest("session.plugins.list", { sessionId }), + }, + extensions: { + list: async (): Promise => + connection.sendRequest("session.extensions.list", { sessionId }), + enable: async (params: Omit): Promise => + connection.sendRequest("session.extensions.enable", { sessionId, ...params }), + disable: async (params: Omit): Promise => + connection.sendRequest("session.extensions.disable", { sessionId, ...params }), + reload: async (): Promise => + connection.sendRequest("session.extensions.reload", { sessionId }), }, compaction: { compact: async (): Promise => diff --git a/nodejs/src/generated/session-events.ts b/nodejs/src/generated/session-events.ts index e9d48bc57..0250a527a 100644 --- a/nodejs/src/generated/session-events.ts +++ b/nodejs/src/generated/session-events.ts @@ -212,6 +212,10 @@ export type SessionEvent = * GitHub request tracing ID (x-github-request-id header) for correlating with server-side logs */ providerCallId?: string; + /** + * Optional URL associated with this error that the user can open in a browser + */ + url?: string; }; } | { @@ -325,6 +329,10 @@ export type SessionEvent = * Human-readable informational message for display in the timeline */ message: string; + /** + * Optional URL associated with this message that the user can open in a browser + */ + url?: string; }; } | { @@ -357,6 +365,10 @@ export type SessionEvent = * Human-readable warning message for display in the timeline */ message: string; + /** + * Optional URL associated with this warning that the user can open in a browser + */ + url?: string; }; } | { @@ -955,11 +967,11 @@ export type SessionEvent = ephemeral?: boolean; type: "session.task_complete"; /** - * Task completion notification with optional summary from the agent + * Task completion notification with summary from the agent */ data: { /** - * Optional summary of the completed task, provided by the agent + * Summary of the completed task, provided by the agent */ summary?: string; }; @@ -982,9 +994,6 @@ export type SessionEvent = */ ephemeral?: boolean; type: "user.message"; - /** - * User message content with optional attachments, source information, and interaction metadata - */ data: { /** * The user's message text as displayed in the timeline @@ -1134,19 +1143,9 @@ export type SessionEvent = } )[]; /** - * Origin of this message, used for timeline filtering and telemetry (e.g., "user", "autopilot", "skill", or "command") + * Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected messages that should be hidden from the user) */ - source?: - | "user" - | "autopilot" - | "skill" - | "system" - | "command" - | "immediate-prompt" - | "jit-instruction" - | "snippy-blocking" - | "thinking-exhausted-continuation" - | "other"; + source?: string; /** * The agent mode that was active when this message was sent */ @@ -2434,6 +2433,21 @@ export type SessionEvent = */ prompt?: string; } + | { + type: "agent_idle"; + /** + * Unique identifier of the background agent + */ + agentId: string; + /** + * Type of the agent (e.g., explore, task, general-purpose) + */ + agentType: string; + /** + * Human-readable description of the agent task + */ + description?: string; + } | { type: "shell_completed"; /** @@ -2785,6 +2799,10 @@ export type SessionEvent = * Whether the user can provide a free-form text response in addition to predefined choices */ allowFreeform?: boolean; + /** + * The LLM-assigned tool call ID that triggered this request; used by remote UIs to correlate responses + */ + toolCallId?: string; }; } | { @@ -3121,4 +3139,155 @@ export type SessionEvent = ephemeral: true; type: "session.background_tasks_changed"; data: {}; + } + | { + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + ephemeral: true; + type: "session.skills_loaded"; + data: { + /** + * Array of resolved skill metadata + */ + skills: { + /** + * Unique identifier for the skill + */ + name: string; + /** + * Description of what the skill does + */ + description: string; + /** + * Source location type of the skill (e.g., project, personal, plugin) + */ + source: string; + /** + * Whether the skill can be invoked by the user as a slash command + */ + userInvocable: boolean; + /** + * Whether the skill is currently enabled + */ + enabled: boolean; + /** + * Absolute path to the skill file, if available + */ + path?: string; + }[]; + }; + } + | { + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + ephemeral: true; + type: "session.mcp_servers_loaded"; + data: { + /** + * Array of MCP server status summaries + */ + servers: { + /** + * Server name (config key) + */ + name: string; + /** + * Connection status: connected, failed, pending, disabled, or not_configured + */ + status: "connected" | "failed" | "pending" | "disabled" | "not_configured"; + /** + * Configuration source: user, workspace, plugin, or builtin + */ + source?: string; + /** + * Error message if the server failed to connect + */ + error?: string; + }[]; + }; + } + | { + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + ephemeral: true; + type: "session.mcp_server_status_changed"; + data: { + /** + * Name of the MCP server whose status changed + */ + serverName: string; + /** + * New connection status: connected, failed, pending, disabled, or not_configured + */ + status: "connected" | "failed" | "pending" | "disabled" | "not_configured"; + }; + } + | { + /** + * Unique event identifier (UUID v4), generated when the event is emitted + */ + id: string; + /** + * ISO 8601 timestamp when the event was created + */ + timestamp: string; + /** + * ID of the chronologically preceding event in the session, forming a linked chain. Null for the first event. + */ + parentId: string | null; + ephemeral: true; + type: "session.extensions_loaded"; + data: { + /** + * Array of discovered extensions and their status + */ + extensions: { + /** + * Source-qualified extension ID (e.g., 'project:my-ext', 'user:auth-helper') + */ + id: string; + /** + * Extension name (directory name) + */ + name: string; + /** + * Discovery source + */ + source: "project" | "user"; + /** + * Current status: running, disabled, failed, or starting + */ + status: "running" | "disabled" | "failed" | "starting"; + }[]; + }; }; diff --git a/python/copilot/generated/rpc.py b/python/copilot/generated/rpc.py index 29b7463df..1bc431ee6 100644 --- a/python/copilot/generated/rpc.py +++ b/python/copilot/generated/rpc.py @@ -74,6 +74,11 @@ def to_enum(c: type[EnumT], x: Any) -> EnumT: return x.value +def from_int(x: Any) -> int: + assert isinstance(x, int) and not isinstance(x, bool) + return x + + @dataclass class PingResult: message: str @@ -760,7 +765,7 @@ def to_dict(self) -> dict: @dataclass -class AgentElement: +class SessionAgentListResultAgent: description: str """Description of the agent's purpose""" @@ -771,12 +776,12 @@ class AgentElement: """Unique identifier of the custom agent""" @staticmethod - def from_dict(obj: Any) -> 'AgentElement': + def from_dict(obj: Any) -> 'SessionAgentListResultAgent': assert isinstance(obj, dict) description = from_str(obj.get("description")) display_name = from_str(obj.get("displayName")) name = from_str(obj.get("name")) - return AgentElement(description, display_name, name) + return SessionAgentListResultAgent(description, display_name, name) def to_dict(self) -> dict: result: dict = {} @@ -788,18 +793,18 @@ def to_dict(self) -> dict: @dataclass class SessionAgentListResult: - agents: list[AgentElement] + agents: list[SessionAgentListResultAgent] """Available custom agents""" @staticmethod def from_dict(obj: Any) -> 'SessionAgentListResult': assert isinstance(obj, dict) - agents = from_list(AgentElement.from_dict, obj.get("agents")) + agents = from_list(SessionAgentListResultAgent.from_dict, obj.get("agents")) return SessionAgentListResult(agents) def to_dict(self) -> dict: result: dict = {} - result["agents"] = from_list(lambda x: to_class(AgentElement, x), self.agents) + result["agents"] = from_list(lambda x: to_class(SessionAgentListResultAgent, x), self.agents) return result @@ -922,6 +927,502 @@ def to_dict(self) -> dict: return result +@dataclass +class SessionAgentReloadResultAgent: + description: str + """Description of the agent's purpose""" + + display_name: str + """Human-readable display name""" + + name: str + """Unique identifier of the custom agent""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionAgentReloadResultAgent': + assert isinstance(obj, dict) + description = from_str(obj.get("description")) + display_name = from_str(obj.get("displayName")) + name = from_str(obj.get("name")) + return SessionAgentReloadResultAgent(description, display_name, name) + + def to_dict(self) -> dict: + result: dict = {} + result["description"] = from_str(self.description) + result["displayName"] = from_str(self.display_name) + result["name"] = from_str(self.name) + return result + + +@dataclass +class SessionAgentReloadResult: + agents: list[SessionAgentReloadResultAgent] + """Reloaded custom agents""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionAgentReloadResult': + assert isinstance(obj, dict) + agents = from_list(SessionAgentReloadResultAgent.from_dict, obj.get("agents")) + return SessionAgentReloadResult(agents) + + def to_dict(self) -> dict: + result: dict = {} + result["agents"] = from_list(lambda x: to_class(SessionAgentReloadResultAgent, x), self.agents) + return result + + +@dataclass +class Skill: + description: str + """Description of what the skill does""" + + enabled: bool + """Whether the skill is currently enabled""" + + name: str + """Unique identifier for the skill""" + + source: str + """Source location type (e.g., project, personal, plugin)""" + + user_invocable: bool + """Whether the skill can be invoked by the user as a slash command""" + + path: str | None = None + """Absolute path to the skill file""" + + @staticmethod + def from_dict(obj: Any) -> 'Skill': + assert isinstance(obj, dict) + description = from_str(obj.get("description")) + enabled = from_bool(obj.get("enabled")) + name = from_str(obj.get("name")) + source = from_str(obj.get("source")) + user_invocable = from_bool(obj.get("userInvocable")) + path = from_union([from_str, from_none], obj.get("path")) + return Skill(description, enabled, name, source, user_invocable, path) + + def to_dict(self) -> dict: + result: dict = {} + result["description"] = from_str(self.description) + result["enabled"] = from_bool(self.enabled) + result["name"] = from_str(self.name) + result["source"] = from_str(self.source) + result["userInvocable"] = from_bool(self.user_invocable) + if self.path is not None: + result["path"] = from_union([from_str, from_none], self.path) + return result + + +@dataclass +class SessionSkillsListResult: + skills: list[Skill] + """Available skills""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionSkillsListResult': + assert isinstance(obj, dict) + skills = from_list(Skill.from_dict, obj.get("skills")) + return SessionSkillsListResult(skills) + + def to_dict(self) -> dict: + result: dict = {} + result["skills"] = from_list(lambda x: to_class(Skill, x), self.skills) + return result + + +@dataclass +class SessionSkillsEnableResult: + @staticmethod + def from_dict(obj: Any) -> 'SessionSkillsEnableResult': + assert isinstance(obj, dict) + return SessionSkillsEnableResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + + +@dataclass +class SessionSkillsEnableParams: + name: str + """Name of the skill to enable""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionSkillsEnableParams': + assert isinstance(obj, dict) + name = from_str(obj.get("name")) + return SessionSkillsEnableParams(name) + + def to_dict(self) -> dict: + result: dict = {} + result["name"] = from_str(self.name) + return result + + +@dataclass +class SessionSkillsDisableResult: + @staticmethod + def from_dict(obj: Any) -> 'SessionSkillsDisableResult': + assert isinstance(obj, dict) + return SessionSkillsDisableResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + + +@dataclass +class SessionSkillsDisableParams: + name: str + """Name of the skill to disable""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionSkillsDisableParams': + assert isinstance(obj, dict) + name = from_str(obj.get("name")) + return SessionSkillsDisableParams(name) + + def to_dict(self) -> dict: + result: dict = {} + result["name"] = from_str(self.name) + return result + + +@dataclass +class SessionSkillsReloadResult: + @staticmethod + def from_dict(obj: Any) -> 'SessionSkillsReloadResult': + assert isinstance(obj, dict) + return SessionSkillsReloadResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + + +class ServerStatus(Enum): + """Connection status: connected, failed, pending, disabled, or not_configured""" + + CONNECTED = "connected" + DISABLED = "disabled" + FAILED = "failed" + NOT_CONFIGURED = "not_configured" + PENDING = "pending" + + +@dataclass +class Server: + name: str + """Server name (config key)""" + + status: ServerStatus + """Connection status: connected, failed, pending, disabled, or not_configured""" + + error: str | None = None + """Error message if the server failed to connect""" + + source: str | None = None + """Configuration source: user, workspace, plugin, or builtin""" + + @staticmethod + def from_dict(obj: Any) -> 'Server': + assert isinstance(obj, dict) + name = from_str(obj.get("name")) + status = ServerStatus(obj.get("status")) + error = from_union([from_str, from_none], obj.get("error")) + source = from_union([from_str, from_none], obj.get("source")) + return Server(name, status, error, source) + + def to_dict(self) -> dict: + result: dict = {} + result["name"] = from_str(self.name) + result["status"] = to_enum(ServerStatus, self.status) + if self.error is not None: + result["error"] = from_union([from_str, from_none], self.error) + if self.source is not None: + result["source"] = from_union([from_str, from_none], self.source) + return result + + +@dataclass +class SessionMCPListResult: + servers: list[Server] + """Configured MCP servers""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionMCPListResult': + assert isinstance(obj, dict) + servers = from_list(Server.from_dict, obj.get("servers")) + return SessionMCPListResult(servers) + + def to_dict(self) -> dict: + result: dict = {} + result["servers"] = from_list(lambda x: to_class(Server, x), self.servers) + return result + + +@dataclass +class SessionMCPEnableResult: + @staticmethod + def from_dict(obj: Any) -> 'SessionMCPEnableResult': + assert isinstance(obj, dict) + return SessionMCPEnableResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + + +@dataclass +class SessionMCPEnableParams: + server_name: str + """Name of the MCP server to enable""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionMCPEnableParams': + assert isinstance(obj, dict) + server_name = from_str(obj.get("serverName")) + return SessionMCPEnableParams(server_name) + + def to_dict(self) -> dict: + result: dict = {} + result["serverName"] = from_str(self.server_name) + return result + + +@dataclass +class SessionMCPDisableResult: + @staticmethod + def from_dict(obj: Any) -> 'SessionMCPDisableResult': + assert isinstance(obj, dict) + return SessionMCPDisableResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + + +@dataclass +class SessionMCPDisableParams: + server_name: str + """Name of the MCP server to disable""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionMCPDisableParams': + assert isinstance(obj, dict) + server_name = from_str(obj.get("serverName")) + return SessionMCPDisableParams(server_name) + + def to_dict(self) -> dict: + result: dict = {} + result["serverName"] = from_str(self.server_name) + return result + + +@dataclass +class SessionMCPReloadResult: + @staticmethod + def from_dict(obj: Any) -> 'SessionMCPReloadResult': + assert isinstance(obj, dict) + return SessionMCPReloadResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + + +@dataclass +class Plugin: + enabled: bool + """Whether the plugin is currently enabled""" + + marketplace: str + """Marketplace the plugin came from""" + + name: str + """Plugin name""" + + version: str | None = None + """Installed version""" + + @staticmethod + def from_dict(obj: Any) -> 'Plugin': + assert isinstance(obj, dict) + enabled = from_bool(obj.get("enabled")) + marketplace = from_str(obj.get("marketplace")) + name = from_str(obj.get("name")) + version = from_union([from_str, from_none], obj.get("version")) + return Plugin(enabled, marketplace, name, version) + + def to_dict(self) -> dict: + result: dict = {} + result["enabled"] = from_bool(self.enabled) + result["marketplace"] = from_str(self.marketplace) + result["name"] = from_str(self.name) + if self.version is not None: + result["version"] = from_union([from_str, from_none], self.version) + return result + + +@dataclass +class SessionPluginsListResult: + plugins: list[Plugin] + """Installed plugins""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionPluginsListResult': + assert isinstance(obj, dict) + plugins = from_list(Plugin.from_dict, obj.get("plugins")) + return SessionPluginsListResult(plugins) + + def to_dict(self) -> dict: + result: dict = {} + result["plugins"] = from_list(lambda x: to_class(Plugin, x), self.plugins) + return result + + +class Source(Enum): + """Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/)""" + + PROJECT = "project" + USER = "user" + + +class ExtensionStatus(Enum): + """Current status: running, disabled, failed, or starting""" + + DISABLED = "disabled" + FAILED = "failed" + RUNNING = "running" + STARTING = "starting" + + +@dataclass +class Extension: + id: str + """Source-qualified ID (e.g., 'project:my-ext', 'user:auth-helper')""" + + name: str + """Extension name (directory name)""" + + source: Source + """Discovery source: project (.github/extensions/) or user (~/.copilot/extensions/)""" + + status: ExtensionStatus + """Current status: running, disabled, failed, or starting""" + + pid: int | None = None + """Process ID if the extension is running""" + + @staticmethod + def from_dict(obj: Any) -> 'Extension': + assert isinstance(obj, dict) + id = from_str(obj.get("id")) + name = from_str(obj.get("name")) + source = Source(obj.get("source")) + status = ExtensionStatus(obj.get("status")) + pid = from_union([from_int, from_none], obj.get("pid")) + return Extension(id, name, source, status, pid) + + def to_dict(self) -> dict: + result: dict = {} + result["id"] = from_str(self.id) + result["name"] = from_str(self.name) + result["source"] = to_enum(Source, self.source) + result["status"] = to_enum(ExtensionStatus, self.status) + if self.pid is not None: + result["pid"] = from_union([from_int, from_none], self.pid) + return result + + +@dataclass +class SessionExtensionsListResult: + extensions: list[Extension] + """Discovered extensions and their current status""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionExtensionsListResult': + assert isinstance(obj, dict) + extensions = from_list(Extension.from_dict, obj.get("extensions")) + return SessionExtensionsListResult(extensions) + + def to_dict(self) -> dict: + result: dict = {} + result["extensions"] = from_list(lambda x: to_class(Extension, x), self.extensions) + return result + + +@dataclass +class SessionExtensionsEnableResult: + @staticmethod + def from_dict(obj: Any) -> 'SessionExtensionsEnableResult': + assert isinstance(obj, dict) + return SessionExtensionsEnableResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + + +@dataclass +class SessionExtensionsEnableParams: + id: str + """Source-qualified extension ID to enable""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionExtensionsEnableParams': + assert isinstance(obj, dict) + id = from_str(obj.get("id")) + return SessionExtensionsEnableParams(id) + + def to_dict(self) -> dict: + result: dict = {} + result["id"] = from_str(self.id) + return result + + +@dataclass +class SessionExtensionsDisableResult: + @staticmethod + def from_dict(obj: Any) -> 'SessionExtensionsDisableResult': + assert isinstance(obj, dict) + return SessionExtensionsDisableResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + + +@dataclass +class SessionExtensionsDisableParams: + id: str + """Source-qualified extension ID to disable""" + + @staticmethod + def from_dict(obj: Any) -> 'SessionExtensionsDisableParams': + assert isinstance(obj, dict) + id = from_str(obj.get("id")) + return SessionExtensionsDisableParams(id) + + def to_dict(self) -> dict: + result: dict = {} + result["id"] = from_str(self.id) + return result + + +@dataclass +class SessionExtensionsReloadResult: + @staticmethod + def from_dict(obj: Any) -> 'SessionExtensionsReloadResult': + assert isinstance(obj, dict) + return SessionExtensionsReloadResult() + + def to_dict(self) -> dict: + result: dict = {} + return result + + @dataclass class SessionCompactionCompactResult: messages_removed: float @@ -1132,6 +1633,8 @@ class SessionLogParams: """Log severity level. Determines how the message is displayed in the timeline. Defaults to "info". """ + url: str | None = None + """Optional URL the user can open in their browser for more details""" @staticmethod def from_dict(obj: Any) -> 'SessionLogParams': @@ -1139,7 +1642,8 @@ def from_dict(obj: Any) -> 'SessionLogParams': message = from_str(obj.get("message")) ephemeral = from_union([from_bool, from_none], obj.get("ephemeral")) level = from_union([Level, from_none], obj.get("level")) - return SessionLogParams(message, ephemeral, level) + url = from_union([from_str, from_none], obj.get("url")) + return SessionLogParams(message, ephemeral, level, url) def to_dict(self) -> dict: result: dict = {} @@ -1148,6 +1652,8 @@ def to_dict(self) -> dict: result["ephemeral"] = from_union([from_bool, from_none], self.ephemeral) if self.level is not None: result["level"] = from_union([lambda x: to_enum(Level, x), from_none], self.level) + if self.url is not None: + result["url"] = from_union([from_str, from_none], self.url) return result @@ -1469,6 +1975,166 @@ def session_agent_deselect_result_to_dict(x: SessionAgentDeselectResult) -> Any: return to_class(SessionAgentDeselectResult, x) +def session_agent_reload_result_from_dict(s: Any) -> SessionAgentReloadResult: + return SessionAgentReloadResult.from_dict(s) + + +def session_agent_reload_result_to_dict(x: SessionAgentReloadResult) -> Any: + return to_class(SessionAgentReloadResult, x) + + +def session_skills_list_result_from_dict(s: Any) -> SessionSkillsListResult: + return SessionSkillsListResult.from_dict(s) + + +def session_skills_list_result_to_dict(x: SessionSkillsListResult) -> Any: + return to_class(SessionSkillsListResult, x) + + +def session_skills_enable_result_from_dict(s: Any) -> SessionSkillsEnableResult: + return SessionSkillsEnableResult.from_dict(s) + + +def session_skills_enable_result_to_dict(x: SessionSkillsEnableResult) -> Any: + return to_class(SessionSkillsEnableResult, x) + + +def session_skills_enable_params_from_dict(s: Any) -> SessionSkillsEnableParams: + return SessionSkillsEnableParams.from_dict(s) + + +def session_skills_enable_params_to_dict(x: SessionSkillsEnableParams) -> Any: + return to_class(SessionSkillsEnableParams, x) + + +def session_skills_disable_result_from_dict(s: Any) -> SessionSkillsDisableResult: + return SessionSkillsDisableResult.from_dict(s) + + +def session_skills_disable_result_to_dict(x: SessionSkillsDisableResult) -> Any: + return to_class(SessionSkillsDisableResult, x) + + +def session_skills_disable_params_from_dict(s: Any) -> SessionSkillsDisableParams: + return SessionSkillsDisableParams.from_dict(s) + + +def session_skills_disable_params_to_dict(x: SessionSkillsDisableParams) -> Any: + return to_class(SessionSkillsDisableParams, x) + + +def session_skills_reload_result_from_dict(s: Any) -> SessionSkillsReloadResult: + return SessionSkillsReloadResult.from_dict(s) + + +def session_skills_reload_result_to_dict(x: SessionSkillsReloadResult) -> Any: + return to_class(SessionSkillsReloadResult, x) + + +def session_mcp_list_result_from_dict(s: Any) -> SessionMCPListResult: + return SessionMCPListResult.from_dict(s) + + +def session_mcp_list_result_to_dict(x: SessionMCPListResult) -> Any: + return to_class(SessionMCPListResult, x) + + +def session_mcp_enable_result_from_dict(s: Any) -> SessionMCPEnableResult: + return SessionMCPEnableResult.from_dict(s) + + +def session_mcp_enable_result_to_dict(x: SessionMCPEnableResult) -> Any: + return to_class(SessionMCPEnableResult, x) + + +def session_mcp_enable_params_from_dict(s: Any) -> SessionMCPEnableParams: + return SessionMCPEnableParams.from_dict(s) + + +def session_mcp_enable_params_to_dict(x: SessionMCPEnableParams) -> Any: + return to_class(SessionMCPEnableParams, x) + + +def session_mcp_disable_result_from_dict(s: Any) -> SessionMCPDisableResult: + return SessionMCPDisableResult.from_dict(s) + + +def session_mcp_disable_result_to_dict(x: SessionMCPDisableResult) -> Any: + return to_class(SessionMCPDisableResult, x) + + +def session_mcp_disable_params_from_dict(s: Any) -> SessionMCPDisableParams: + return SessionMCPDisableParams.from_dict(s) + + +def session_mcp_disable_params_to_dict(x: SessionMCPDisableParams) -> Any: + return to_class(SessionMCPDisableParams, x) + + +def session_mcp_reload_result_from_dict(s: Any) -> SessionMCPReloadResult: + return SessionMCPReloadResult.from_dict(s) + + +def session_mcp_reload_result_to_dict(x: SessionMCPReloadResult) -> Any: + return to_class(SessionMCPReloadResult, x) + + +def session_plugins_list_result_from_dict(s: Any) -> SessionPluginsListResult: + return SessionPluginsListResult.from_dict(s) + + +def session_plugins_list_result_to_dict(x: SessionPluginsListResult) -> Any: + return to_class(SessionPluginsListResult, x) + + +def session_extensions_list_result_from_dict(s: Any) -> SessionExtensionsListResult: + return SessionExtensionsListResult.from_dict(s) + + +def session_extensions_list_result_to_dict(x: SessionExtensionsListResult) -> Any: + return to_class(SessionExtensionsListResult, x) + + +def session_extensions_enable_result_from_dict(s: Any) -> SessionExtensionsEnableResult: + return SessionExtensionsEnableResult.from_dict(s) + + +def session_extensions_enable_result_to_dict(x: SessionExtensionsEnableResult) -> Any: + return to_class(SessionExtensionsEnableResult, x) + + +def session_extensions_enable_params_from_dict(s: Any) -> SessionExtensionsEnableParams: + return SessionExtensionsEnableParams.from_dict(s) + + +def session_extensions_enable_params_to_dict(x: SessionExtensionsEnableParams) -> Any: + return to_class(SessionExtensionsEnableParams, x) + + +def session_extensions_disable_result_from_dict(s: Any) -> SessionExtensionsDisableResult: + return SessionExtensionsDisableResult.from_dict(s) + + +def session_extensions_disable_result_to_dict(x: SessionExtensionsDisableResult) -> Any: + return to_class(SessionExtensionsDisableResult, x) + + +def session_extensions_disable_params_from_dict(s: Any) -> SessionExtensionsDisableParams: + return SessionExtensionsDisableParams.from_dict(s) + + +def session_extensions_disable_params_to_dict(x: SessionExtensionsDisableParams) -> Any: + return to_class(SessionExtensionsDisableParams, x) + + +def session_extensions_reload_result_from_dict(s: Any) -> SessionExtensionsReloadResult: + return SessionExtensionsReloadResult.from_dict(s) + + +def session_extensions_reload_result_to_dict(x: SessionExtensionsReloadResult) -> Any: + return to_class(SessionExtensionsReloadResult, x) + + def session_compaction_compact_result_from_dict(s: Any) -> SessionCompactionCompactResult: return SessionCompactionCompactResult.from_dict(s) @@ -1696,6 +2362,84 @@ async def select(self, params: SessionAgentSelectParams, *, timeout: float | Non async def deselect(self, *, timeout: float | None = None) -> SessionAgentDeselectResult: return SessionAgentDeselectResult.from_dict(await self._client.request("session.agent.deselect", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + async def reload(self, *, timeout: float | None = None) -> SessionAgentReloadResult: + return SessionAgentReloadResult.from_dict(await self._client.request("session.agent.reload", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + + +class SkillsApi: + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + + async def list(self, *, timeout: float | None = None) -> SessionSkillsListResult: + return SessionSkillsListResult.from_dict(await self._client.request("session.skills.list", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + + async def enable(self, params: SessionSkillsEnableParams, *, timeout: float | None = None) -> SessionSkillsEnableResult: + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return SessionSkillsEnableResult.from_dict(await self._client.request("session.skills.enable", params_dict, **_timeout_kwargs(timeout))) + + async def disable(self, params: SessionSkillsDisableParams, *, timeout: float | None = None) -> SessionSkillsDisableResult: + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return SessionSkillsDisableResult.from_dict(await self._client.request("session.skills.disable", params_dict, **_timeout_kwargs(timeout))) + + async def reload(self, *, timeout: float | None = None) -> SessionSkillsReloadResult: + return SessionSkillsReloadResult.from_dict(await self._client.request("session.skills.reload", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + + +class McpApi: + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + + async def list(self, *, timeout: float | None = None) -> SessionMcpListResult: + return SessionMcpListResult.from_dict(await self._client.request("session.mcp.list", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + + async def enable(self, params: SessionMcpEnableParams, *, timeout: float | None = None) -> SessionMcpEnableResult: + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return SessionMcpEnableResult.from_dict(await self._client.request("session.mcp.enable", params_dict, **_timeout_kwargs(timeout))) + + async def disable(self, params: SessionMcpDisableParams, *, timeout: float | None = None) -> SessionMcpDisableResult: + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return SessionMcpDisableResult.from_dict(await self._client.request("session.mcp.disable", params_dict, **_timeout_kwargs(timeout))) + + async def reload(self, *, timeout: float | None = None) -> SessionMcpReloadResult: + return SessionMcpReloadResult.from_dict(await self._client.request("session.mcp.reload", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + + +class PluginsApi: + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + + async def list(self, *, timeout: float | None = None) -> SessionPluginsListResult: + return SessionPluginsListResult.from_dict(await self._client.request("session.plugins.list", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + + +class ExtensionsApi: + def __init__(self, client: "JsonRpcClient", session_id: str): + self._client = client + self._session_id = session_id + + async def list(self, *, timeout: float | None = None) -> SessionExtensionsListResult: + return SessionExtensionsListResult.from_dict(await self._client.request("session.extensions.list", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + + async def enable(self, params: SessionExtensionsEnableParams, *, timeout: float | None = None) -> SessionExtensionsEnableResult: + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return SessionExtensionsEnableResult.from_dict(await self._client.request("session.extensions.enable", params_dict, **_timeout_kwargs(timeout))) + + async def disable(self, params: SessionExtensionsDisableParams, *, timeout: float | None = None) -> SessionExtensionsDisableResult: + params_dict = {k: v for k, v in params.to_dict().items() if v is not None} + params_dict["sessionId"] = self._session_id + return SessionExtensionsDisableResult.from_dict(await self._client.request("session.extensions.disable", params_dict, **_timeout_kwargs(timeout))) + + async def reload(self, *, timeout: float | None = None) -> SessionExtensionsReloadResult: + return SessionExtensionsReloadResult.from_dict(await self._client.request("session.extensions.reload", {"sessionId": self._session_id}, **_timeout_kwargs(timeout))) + class CompactionApi: def __init__(self, client: "JsonRpcClient", session_id: str): @@ -1755,6 +2499,10 @@ def __init__(self, client: "JsonRpcClient", session_id: str): self.workspace = WorkspaceApi(client, session_id) self.fleet = FleetApi(client, session_id) self.agent = AgentApi(client, session_id) + self.skills = SkillsApi(client, session_id) + self.mcp = McpApi(client, session_id) + self.plugins = PluginsApi(client, session_id) + self.extensions = ExtensionsApi(client, session_id) self.compaction = CompactionApi(client, session_id) self.tools = ToolsApi(client, session_id) self.permissions = PermissionsApi(client, session_id) diff --git a/python/copilot/generated/session_events.py b/python/copilot/generated/session_events.py index 3fc313399..f2f563793 100644 --- a/python/copilot/generated/session_events.py +++ b/python/copilot/generated/session_events.py @@ -605,7 +605,55 @@ def to_dict(self) -> dict: return result -class Status(Enum): +class Source(Enum): + """Discovery source""" + + PROJECT = "project" + USER = "user" + + +class ExtensionStatus(Enum): + """Current status: running, disabled, failed, or starting""" + + DISABLED = "disabled" + FAILED = "failed" + RUNNING = "running" + STARTING = "starting" + + +@dataclass +class Extension: + id: str + """Source-qualified extension ID (e.g., 'project:my-ext', 'user:auth-helper')""" + + name: str + """Extension name (directory name)""" + + source: Source + """Discovery source""" + + status: ExtensionStatus + """Current status: running, disabled, failed, or starting""" + + @staticmethod + def from_dict(obj: Any) -> 'Extension': + assert isinstance(obj, dict) + id = from_str(obj.get("id")) + name = from_str(obj.get("name")) + source = Source(obj.get("source")) + status = ExtensionStatus(obj.get("status")) + return Extension(id, name, source, status) + + def to_dict(self) -> dict: + result: dict = {} + result["id"] = from_str(self.id) + result["name"] = from_str(self.name) + result["source"] = to_enum(Source, self.source) + result["status"] = to_enum(ExtensionStatus, self.status) + return result + + +class KindStatus(Enum): """Whether the agent completed successfully or failed""" COMPLETED = "completed" @@ -614,6 +662,7 @@ class Status(Enum): class KindType(Enum): AGENT_COMPLETED = "agent_completed" + AGENT_IDLE = "agent_idle" SHELL_COMPLETED = "shell_completed" SHELL_DETACHED_COMPLETED = "shell_detached_completed" @@ -637,7 +686,7 @@ class KindClass: prompt: str | None = None """The full prompt given to the background agent""" - status: Status | None = None + status: KindStatus | None = None """Whether the agent completed successfully or failed""" exit_code: float | None = None @@ -657,7 +706,7 @@ def from_dict(obj: Any) -> 'KindClass': agent_type = from_union([from_str, from_none], obj.get("agentType")) description = from_union([from_str, from_none], obj.get("description")) prompt = from_union([from_str, from_none], obj.get("prompt")) - status = from_union([Status, from_none], obj.get("status")) + status = from_union([KindStatus, from_none], obj.get("status")) exit_code = from_union([from_float, from_none], obj.get("exitCode")) shell_id = from_union([from_str, from_none], obj.get("shellId")) return KindClass(type, agent_id, agent_type, description, prompt, status, exit_code, shell_id) @@ -674,7 +723,7 @@ def to_dict(self) -> dict: if self.prompt is not None: result["prompt"] = from_union([from_str, from_none], self.prompt) if self.status is not None: - result["status"] = from_union([lambda x: to_enum(Status, x), from_none], self.status) + result["status"] = from_union([lambda x: to_enum(KindStatus, x), from_none], self.status) if self.exit_code is not None: result["exitCode"] = from_union([to_float, from_none], self.exit_code) if self.shell_id is not None: @@ -1430,6 +1479,52 @@ class Role(Enum): SYSTEM = "system" +class ServerStatus(Enum): + """Connection status: connected, failed, pending, disabled, or not_configured + + New connection status: connected, failed, pending, disabled, or not_configured + """ + CONNECTED = "connected" + DISABLED = "disabled" + FAILED = "failed" + NOT_CONFIGURED = "not_configured" + PENDING = "pending" + + +@dataclass +class Server: + name: str + """Server name (config key)""" + + status: ServerStatus + """Connection status: connected, failed, pending, disabled, or not_configured""" + + error: str | None = None + """Error message if the server failed to connect""" + + source: str | None = None + """Configuration source: user, workspace, plugin, or builtin""" + + @staticmethod + def from_dict(obj: Any) -> 'Server': + assert isinstance(obj, dict) + name = from_str(obj.get("name")) + status = ServerStatus(obj.get("status")) + error = from_union([from_str, from_none], obj.get("error")) + source = from_union([from_str, from_none], obj.get("source")) + return Server(name, status, error, source) + + def to_dict(self) -> dict: + result: dict = {} + result["name"] = from_str(self.name) + result["status"] = to_enum(ServerStatus, self.status) + if self.error is not None: + result["error"] = from_union([from_str, from_none], self.error) + if self.source is not None: + result["source"] = from_union([from_str, from_none], self.source) + return result + + class ShutdownType(Enum): """Whether the session ended normally ("routine") or due to a crash/fatal error ("error")""" @@ -1437,20 +1532,47 @@ class ShutdownType(Enum): ROUTINE = "routine" -class Source(Enum): - """Origin of this message, used for timeline filtering and telemetry (e.g., "user", - "autopilot", "skill", or "command") - """ - AUTOPILOT = "autopilot" - COMMAND = "command" - IMMEDIATE_PROMPT = "immediate-prompt" - JIT_INSTRUCTION = "jit-instruction" - OTHER = "other" - SKILL = "skill" - SNIPPY_BLOCKING = "snippy-blocking" - SYSTEM = "system" - THINKING_EXHAUSTED_CONTINUATION = "thinking-exhausted-continuation" - USER = "user" +@dataclass +class Skill: + description: str + """Description of what the skill does""" + + enabled: bool + """Whether the skill is currently enabled""" + + name: str + """Unique identifier for the skill""" + + source: str + """Source location type of the skill (e.g., project, personal, plugin)""" + + user_invocable: bool + """Whether the skill can be invoked by the user as a slash command""" + + path: str | None = None + """Absolute path to the skill file, if available""" + + @staticmethod + def from_dict(obj: Any) -> 'Skill': + assert isinstance(obj, dict) + description = from_str(obj.get("description")) + enabled = from_bool(obj.get("enabled")) + name = from_str(obj.get("name")) + source = from_str(obj.get("source")) + user_invocable = from_bool(obj.get("userInvocable")) + path = from_union([from_str, from_none], obj.get("path")) + return Skill(description, enabled, name, source, user_invocable, path) + + def to_dict(self) -> dict: + result: dict = {} + result["description"] = from_str(self.description) + result["enabled"] = from_bool(self.enabled) + result["name"] = from_str(self.name) + result["source"] = from_str(self.source) + result["userInvocable"] = from_bool(self.user_invocable) + if self.path is not None: + result["path"] = from_union([from_str, from_none], self.path) + return result class SourceType(Enum): @@ -1560,10 +1682,7 @@ class Data: Conversation compaction results including success status, metrics, and optional error details - Task completion notification with optional summary from the agent - - User message content with optional attachments, source information, and interaction - metadata + Task completion notification with summary from the agent Empty payload; the event signals that the pending message queue has changed @@ -1716,6 +1835,13 @@ class Data: status_code: int | None = None """HTTP status code from the upstream request, if applicable""" + url: str | None = None + """Optional URL associated with this error that the user can open in a browser + + Optional URL associated with this message that the user can open in a browser + + Optional URL associated with this warning that the user can open in a browser + """ background_tasks: BackgroundTasks | None = None """Background tasks still running when the agent became idle""" @@ -1772,7 +1898,7 @@ class Data: summary: str | None = None """Summary of the work done in the source session - Optional summary of the completed task, provided by the agent + Summary of the completed task, provided by the agent Summary of the plan that was created """ @@ -1961,9 +2087,9 @@ class Data: CAPI interaction ID for correlating this tool execution with upstream telemetry """ - source: Source | None = None - """Origin of this message, used for timeline filtering and telemetry (e.g., "user", - "autopilot", "skill", or "command") + source: str | None = None + """Origin of this message, used for timeline filtering (e.g., "skill-pdf" for skill-injected + messages that should be hidden from the user) """ transformed_content: str | None = None """Transformed version of the message sent to the model, with XML wrapping, timestamps, and @@ -2077,6 +2203,9 @@ class Data: Tool call ID of the parent tool invocation that spawned this sub-agent + The LLM-assigned tool call ID that triggered this request; used by remote UIs to + correlate responses + Tool call ID assigned to this external tool invocation """ tool_name: str | None = None @@ -2200,6 +2329,21 @@ class Data: recommended_action: str | None = None """The recommended action for the user to take""" + skills: list[Skill] | None = None + """Array of resolved skill metadata""" + + servers: list[Server] | None = None + """Array of MCP server status summaries""" + + server_name: str | None = None + """Name of the MCP server whose status changed""" + + status: ServerStatus | None = None + """New connection status: connected, failed, pending, disabled, or not_configured""" + + extensions: list[Extension] | None = None + """Array of discovered extensions and their status""" + @staticmethod def from_dict(obj: Any) -> 'Data': assert isinstance(obj, dict) @@ -2219,6 +2363,7 @@ def from_dict(obj: Any) -> 'Data': provider_call_id = from_union([from_str, from_none], obj.get("providerCallId")) stack = from_union([from_str, from_none], obj.get("stack")) status_code = from_union([from_int, from_none], obj.get("statusCode")) + url = from_union([from_str, from_none], obj.get("url")) background_tasks = from_union([BackgroundTasks.from_dict, from_none], obj.get("backgroundTasks")) title = from_union([from_str, from_none], obj.get("title")) info_type = from_union([from_str, from_none], obj.get("infoType")) @@ -2277,7 +2422,7 @@ def from_dict(obj: Any) -> 'Data': attachments = from_union([lambda x: from_list(Attachment.from_dict, x), from_none], obj.get("attachments")) content = from_union([from_str, from_none], obj.get("content")) interaction_id = from_union([from_str, from_none], obj.get("interactionId")) - source = from_union([Source, from_none], obj.get("source")) + source = from_union([from_str, from_none], obj.get("source")) transformed_content = from_union([from_str, from_none], obj.get("transformedContent")) turn_id = from_union([from_str, from_none], obj.get("turnId")) intent = from_union([from_str, from_none], obj.get("intent")) @@ -2340,7 +2485,12 @@ def from_dict(obj: Any) -> 'Data': actions = from_union([lambda x: from_list(from_str, x), from_none], obj.get("actions")) plan_content = from_union([from_str, from_none], obj.get("planContent")) recommended_action = from_union([from_str, from_none], obj.get("recommendedAction")) - return Data(already_in_use, context, copilot_version, producer, reasoning_effort, selected_model, session_id, start_time, version, event_count, resume_time, error_type, message, provider_call_id, stack, status_code, background_tasks, title, info_type, warning_type, new_model, previous_model, previous_reasoning_effort, new_mode, previous_mode, operation, path, handoff_time, remote_session_id, repository, source_type, summary, messages_removed_during_truncation, performed_by, post_truncation_messages_length, post_truncation_tokens_in_messages, pre_truncation_messages_length, pre_truncation_tokens_in_messages, token_limit, tokens_removed_during_truncation, events_removed, up_to_event_id, code_changes, current_model, error_reason, model_metrics, session_start_time, shutdown_type, total_api_duration_ms, total_premium_requests, base_commit, branch, cwd, git_root, head_commit, host_type, current_tokens, messages_length, checkpoint_number, checkpoint_path, compaction_tokens_used, error, messages_removed, post_compaction_tokens, pre_compaction_messages_length, pre_compaction_tokens, request_id, success, summary_content, tokens_removed, agent_mode, attachments, content, interaction_id, source, transformed_content, turn_id, intent, reasoning_id, delta_content, total_response_size_bytes, encrypted_content, message_id, output_tokens, parent_tool_call_id, phase, reasoning_opaque, reasoning_text, tool_requests, api_call_id, cache_read_tokens, cache_write_tokens, copilot_usage, cost, duration, initiator, input_tokens, model, quota_snapshots, reason, arguments, tool_call_id, tool_name, mcp_server_name, mcp_tool_name, partial_output, progress_message, is_user_requested, result, tool_telemetry, allowed_tools, name, plugin_name, plugin_version, agent_description, agent_display_name, agent_name, tools, hook_invocation_id, hook_type, input, output, metadata, role, kind, permission_request, allow_freeform, choices, question, mode, requested_schema, traceparent, tracestate, command, actions, plan_content, recommended_action) + skills = from_union([lambda x: from_list(Skill.from_dict, x), from_none], obj.get("skills")) + servers = from_union([lambda x: from_list(Server.from_dict, x), from_none], obj.get("servers")) + server_name = from_union([from_str, from_none], obj.get("serverName")) + status = from_union([ServerStatus, from_none], obj.get("status")) + extensions = from_union([lambda x: from_list(Extension.from_dict, x), from_none], obj.get("extensions")) + return Data(already_in_use, context, copilot_version, producer, reasoning_effort, selected_model, session_id, start_time, version, event_count, resume_time, error_type, message, provider_call_id, stack, status_code, url, background_tasks, title, info_type, warning_type, new_model, previous_model, previous_reasoning_effort, new_mode, previous_mode, operation, path, handoff_time, remote_session_id, repository, source_type, summary, messages_removed_during_truncation, performed_by, post_truncation_messages_length, post_truncation_tokens_in_messages, pre_truncation_messages_length, pre_truncation_tokens_in_messages, token_limit, tokens_removed_during_truncation, events_removed, up_to_event_id, code_changes, current_model, error_reason, model_metrics, session_start_time, shutdown_type, total_api_duration_ms, total_premium_requests, base_commit, branch, cwd, git_root, head_commit, host_type, current_tokens, messages_length, checkpoint_number, checkpoint_path, compaction_tokens_used, error, messages_removed, post_compaction_tokens, pre_compaction_messages_length, pre_compaction_tokens, request_id, success, summary_content, tokens_removed, agent_mode, attachments, content, interaction_id, source, transformed_content, turn_id, intent, reasoning_id, delta_content, total_response_size_bytes, encrypted_content, message_id, output_tokens, parent_tool_call_id, phase, reasoning_opaque, reasoning_text, tool_requests, api_call_id, cache_read_tokens, cache_write_tokens, copilot_usage, cost, duration, initiator, input_tokens, model, quota_snapshots, reason, arguments, tool_call_id, tool_name, mcp_server_name, mcp_tool_name, partial_output, progress_message, is_user_requested, result, tool_telemetry, allowed_tools, name, plugin_name, plugin_version, agent_description, agent_display_name, agent_name, tools, hook_invocation_id, hook_type, input, output, metadata, role, kind, permission_request, allow_freeform, choices, question, mode, requested_schema, traceparent, tracestate, command, actions, plan_content, recommended_action, skills, servers, server_name, status, extensions) def to_dict(self) -> dict: result: dict = {} @@ -2376,6 +2526,8 @@ def to_dict(self) -> dict: result["stack"] = from_union([from_str, from_none], self.stack) if self.status_code is not None: result["statusCode"] = from_union([from_int, from_none], self.status_code) + if self.url is not None: + result["url"] = from_union([from_str, from_none], self.url) if self.background_tasks is not None: result["backgroundTasks"] = from_union([lambda x: to_class(BackgroundTasks, x), from_none], self.background_tasks) if self.title is not None: @@ -2493,7 +2645,7 @@ def to_dict(self) -> dict: if self.interaction_id is not None: result["interactionId"] = from_union([from_str, from_none], self.interaction_id) if self.source is not None: - result["source"] = from_union([lambda x: to_enum(Source, x), from_none], self.source) + result["source"] = from_union([from_str, from_none], self.source) if self.transformed_content is not None: result["transformedContent"] = from_union([from_str, from_none], self.transformed_content) if self.turn_id is not None: @@ -2618,6 +2770,16 @@ def to_dict(self) -> dict: result["planContent"] = from_union([from_str, from_none], self.plan_content) if self.recommended_action is not None: result["recommendedAction"] = from_union([from_str, from_none], self.recommended_action) + if self.skills is not None: + result["skills"] = from_union([lambda x: from_list(lambda x: to_class(Skill, x), x), from_none], self.skills) + if self.servers is not None: + result["servers"] = from_union([lambda x: from_list(lambda x: to_class(Server, x), x), from_none], self.servers) + if self.server_name is not None: + result["serverName"] = from_union([from_str, from_none], self.server_name) + if self.status is not None: + result["status"] = from_union([lambda x: to_enum(ServerStatus, x), from_none], self.status) + if self.extensions is not None: + result["extensions"] = from_union([lambda x: from_list(lambda x: to_class(Extension, x), x), from_none], self.extensions) return result @@ -2650,14 +2812,18 @@ class SessionEventType(Enum): SESSION_COMPACTION_START = "session.compaction_start" SESSION_CONTEXT_CHANGED = "session.context_changed" SESSION_ERROR = "session.error" + SESSION_EXTENSIONS_LOADED = "session.extensions_loaded" SESSION_HANDOFF = "session.handoff" SESSION_IDLE = "session.idle" SESSION_INFO = "session.info" + SESSION_MCP_SERVERS_LOADED = "session.mcp_servers_loaded" + SESSION_MCP_SERVER_STATUS_CHANGED = "session.mcp_server_status_changed" SESSION_MODEL_CHANGE = "session.model_change" SESSION_MODE_CHANGED = "session.mode_changed" SESSION_PLAN_CHANGED = "session.plan_changed" SESSION_RESUME = "session.resume" SESSION_SHUTDOWN = "session.shutdown" + SESSION_SKILLS_LOADED = "session.skills_loaded" SESSION_SNAPSHOT_REWIND = "session.snapshot_rewind" SESSION_START = "session.start" SESSION_TASK_COMPLETE = "session.task_complete" @@ -2736,10 +2902,7 @@ class SessionEvent: Conversation compaction results including success status, metrics, and optional error details - Task completion notification with optional summary from the agent - - User message content with optional attachments, source information, and interaction - metadata + Task completion notification with summary from the agent Empty payload; the event signals that the pending message queue has changed diff --git a/test/harness/package-lock.json b/test/harness/package-lock.json index bf9564d9a..d77cf3b7b 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.4", + "@github/copilot": "^1.0.7", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "openai": "^6.17.0", @@ -462,27 +462,27 @@ } }, "node_modules/@github/copilot": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.4.tgz", - "integrity": "sha512-IpPg+zYplLu4F4lmatEDdR/1Y/jJ9cGWt89m3K3H4YSfYrZ5Go4UlM28llulYCG7sVdQeIGauQN1/KiBI/Rocg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot/-/copilot-1.0.7.tgz", + "integrity": "sha512-KHBaJ1kbc19pqUMnB9LubPtwWVOaDCzWbzwsJss+DvHyCpr8wP8jR3GEZUnhq3rsuXI96ZKEeEozXM0NqxCAiw==", "dev": true, "license": "SEE LICENSE IN LICENSE.md", "bin": { "copilot": "npm-loader.js" }, "optionalDependencies": { - "@github/copilot-darwin-arm64": "1.0.4", - "@github/copilot-darwin-x64": "1.0.4", - "@github/copilot-linux-arm64": "1.0.4", - "@github/copilot-linux-x64": "1.0.4", - "@github/copilot-win32-arm64": "1.0.4", - "@github/copilot-win32-x64": "1.0.4" + "@github/copilot-darwin-arm64": "1.0.7", + "@github/copilot-darwin-x64": "1.0.7", + "@github/copilot-linux-arm64": "1.0.7", + "@github/copilot-linux-x64": "1.0.7", + "@github/copilot-win32-arm64": "1.0.7", + "@github/copilot-win32-x64": "1.0.7" } }, "node_modules/@github/copilot-darwin-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.4.tgz", - "integrity": "sha512-/YGGhv6cp0ItolsF0HsLq2KmesA4atn0IEYApBs770fzJ8OP2pkOEzrxo3gWU3wc7fHF2uDB1RrJEZ7QSFLdEQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-arm64/-/copilot-darwin-arm64-1.0.7.tgz", + "integrity": "sha512-yQITowpkQYamww59CwcG5JTWV9ahj7nMH6oqObMJaeqXnG7j7dqE/YhLkujQZ3XR8VXAoIa1rZ3TahdMu94gOA==", "cpu": [ "arm64" ], @@ -497,9 +497,9 @@ } }, "node_modules/@github/copilot-darwin-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.4.tgz", - "integrity": "sha512-gwn2QjZbc1SqPVSAtDMesU1NopyHZT8Qsn37xPfznpV9s94KVyX4TTiDZaUwfnI0wr8kVHBL46RPLNz6I8kR9A==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-darwin-x64/-/copilot-darwin-x64-1.0.7.tgz", + "integrity": "sha512-23vP5bHaFA030nB3tr+dUUdRm2SqmQbs2fZUQ4F7JeYy59jp9hi8lBdaZp/TeQnjEirAUU9H2HZxsGRIIUWp7g==", "cpu": [ "x64" ], @@ -514,9 +514,9 @@ } }, "node_modules/@github/copilot-linux-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.4.tgz", - "integrity": "sha512-92vzHKxN55BpI76sP/5fXIXfat1gzAhsq4bNLqLENGfZyMP/25OiVihCZuQHnvxzXaHBITFGUvtxfdll2kbcng==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-arm64/-/copilot-linux-arm64-1.0.7.tgz", + "integrity": "sha512-g0mB98oyXKcpd4sMNBc5n1h3UhLy9AGRlT//VL8BXPSzvlTH/dJP3fdx74pbLSgvz105to/YUMmEAFfv25VNaw==", "cpu": [ "arm64" ], @@ -531,9 +531,9 @@ } }, "node_modules/@github/copilot-linux-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.4.tgz", - "integrity": "sha512-wQvpwf4/VMTnSmWyYzq07Xg18Vxg7aZ5NVkkXqlLTuXRASW0kvCCb5USEtXHHzR7E6rJztkhCjFRE1bZW8jAGw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-linux-x64/-/copilot-linux-x64-1.0.7.tgz", + "integrity": "sha512-TRxzvTo9I4ehYJLFHTCJSJYQ4QnO/V9zebqwszxHpJRxuBd7FV4cxLmfOBqZcUpEpZgBH+VJ4OG98BPW7YEtJQ==", "cpu": [ "x64" ], @@ -548,9 +548,9 @@ } }, "node_modules/@github/copilot-win32-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.4.tgz", - "integrity": "sha512-zOvD/5GVxDf0ZdlTkK+m55Vs55xuHNmACX50ZO2N23ZGG2dmkdS4mkruL59XB5ISgrOfeqvnqrwTFHbmPZtLfw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-arm64/-/copilot-win32-arm64-1.0.7.tgz", + "integrity": "sha512-4yFgW1K0MlKBrK5BwMIj4nMu5KSFfytNXrs8iOpVgp7erEvKVyN7VXb6SWkoU3M9TfeNlqP6Uje2rxDvgR1u5w==", "cpu": [ "arm64" ], @@ -565,9 +565,9 @@ } }, "node_modules/@github/copilot-win32-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.4.tgz", - "integrity": "sha512-yQenHMdkV0b77mF6aLM60TuwtNZ592TluptVDF+80Sj2zPfCpLyvrRh2FCIHRtuwTy4BfxETh2hCFHef8E6IOw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@github/copilot-win32-x64/-/copilot-win32-x64-1.0.7.tgz", + "integrity": "sha512-RDZlvPf/q6B54wLXJRmI39fc9+pwfcAjSwUqw0FeQruCTQgoUl8eo9NqeVWDFlr3RdzgVSMUiJHc3aiifVG6lA==", "cpu": [ "x64" ], diff --git a/test/harness/package.json b/test/harness/package.json index 9f336dfd4..43bb69c27 100644 --- a/test/harness/package.json +++ b/test/harness/package.json @@ -11,7 +11,7 @@ "test": "vitest run" }, "devDependencies": { - "@github/copilot": "^1.0.4", + "@github/copilot": "^1.0.7", "@modelcontextprotocol/sdk": "^1.26.0", "@types/node": "^25.3.3", "openai": "^6.17.0",