Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 81 additions & 2 deletions dotnet/src/Generated/Rpc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,30 @@ public class AccountGetQuotaResult
public Dictionary<string, AccountGetQuotaResultQuotaSnapshotsValue> QuotaSnapshots { get => field ??= []; set; }
}

/// <summary>RPC data type for SessionFsSetProvider operations.</summary>
public class SessionFsSetProviderResult
{
/// <summary>Whether the provider was set successfully.</summary>
[JsonPropertyName("success")]
public bool Success { get; set; }
}

/// <summary>RPC data type for SessionFsSetProvider operations.</summary>
internal class SessionFsSetProviderRequest
{
/// <summary>Initial working directory for sessions.</summary>
[JsonPropertyName("initialCwd")]
public string InitialCwd { get; set; } = string.Empty;

/// <summary>Path within each session's SessionFs where the runtime stores files for that session.</summary>
[JsonPropertyName("sessionStatePath")]
public string SessionStatePath { get; set; } = string.Empty;

/// <summary>Path conventions used by this filesystem.</summary>
[JsonPropertyName("conventions")]
public SessionFsSetProviderRequestConventions Conventions { get; set; }
}

/// <summary>RPC data type for SessionLog operations.</summary>
public class SessionLogResult
{
Expand Down Expand Up @@ -705,7 +729,7 @@ public class Server
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;

/// <summary>Connection status: connected, failed, pending, disabled, or not_configured.</summary>
/// <summary>Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.</summary>
[JsonPropertyName("status")]
public ServerStatus Status { get; set; }

Expand Down Expand Up @@ -1156,6 +1180,19 @@ internal class SessionShellKillRequest
public SessionShellKillRequestSignal? Signal { get; set; }
}

/// <summary>Path conventions used by this filesystem.</summary>
[JsonConverter(typeof(JsonStringEnumConverter<SessionFsSetProviderRequestConventions>))]
public enum SessionFsSetProviderRequestConventions
{
/// <summary>The <c>windows</c> variant.</summary>
[JsonStringEnumMemberName("windows")]
Windows,
/// <summary>The <c>posix</c> variant.</summary>
[JsonStringEnumMemberName("posix")]
Posix,
}


/// <summary>Log severity level. Determines how the message is displayed in the timeline. Defaults to "info".</summary>
[JsonConverter(typeof(JsonStringEnumConverter<SessionLogRequestLevel>))]
public enum SessionLogRequestLevel
Expand Down Expand Up @@ -1188,7 +1225,7 @@ public enum SessionModeGetResultMode
}


/// <summary>Connection status: connected, failed, pending, disabled, or not_configured.</summary>
/// <summary>Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.</summary>
[JsonConverter(typeof(JsonStringEnumConverter<ServerStatus>))]
public enum ServerStatus
{
Expand All @@ -1198,6 +1235,9 @@ public enum ServerStatus
/// <summary>The <c>failed</c> variant.</summary>
[JsonStringEnumMemberName("failed")]
Failed,
/// <summary>The <c>needs-auth</c> variant.</summary>
[JsonStringEnumMemberName("needs-auth")]
NeedsAuth,
/// <summary>The <c>pending</c> variant.</summary>
[JsonStringEnumMemberName("pending")]
Pending,
Expand Down Expand Up @@ -1285,6 +1325,8 @@ internal ServerRpc(JsonRpc rpc)
Models = new ServerModelsApi(rpc);
Tools = new ServerToolsApi(rpc);
Account = new ServerAccountApi(rpc);
Mcp = new ServerMcpApi(rpc);
SessionFs = new ServerSessionFsApi(rpc);
}

/// <summary>Calls "ping".</summary>
Expand All @@ -1302,6 +1344,12 @@ public async Task<PingResult> PingAsync(string? message = null, CancellationToke

/// <summary>Account APIs.</summary>
public ServerAccountApi Account { get; }

/// <summary>Mcp APIs.</summary>
public ServerMcpApi Mcp { get; }

/// <summary>SessionFs APIs.</summary>
public ServerSessionFsApi SessionFs { get; }
}

/// <summary>Provides server-scoped Models APIs.</summary>
Expand Down Expand Up @@ -1356,6 +1404,35 @@ public async Task<AccountGetQuotaResult> GetQuotaAsync(CancellationToken cancell
}
}

/// <summary>Provides server-scoped Mcp APIs.</summary>
public class ServerMcpApi
{
private readonly JsonRpc _rpc;

internal ServerMcpApi(JsonRpc rpc)
{
_rpc = rpc;
}
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServerMcpApi is generated and exposed on ServerRpc, but it contains no methods. Given the TS SDK generates nested mcp.config.* RPCs, this looks like the C# RPC generator doesn’t recurse into nested server groups (e.g. mcp -> config -> list/add/...). Either update the generator to emit nested group APIs, or avoid emitting empty placeholder APIs to prevent a misleading surface area.

Suggested change
}
}
/// <summary>
/// MCP server APIs are not currently supported by this .NET SDK.
/// This method will always throw <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="cancellationToken">Cancellation token (currently unused).</param>
/// <returns>A task that always faults with <see cref="NotSupportedException"/>.</returns>
public Task EnsureSupportedAsync(CancellationToken cancellationToken = default)
{
return Task.FromException(new NotSupportedException("MCP server APIs are not currently supported by the GitHub Copilot .NET SDK."));
}

Copilot uses AI. Check for mistakes.
}

/// <summary>Provides server-scoped SessionFs APIs.</summary>
public class ServerSessionFsApi
{
private readonly JsonRpc _rpc;

internal ServerSessionFsApi(JsonRpc rpc)
{
_rpc = rpc;
}

/// <summary>Calls "sessionFs.setProvider".</summary>
public async Task<SessionFsSetProviderResult> SetProviderAsync(string initialCwd, string sessionStatePath, SessionFsSetProviderRequestConventions conventions, CancellationToken cancellationToken = default)
{
var request = new SessionFsSetProviderRequest { InitialCwd = initialCwd, SessionStatePath = sessionStatePath, Conventions = conventions };
return await CopilotClient.InvokeRpcAsync<SessionFsSetProviderResult>(_rpc, "sessionFs.setProvider", [request], cancellationToken);
}
}

/// <summary>Provides typed session-scoped RPC methods.</summary>
public class SessionRpc
{
Expand Down Expand Up @@ -1959,6 +2036,8 @@ public async Task<SessionShellKillResult> KillAsync(string processId, SessionShe
[JsonSerializable(typeof(SessionExtensionsReloadResult))]
[JsonSerializable(typeof(SessionFleetStartRequest))]
[JsonSerializable(typeof(SessionFleetStartResult))]
[JsonSerializable(typeof(SessionFsSetProviderRequest))]
[JsonSerializable(typeof(SessionFsSetProviderResult))]
[JsonSerializable(typeof(SessionLogRequest))]
[JsonSerializable(typeof(SessionLogResult))]
[JsonSerializable(typeof(SessionMcpDisableRequest))]
Expand Down
14 changes: 11 additions & 3 deletions dotnet/src/Generated/SessionEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,11 @@ public partial class SessionIdleData
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("backgroundTasks")]
public SessionIdleDataBackgroundTasks? BackgroundTasks { get; set; }

/// <summary>True when the preceding agentic loop was cancelled via abort signal.</summary>
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("aborted")]
public bool? Aborted { get; set; }
}

/// <summary>Session title change payload containing the new display title.</summary>
Expand Down Expand Up @@ -2593,7 +2598,7 @@ public partial class SessionMcpServerStatusChangedData
[JsonPropertyName("serverName")]
public required string ServerName { get; set; }

/// <summary>New connection status: connected, failed, pending, disabled, or not_configured.</summary>
/// <summary>New connection status: connected, failed, needs-auth, pending, disabled, or not_configured.</summary>
[JsonPropertyName("status")]
public required SessionMcpServersLoadedDataServersItemStatus Status { get; set; }
}
Expand Down Expand Up @@ -3786,7 +3791,7 @@ public partial class SessionMcpServersLoadedDataServersItem
[JsonPropertyName("name")]
public required string Name { get; set; }

/// <summary>Connection status: connected, failed, pending, disabled, or not_configured.</summary>
/// <summary>Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.</summary>
[JsonPropertyName("status")]
public required SessionMcpServersLoadedDataServersItemStatus Status { get; set; }

Expand Down Expand Up @@ -3998,7 +4003,7 @@ public enum ElicitationRequestedDataMode
Url,
}

/// <summary>Connection status: connected, failed, pending, disabled, or not_configured.</summary>
/// <summary>Connection status: connected, failed, needs-auth, pending, disabled, or not_configured.</summary>
[JsonConverter(typeof(JsonStringEnumConverter<SessionMcpServersLoadedDataServersItemStatus>))]
public enum SessionMcpServersLoadedDataServersItemStatus
{
Expand All @@ -4008,6 +4013,9 @@ public enum SessionMcpServersLoadedDataServersItemStatus
/// <summary>The <c>failed</c> variant.</summary>
[JsonStringEnumMemberName("failed")]
Failed,
/// <summary>The <c>needs-auth</c> variant.</summary>
[JsonStringEnumMemberName("needs-auth")]
NeedsAuth,
/// <summary>The <c>pending</c> variant.</summary>
[JsonStringEnumMemberName("pending")]
Pending,
Expand Down
6 changes: 4 additions & 2 deletions dotnet/test/HooksTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ await session.SendAsync(new MessageOptions
Assert.Contains(preToolUseInputs, i => !string.IsNullOrEmpty(i.ToolName));
}

[Fact]
// TODO: Re-enable once runtime postToolUse hooks are fixed (https://github.com/github/copilot-sdk/issues/972)
[Fact(Skip = "Runtime postToolUse hooks broken")]
public async Task Should_Invoke_PostToolUse_Hook_After_Model_Runs_A_Tool()
{
var postToolUseInputs = new List<PostToolUseHookInput>();
Expand Down Expand Up @@ -83,7 +84,8 @@ await session.SendAsync(new MessageOptions
Assert.Contains(postToolUseInputs, i => i.ToolResult != null);
}

[Fact]
// TODO: Re-enable once runtime postToolUse hooks are fixed (https://github.com/github/copilot-sdk/issues/972)
[Fact(Skip = "Runtime postToolUse hooks broken")]
public async Task Should_Invoke_Both_PreToolUse_And_PostToolUse_Hooks_For_Single_Tool_Call()
{
var preToolUseInputs = new List<PreToolUseHookInput>();
Expand Down
11 changes: 7 additions & 4 deletions go/generated_session_events.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions go/internal/e2e/hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ func TestHooks(t *testing.T) {
}
})

// TODO: Re-enable once runtime postToolUse hooks are fixed (https://github.com/github/copilot-sdk/issues/972)
t.Run("should invoke postToolUse hook after model runs a tool", func(t *testing.T) {
t.Skip("Runtime postToolUse hooks broken")
ctx.ConfigureForTest(t)

var postToolUseInputs []copilot.PostToolUseHookInput
Expand Down Expand Up @@ -139,7 +141,9 @@ func TestHooks(t *testing.T) {
}
})

// TODO: Re-enable once runtime postToolUse hooks are fixed (https://github.com/github/copilot-sdk/issues/972)
t.Run("should invoke both preToolUse and postToolUse hooks for a single tool call", func(t *testing.T) {
t.Skip("Runtime postToolUse hooks broken")
ctx.ConfigureForTest(t)

var preToolUseInputs []copilot.PreToolUseHookInput
Expand Down
Loading
Loading