From 013a295d046afeb0b9f6903b2a19ba8c9fc5def5 Mon Sep 17 00:00:00 2001 From: Dean Schmigelski Date: Wed, 12 Nov 2025 10:50:27 -0500 Subject: [PATCH 1/2] fix(models): allow setter on system_prompt and system_prompt_content --- src/strands/agent/agent.py | 14 ++++++++++++-- tests/strands/agent/test_agent.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/strands/agent/agent.py b/src/strands/agent/agent.py index b7633d5e8..9ccb5a2f1 100644 --- a/src/strands/agent/agent.py +++ b/src/strands/agent/agent.py @@ -287,8 +287,8 @@ def __init__( """ self.model = BedrockModel() if not model else BedrockModel(model_id=model) if isinstance(model, str) else model self.messages = messages if messages is not None else [] - # initializing self.system_prompt for backwards compatibility - self.system_prompt, self._system_prompt_content = self._initialize_system_prompt(system_prompt) + # initializing self._system_prompt for backwards compatibility + self._system_prompt, self._system_prompt_content = self._initialize_system_prompt(system_prompt) self._default_structured_output_model = structured_output_model self.agent_id = _identifier.validate(agent_id or _DEFAULT_AGENT_ID, _identifier.Identifier.AGENT) self.name = name or _DEFAULT_AGENT_NAME @@ -365,6 +365,16 @@ def __init__( self.hooks.add_hook(hook) self.hooks.invoke_callbacks(AgentInitializedEvent(agent=self)) + @property + def system_prompt(self) -> str | None: + """Get the system prompt.""" + return self._system_prompt + + @system_prompt.setter + def system_prompt(self, value: str | list[SystemContentBlock] | None) -> None: + """Set the system prompt and update internal content representation.""" + self._system_prompt, self._system_prompt_content = self._initialize_system_prompt(value) + @property def tool(self) -> ToolCaller: """Call tool as a function. diff --git a/tests/strands/agent/test_agent.py b/tests/strands/agent/test_agent.py index b96a04b21..d04f57948 100644 --- a/tests/strands/agent/test_agent.py +++ b/tests/strands/agent/test_agent.py @@ -1221,6 +1221,37 @@ async def test_stream_async_multi_modal_input(mock_model, agent, agenerator, ali assert tru_message == exp_message +def test_system_prompt_setter_string(): + """Test that setting system_prompt with string updates both internal fields.""" + agent = Agent(system_prompt="initial prompt") + + agent.system_prompt = "updated prompt" + + assert agent.system_prompt == "updated prompt" + assert agent._system_prompt_content == [{"text": "updated prompt"}] + + +def test_system_prompt_setter_list(): + """Test that setting system_prompt with list updates both internal fields.""" + agent = Agent() + + content_blocks = [{"text": "You are helpful"}, {"cache_control": {"type": "ephemeral"}}] + agent.system_prompt = content_blocks + + assert agent.system_prompt == "You are helpful" + assert agent._system_prompt_content == content_blocks + + +def test_system_prompt_setter_none(): + """Test that setting system_prompt to None clears both internal fields.""" + agent = Agent(system_prompt="initial prompt") + + agent.system_prompt = None + + assert agent.system_prompt is None + assert agent._system_prompt_content is None + + @pytest.mark.asyncio async def test_stream_async_passes_invocation_state(agent, mock_model, mock_event_loop_cycle, agenerator, alist): mock_model.mock_stream.side_effect = [ From 920c48f8558290b0305e9b9c0d3bf04456dd9df4 Mon Sep 17 00:00:00 2001 From: Dean Schmigelski Date: Wed, 12 Nov 2025 11:13:14 -0500 Subject: [PATCH 2/2] chore: add documentation for system_prompt setter and getter --- src/strands/agent/agent.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/strands/agent/agent.py b/src/strands/agent/agent.py index 9ccb5a2f1..e13b9f6d8 100644 --- a/src/strands/agent/agent.py +++ b/src/strands/agent/agent.py @@ -367,12 +367,31 @@ def __init__( @property def system_prompt(self) -> str | None: - """Get the system prompt.""" + """Get the system prompt as a string for backwards compatibility. + + Returns the system prompt as a concatenated string when it contains text content, + or None if no text content is present. This maintains backwards compatibility + with existing code that expects system_prompt to be a string. + + Returns: + The system prompt as a string, or None if no text content exists. + """ return self._system_prompt @system_prompt.setter def system_prompt(self, value: str | list[SystemContentBlock] | None) -> None: - """Set the system prompt and update internal content representation.""" + """Set the system prompt and update internal content representation. + + Accepts either a string or list of SystemContentBlock objects. + When set, both the backwards-compatible string representation and the internal + content block representation are updated to maintain consistency. + + Args: + value: System prompt as string, list of SystemContentBlock objects, or None. + - str: Simple text prompt (most common use case) + - list[SystemContentBlock]: Content blocks with features like caching + - None: Clear the system prompt + """ self._system_prompt, self._system_prompt_content = self._initialize_system_prompt(value) @property