Skip to content

Commit ba94f95

Browse files
github-actions[bot]stephentoubCopilot
authored
Update @github/copilot to 1.0.60 (#1597)
* Update @github/copilot to 1.0.60 - Updated nodejs and test harness dependencies - Re-ran code generators - Formatted generated code * Regenerate codegen and adjust tests for 1.0.60 - scripts/codegen/go.ts: also match discriminator method name on the discriminator property itself, so sum types with a single variant (e.g. PermissionDecisionNoResult) get the sealing method. - scripts/codegen/python.ts: add reorderPythonDataclassFields pass that moves required fields before optional ones (Python dataclass rule). - Regenerate Go/Python/Java artifacts and adapt E2E tests across all SDKs to the updated RPC surface. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix lint/format failures in Node and Python e2e tests - nodejs/test/e2e/rpc_remote.e2e.test.ts: re-run prettier --write to fix a small indent in waitForCondition call. - python/e2e/test_rpc_server_e2e.py: move LocalSessionMetadataValue into its correct alphabetical position in the from copilot.rpc import block (ruff I001). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Python codegen so ReasoningSummary import is not shadowed The 1.0.60 schema introduces OptionsUpdateReasoningSummary and SessionOpenOptionsReasoningSummary, structurally identical to the shared ReasoningSummary enum. quicktype's enum-merging path (independent of combineClasses) collapsed them into a single locally-defined `class ReasoningSummary(Enum)` that shadowed the import from session_events at the top of rpc.py. ModelSwitchToRequest.to_dict() then called `to_enum(ReasoningSummary, x)` against the local class while session.py constructed values via the imported one, so the isinstance check inside to_enum failed and the unit test TestSessionConfigForwarding.test_set_model_sends_correct_rpc broke. Add a small post-processing step that strips locally-emitted enum classes whose name and value set exactly match a name imported from .session_events. The existing aliases at the end of rpc.py (OptionsUpdateReasoningSummary = ReasoningSummary etc.) now resolve to the imported enum, restoring isinstance equality across the SDK. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Scope down Go discriminator-method collision detection The previous change to `goDiscriminatorMethodName` over-broadly flagged collisions whenever the discriminator property's natural Go name matched the chosen method name, even on multi-variant unions where the discriminator field is elided or renamed to `Discriminator` on the emitted variant structs. The result was 98 unnecessary `Kind()` -> `xxxKind()` method renames across 8 multi-variant unions (PermissionPromptRequest, PermissionDecision, AgentRegistrySpawnResult, SlashCommandInvocationResult, UserToolSessionApproval, PermissionsLocationsAddToolApprovalDetails, and the two ApproveFor* variants). The real natural-name collision case is when the variant struct is a pre-existing type (already in `ctx.generatedNames`) that retained the discriminator as a struct field with its natural Go name -- e.g., `SessionListEntry`'s `LocalSessionMetadataValue.IsRemote bool` field, which would clash with an exported `IsRemote() bool` interface method on the union. This commit narrows the natural-name check to that pre-existing-variant case, leaving the independent `Discriminator`-rename collision clause unchanged. Also drops the now-dead `permissionDecisionKind()` helper from the hand-written `permission_decision_no_result.go`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Stephen Toub <stoub@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 7d6bc92 commit ba94f95

167 files changed

Lines changed: 25769 additions & 4308 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

dotnet/src/Generated/Rpc.cs

Lines changed: 4117 additions & 1157 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dotnet/src/Generated/SessionEvents.cs

Lines changed: 48 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dotnet/test/E2E/RpcRemoteE2ETests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,10 @@ public async Task Should_Notify_Steerable_Changed_Event_And_Persist_Flag()
4848
await session.Rpc.Remote.NotifySteerableChangedAsync(true);
4949

5050
await WaitForRemoteSteerableEventAsync(session, expected: true);
51-
Assert.True((await Client.Rpc.Sessions.GetPersistedRemoteSteerableAsync(session.SessionId)).RemoteSteerable);
5251

5352
await session.Rpc.Remote.NotifySteerableChangedAsync(false);
5453

5554
await WaitForRemoteSteerableEventAsync(session, expected: false);
56-
Assert.False((await Client.Rpc.Sessions.GetPersistedRemoteSteerableAsync(session.SessionId)).RemoteSteerable);
5755
}
5856

5957
private static async Task WaitForRemoteSteerableEventAsync(CopilotSession session, bool expected)

dotnet/test/E2E/RpcServerE2ETests.cs

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
using RpcSessionFsSetProviderConventions = GitHub.Copilot.Rpc.SessionFsSetProviderConventions;
1010
using RpcSessionContext = GitHub.Copilot.Rpc.SessionContext;
1111
using RpcSessionListFilter = GitHub.Copilot.Rpc.SessionListFilter;
12-
using RpcSessionMetadata = GitHub.Copilot.Rpc.SessionMetadata;
12+
using RpcLocalSessionMetadataValue = GitHub.Copilot.Rpc.LocalSessionMetadataValue;
13+
using RpcSessionListEntry = GitHub.Copilot.Rpc.SessionListEntry;
1314

1415
namespace GitHub.Copilot.Test.E2E;
1516

@@ -73,41 +74,34 @@ private static bool PathEquals(string? expected, string? actual)
7374
return string.Equals(normalizedExpected, normalizedActual, comparison);
7475
}
7576

76-
private async Task<string> SaveAndWaitForEventFileAsync(string sessionId)
77-
=> await SaveAndWaitForEventFileAsync(Client, sessionId);
77+
private async Task SaveSessionAsync(string sessionId)
78+
=> await SaveSessionAsync(Client, sessionId);
7879

79-
private static async Task<string> SaveAndWaitForEventFileAsync(CopilotClient client, string sessionId)
80+
private static async Task SaveSessionAsync(CopilotClient client, string sessionId)
8081
{
8182
var saveResult = await client.Rpc.Sessions.SaveAsync(sessionId);
8283
Assert.NotNull(saveResult);
83-
84-
var pathResult = await client.Rpc.Sessions.GetEventFilePathAsync(sessionId);
85-
Assert.False(string.IsNullOrWhiteSpace(pathResult.FilePath));
86-
Assert.True(Path.IsPathRooted(pathResult.FilePath), $"Expected an absolute event file path, got '{pathResult.FilePath}'.");
87-
Assert.Equal("events.jsonl", Path.GetFileName(pathResult.FilePath));
88-
89-
return pathResult.FilePath;
9084
}
9185

92-
private static async Task<string> PersistSessionAsync(CopilotClient client, CopilotSession session, string marker)
86+
private static async Task PersistSessionAsync(CopilotClient client, CopilotSession session, string marker)
9387
{
9488
await session.LogAsync(marker);
95-
return await SaveAndWaitForEventFileAsync(client, session.SessionId);
89+
await SaveSessionAsync(client, session.SessionId);
9690
}
9791

98-
private async Task<RpcSessionMetadata> WaitForListedSessionAsync(
92+
private async Task<RpcSessionListEntry> WaitForListedSessionAsync(
9993
string sessionId,
10094
RpcSessionListFilter? filter = null,
10195
long? metadataLimit = null)
10296
=> await WaitForListedSessionAsync(Client, sessionId, filter, metadataLimit);
10397

104-
private static async Task<RpcSessionMetadata> WaitForListedSessionAsync(
98+
private static async Task<RpcSessionListEntry> WaitForListedSessionAsync(
10599
CopilotClient client,
106100
string sessionId,
107101
RpcSessionListFilter? filter = null,
108102
long? metadataLimit = null)
109103
{
110-
RpcSessionMetadata? metadata = null;
104+
RpcSessionListEntry? metadata = null;
111105
await TestHelper.WaitForConditionAsync(
112106
async () =>
113107
{
@@ -241,8 +235,7 @@ public async Task Should_List_Find_And_Inspect_Persisted_Session_State()
241235

242236
try
243237
{
244-
var eventFilePath = await SaveAndWaitForEventFileAsync(client, sessionId);
245-
Assert.Contains(sessionId, eventFilePath, StringComparison.OrdinalIgnoreCase);
238+
await SaveSessionAsync(client, sessionId);
246239

247240
var listed = await client.Rpc.Sessions.ListAsync(
248241
metadataLimit: 0,
@@ -269,9 +262,6 @@ public async Task Should_List_Find_And_Inspect_Persisted_Session_State()
269262

270263
var inUse = await client.Rpc.Sessions.CheckInUseAsync([sessionId, missingSessionId]);
271264
Assert.DoesNotContain(missingSessionId, inUse.InUse);
272-
273-
var remoteSteerable = await client.Rpc.Sessions.GetPersistedRemoteSteerableAsync(sessionId);
274-
Assert.Null(remoteSteerable.RemoteSteerable);
275265
}
276266
finally
277267
{
@@ -297,9 +287,9 @@ public async Task Should_Enrich_Basic_Session_Metadata()
297287

298288
try
299289
{
300-
await SaveAndWaitForEventFileAsync(client, sessionId);
290+
await SaveSessionAsync(client, sessionId);
301291

302-
var basic = new RpcSessionMetadata
292+
var basic = new RpcLocalSessionMetadataValue
303293
{
304294
SessionId = sessionId,
305295
StartTime = DateTimeOffset.UtcNow.ToString("O"),
@@ -406,7 +396,7 @@ public async Task Should_Prune_DryRun_And_BulkDelete_Persisted_Session()
406396
OnPermissionRequest = PermissionHandler.ApproveAll,
407397
});
408398

409-
await SaveAndWaitForEventFileAsync(client, sessionId);
399+
await SaveSessionAsync(client, sessionId);
410400
await client.Rpc.Sessions.CloseAsync(sessionId);
411401

412402
var prune = await client.Rpc.Sessions.PruneOldAsync(

go/internal/e2e/rpc_remote_e2e_test.go

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,11 @@ func TestRPCRemoteE2E(t *testing.T) {
5151
t.Fatalf("Remote.NotifySteerableChanged(true) failed: %v", err)
5252
}
5353
waitForRemoteSteerableEvent(t, session, true)
54-
persisted, err := client.RPC.Sessions.GetPersistedRemoteSteerable(t.Context(), &rpc.SessionsGetPersistedRemoteSteerableRequest{SessionID: session.SessionID})
55-
if err != nil {
56-
t.Fatalf("Sessions.GetPersistedRemoteSteerable(true) failed: %v", err)
57-
}
58-
if persisted.RemoteSteerable == nil || !*persisted.RemoteSteerable {
59-
t.Fatalf("Expected persisted RemoteSteerable=true, got %+v", persisted)
60-
}
6154

6255
if _, err := session.RPC.Remote.NotifySteerableChanged(t.Context(), &rpc.RemoteNotifySteerableChangedRequest{RemoteSteerable: false}); err != nil {
6356
t.Fatalf("Remote.NotifySteerableChanged(false) failed: %v", err)
6457
}
6558
waitForRemoteSteerableEvent(t, session, false)
66-
persisted, err = client.RPC.Sessions.GetPersistedRemoteSteerable(t.Context(), &rpc.SessionsGetPersistedRemoteSteerableRequest{SessionID: session.SessionID})
67-
if err != nil {
68-
t.Fatalf("Sessions.GetPersistedRemoteSteerable(false) failed: %v", err)
69-
}
70-
if persisted.RemoteSteerable == nil || *persisted.RemoteSteerable {
71-
t.Fatalf("Expected persisted RemoteSteerable=false, got %+v", persisted)
72-
}
7359
})
7460
}
7561

go/internal/e2e/rpc_server_e2e_test.go

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,7 @@ func TestRPCServerE2E(t *testing.T) {
221221
t.Fatalf("Log failed: %v", err)
222222
}
223223

224-
eventFilePath := saveAndGetEventFilePath(t, client, sessionID)
225-
if !strings.Contains(strings.ToLower(eventFilePath), strings.ToLower(sessionID)) {
226-
t.Fatalf("Expected event file path %q to contain session ID %q", eventFilePath, sessionID)
227-
}
224+
saveSession(t, client, sessionID)
228225

229226
metadataLimit := int64(0)
230227
filter := &rpc.SessionListFilter{Cwd: &workingDirectory}
@@ -239,8 +236,9 @@ func TestRPCServerE2E(t *testing.T) {
239236
t.Fatal("Expected non-nil sessions list")
240237
}
241238
for _, metadata := range listed.Sessions {
242-
if metadata.Context != nil {
243-
assertRPCPathEqual(t, workingDirectory, metadata.Context.Cwd)
239+
local, ok := metadata.(*rpc.LocalSessionMetadataValue)
240+
if ok && local.Context != nil {
241+
assertRPCPathEqual(t, workingDirectory, local.Context.Cwd)
244242
}
245243
}
246244

@@ -289,13 +287,6 @@ func TestRPCServerE2E(t *testing.T) {
289287
t.Fatalf("Did not expect missing session %q to be in use: %+v", missingSessionID, inUse.InUse)
290288
}
291289

292-
remoteSteerable, err := client.RPC.Sessions.GetPersistedRemoteSteerable(t.Context(), &rpc.SessionsGetPersistedRemoteSteerableRequest{SessionID: sessionID})
293-
if err != nil {
294-
t.Fatalf("Sessions.GetPersistedRemoteSteerable failed: %v", err)
295-
}
296-
if remoteSteerable.RemoteSteerable != nil {
297-
t.Fatalf("Expected no persisted remote steerable flag, got %v", *remoteSteerable.RemoteSteerable)
298-
}
299290
})
300291

301292
t.Run("should enrich basic session metadata", func(t *testing.T) {
@@ -319,11 +310,11 @@ func TestRPCServerE2E(t *testing.T) {
319310
if err := session.Log(t.Context(), "SERVER_RPC_ENRICH_READY", nil); err != nil {
320311
t.Fatalf("Log failed: %v", err)
321312
}
322-
saveAndGetEventFilePath(t, client, sessionID)
313+
saveSession(t, client, sessionID)
323314

324315
now := time.Now().UTC().Format(time.RFC3339Nano)
325316
result, err := client.RPC.Sessions.EnrichMetadata(t.Context(), &rpc.SessionsEnrichMetadataRequest{
326-
Sessions: []rpc.SessionMetadata{{
317+
Sessions: []rpc.LocalSessionMetadataValue{{
327318
SessionID: sessionID,
328319
StartTime: now,
329320
ModifiedTime: now,
@@ -371,7 +362,7 @@ func TestRPCServerE2E(t *testing.T) {
371362
if err := session.Log(t.Context(), "SERVER_RPC_CLOSE_READY", nil); err != nil {
372363
t.Fatalf("Log failed: %v", err)
373364
}
374-
saveAndGetEventFilePath(t, client, sessionID)
365+
saveSession(t, client, sessionID)
375366

376367
if _, err := client.RPC.Sessions.Close(t.Context(), &rpc.SessionsCloseRequest{SessionID: sessionID}); err != nil {
377368
t.Fatalf("Sessions.Close failed: %v", err)
@@ -410,7 +401,7 @@ func TestRPCServerE2E(t *testing.T) {
410401
t.Fatalf("Log failed: %v", err)
411402
}
412403

413-
saveAndGetEventFilePath(t, client, sessionID)
404+
saveSession(t, client, sessionID)
414405
if _, err := client.RPC.Sessions.Close(t.Context(), &rpc.SessionsCloseRequest{SessionID: sessionID}); err != nil {
415406
t.Fatalf("Sessions.Close failed: %v", err)
416407
}
@@ -624,23 +615,9 @@ func findServerSkill(skills []rpc.ServerSkill, name string) *rpc.ServerSkill {
624615
return nil
625616
}
626617

627-
func saveAndGetEventFilePath(t *testing.T, client *copilot.Client, sessionID string) string {
618+
func saveSession(t *testing.T, client *copilot.Client, sessionID string) {
628619
t.Helper()
629620
if _, err := client.RPC.Sessions.Save(t.Context(), &rpc.SessionsSaveRequest{SessionID: sessionID}); err != nil {
630621
t.Fatalf("Sessions.Save failed: %v", err)
631622
}
632-
path, err := client.RPC.Sessions.GetEventFilePath(t.Context(), &rpc.SessionsGetEventFilePathRequest{SessionID: sessionID})
633-
if err != nil {
634-
t.Fatalf("Sessions.GetEventFilePath failed: %v", err)
635-
}
636-
if strings.TrimSpace(path.FilePath) == "" {
637-
t.Fatal("Expected non-empty event file path")
638-
}
639-
if !filepath.IsAbs(path.FilePath) {
640-
t.Fatalf("Expected absolute event file path, got %q", path.FilePath)
641-
}
642-
if filepath.Base(path.FilePath) != "events.jsonl" {
643-
t.Fatalf("Expected events.jsonl event file, got %q", path.FilePath)
644-
}
645-
return path.FilePath
646623
}

go/rpc/generated_rpc_union_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ func TestUIElicitationSchemaPropertyJSONUnion(t *testing.T) {
322322
if !ok {
323323
t.Fatalf("count property = %T, want *UIElicitationSchemaPropertyNumber", schema.Properties["count"])
324324
}
325-
if count.Type() != UIElicitationSchemaPropertyTypeInteger {
326-
t.Fatalf("count type = %q, want %q", count.Type(), UIElicitationSchemaPropertyTypeInteger)
325+
if count.Discriminator != UIElicitationSchemaPropertyNumberTypeInteger {
326+
t.Fatalf("count type = %q, want %q", count.Discriminator, UIElicitationSchemaPropertyNumberTypeInteger)
327327
}
328328

329329
arrayChoice, ok := schema.Properties["arrayChoice"].(*UIElicitationArrayEnumField)

0 commit comments

Comments
 (0)