From 1f35e33e8a3f95a573ee73ffc33380ca0fc404eb Mon Sep 17 00:00:00 2001 From: Matt Ellis Date: Mon, 20 Jul 2026 16:05:12 -0700 Subject: [PATCH] Report authoritative cwd in recordContextChange E2E tests The runtime now treats a local session's cwd as authoritative: it is changed via setWorkingDirectory, and a recordContextChange that reports a divergent cwd is ignored (the RPC still succeeds but emits no session.context_changed event). See github/copilot-agent-runtime#12896. The RPC session-state E2E tests set the working directory to a second directory and then reported a third, divergent cwd while waiting for a session.context_changed event. Under the updated contract that event is never emitted, so the C# test timed out. Report the authoritative current cwd (secondDirectory) instead so the event fires, and update the C#, Node, Python, and Go tests accordingly. The Rust test already reported the authoritative cwd and is unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d99e2065-4f40-4f33-90a6-04b2786ac87f --- dotnet/test/E2E/RpcSessionStateE2ETests.cs | 10 ++++++---- go/internal/e2e/rpc_session_state_e2e_test.go | 8 +++++--- nodejs/test/e2e/rpc_session_state.e2e.test.ts | 8 +++++--- python/e2e/test_rpc_session_state_e2e.py | 8 +++++--- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/dotnet/test/E2E/RpcSessionStateE2ETests.cs b/dotnet/test/E2E/RpcSessionStateE2ETests.cs index dfd76fb34f..6dce3c250f 100644 --- a/dotnet/test/E2E/RpcSessionStateE2ETests.cs +++ b/dotnet/test/E2E/RpcSessionStateE2ETests.cs @@ -278,7 +278,6 @@ public async Task Should_Call_Metadata_Snapshot_SetWorkingDirectory_And_RecordCo { var firstDirectory = CreateUniqueDirectory(); var secondDirectory = CreateUniqueDirectory(); - var contextDirectory = CreateUniqueDirectory(); var branch = $"rpc-context-{Guid.NewGuid():N}"; await using var session = await CreateSessionAsync(new SessionConfig { @@ -322,9 +321,12 @@ await TestHelper.WaitForConditionAsync( TimeSpan.FromSeconds(15), timeoutDescription: "session.context_changed event after metadata.recordContextChange"); + // For local sessions the CLI treats the session cwd as authoritative, so a + // recordContextChange that reports a divergent cwd is ignored and emits no event. + // Report the current working directory (secondDirectory) to observe the change. var context = new SessionWorkingDirectoryContext { - Cwd = contextDirectory, + Cwd = secondDirectory, GitRoot = firstDirectory, Branch = branch, Repository = "github/copilot-sdk-e2e", @@ -338,8 +340,8 @@ await TestHelper.WaitForConditionAsync( Assert.NotNull(recordResult); var contextChanged = await contextChangedTask; - Assert.True(PathEquals(contextDirectory, contextChanged.Data.Cwd), - $"Expected context cwd '{contextDirectory}', actual '{contextChanged.Data.Cwd}'."); + Assert.True(PathEquals(secondDirectory, contextChanged.Data.Cwd), + $"Expected context cwd '{secondDirectory}', actual '{contextChanged.Data.Cwd}'."); Assert.True(PathEquals(firstDirectory, contextChanged.Data.GitRoot), $"Expected context git root '{firstDirectory}', actual '{contextChanged.Data.GitRoot}'."); Assert.Equal(branch, contextChanged.Data.Branch); diff --git a/go/internal/e2e/rpc_session_state_e2e_test.go b/go/internal/e2e/rpc_session_state_e2e_test.go index 07ec4138d6..00c2e9ef63 100644 --- a/go/internal/e2e/rpc_session_state_e2e_test.go +++ b/go/internal/e2e/rpc_session_state_e2e_test.go @@ -482,7 +482,6 @@ func TestRPCSessionStateE2E(t *testing.T) { t.Run("should call metadata snapshot set working directory and record context change", func(t *testing.T) { firstDirectory := createUniqueRPCWorkDirectory(t, ctx, "rpc-session-state-first") secondDirectory := createUniqueRPCWorkDirectory(t, ctx, "rpc-session-state-second") - contextDirectory := createUniqueRPCWorkDirectory(t, ctx, "rpc-session-state-context") branch := "rpc-context-" + randomHex(t) session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{ @@ -532,9 +531,12 @@ func TestRPCSessionStateE2E(t *testing.T) { hostType := rpc.SessionWorkingDirectoryContextHostTypeGitHub baseCommit := "0000000000000000000000000000000000000000" headCommit := "1111111111111111111111111111111111111111" + // For local sessions the CLI treats the session cwd as authoritative, so a + // RecordContextChange that reports a divergent cwd is ignored and emits no event. + // Report the current working directory (secondDirectory) to observe the change. if _, err := session.RPC.Metadata.RecordContextChange(t.Context(), &rpc.MetadataRecordContextChangeRequest{ Context: rpc.SessionWorkingDirectoryContext{ - Cwd: contextDirectory, + Cwd: secondDirectory, GitRoot: &firstDirectory, Branch: &branch, Repository: &repo, @@ -548,7 +550,7 @@ func TestRPCSessionStateE2E(t *testing.T) { } contextChanged := awaitEvent(t, awaitContextChanged) data := contextChanged.Data.(*copilot.SessionContextChangedData) - assertRPCPathEqual(t, contextDirectory, data.Cwd) + assertRPCPathEqual(t, secondDirectory, data.Cwd) if data.GitRoot == nil { t.Fatal("Expected context changed git root") } diff --git a/nodejs/test/e2e/rpc_session_state.e2e.test.ts b/nodejs/test/e2e/rpc_session_state.e2e.test.ts index 7c33d55d68..5164f99232 100644 --- a/nodejs/test/e2e/rpc_session_state.e2e.test.ts +++ b/nodejs/test/e2e/rpc_session_state.e2e.test.ts @@ -312,7 +312,6 @@ describe("Session-scoped RPC", async () => { it("should call metadata snapshot, setWorkingDirectory, and recordContextChange", async () => { const firstDirectory = createUniqueDirectory(workDir, "rpc-session-state-first"); const secondDirectory = createUniqueDirectory(workDir, "rpc-session-state-second"); - const contextDirectory = createUniqueDirectory(workDir, "rpc-session-state-context"); const branch = `rpc-context-${randomUUID()}`; const session = await client.createSession({ onPermissionRequest: approveAll, @@ -353,8 +352,11 @@ describe("Session-scoped RPC", async () => { "session.context_changed event" ); + // For local sessions the CLI treats the session cwd as authoritative, so a + // recordContextChange that reports a divergent cwd is ignored and emits no event. + // Report the current working directory (secondDirectory) to observe the change. const context = { - cwd: contextDirectory, + cwd: secondDirectory, gitRoot: firstDirectory, branch, repository: "github/copilot-sdk-e2e", @@ -366,7 +368,7 @@ describe("Session-scoped RPC", async () => { await session.rpc.metadata.recordContextChange({ context }); const event = await contextChanged; - expect(pathsEqual(event.data.cwd, contextDirectory)).toBe(true); + expect(pathsEqual(event.data.cwd, secondDirectory)).toBe(true); expect(pathsEqual(event.data.gitRoot ?? "", firstDirectory)).toBe(true); expect(event.data.branch).toBe(branch); expect(event.data.repository).toBe("github/copilot-sdk-e2e"); diff --git a/python/e2e/test_rpc_session_state_e2e.py b/python/e2e/test_rpc_session_state_e2e.py index 12688f2803..51c1059bb7 100644 --- a/python/e2e/test_rpc_session_state_e2e.py +++ b/python/e2e/test_rpc_session_state_e2e.py @@ -259,7 +259,6 @@ async def test_should_call_metadata_snapshot_set_working_directory_and_record_co ): first_dir = _create_unique_directory(ctx, "metadata-first") second_dir = _create_unique_directory(ctx, "metadata-second") - context_dir = _create_unique_directory(ctx, "metadata-context") branch = f"rpc-context-{uuid.uuid4().hex}" session = await ctx.client.create_session( @@ -304,10 +303,13 @@ def on_event(event): unsubscribe = session.on(on_event) try: + # For local sessions the CLI treats the session cwd as authoritative, so a + # record_context_change that reports a divergent cwd is ignored and emits + # no event. Report the current working directory (second_dir) to observe it. result = await session.rpc.metadata.record_context_change( MetadataRecordContextChangeRequest( context=SessionWorkingDirectoryContext( - cwd=context_dir, + cwd=second_dir, git_root=first_dir, branch=branch, repository="github/copilot-sdk-e2e", @@ -321,7 +323,7 @@ def on_event(event): assert result is not None event = await asyncio.wait_for(context_future, timeout=15.0) - assert _path_equals(context_dir, event.data.cwd) + assert _path_equals(second_dir, event.data.cwd) assert _path_equals(first_dir, event.data.git_root) assert event.data.branch == branch assert event.data.repository == "github/copilot-sdk-e2e"