@@ -63,37 +63,52 @@ async def run_async(self, messages: list[ChatMessage], **kwargs) -> dict[str, An
6363
6464class TestLLM :
6565 class TestInit :
66+ USER_PROMPT = '{% message role="user" %}{{ query }}{% endmessage %}'
67+
6668 def test_is_subclass_of_agent (self ):
6769 assert issubclass (LLM , Agent )
6870
6971 def test_defaults (self ):
70- llm = LLM (chat_generator = MockChatGenerator ())
72+ llm = LLM (chat_generator = MockChatGenerator (), user_prompt = self . USER_PROMPT )
7173 assert llm .chat_generator is not None
7274 assert llm .tools == []
7375 assert llm .system_prompt is None
74- assert llm .user_prompt is None
76+ assert llm .user_prompt == self .USER_PROMPT
77+ assert llm .required_variables == "*"
7578 assert llm .streaming_callback is None
7679 assert llm ._tool_invoker is None
7780
7881 def test_output_sockets (self ):
79- llm = LLM (chat_generator = MockChatGenerator ())
82+ llm = LLM (chat_generator = MockChatGenerator (), user_prompt = self . USER_PROMPT )
8083 assert llm .__haystack_output__ ._sockets_dict == {
8184 "messages" : OutputSocket (name = "messages" , type = list [ChatMessage ], receivers = []),
8285 "last_message" : OutputSocket (name = "last_message" , type = ChatMessage , receivers = []),
8386 }
8487
8588 def test_detects_no_tools_support (self ):
86- llm = LLM (chat_generator = MockChatGenerator ())
89+ llm = LLM (chat_generator = MockChatGenerator (), user_prompt = self . USER_PROMPT )
8790 assert llm ._chat_generator_supports_tools is False
8891
8992 def test_detects_tools_support (self ):
90- llm = LLM (chat_generator = MockChatGeneratorWithTools ())
93+ llm = LLM (chat_generator = MockChatGeneratorWithTools (), user_prompt = self . USER_PROMPT )
9194 assert llm ._chat_generator_supports_tools is True
9295
96+ def test_raises_if_user_prompt_has_no_variables (self ):
97+ with pytest .raises (ValueError , match = "at least one template variable" ):
98+ LLM (
99+ chat_generator = MockChatGenerator (),
100+ user_prompt = '{% message role="user" %}Hello world{% endmessage %}' ,
101+ )
102+
103+ def test_raises_if_required_variables_empty (self ):
104+ with pytest .raises (ValueError , match = "required_variables must not be empty" ):
105+ LLM (chat_generator = MockChatGenerator (), user_prompt = self .USER_PROMPT , required_variables = [])
106+
93107 class TestSerialization :
94108 def test_to_dict_excludes_agent_only_params (self , monkeypatch ):
95109 monkeypatch .setenv ("OPENAI_API_KEY" , "fake-key" )
96- llm = LLM (chat_generator = OpenAIChatGenerator (), system_prompt = "You are helpful." )
110+ user_prompt = '{% message role="user" %}{{ query }}{% endmessage %}'
111+ llm = LLM (chat_generator = OpenAIChatGenerator (), system_prompt = "You are helpful." , user_prompt = user_prompt )
97112
98113 serialized = llm .to_dict ()
99114
@@ -153,8 +168,8 @@ def test_from_dict(self, monkeypatch):
153168 },
154169 },
155170 "system_prompt" : "You are helpful." ,
156- "user_prompt" : None ,
157- "required_variables" : None ,
171+ "user_prompt" : '{% message role="user" %}{{ query }}{% endmessage %}' ,
172+ "required_variables" : "*" ,
158173 "streaming_callback" : None ,
159174 },
160175 }
@@ -168,7 +183,10 @@ def test_from_dict(self, monkeypatch):
168183
169184 def test_roundtrip (self , monkeypatch ):
170185 monkeypatch .setenv ("OPENAI_API_KEY" , "fake-key" )
171- original = LLM (chat_generator = OpenAIChatGenerator (), system_prompt = "You are a poet." )
186+ user_prompt = '{% message role="user" %}{{ query }}{% endmessage %}'
187+ original = LLM (
188+ chat_generator = OpenAIChatGenerator (), system_prompt = "You are a poet." , user_prompt = user_prompt
189+ )
172190
173191 restored = LLM .from_dict (original .to_dict ())
174192
0 commit comments