1111from agents .models .openai_chatcompletions import OpenAIChatCompletionsModel
1212from agents .models .openai_responses import OpenAIResponsesModel
1313
14- from bot .agents import DEFAULT_INSTRUCTIONS
1514from bot .agents import MAX_TURNS
1615from bot .agents import OpenAIAgent
1716from bot .agents import _get_model
1817
1918
19+ @pytest .fixture
20+ def _stub_instructions (monkeypatch ):
21+ """Stub out instructions.md loading for from_dict tests."""
22+ monkeypatch .setattr ("bot.agents._load_instructions" , lambda : "stub instructions" )
23+
24+
2025@pytest .fixture (autouse = True )
2126def _mock_model (monkeypatch ):
2227 """Prevent tests from constructing a real OpenAI client."""
@@ -49,7 +54,7 @@ def test_returns_chat_completions_model_when_api_type_is_chat_completions(self,
4954class TestPerChatConversations :
5055 def test_separate_chats_have_independent_history (self ):
5156 """Different chat_ids should maintain separate message histories."""
52- agent = OpenAIAgent (name = "test" )
57+ agent = OpenAIAgent (name = "test" , instructions = "test-prompt" )
5358 agent .append_user_message (chat_id = 100 , message = "hello from chat 100" )
5459 agent .append_user_message (chat_id = 200 , message = "hello from chat 200" )
5560
@@ -62,7 +67,7 @@ def test_separate_chats_have_independent_history(self):
6267 assert msgs_200 [0 ]["content" ] == "hello from chat 200"
6368
6469 def test_same_chat_accumulates_messages (self ):
65- agent = OpenAIAgent (name = "test" )
70+ agent = OpenAIAgent (name = "test" , instructions = "test-prompt" )
6671 agent .append_user_message (chat_id = 100 , message = "first" )
6772 agent .append_user_message (chat_id = 100 , message = "second" )
6873
@@ -72,18 +77,18 @@ def test_same_chat_accumulates_messages(self):
7277 assert msgs [1 ]["content" ] == "second"
7378
7479 def test_unknown_chat_returns_empty (self ):
75- agent = OpenAIAgent (name = "test" )
80+ agent = OpenAIAgent (name = "test" , instructions = "test-prompt" )
7681 assert agent .get_messages (chat_id = 999 ) == []
7782
7883 def test_set_messages_replaces_history (self ):
79- agent = OpenAIAgent (name = "test" )
84+ agent = OpenAIAgent (name = "test" , instructions = "test-prompt" )
8085 agent .append_user_message (chat_id = 100 , message = "old" )
8186 new_msgs = [{"role" : "user" , "content" : "replaced" }]
8287 agent .set_messages (chat_id = 100 , messages = new_msgs )
8388 assert agent .get_messages (chat_id = 100 ) == new_msgs
8489
8590 def test_set_messages_does_not_affect_other_chats (self ):
86- agent = OpenAIAgent (name = "test" )
91+ agent = OpenAIAgent (name = "test" , instructions = "test-prompt" )
8792 agent .append_user_message (chat_id = 100 , message = "chat 100" )
8893 agent .append_user_message (chat_id = 200 , message = "chat 200" )
8994 agent .set_messages (chat_id = 100 , messages = [])
@@ -92,30 +97,23 @@ def test_set_messages_does_not_affect_other_chats(self):
9297
9398
9499class TestInstructions :
95- def test_default_instructions_when_none_provided (self ):
96- agent = OpenAIAgent (name = "test" )
97- assert agent .agent .instructions == DEFAULT_INSTRUCTIONS
98-
99100 def test_custom_instructions (self ):
100101 agent = OpenAIAgent (name = "test" , instructions = "Be a HN bot." )
101102 assert agent .agent .instructions == "Be a HN bot."
102103
103- def test_from_dict_reads_instructions (self ):
104- config = {
105- "instructions" : "Custom prompt here." ,
106- "mcpServers" : {},
107- }
108- agent = OpenAIAgent .from_dict ("test" , config )
109- assert agent .agent .instructions == "Custom prompt here."
104+ def test_from_dict_loads_instructions_from_file (self , tmp_path , monkeypatch ):
105+ monkeypatch .chdir (tmp_path )
106+ (tmp_path / "instructions.md" ).write_text ("From file prompt." , encoding = "utf-8" )
107+ agent = OpenAIAgent .from_dict ("test" , {"mcpServers" : {}})
108+ assert agent .agent .instructions == "From file prompt."
110109
111- def test_from_dict_uses_default_without_instructions (self ):
112- config = {
113- "mcpServers" : {},
114- }
115- agent = OpenAIAgent .from_dict ("test" , config )
116- assert agent .agent .instructions == DEFAULT_INSTRUCTIONS
110+ def test_from_dict_fails_fast_when_instructions_file_missing (self , tmp_path , monkeypatch ):
111+ monkeypatch .chdir (tmp_path )
112+ with pytest .raises (FileNotFoundError , match = "Instructions file not found" ):
113+ OpenAIAgent .from_dict ("test" , {"mcpServers" : {}})
117114
118115
116+ @pytest .mark .usefixtures ("_stub_instructions" )
119117class TestFromDictMcpServers :
120118 def test_url_creates_streamable_http_server (self ):
121119 config = {
@@ -172,7 +170,7 @@ def test_default_max_turns(self):
172170 assert MAX_TURNS == 10
173171
174172 def test_truncate_keeps_recent_turns (self ):
175- agent = OpenAIAgent (name = "test" )
173+ agent = OpenAIAgent (name = "test" , instructions = "test-prompt" )
176174 # Simulate 30 turns: each turn is a user msg + assistant msg
177175 for i in range (30 ):
178176 agent .set_messages (
@@ -196,7 +194,7 @@ def test_truncate_keeps_recent_turns(self):
196194 assert user_msgs [- 1 ]["content" ] == "user-29"
197195
198196 def test_truncate_preserves_tool_messages_within_turn (self ):
199- agent = OpenAIAgent (name = "test" )
197+ agent = OpenAIAgent (name = "test" , instructions = "test-prompt" )
200198 # Build history with tool calls in a turn
201199 history = []
202200 for i in range (MAX_TURNS + 2 ):
@@ -218,7 +216,7 @@ def test_truncate_preserves_tool_messages_within_turn(self):
218216 assert len (tool_msgs ) == 1
219217
220218 def test_no_truncation_when_under_limit (self ):
221- agent = OpenAIAgent (name = "test" )
219+ agent = OpenAIAgent (name = "test" , instructions = "test-prompt" )
222220 for i in range (3 ):
223221 agent .set_messages (
224222 chat_id = 100 ,
0 commit comments