Skip to content

Commit 26c4a2e

Browse files
sjrljulian-risch
andauthored
fix: require messages input parameter in Agent component (#11147)
Co-authored-by: Julian Risch <julian.risch@deepset.ai>
1 parent c2d1bb8 commit 26c4a2e

4 files changed

Lines changed: 28 additions & 22 deletions

File tree

haystack/components/agents/agent.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ def translate(
215215
216216
# The template variables 'language' and 'document' become inputs to the run method
217217
result = agent.run(
218+
messages=[],
218219
language="French",
219220
document="The weather is lovely today and the sun is shining.",
220221
)
@@ -502,7 +503,7 @@ def _create_agent_span(self) -> Any:
502503

503504
def _initialize_fresh_execution(
504505
self,
505-
messages: list[ChatMessage] | None,
506+
messages: list[ChatMessage],
506507
streaming_callback: StreamingCallbackT | None,
507508
requires_async: bool,
508509
*,
@@ -532,11 +533,6 @@ def _initialize_fresh_execution(
532533
"""
533534
user_prompt = user_prompt or self.user_prompt
534535
system_prompt = system_prompt or self.system_prompt
535-
if messages is None and user_prompt is None and system_prompt is None:
536-
raise ValueError(
537-
"No messages provided to the Agent and neither user_prompt nor system_prompt is set. "
538-
"Please provide at least one of these inputs."
539-
)
540536
messages = messages or []
541537

542538
if user_prompt is not None:
@@ -744,7 +740,7 @@ def _runtime_checks(self, break_point: AgentBreakpoint | None, tools: ToolsType)
744740

745741
def run( # noqa: PLR0915
746742
self,
747-
messages: list[ChatMessage] | None = None,
743+
messages: list[ChatMessage],
748744
streaming_callback: StreamingCallbackT | None = None,
749745
*,
750746
generation_kwargs: dict[str, Any] | None = None,
@@ -975,7 +971,7 @@ def run( # noqa: PLR0915
975971

976972
async def run_async( # noqa: PLR0915
977973
self,
978-
messages: list[ChatMessage] | None = None,
974+
messages: list[ChatMessage],
979975
streaming_callback: StreamingCallbackT | None = None,
980976
*,
981977
generation_kwargs: dict[str, Any] | None = None,

haystack/components/generators/chat/llm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def run(
132132
- "last_message": The last message exchanged during the LLM's run.
133133
"""
134134
return super(LLM, self).run( # noqa: UP008
135-
messages=messages,
135+
messages=messages or [],
136136
streaming_callback=streaming_callback,
137137
generation_kwargs=generation_kwargs,
138138
system_prompt=system_prompt,
@@ -169,7 +169,7 @@ async def run_async(
169169
- "last_message": The last message exchanged during the LLM's run.
170170
"""
171171
return await super(LLM, self).run_async( # noqa: UP008
172-
messages=messages,
172+
messages=messages or [],
173173
streaming_callback=streaming_callback,
174174
generation_kwargs=generation_kwargs,
175175
system_prompt=system_prompt,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
upgrade:
3+
- |
4+
``Agent.run()`` and ``Agent.run_async()`` now require ``messages`` as an explicit argument (no longer
5+
optional). If you were relying on the default ``None`` value in Haystack version 2.26 or 2.27, pass an empty list instead:
6+
7+
.. code:: python
8+
9+
agent.run(messages=[], ...)
10+
11+
``LLM.run()`` and ``LLM.run_async()`` are unaffected — they still accept ``None`` and default to
12+
an empty list internally.
13+
fixes:
14+
- |
15+
Reverts the change that made ``Agent`` messages optional as it caused issues with pipeline execution.
16+
As a consequence, the ``LLM`` component now defaults to an empty messages list unless provided at runtime.

test/components/agents/test_agent.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,17 +1517,10 @@ def test_system_prompt_runtime_override(self, make_agent):
15171517
assert result["messages"][0].text == "You are an Haystack expert."
15181518
assert result["messages"][1].text == "Hi"
15191519

1520-
def test_user_prompt_raises_when_no_messages_and_no_prompt(self, weather_tool):
1521-
agent = Agent(chat_generator=MockChatGenerator(), tools=[weather_tool])
1522-
with pytest.raises(
1523-
ValueError, match="No messages provided to the Agent and neither user_prompt nor system_prompt is set"
1524-
):
1525-
agent.run()
1526-
15271520
def test_user_prompt_only_variables_forwarded_to_builder(self, make_agent):
15281521
agent = make_agent(user_prompt=_user_msg("Question: {{question}}"))
15291522
# 'irrelevant_kwarg' is not a template variable — must not raise
1530-
result = agent.run(question="Will it snow?", irrelevant_kwarg="unused")
1523+
result = agent.run(messages=[], question="Will it snow?", irrelevant_kwarg="unused")
15311524
assert "messages" in result
15321525

15331526
def test_user_prompt_with_template_variables(self, make_agent):
@@ -1538,7 +1531,7 @@ def test_user_prompt_with_template_variables(self, make_agent):
15381531
+ " on {{date}}?"
15391532
)
15401533
)
1541-
result = agent.run(name="Alice", cities=["Berlin", "Paris", "Rome"], date="2024-01-15")
1534+
result = agent.run(messages=[], name="Alice", cities=["Berlin", "Paris", "Rome"], date="2024-01-15")
15421535
user_messages = [m for m in result["messages"] if m.is_from(ChatRole.USER)]
15431536
assert user_messages[0].text == "Hello ALICE, check weather for: Berlin, Paris, Rome on 2024-01-15?"
15441537

@@ -1549,7 +1542,7 @@ def test_user_prompt_with_template_variables(self, make_agent):
15491542

15501543
def test_runtime_user_prompt_overrides_init_prompt(self, make_agent):
15511544
agent = make_agent(user_prompt=_user_msg("Default prompt for {{city}}."))
1552-
result = agent.run(user_prompt=_user_msg("Runtime prompt for {{city}}."), city="Berlin")
1545+
result = agent.run(messages=[], user_prompt=_user_msg("Runtime prompt for {{city}}."), city="Berlin")
15531546
user_messages = [m for m in result["messages"] if m.is_from(ChatRole.USER)]
15541547
assert user_messages[0].text == "Runtime prompt for Berlin."
15551548

@@ -1580,7 +1573,7 @@ def test_system_prompt_and_user_prompt(self, make_agent):
15801573
assert agent._system_chat_prompt_builder is not None
15811574
assert agent._user_chat_prompt_builder is not None
15821575

1583-
result = agent.run(project="Haystack", topic="pipelines")
1576+
result = agent.run(messages=[], project="Haystack", topic="pipelines")
15841577
messages = result["messages"]
15851578
assert messages[0].is_from(ChatRole.SYSTEM)
15861579
assert messages[0].text == "You help users of Haystack."
@@ -1629,7 +1622,7 @@ def _factory(user_prompt: str | None = None):
16291622
def test_rag_pipeline_user_prompt_init_only(self, make_rag_pipeline):
16301623
pipeline = make_rag_pipeline()
16311624
query = "Where is the Colosseum?"
1632-
result = pipeline.run(data={"retriever": {"query": query}, "agent": {"query": query}})
1625+
result = pipeline.run(data={"retriever": {"query": query}, "agent": {"query": query, "messages": []}})
16331626
assert "agent" in result
16341627
agent_output = result["agent"]
16351628
assert "messages" in agent_output
@@ -1662,6 +1655,7 @@ def test_rag_pipeline_user_prompt_runtime_override(self, make_rag_pipeline):
16621655
"Answer: {{query}}"
16631656
),
16641657
"query": query,
1658+
"messages": [],
16651659
},
16661660
}
16671661
)

0 commit comments

Comments
 (0)