From 33ab44acac4acd5a35e425de77282ce92661ef5e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Jun 2026 18:39:08 +0000 Subject: [PATCH 1/3] Initial plan From ce2857c7b4e66c415849e0819d0f6d317fb2e5bc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Jun 2026 18:54:15 +0000 Subject: [PATCH 2/3] Port shouldUseReplacedIdentitySectionInResponse E2E test to all 5 non-Java languages Co-authored-by: edburns <75821+edburns@users.noreply.github.com> --- .../test/E2E/SystemMessageSectionsE2ETests.cs | 43 ++++++++++++++ .../e2e/system_message_sections_e2e_test.go | 57 ++++++++++++++++++ .../e2e/system_message_sections.e2e.test.ts | 38 ++++++++++++ .../e2e/test_system_message_sections_e2e.py | 42 +++++++++++++ rust/tests/e2e.rs | 2 + rust/tests/e2e/system_message_sections.rs | 59 +++++++++++++++++++ 6 files changed, 241 insertions(+) create mode 100644 dotnet/test/E2E/SystemMessageSectionsE2ETests.cs create mode 100644 go/internal/e2e/system_message_sections_e2e_test.go create mode 100644 nodejs/test/e2e/system_message_sections.e2e.test.ts create mode 100644 python/e2e/test_system_message_sections_e2e.py create mode 100644 rust/tests/e2e/system_message_sections.rs diff --git a/dotnet/test/E2E/SystemMessageSectionsE2ETests.cs b/dotnet/test/E2E/SystemMessageSectionsE2ETests.cs new file mode 100644 index 000000000..210fbcd21 --- /dev/null +++ b/dotnet/test/E2E/SystemMessageSectionsE2ETests.cs @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +using GitHub.Copilot.Rpc; +using GitHub.Copilot.Test.Harness; +using Xunit; +using Xunit.Abstractions; + +namespace GitHub.Copilot.Test.E2E; + +public class SystemMessageSectionsE2ETests(E2ETestFixture fixture, ITestOutputHelper output) : E2ETestBase(fixture, "system_message_sections", output) +{ + [Fact] + public async Task Should_Use_Replaced_Identity_Section_In_Response() + { + var session = await CreateSessionAsync(new SessionConfig + { + OnPermissionRequest = PermissionHandler.ApproveAll, + SystemMessage = new SystemMessageConfig + { + Mode = SystemMessageMode.Customize, + Sections = new Dictionary + { + [SystemMessageSection.Identity] = new SectionOverride + { + Action = SectionOverrideAction.Replace, + Content = "You are a helpful gardening assistant called Botanica. You only answer questions about plants and gardening." + } + } + } + }); + + await session.SendAsync(new MessageOptions { Prompt = "Who are you?" }); + var response = await TestHelper.GetFinalAssistantMessageAsync(session); + + Assert.NotNull(response); + var content = response.Data.Content.ToLowerInvariant(); + Assert.True( + content.Contains("botanica") || content.Contains("garden") || content.Contains("plant"), + $"Expected response to reflect the replaced identity section, but got: {response.Data.Content}"); + } +} diff --git a/go/internal/e2e/system_message_sections_e2e_test.go b/go/internal/e2e/system_message_sections_e2e_test.go new file mode 100644 index 000000000..dfdb466be --- /dev/null +++ b/go/internal/e2e/system_message_sections_e2e_test.go @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package e2e + +import ( + "strings" + "testing" + + copilot "github.com/github/copilot-sdk/go" + "github.com/github/copilot-sdk/go/internal/e2e/testharness" +) + +func TestSystemMessageSectionsE2E(t *testing.T) { + ctx := testharness.NewTestContext(t) + client := ctx.NewClient() + t.Cleanup(func() { client.ForceStop() }) + + t.Run("should_use_replaced_identity_section_in_response", func(t *testing.T) { + ctx.ConfigureForTest(t) + + session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{ + OnPermissionRequest: copilot.PermissionHandler.ApproveAll, + SystemMessage: &copilot.SystemMessageConfig{ + Mode: "customize", + Sections: map[string]copilot.SectionOverride{ + "identity": { + Action: copilot.SectionActionReplace, + Content: "You are a helpful gardening assistant called Botanica. You only answer questions about plants and gardening.", + }, + }, + }, + }) + if err != nil { + t.Fatalf("Failed to create session: %v", err) + } + + response, err := session.SendAndWait(t.Context(), copilot.MessageOptions{ + Prompt: "Who are you?", + }) + if err != nil { + t.Fatalf("Failed to send message: %v", err) + } + if response == nil { + t.Fatal("Expected a response from the assistant") + } + + ad, ok := response.Data.(*copilot.AssistantMessageData) + if !ok { + t.Fatalf("Expected AssistantMessageData, got %T", response.Data) + } + content := strings.ToLower(ad.Content) + if !strings.Contains(content, "botanica") && !strings.Contains(content, "garden") && !strings.Contains(content, "plant") { + t.Errorf("Expected response to reflect the replaced identity section, but got: %s", ad.Content) + } + }) +} diff --git a/nodejs/test/e2e/system_message_sections.e2e.test.ts b/nodejs/test/e2e/system_message_sections.e2e.test.ts new file mode 100644 index 000000000..6a1d5814d --- /dev/null +++ b/nodejs/test/e2e/system_message_sections.e2e.test.ts @@ -0,0 +1,38 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + *--------------------------------------------------------------------------------------------*/ + +import { describe, expect, it } from "vitest"; +import { approveAll } from "../../src/index.js"; +import { createSdkTestContext } from "./harness/sdkTestContext.js"; + +describe("System message sections", async () => { + const { copilotClient: client } = await createSdkTestContext(); + + it("should_use_replaced_identity_section_in_response", async () => { + const session = await client.createSession({ + onPermissionRequest: approveAll, + systemMessage: { + mode: "customize", + sections: { + identity: { + action: "replace", + content: + "You are a helpful gardening assistant called Botanica. You only answer questions about plants and gardening.", + }, + }, + }, + }); + + const response = await session.sendAndWait({ prompt: "Who are you?" }); + + expect(response).not.toBeNull(); + const content = response!.data.content.toLowerCase(); + expect( + content.includes("botanica") || content.includes("garden") || content.includes("plant"), + `Expected response to reflect the replaced identity section, but got: ${response!.data.content}` + ).toBe(true); + + await session.disconnect(); + }); +}); diff --git a/python/e2e/test_system_message_sections_e2e.py b/python/e2e/test_system_message_sections_e2e.py new file mode 100644 index 000000000..76db6127f --- /dev/null +++ b/python/e2e/test_system_message_sections_e2e.py @@ -0,0 +1,42 @@ +""" +Copyright (c) Microsoft Corporation. + +Tests for system message sections functionality +""" + +import pytest + +from copilot.session import PermissionHandler + +from .testharness import E2ETestContext + +pytestmark = pytest.mark.asyncio(loop_scope="module") + + +class TestSystemMessageSections: + async def test_should_use_replaced_identity_section_in_response( + self, ctx: E2ETestContext + ): + """Test that replacing the identity section causes the assistant to adopt the custom identity""" + session = await ctx.client.create_session( + system_message={ + "mode": "customize", + "sections": { + "identity": { + "action": "replace", + "content": "You are a helpful gardening assistant called Botanica. You only answer questions about plants and gardening.", + }, + }, + }, + on_permission_request=PermissionHandler.approve_all, + ) + + response = await session.send_and_wait("Who are you?") + + assert response is not None, "Expected a response from the assistant" + content = response.data.content.lower() + assert ( + "botanica" in content or "garden" in content or "plant" in content + ), f"Expected response to reflect the replaced identity section, but got: {response.data.content}" + + await session.disconnect() diff --git a/rust/tests/e2e.rs b/rust/tests/e2e.rs index e3058a998..0df63e15e 100644 --- a/rust/tests/e2e.rs +++ b/rust/tests/e2e.rs @@ -119,6 +119,8 @@ mod subagent_hooks; mod support; #[path = "e2e/suspend.rs"] mod suspend; +#[path = "e2e/system_message_sections.rs"] +mod system_message_sections; #[path = "e2e/system_message_transform.rs"] mod system_message_transform; #[path = "e2e/telemetry.rs"] diff --git a/rust/tests/e2e/system_message_sections.rs b/rust/tests/e2e/system_message_sections.rs new file mode 100644 index 000000000..945b8b8ea --- /dev/null +++ b/rust/tests/e2e/system_message_sections.rs @@ -0,0 +1,59 @@ +use std::collections::HashMap; + +use github_copilot_sdk::{SectionOverride, SystemMessageConfig}; + +use super::support::{assistant_message_content, with_e2e_context}; + +#[tokio::test] +async fn should_use_replaced_identity_section_in_response() { + with_e2e_context( + "system_message_sections", + "should_use_replaced_identity_section_in_response", + |ctx| { + Box::pin(async move { + ctx.set_default_copilot_user(); + let mut sections = HashMap::new(); + sections.insert( + "identity".to_string(), + SectionOverride { + action: Some("replace".to_string()), + content: Some( + "You are a helpful gardening assistant called Botanica. \ + You only answer questions about plants and gardening." + .to_string(), + ), + }, + ); + let client = ctx.start_client().await; + let session = client + .create_session( + ctx.approve_all_session_config().with_system_message( + SystemMessageConfig::new() + .with_mode("customize") + .with_sections(sections), + ), + ) + .await + .expect("create session"); + + let answer = session + .send_and_wait("Who are you?") + .await + .expect("send") + .expect("assistant message"); + let content = assistant_message_content(&answer).to_lowercase(); + assert!( + content.contains("botanica") + || content.contains("garden") + || content.contains("plant"), + "Expected response to reflect the replaced identity section, but got: {}", + assistant_message_content(&answer) + ); + + session.disconnect().await.expect("disconnect session"); + client.stop().await.expect("stop client"); + }) + }, + ) + .await; +} From c67f56f5ddfab347c0e316c3659654b4569aa81d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Jun 2026 20:13:49 +0000 Subject: [PATCH 3/3] fix(python): fix ruff format and lint violations in system_message_sections e2e test Co-authored-by: edburns <75821+edburns@users.noreply.github.com> --- python/e2e/test_system_message_sections_e2e.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/python/e2e/test_system_message_sections_e2e.py b/python/e2e/test_system_message_sections_e2e.py index 76db6127f..a8f2345fe 100644 --- a/python/e2e/test_system_message_sections_e2e.py +++ b/python/e2e/test_system_message_sections_e2e.py @@ -14,17 +14,18 @@ class TestSystemMessageSections: - async def test_should_use_replaced_identity_section_in_response( - self, ctx: E2ETestContext - ): - """Test that replacing the identity section causes the assistant to adopt the custom identity""" + async def test_should_use_replaced_identity_section_in_response(self, ctx: E2ETestContext): + """Test that replacing the identity section causes the assistant to adopt a new persona""" session = await ctx.client.create_session( system_message={ "mode": "customize", "sections": { "identity": { "action": "replace", - "content": "You are a helpful gardening assistant called Botanica. You only answer questions about plants and gardening.", + "content": ( + "You are a helpful gardening assistant called Botanica." + " You only answer questions about plants and gardening." + ), }, }, }, @@ -35,8 +36,9 @@ async def test_should_use_replaced_identity_section_in_response( assert response is not None, "Expected a response from the assistant" content = response.data.content.lower() - assert ( - "botanica" in content or "garden" in content or "plant" in content - ), f"Expected response to reflect the replaced identity section, but got: {response.data.content}" + assert "botanica" in content or "garden" in content or "plant" in content, ( + f"Expected response to reflect the replaced identity section," + f" but got: {response.data.content}" + ) await session.disconnect()