From 77a9acb0103538e42303eec2451348f31e399c42 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Mon, 2 Feb 2026 01:17:02 -0800 Subject: [PATCH 1/3] Updated instructions handling --- .../agent_framework_github_copilot/_agent.py | 40 +++++++++++++--- .../tests/test_github_copilot_agent.py | 46 ++++++++++++++++--- .../github_copilot/github_copilot_basic.py | 10 ++-- .../github_copilot_with_file_operations.py | 10 ++-- .../github_copilot/github_copilot_with_mcp.py | 6 +-- ...ithub_copilot_with_multiple_permissions.py | 10 ++-- .../github_copilot_with_session.py | 18 ++++---- .../github_copilot_with_shell.py | 10 ++-- .../github_copilot/github_copilot_with_url.py | 10 ++-- 9 files changed, 106 insertions(+), 54 deletions(-) diff --git a/python/packages/github_copilot/agent_framework_github_copilot/_agent.py b/python/packages/github_copilot/agent_framework_github_copilot/_agent.py index 8bcfa9a5ba..e59c832d8b 100644 --- a/python/packages/github_copilot/agent_framework_github_copilot/_agent.py +++ b/python/packages/github_copilot/agent_framework_github_copilot/_agent.py @@ -31,6 +31,7 @@ PermissionRequestResult, ResumeSessionConfig, SessionConfig, + SystemMessageConfig, ToolInvocation, ToolResult, ) @@ -57,8 +58,9 @@ class GitHubCopilotOptions(TypedDict, total=False): """GitHub Copilot-specific options.""" - instructions: str - """System message to append to the session.""" + system_message: SystemMessageConfig + """System message configuration for the session. Use mode 'append' to add to the default + system prompt, or 'replace' to completely override it.""" cli_path: str """Path to the Copilot CLI executable. Defaults to GITHUB_COPILOT_CLI_PATH environment variable @@ -139,6 +141,7 @@ def get_weather(city: str) -> str: def __init__( self, + instructions: str | None = None, *, client: CopilotClient | None = None, id: str | None = None, @@ -157,6 +160,9 @@ def __init__( ) -> None: """Initialize the GitHub Copilot Agent. + Args: + instructions: System message for the agent. + Keyword Args: client: Optional pre-configured CopilotClient instance. If not provided, a new client will be created using the other parameters. @@ -188,7 +194,10 @@ def __init__( # Parse options opts: dict[str, Any] = dict(default_options) if default_options else {} - instructions = opts.pop("instructions", None) + + # Handle instructions - direct parameter takes precedence over default_options.system_message + self._prepare_system_message(instructions, opts) + cli_path = opts.pop("cli_path", None) model = opts.pop("model", None) timeout = opts.pop("timeout", None) @@ -208,7 +217,6 @@ def __init__( except ValidationError as ex: raise ServiceInitializationError("Failed to create GitHub Copilot settings.", ex) from ex - self._instructions = instructions self._tools = normalize_tools(tools) self._permission_handler = on_permission_request self._mcp_servers = mcp_servers @@ -400,6 +408,26 @@ def event_handler(event: SessionEvent) -> None: finally: unsubscribe() + @staticmethod + def _prepare_system_message( + instructions: str | None, + opts: dict[str, Any], + ) -> None: + """Prepare system message configuration in opts. + + Direct instructions parameter takes precedence over opts["system_message"]. + Modifies opts in place. + + Args: + instructions: Direct instructions parameter (creates append mode). + opts: Options dictionary to modify. + """ + opts_system_message = opts.pop("system_message", None) + if instructions is not None: + opts["system_message"] = {"mode": "append", "content": instructions} + elif opts_system_message is not None: + opts["system_message"] = opts_system_message + def _prepare_tools( self, tools: list[ToolProtocol | MutableMapping[str, Any]], @@ -495,8 +523,8 @@ async def _create_session(self, streaming: bool) -> CopilotSession: if self._settings.model: config["model"] = self._settings.model # type: ignore[typeddict-item] - if self._instructions: - config["system_message"] = {"mode": "append", "content": self._instructions} + if self._default_options.get("system_message"): + config["system_message"] = self._default_options["system_message"] if self._tools: config["tools"] = self._prepare_tools(self._tools) diff --git a/python/packages/github_copilot/tests/test_github_copilot_agent.py b/python/packages/github_copilot/tests/test_github_copilot_agent.py index f53aa0fe59..babf32d8b0 100644 --- a/python/packages/github_copilot/tests/test_github_copilot_agent.py +++ b/python/packages/github_copilot/tests/test_github_copilot_agent.py @@ -135,12 +135,44 @@ def my_tool(arg: str) -> str: agent = GitHubCopilotAgent(tools=[my_tool]) assert len(agent._tools) == 1 # type: ignore - def test_init_with_instructions(self) -> None: - """Test initialization with custom instructions.""" + def test_init_with_instructions_parameter(self) -> None: + """Test initialization with instructions parameter.""" + agent = GitHubCopilotAgent(instructions="You are a helpful assistant.") + assert agent._default_options.get("system_message") == { # type: ignore + "mode": "append", + "content": "You are a helpful assistant.", + } + + def test_init_with_system_message_in_default_options(self) -> None: + """Test initialization with system_message object in default_options.""" + agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( + default_options={"system_message": {"mode": "append", "content": "You are a helpful assistant."}} + ) + assert agent._default_options.get("system_message") == { # type: ignore + "mode": "append", + "content": "You are a helpful assistant.", + } + + def test_init_with_system_message_replace_mode(self) -> None: + """Test initialization with system_message in replace mode.""" agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={"instructions": "You are a helpful assistant."} + default_options={"system_message": {"mode": "replace", "content": "Custom system prompt."}} ) - assert agent._instructions == "You are a helpful assistant." # type: ignore + assert agent._default_options.get("system_message") == { # type: ignore + "mode": "replace", + "content": "Custom system prompt.", + } + + def test_instructions_parameter_takes_precedence(self) -> None: + """Test that direct instructions parameter takes precedence over default_options.""" + agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( + instructions="Direct instructions", + default_options={"system_message": {"mode": "replace", "content": "Options system_message"}}, + ) + assert agent._default_options.get("system_message") == { # type: ignore + "mode": "append", + "content": "Direct instructions", + } class TestGitHubCopilotAgentLifecycle: @@ -462,10 +494,10 @@ async def test_session_config_includes_instructions( mock_client: MagicMock, mock_session: MagicMock, ) -> None: - """Test that session config includes instructions.""" - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( + """Test that session config includes instructions from direct parameter.""" + agent = GitHubCopilotAgent( + instructions="You are a helpful assistant.", client=mock_client, - default_options={"instructions": "You are a helpful assistant."}, ) await agent.start() diff --git a/python/samples/getting_started/agents/github_copilot/github_copilot_basic.py b/python/samples/getting_started/agents/github_copilot/github_copilot_basic.py index 826113aa2a..5643a005de 100644 --- a/python/samples/getting_started/agents/github_copilot/github_copilot_basic.py +++ b/python/samples/getting_started/agents/github_copilot/github_copilot_basic.py @@ -18,7 +18,7 @@ from typing import Annotated from agent_framework import tool -from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions +from agent_framework.github import GitHubCopilotAgent from pydantic import Field @@ -36,8 +36,8 @@ async def non_streaming_example() -> None: """Example of non-streaming response (get the complete result at once).""" print("=== Non-streaming Response Example ===") - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={"instructions": "You are a helpful weather agent."}, + agent = GitHubCopilotAgent( + instructions="You are a helpful weather agent.", tools=[get_weather], ) @@ -52,8 +52,8 @@ async def streaming_example() -> None: """Example of streaming response (get results as they are generated).""" print("=== Streaming Response Example ===") - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={"instructions": "You are a helpful weather agent."}, + agent = GitHubCopilotAgent( + instructions="You are a helpful weather agent.", tools=[get_weather], ) diff --git a/python/samples/getting_started/agents/github_copilot/github_copilot_with_file_operations.py b/python/samples/getting_started/agents/github_copilot/github_copilot_with_file_operations.py index 70386f8cbd..b5a17262ec 100644 --- a/python/samples/getting_started/agents/github_copilot/github_copilot_with_file_operations.py +++ b/python/samples/getting_started/agents/github_copilot/github_copilot_with_file_operations.py @@ -14,7 +14,7 @@ import asyncio -from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions +from agent_framework.github import GitHubCopilotAgent from copilot.types import PermissionRequest, PermissionRequestResult @@ -35,11 +35,9 @@ def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> Pe async def main() -> None: print("=== GitHub Copilot Agent with File Operation Permissions ===\n") - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={ - "instructions": "You are a helpful assistant that can read and write files.", - "on_permission_request": prompt_permission, - }, + agent = GitHubCopilotAgent( + instructions="You are a helpful assistant that can read and write files.", + default_options={"on_permission_request": prompt_permission}, ) async with agent: diff --git a/python/samples/getting_started/agents/github_copilot/github_copilot_with_mcp.py b/python/samples/getting_started/agents/github_copilot/github_copilot_with_mcp.py index 6f940b4f91..61e9959793 100644 --- a/python/samples/getting_started/agents/github_copilot/github_copilot_with_mcp.py +++ b/python/samples/getting_started/agents/github_copilot/github_copilot_with_mcp.py @@ -14,7 +14,7 @@ import asyncio -from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions +from agent_framework.github import GitHubCopilotAgent from copilot.types import MCPServerConfig, PermissionRequest, PermissionRequestResult @@ -49,9 +49,9 @@ async def main() -> None: }, } - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( + agent = GitHubCopilotAgent( + instructions="You are a helpful assistant with access to the local filesystem and Microsoft Learn.", default_options={ - "instructions": "You are a helpful assistant with access to the local filesystem and Microsoft Learn.", "on_permission_request": prompt_permission, "mcp_servers": mcp_servers, }, diff --git a/python/samples/getting_started/agents/github_copilot/github_copilot_with_multiple_permissions.py b/python/samples/getting_started/agents/github_copilot/github_copilot_with_multiple_permissions.py index 4b6e8948d4..8ecc26ab01 100644 --- a/python/samples/getting_started/agents/github_copilot/github_copilot_with_multiple_permissions.py +++ b/python/samples/getting_started/agents/github_copilot/github_copilot_with_multiple_permissions.py @@ -20,7 +20,7 @@ import asyncio -from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions +from agent_framework.github import GitHubCopilotAgent from copilot.types import PermissionRequest, PermissionRequestResult @@ -43,11 +43,9 @@ def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> Pe async def main() -> None: print("=== GitHub Copilot Agent with Multiple Permissions ===\n") - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={ - "instructions": "You are a helpful development assistant that can read, write files and run commands.", - "on_permission_request": prompt_permission, - }, + agent = GitHubCopilotAgent( + instructions="You are a helpful development assistant that can read, write files and run commands.", + default_options={"on_permission_request": prompt_permission}, ) async with agent: diff --git a/python/samples/getting_started/agents/github_copilot/github_copilot_with_session.py b/python/samples/getting_started/agents/github_copilot/github_copilot_with_session.py index 1150091022..fa1c2e4640 100644 --- a/python/samples/getting_started/agents/github_copilot/github_copilot_with_session.py +++ b/python/samples/getting_started/agents/github_copilot/github_copilot_with_session.py @@ -13,7 +13,7 @@ from typing import Annotated from agent_framework import tool -from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions +from agent_framework.github import GitHubCopilotAgent from pydantic import Field @@ -31,8 +31,8 @@ async def example_with_automatic_session_creation() -> None: """Each run() without thread creates a new session.""" print("=== Automatic Session Creation Example ===") - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={"instructions": "You are a helpful weather agent."}, + agent = GitHubCopilotAgent( + instructions="You are a helpful weather agent.", tools=[get_weather], ) @@ -55,8 +55,8 @@ async def example_with_session_persistence() -> None: """Reuse session via thread object for multi-turn conversations.""" print("=== Session Persistence Example ===") - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={"instructions": "You are a helpful weather agent."}, + agent = GitHubCopilotAgent( + instructions="You are a helpful weather agent.", tools=[get_weather], ) @@ -91,8 +91,8 @@ async def example_with_existing_session_id() -> None: existing_session_id = None # First agent instance - start a conversation - agent1: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={"instructions": "You are a helpful weather agent."}, + agent1 = GitHubCopilotAgent( + instructions="You are a helpful weather agent.", tools=[get_weather], ) @@ -112,8 +112,8 @@ async def example_with_existing_session_id() -> None: print("\n--- Continuing with the same session ID in a new agent instance ---") # Second agent instance - resume the conversation - agent2: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={"instructions": "You are a helpful weather agent."}, + agent2 = GitHubCopilotAgent( + instructions="You are a helpful weather agent.", tools=[get_weather], ) diff --git a/python/samples/getting_started/agents/github_copilot/github_copilot_with_shell.py b/python/samples/getting_started/agents/github_copilot/github_copilot_with_shell.py index dae7302c6e..f5e00aedca 100644 --- a/python/samples/getting_started/agents/github_copilot/github_copilot_with_shell.py +++ b/python/samples/getting_started/agents/github_copilot/github_copilot_with_shell.py @@ -13,7 +13,7 @@ import asyncio -from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions +from agent_framework.github import GitHubCopilotAgent from copilot.types import PermissionRequest, PermissionRequestResult @@ -34,11 +34,9 @@ def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> Pe async def main() -> None: print("=== GitHub Copilot Agent with Shell Permissions ===\n") - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={ - "instructions": "You are a helpful assistant that can execute shell commands.", - "on_permission_request": prompt_permission, - }, + agent = GitHubCopilotAgent( + instructions="You are a helpful assistant that can execute shell commands.", + default_options={"on_permission_request": prompt_permission}, ) async with agent: diff --git a/python/samples/getting_started/agents/github_copilot/github_copilot_with_url.py b/python/samples/getting_started/agents/github_copilot/github_copilot_with_url.py index 89d5ffbf58..4c46017468 100644 --- a/python/samples/getting_started/agents/github_copilot/github_copilot_with_url.py +++ b/python/samples/getting_started/agents/github_copilot/github_copilot_with_url.py @@ -13,7 +13,7 @@ import asyncio -from agent_framework.github import GitHubCopilotAgent, GitHubCopilotOptions +from agent_framework.github import GitHubCopilotAgent from copilot.types import PermissionRequest, PermissionRequestResult @@ -34,11 +34,9 @@ def prompt_permission(request: PermissionRequest, context: dict[str, str]) -> Pe async def main() -> None: print("=== GitHub Copilot Agent with URL Fetching ===\n") - agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( - default_options={ - "instructions": "You are a helpful assistant that can fetch and summarize web content.", - "on_permission_request": prompt_permission, - }, + agent = GitHubCopilotAgent( + instructions="You are a helpful assistant that can fetch and summarize web content.", + default_options={"on_permission_request": prompt_permission}, ) async with agent: From b83690310c632541550e6f8d0c6b0e01dd46eb20 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Mon, 2 Feb 2026 08:22:41 -0800 Subject: [PATCH 2/3] Small improvement --- .../agent_framework_github_copilot/_agent.py | 9 ++++++--- .../tests/test_github_copilot_agent.py | 12 ++++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/python/packages/github_copilot/agent_framework_github_copilot/_agent.py b/python/packages/github_copilot/agent_framework_github_copilot/_agent.py index e59c832d8b..c753b437d7 100644 --- a/python/packages/github_copilot/agent_framework_github_copilot/_agent.py +++ b/python/packages/github_copilot/agent_framework_github_copilot/_agent.py @@ -415,16 +415,19 @@ def _prepare_system_message( ) -> None: """Prepare system message configuration in opts. - Direct instructions parameter takes precedence over opts["system_message"]. + If instructions is provided, it takes precedence for content. + If system_message is also provided, its mode is preserved. Modifies opts in place. Args: - instructions: Direct instructions parameter (creates append mode). + instructions: Direct instructions parameter for content. opts: Options dictionary to modify. """ opts_system_message = opts.pop("system_message", None) if instructions is not None: - opts["system_message"] = {"mode": "append", "content": instructions} + # Use instructions for content, but preserve mode from system_message if provided + mode = opts_system_message.get("mode", "append") if opts_system_message else "append" + opts["system_message"] = {"mode": mode, "content": instructions} elif opts_system_message is not None: opts["system_message"] = opts_system_message diff --git a/python/packages/github_copilot/tests/test_github_copilot_agent.py b/python/packages/github_copilot/tests/test_github_copilot_agent.py index babf32d8b0..38a9c5107f 100644 --- a/python/packages/github_copilot/tests/test_github_copilot_agent.py +++ b/python/packages/github_copilot/tests/test_github_copilot_agent.py @@ -163,12 +163,20 @@ def test_init_with_system_message_replace_mode(self) -> None: "content": "Custom system prompt.", } - def test_instructions_parameter_takes_precedence(self) -> None: - """Test that direct instructions parameter takes precedence over default_options.""" + def test_instructions_parameter_takes_precedence_for_content(self) -> None: + """Test that direct instructions parameter takes precedence for content but preserves mode.""" agent: GitHubCopilotAgent[GitHubCopilotOptions] = GitHubCopilotAgent( instructions="Direct instructions", default_options={"system_message": {"mode": "replace", "content": "Options system_message"}}, ) + assert agent._default_options.get("system_message") == { # type: ignore + "mode": "replace", + "content": "Direct instructions", + } + + def test_instructions_parameter_defaults_to_append_mode(self) -> None: + """Test that instructions parameter defaults to append mode when no system_message provided.""" + agent = GitHubCopilotAgent(instructions="Direct instructions") assert agent._default_options.get("system_message") == { # type: ignore "mode": "append", "content": "Direct instructions", From 4faa9ff3bdd60e1a36bccbd39939efe4a3d44f57 Mon Sep 17 00:00:00 2001 From: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com> Date: Mon, 2 Feb 2026 08:42:55 -0800 Subject: [PATCH 3/3] Included runtime options in session creation logic --- .../agent_framework_github_copilot/_agent.py | 44 +++++++++++++------ .../tests/test_github_copilot_agent.py | 25 +++++++++++ .../github_copilot/github_copilot_basic.py | 35 +++++++++++++++ 3 files changed, 91 insertions(+), 13 deletions(-) diff --git a/python/packages/github_copilot/agent_framework_github_copilot/_agent.py b/python/packages/github_copilot/agent_framework_github_copilot/_agent.py index c753b437d7..90655ae055 100644 --- a/python/packages/github_copilot/agent_framework_github_copilot/_agent.py +++ b/python/packages/github_copilot/agent_framework_github_copilot/_agent.py @@ -310,7 +310,7 @@ async def run( opts: dict[str, Any] = dict(options) if options else {} timeout = opts.pop("timeout", None) or self._settings.timeout or DEFAULT_TIMEOUT_SECONDS - session = await self._get_or_create_session(thread, streaming=False) + session = await self._get_or_create_session(thread, streaming=False, runtime_options=opts) input_messages = normalize_messages(messages) prompt = "\n".join([message.text for message in input_messages]) @@ -373,7 +373,9 @@ async def run_stream( if not thread: thread = self.get_new_thread() - session = await self._get_or_create_session(thread, streaming=True) + opts: dict[str, Any] = dict(options) if options else {} + + session = await self._get_or_create_session(thread, streaming=True, runtime_options=opts) input_messages = normalize_messages(messages) prompt = "\n".join([message.text for message in input_messages]) @@ -490,12 +492,14 @@ async def _get_or_create_session( self, thread: AgentThread, streaming: bool = False, + runtime_options: dict[str, Any] | None = None, ) -> CopilotSession: """Get an existing session or create a new one for the thread. Args: thread: The conversation thread. streaming: Whether to enable streaming for the session. + runtime_options: Runtime options from run/run_stream that take precedence. Returns: A CopilotSession instance. @@ -510,33 +514,47 @@ async def _get_or_create_session( if thread.service_thread_id: return await self._resume_session(thread.service_thread_id, streaming) - session = await self._create_session(streaming) + session = await self._create_session(streaming, runtime_options) thread.service_thread_id = session.session_id return session except Exception as ex: raise ServiceException(f"Failed to create GitHub Copilot session: {ex}") from ex - async def _create_session(self, streaming: bool) -> CopilotSession: - """Create a new Copilot session.""" + async def _create_session( + self, + streaming: bool, + runtime_options: dict[str, Any] | None = None, + ) -> CopilotSession: + """Create a new Copilot session. + + Args: + streaming: Whether to enable streaming for the session. + runtime_options: Runtime options that take precedence over default_options. + """ if not self._client: raise ServiceException("GitHub Copilot client not initialized. Call start() first.") + opts = runtime_options or {} config: SessionConfig = {"streaming": streaming} - if self._settings.model: - config["model"] = self._settings.model # type: ignore[typeddict-item] + model = opts.get("model") or self._settings.model + if model: + config["model"] = model # type: ignore[typeddict-item] - if self._default_options.get("system_message"): - config["system_message"] = self._default_options["system_message"] + system_message = opts.get("system_message") or self._default_options.get("system_message") + if system_message: + config["system_message"] = system_message if self._tools: config["tools"] = self._prepare_tools(self._tools) - if self._permission_handler: - config["on_permission_request"] = self._permission_handler + permission_handler = opts.get("on_permission_request") or self._permission_handler + if permission_handler: + config["on_permission_request"] = permission_handler - if self._mcp_servers: - config["mcp_servers"] = self._mcp_servers + mcp_servers = opts.get("mcp_servers") or self._mcp_servers + if mcp_servers: + config["mcp_servers"] = mcp_servers return await self._client.create_session(config) diff --git a/python/packages/github_copilot/tests/test_github_copilot_agent.py b/python/packages/github_copilot/tests/test_github_copilot_agent.py index 38a9c5107f..e68b58c243 100644 --- a/python/packages/github_copilot/tests/test_github_copilot_agent.py +++ b/python/packages/github_copilot/tests/test_github_copilot_agent.py @@ -516,6 +516,31 @@ async def test_session_config_includes_instructions( assert config["system_message"]["mode"] == "append" assert config["system_message"]["content"] == "You are a helpful assistant." + async def test_runtime_options_take_precedence_over_default( + self, + mock_client: MagicMock, + mock_session: MagicMock, + ) -> None: + """Test that runtime options from run() take precedence over default_options.""" + agent = GitHubCopilotAgent( + instructions="Default instructions", + client=mock_client, + ) + await agent.start() + + runtime_options: GitHubCopilotOptions = { + "system_message": {"mode": "replace", "content": "Runtime instructions"} + } + await agent._get_or_create_session( # type: ignore + AgentThread(), + runtime_options=runtime_options, + ) + + call_args = mock_client.create_session.call_args + config = call_args[0][0] + assert config["system_message"]["mode"] == "replace" + assert config["system_message"]["content"] == "Runtime instructions" + async def test_session_config_includes_streaming_flag( self, mock_client: MagicMock, diff --git a/python/samples/getting_started/agents/github_copilot/github_copilot_basic.py b/python/samples/getting_started/agents/github_copilot/github_copilot_basic.py index 5643a005de..d23591eb02 100644 --- a/python/samples/getting_started/agents/github_copilot/github_copilot_basic.py +++ b/python/samples/getting_started/agents/github_copilot/github_copilot_basic.py @@ -67,11 +67,46 @@ async def streaming_example() -> None: print("\n") +async def runtime_options_example() -> None: + """Example of overriding system message at runtime.""" + print("=== Runtime Options Example ===") + + agent = GitHubCopilotAgent( + instructions="Always respond in exactly 3 words.", + tools=[get_weather], + ) + + async with agent: + query = "What's the weather like in Paris?" + + # First call uses default instructions (3 words response) + print("Using default instructions (3 words):") + print(f"User: {query}") + result1 = await agent.run(query) + print(f"Agent: {result1}\n") + + # Second call overrides with runtime system_message in replace mode + print("Using runtime system_message with replace mode (detailed response):") + print(f"User: {query}") + result2 = await agent.run( + query, + options={ + "system_message": { + "mode": "replace", + "content": "You are a weather expert. Provide detailed weather information " + "with temperature, and recommendations.", + } + }, + ) + print(f"Agent: {result2}\n") + + async def main() -> None: print("=== Basic GitHub Copilot Agent Example ===") await non_streaming_example() await streaming_example() + await runtime_options_example() if __name__ == "__main__":