Skip to content

Commit a493e0e

Browse files
syf2211roji
authored andcommitted
fix(dotnet): forward CustomAgentsLocalOnly in session.create and session.resume
CustomAgentsLocalOnly was only sent via the post-create session.options.update call, which arrives after agent discovery has already completed. Mirror the Go SDK by including customAgentsLocalOnly in CreateSessionRequest and ResumeSessionRequest wire payloads. Fixes #1888
1 parent a1334be commit a493e0e

3 files changed

Lines changed: 115 additions & 0 deletions

File tree

dotnet/src/Client.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,7 @@ public async Task<CopilotSession> CreateSessionAsync(SessionConfig config, Cance
11581158
config.Agent,
11591159
config.ConfigDirectory,
11601160
config.EnableConfigDiscovery,
1161+
config.CustomAgentsLocalOnly,
11611162
config.SkipEmbeddingRetrieval,
11621163
config.EmbeddingCacheStorage,
11631164
config.OrganizationCustomInstructions,
@@ -1361,6 +1362,7 @@ public async Task<CopilotSession> ResumeSessionAsync(string sessionId, ResumeSes
13611362
config.WorkingDirectory,
13621363
config.ConfigDirectory,
13631364
config.EnableConfigDiscovery,
1365+
config.CustomAgentsLocalOnly,
13641366
config.SkipEmbeddingRetrieval,
13651367
config.EmbeddingCacheStorage,
13661368
config.OrganizationCustomInstructions,
@@ -2722,6 +2724,7 @@ internal record CreateSessionRequest(
27222724
string? Agent,
27232725
[property: JsonPropertyName("configDir")] string? ConfigDirectory,
27242726
bool? EnableConfigDiscovery,
2727+
[property: JsonPropertyName("customAgentsLocalOnly")] bool? CustomAgentsLocalOnly,
27252728
bool? SkipEmbeddingRetrieval,
27262729
EmbeddingCacheStorageMode? EmbeddingCacheStorage,
27272730
string? OrganizationCustomInstructions,
@@ -2818,6 +2821,7 @@ internal record ResumeSessionRequest(
28182821
string? WorkingDirectory,
28192822
[property: JsonPropertyName("configDir")] string? ConfigDirectory,
28202823
bool? EnableConfigDiscovery,
2824+
[property: JsonPropertyName("customAgentsLocalOnly")] bool? CustomAgentsLocalOnly,
28212825
bool? SkipEmbeddingRetrieval,
28222826
EmbeddingCacheStorageMode? EmbeddingCacheStorage,
28232827
string? OrganizationCustomInstructions,

dotnet/test/E2E/ClientOptionsE2ETests.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,65 @@ public async Task Should_Omit_EnableSessionTelemetry_When_Not_Set()
178178
await session.DisposeAsync();
179179
}
180180

181+
[Fact]
182+
public async Task Should_Forward_CustomAgentsLocalOnly_In_Create_Wire_Request()
183+
{
184+
var (cliPath, capturePath) = await CreateFakeCliCaptureAsync();
185+
186+
await using var client = Ctx.CreateClient(options: new CopilotClientOptions
187+
{
188+
Connection = RuntimeConnection.ForStdio(path: cliPath, args: ["--capture-file", capturePath]),
189+
UseLoggedInUser = false,
190+
});
191+
192+
await client.StartAsync();
193+
194+
var session = await client.CreateSessionAsync(new SessionConfig
195+
{
196+
CustomAgentsLocalOnly = true,
197+
OnPermissionRequest = PermissionHandler.ApproveAll,
198+
});
199+
200+
using var capture = JsonDocument.Parse(await File.ReadAllTextAsync(capturePath));
201+
var createRequest = GetCapturedRequestParams(capture.RootElement, "session.create");
202+
Assert.True(createRequest.GetProperty("customAgentsLocalOnly").GetBoolean());
203+
204+
await session.DisposeAsync();
205+
}
206+
207+
[Fact]
208+
public async Task Should_Forward_CustomAgentsLocalOnly_In_Resume_Wire_Request()
209+
{
210+
var (cliPath, capturePath) = await CreateFakeCliCaptureAsync();
211+
212+
await using var client = Ctx.CreateClient(options: new CopilotClientOptions
213+
{
214+
Connection = RuntimeConnection.ForStdio(path: cliPath, args: ["--capture-file", capturePath]),
215+
UseLoggedInUser = false,
216+
});
217+
218+
await client.StartAsync();
219+
220+
var createSession = await client.CreateSessionAsync(new SessionConfig
221+
{
222+
OnPermissionRequest = PermissionHandler.ApproveAll,
223+
});
224+
var sessionId = createSession.SessionId;
225+
await createSession.DisposeAsync();
226+
227+
var resumeSession = await client.ResumeSessionAsync(sessionId, new ResumeSessionConfig
228+
{
229+
CustomAgentsLocalOnly = true,
230+
OnPermissionRequest = PermissionHandler.ApproveAll,
231+
});
232+
233+
using var capture = JsonDocument.Parse(await File.ReadAllTextAsync(capturePath));
234+
var resumeRequest = GetCapturedRequestParams(capture.RootElement, "session.resume");
235+
Assert.True(resumeRequest.GetProperty("customAgentsLocalOnly").GetBoolean());
236+
237+
await resumeSession.DisposeAsync();
238+
}
239+
181240
[Fact]
182241
public async Task Should_Forward_Granular_Multitenancy_Fields_In_Create_Wire_Request()
183242
{

dotnet/test/Unit/SerializationTests.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,58 @@ public void CreateSessionRequest_CanSerializeEnableSessionTelemetry_WithSdkOptio
590590
Assert.False(root.GetProperty("enableSessionTelemetry").GetBoolean());
591591
}
592592

593+
[Fact]
594+
public void CreateSessionRequest_CanSerializeCustomAgentsLocalOnly_WithSdkOptions()
595+
{
596+
var options = GetSerializerOptions();
597+
var requestType = GetNestedType(typeof(CopilotClient), "CreateSessionRequest");
598+
var request = CreateInternalRequest(
599+
requestType,
600+
("SessionId", "session-id"),
601+
("CustomAgentsLocalOnly", true));
602+
603+
var json = JsonSerializer.Serialize(request, requestType, options);
604+
using var document = JsonDocument.Parse(json);
605+
Assert.True(document.RootElement.GetProperty("customAgentsLocalOnly").GetBoolean());
606+
}
607+
608+
[Fact]
609+
public void ResumeSessionRequest_CanSerializeCustomAgentsLocalOnly_WithSdkOptions()
610+
{
611+
var options = GetSerializerOptions();
612+
var requestType = GetNestedType(typeof(CopilotClient), "ResumeSessionRequest");
613+
var request = CreateInternalRequest(
614+
requestType,
615+
("SessionId", "session-id"),
616+
("CustomAgentsLocalOnly", true));
617+
618+
var json = JsonSerializer.Serialize(request, requestType, options);
619+
using var document = JsonDocument.Parse(json);
620+
Assert.True(document.RootElement.GetProperty("customAgentsLocalOnly").GetBoolean());
621+
}
622+
623+
[Fact]
624+
public void SessionRequests_OmitCustomAgentsLocalOnly_WhenUnset()
625+
{
626+
var options = GetSerializerOptions();
627+
628+
var createRequestType = GetNestedType(typeof(CopilotClient), "CreateSessionRequest");
629+
var createRequest = CreateInternalRequest(
630+
createRequestType,
631+
("SessionId", "session-id"));
632+
var createJson = JsonSerializer.Serialize(createRequest, createRequestType, options);
633+
using var createDocument = JsonDocument.Parse(createJson);
634+
Assert.False(createDocument.RootElement.TryGetProperty("customAgentsLocalOnly", out _));
635+
636+
var resumeRequestType = GetNestedType(typeof(CopilotClient), "ResumeSessionRequest");
637+
var resumeRequest = CreateInternalRequest(
638+
resumeRequestType,
639+
("SessionId", "session-id"));
640+
var resumeJson = JsonSerializer.Serialize(resumeRequest, resumeRequestType, options);
641+
using var resumeDocument = JsonDocument.Parse(resumeJson);
642+
Assert.False(resumeDocument.RootElement.TryGetProperty("customAgentsLocalOnly", out _));
643+
}
644+
593645
[Fact]
594646
public void ResumeSessionRequest_CanSerializeEnableSessionTelemetry_WithSdkOptions()
595647
{

0 commit comments

Comments
 (0)