Skip to content
Open
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
4 changes: 4 additions & 0 deletions dotnet/src/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,7 @@ public async Task<CopilotSession> CreateSessionAsync(SessionConfig config, Cance
config.Agent,
config.ConfigDirectory,
config.EnableConfigDiscovery,
config.CustomAgentsLocalOnly,
config.SkipEmbeddingRetrieval,
config.EmbeddingCacheStorage,
config.OrganizationCustomInstructions,
Expand Down Expand Up @@ -1205,6 +1206,7 @@ public async Task<CopilotSession> ResumeSessionAsync(string sessionId, ResumeSes
config.WorkingDirectory,
config.ConfigDirectory,
config.EnableConfigDiscovery,
config.CustomAgentsLocalOnly,
config.SkipEmbeddingRetrieval,
config.EmbeddingCacheStorage,
config.OrganizationCustomInstructions,
Expand Down Expand Up @@ -2467,6 +2469,7 @@ internal record CreateSessionRequest(
string? Agent,
[property: JsonPropertyName("configDir")] string? ConfigDirectory,
bool? EnableConfigDiscovery,
[property: JsonPropertyName("customAgentsLocalOnly")] bool? CustomAgentsLocalOnly,
bool? SkipEmbeddingRetrieval,
EmbeddingCacheStorageMode? EmbeddingCacheStorage,
string? OrganizationCustomInstructions,
Expand Down Expand Up @@ -2557,6 +2560,7 @@ internal record ResumeSessionRequest(
string? WorkingDirectory,
[property: JsonPropertyName("configDir")] string? ConfigDirectory,
bool? EnableConfigDiscovery,
[property: JsonPropertyName("customAgentsLocalOnly")] bool? CustomAgentsLocalOnly,
bool? SkipEmbeddingRetrieval,
EmbeddingCacheStorageMode? EmbeddingCacheStorage,
string? OrganizationCustomInstructions,
Expand Down
59 changes: 59 additions & 0 deletions dotnet/test/E2E/ClientOptionsE2ETests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,65 @@ public async Task Should_Omit_EnableSessionTelemetry_When_Not_Set()
await session.DisposeAsync();
}

[Fact]
public async Task Should_Forward_CustomAgentsLocalOnly_In_Create_Wire_Request()
{
var (cliPath, capturePath) = await CreateFakeCliCaptureAsync();

await using var client = Ctx.CreateClient(options: new CopilotClientOptions
{
Connection = RuntimeConnection.ForStdio(path: cliPath, args: ["--capture-file", capturePath]),
UseLoggedInUser = false,
});

await client.StartAsync();

var session = await client.CreateSessionAsync(new SessionConfig
{
CustomAgentsLocalOnly = true,
OnPermissionRequest = PermissionHandler.ApproveAll,
});

using var capture = JsonDocument.Parse(await File.ReadAllTextAsync(capturePath));
var createRequest = GetCapturedRequestParams(capture.RootElement, "session.create");
Assert.True(createRequest.GetProperty("customAgentsLocalOnly").GetBoolean());

await session.DisposeAsync();
}

[Fact]
public async Task Should_Forward_CustomAgentsLocalOnly_In_Resume_Wire_Request()
{
var (cliPath, capturePath) = await CreateFakeCliCaptureAsync();

await using var client = Ctx.CreateClient(options: new CopilotClientOptions
{
Connection = RuntimeConnection.ForStdio(path: cliPath, args: ["--capture-file", capturePath]),
UseLoggedInUser = false,
});

await client.StartAsync();

var createSession = await client.CreateSessionAsync(new SessionConfig
{
OnPermissionRequest = PermissionHandler.ApproveAll,
});
var sessionId = createSession.SessionId;
await createSession.DisposeAsync();

var resumeSession = await client.ResumeSessionAsync(sessionId, new ResumeSessionConfig
{
CustomAgentsLocalOnly = true,
OnPermissionRequest = PermissionHandler.ApproveAll,
});

using var capture = JsonDocument.Parse(await File.ReadAllTextAsync(capturePath));
var resumeRequest = GetCapturedRequestParams(capture.RootElement, "session.resume");
Assert.True(resumeRequest.GetProperty("customAgentsLocalOnly").GetBoolean());

await resumeSession.DisposeAsync();
}

[Fact]
public async Task Should_Forward_Granular_Multitenancy_Fields_In_Create_Wire_Request()
{
Expand Down
52 changes: 52 additions & 0 deletions dotnet/test/Unit/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,58 @@ public void CreateSessionRequest_CanSerializeEnableSessionTelemetry_WithSdkOptio
Assert.False(root.GetProperty("enableSessionTelemetry").GetBoolean());
}

[Fact]
public void CreateSessionRequest_CanSerializeCustomAgentsLocalOnly_WithSdkOptions()
{
var options = GetSerializerOptions();
var requestType = GetNestedType(typeof(CopilotClient), "CreateSessionRequest");
var request = CreateInternalRequest(
requestType,
("SessionId", "session-id"),
("CustomAgentsLocalOnly", true));

var json = JsonSerializer.Serialize(request, requestType, options);
using var document = JsonDocument.Parse(json);
Assert.True(document.RootElement.GetProperty("customAgentsLocalOnly").GetBoolean());
}

[Fact]
public void ResumeSessionRequest_CanSerializeCustomAgentsLocalOnly_WithSdkOptions()
{
var options = GetSerializerOptions();
var requestType = GetNestedType(typeof(CopilotClient), "ResumeSessionRequest");
var request = CreateInternalRequest(
requestType,
("SessionId", "session-id"),
("CustomAgentsLocalOnly", true));

var json = JsonSerializer.Serialize(request, requestType, options);
using var document = JsonDocument.Parse(json);
Assert.True(document.RootElement.GetProperty("customAgentsLocalOnly").GetBoolean());
}

[Fact]
public void SessionRequests_OmitCustomAgentsLocalOnly_WhenUnset()
{
var options = GetSerializerOptions();

var createRequestType = GetNestedType(typeof(CopilotClient), "CreateSessionRequest");
var createRequest = CreateInternalRequest(
createRequestType,
("SessionId", "session-id"));
var createJson = JsonSerializer.Serialize(createRequest, createRequestType, options);
using var createDocument = JsonDocument.Parse(createJson);
Assert.False(createDocument.RootElement.TryGetProperty("customAgentsLocalOnly", out _));

var resumeRequestType = GetNestedType(typeof(CopilotClient), "ResumeSessionRequest");
var resumeRequest = CreateInternalRequest(
resumeRequestType,
("SessionId", "session-id"));
var resumeJson = JsonSerializer.Serialize(resumeRequest, resumeRequestType, options);
using var resumeDocument = JsonDocument.Parse(resumeJson);
Assert.False(resumeDocument.RootElement.TryGetProperty("customAgentsLocalOnly", out _));
}

[Fact]
public void ResumeSessionRequest_CanSerializeEnableSessionTelemetry_WithSdkOptions()
{
Expand Down