Skip to content
Closed
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
10 changes: 9 additions & 1 deletion dotnet/src/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1802,7 +1802,15 @@ private async Task VerifyProtocolVersionAsync(Connection connection, Cancellatio
_ => null,
};
var connectResponse = await InvokeRpcAsync<ConnectResult>(
connection.Rpc, "connect", [new ConnectRequest { Token = token }], connection.StderrBuffer, cancellationToken);
connection.Rpc,
"connect",
[new ConnectRequest
{
Token = token,
EnableGitHubTelemetryForwarding = _options.OnGitHubTelemetry != null ? true : null,
}],
connection.StderrBuffer,
cancellationToken);
serverVersion = (int)connectResponse.ProtocolVersion;
}
catch (IOException ex) when (ex.InnerException is RemoteRpcException remoteEx && IsUnsupportedConnectMethod(remoteEx))
Expand Down
10 changes: 7 additions & 3 deletions dotnet/test/E2E/GitHubTelemetryForwardingE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*--------------------------------------------------------------------------------------------*/

using System.Collections.Concurrent;
using System.Linq;
using GitHub.Copilot.Rpc;
using GitHub.Copilot.Test.Harness;
using Xunit;
Expand Down Expand Up @@ -37,13 +38,16 @@ public async Task Should_Forward_GitHub_Telemetry_For_A_Live_Session()
OnPermissionRequest = PermissionHandler.ApproveAll,
});

var answer = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2+2?" });
Assert.NotNull(answer);

await TestHelper.WaitForConditionAsync(
() => !notifications.IsEmpty,
() => notifications.Any(notification => string.Equals(notification.SessionId, session.SessionId, StringComparison.Ordinal)),
timeout: TimeSpan.FromSeconds(30),
timeoutMessage: "Timed out waiting for GitHub telemetry notification.");

Assert.True(notifications.TryPeek(out var notification));
Assert.NotEmpty(notification.SessionId);
var notification = notifications.First(notification => string.Equals(notification.SessionId, session.SessionId, StringComparison.Ordinal));
Assert.Equal(session.SessionId, notification.SessionId);
Assert.NotNull(notification.Event);
Assert.NotEmpty(notification.Event.Kind);
Assert.IsType<bool>(notification.Restricted);
Expand Down
6 changes: 3 additions & 3 deletions dotnet/test/E2E/RpcSessionStateExtrasE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,19 @@ public async Task Should_Get_And_Set_AllowAll_Permissions()
var initial = await session.Rpc.Permissions.GetAllowAllAsync();
Assert.False(initial.Enabled, "Allow-all should be disabled on a fresh session.");

var enable = await session.Rpc.Permissions.SetAllowAllAsync(true);
var enable = await session.Rpc.Permissions.SetAllowAllAsync(enabled: true);
Assert.True(enable.Success);
Assert.True(enable.Enabled);
Assert.True((await session.Rpc.Permissions.GetAllowAllAsync()).Enabled);

var disable = await session.Rpc.Permissions.SetAllowAllAsync(false);
var disable = await session.Rpc.Permissions.SetAllowAllAsync(enabled: false);
Assert.True(disable.Success);
Assert.False(disable.Enabled);
Assert.False((await session.Rpc.Permissions.GetAllowAllAsync()).Enabled);
}
finally
{
await session.Rpc.Permissions.SetAllowAllAsync(false);
await session.Rpc.Permissions.SetAllowAllAsync(enabled: false);
}
}

Expand Down
36 changes: 20 additions & 16 deletions dotnet/test/Unit/GitHubTelemetryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace GitHub.Copilot.Test.Unit;
public sealed class GitHubTelemetryTests
{
[Fact]
public async Task CreateSession_Opts_Into_Forwarding_When_Handler_Provided()
public async Task Connect_Opts_Into_Forwarding_When_Handler_Provided()
{
await using var server = await FakeTelemetryServer.StartAsync();
await using var client = new CopilotClient(new CopilotClientOptions
Expand All @@ -28,10 +28,8 @@ public async Task CreateSession_Opts_Into_Forwarding_When_Handler_Provided()
});
await client.StartAsync();

await client.CreateSessionAsync(new SessionConfig { OnPermissionRequest = PermissionHandler.ApproveAll });

var createParams = server.LastCreateParams ?? throw new InvalidOperationException("session.create was not captured.");
Assert.True(createParams.TryGetProperty("enableGitHubTelemetryForwarding", out var flag));
var connectParams = server.LastConnectParams ?? throw new InvalidOperationException("connect was not captured.");
Assert.True(connectParams.TryGetProperty("enableGitHubTelemetryForwarding", out var flag));
Assert.True(flag.GetBoolean());
}

Expand All @@ -54,7 +52,7 @@ public async Task ResumeSession_Opts_Into_Forwarding_When_Handler_Provided()
}

[Fact]
public async Task CreateSession_Does_Not_Opt_In_Without_Handler()
public async Task Connect_Does_Not_Opt_In_Without_Handler()
{
await using var server = await FakeTelemetryServer.StartAsync();
await using var client = new CopilotClient(new CopilotClientOptions
Expand All @@ -63,10 +61,8 @@ public async Task CreateSession_Does_Not_Opt_In_Without_Handler()
});
await client.StartAsync();

await client.CreateSessionAsync(new SessionConfig { OnPermissionRequest = PermissionHandler.ApproveAll });

var createParams = server.LastCreateParams ?? throw new InvalidOperationException("session.create was not captured.");
var optedIn = createParams.TryGetProperty("enableGitHubTelemetryForwarding", out var flag)
var connectParams = server.LastConnectParams ?? throw new InvalidOperationException("connect was not captured.");
var optedIn = connectParams.TryGetProperty("enableGitHubTelemetryForwarding", out var flag)
&& flag.ValueKind == JsonValueKind.True;
Assert.False(optedIn);
}
Expand Down Expand Up @@ -185,6 +181,8 @@ public string Url

public JsonElement? LastCreateParams { get; private set; }

public JsonElement? LastConnectParams { get; private set; }

public JsonElement? LastResumeParams { get; private set; }

public static Task<FakeTelemetryServer> StartAsync()
Expand Down Expand Up @@ -267,12 +265,7 @@ private async Task HandleRequestAsync(Stream stream, JsonElement request, Cancel

object? result = method switch
{
"connect" => new Dictionary<string, object?>
{
["ok"] = true,
["protocolVersion"] = 3,
["version"] = "test",
},
"connect" => CaptureConnect(request),
"session.create" => CaptureCreate(request),
"session.resume" => CaptureResume(request),
"session.send" => new Dictionary<string, object?> { ["messageId"] = "message-1" },
Expand All @@ -295,6 +288,17 @@ private async Task HandleRequestAsync(Stream stream, JsonElement request, Cancel
return SessionResult(LastCreateParams);
}

private Dictionary<string, object?> CaptureConnect(JsonElement request)
{
LastConnectParams = request.TryGetProperty("params", out var p) ? p.Clone() : null;
return new Dictionary<string, object?>
{
["ok"] = true,
["protocolVersion"] = 3,
["version"] = "test",
};
}

private Dictionary<string, object?> CaptureResume(JsonElement request)
{
LastResumeParams = request.TryGetProperty("params", out var p) ? p.Clone() : null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
models:
- claude-sonnet-4.5
conversations:
- messages:
- role: system
content: ${system}
- role: user
content: What is 2+2?
- role: assistant
content: "4"
Loading