66from a2a .types import AgentCapabilities , AgentCard
77from fastapi import FastAPI
88from starlette .applications import Starlette
9-
109from strands .multiagent .a2a .server import A2AServer
1110
1211
@@ -16,7 +15,7 @@ def test_a2a_agent_initialization(mock_strands_agent):
1615 mock_tool_config = {"test_tool" : {"name" : "test_tool" , "description" : "A test tool" }}
1716 mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
1817
19- a2a_agent = A2AServer (mock_strands_agent , skills = None )
18+ a2a_agent = A2AServer (mock_strands_agent )
2019
2120 assert a2a_agent .strands_agent == mock_strands_agent
2221 assert a2a_agent .name == "Test Agent"
@@ -26,7 +25,6 @@ def test_a2a_agent_initialization(mock_strands_agent):
2625 assert a2a_agent .http_url == "http://0.0.0.0:9000/"
2726 assert a2a_agent .version == "0.0.1"
2827 assert isinstance (a2a_agent .capabilities , AgentCapabilities )
29- # Should have skills from tools
3028 assert len (a2a_agent .agent_skills ) == 1
3129 assert a2a_agent .agent_skills [0 ].name == "test_tool"
3230
@@ -38,7 +36,6 @@ def test_a2a_agent_initialization_with_custom_values(mock_strands_agent):
3836 host = "127.0.0.1" ,
3937 port = 8080 ,
4038 version = "1.0.0" ,
41- skills = None ,
4239 )
4340
4441 assert a2a_agent .host == "127.0.0.1"
@@ -110,7 +107,7 @@ def test_agent_skills_empty_registry(mock_strands_agent):
110107 # Mock empty tool registry
111108 mock_strands_agent .tool_registry .get_all_tools_config .return_value = {}
112109
113- a2a_agent = A2AServer (mock_strands_agent , skills = None )
110+ a2a_agent = A2AServer (mock_strands_agent )
114111 skills = a2a_agent .agent_skills
115112
116113 assert isinstance (skills , list )
@@ -123,7 +120,7 @@ def test_agent_skills_with_single_tool(mock_strands_agent):
123120 mock_tool_config = {"calculator" : {"name" : "calculator" , "description" : "Performs basic mathematical calculations" }}
124121 mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
125122
126- a2a_agent = A2AServer (mock_strands_agent , skills = None )
123+ a2a_agent = A2AServer (mock_strands_agent )
127124 skills = a2a_agent .agent_skills
128125
129126 assert isinstance (skills , list )
@@ -146,7 +143,7 @@ def test_agent_skills_with_multiple_tools(mock_strands_agent):
146143 }
147144 mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
148145
149- a2a_agent = A2AServer (mock_strands_agent , skills = None )
146+ a2a_agent = A2AServer (mock_strands_agent )
150147 skills = a2a_agent .agent_skills
151148
152149 assert isinstance (skills , list )
@@ -186,7 +183,7 @@ def test_agent_skills_with_complex_tool_config(mock_strands_agent):
186183 }
187184 mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
188185
189- a2a_agent = A2AServer (mock_strands_agent , skills = None )
186+ a2a_agent = A2AServer (mock_strands_agent )
190187 skills = a2a_agent .agent_skills
191188
192189 assert isinstance (skills , list )
@@ -213,7 +210,7 @@ def test_agent_skills_preserves_tool_order(mock_strands_agent):
213210 )
214211 mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
215212
216- a2a_agent = A2AServer (mock_strands_agent , skills = None )
213+ a2a_agent = A2AServer (mock_strands_agent )
217214 skills = a2a_agent .agent_skills
218215
219216 assert len (skills ) == 3
@@ -233,9 +230,11 @@ def test_agent_skills_handles_missing_description(mock_strands_agent):
233230 }
234231 mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
235232
236- # This should raise a KeyError during initialization when trying to access missing description
233+ a2a_agent = A2AServer (mock_strands_agent )
234+
235+ # This should raise a KeyError when accessing agent_skills due to missing description
237236 with pytest .raises (KeyError ):
238- A2AServer ( mock_strands_agent , skills = None )
237+ _ = a2a_agent . agent_skills
239238
240239
241240def test_agent_skills_handles_missing_name (mock_strands_agent ):
@@ -249,9 +248,11 @@ def test_agent_skills_handles_missing_name(mock_strands_agent):
249248 }
250249 mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
251250
252- # This should raise a KeyError during initialization when trying to access missing name
251+ a2a_agent = A2AServer (mock_strands_agent )
252+
253+ # This should raise a KeyError when accessing agent_skills due to missing name
253254 with pytest .raises (KeyError ):
254- A2AServer ( mock_strands_agent , skills = None )
255+ _ = a2a_agent . agent_skills
255256
256257
257258def test_agent_skills_setter (mock_strands_agent ):
@@ -262,9 +263,9 @@ def test_agent_skills_setter(mock_strands_agent):
262263 mock_tool_config = {"test_tool" : {"name" : "test_tool" , "description" : "A test tool" }}
263264 mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
264265
265- a2a_agent = A2AServer (mock_strands_agent , skills = None )
266+ a2a_agent = A2AServer (mock_strands_agent )
266267
267- # Initially should get skills from tools
268+ # Initially should get skills from tools (lazy loaded)
268269 initial_skills = a2a_agent .agent_skills
269270 assert len (initial_skills ) == 1
270271 assert initial_skills [0 ].name == "test_tool"
@@ -293,7 +294,7 @@ def test_get_skills_from_tools_method(mock_strands_agent):
293294 }
294295 mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
295296
296- a2a_agent = A2AServer (mock_strands_agent , skills = None )
297+ a2a_agent = A2AServer (mock_strands_agent )
297298 skills = a2a_agent ._get_skills_from_tools ()
298299
299300 assert isinstance (skills , list )
@@ -317,7 +318,7 @@ def test_initialization_with_none_skills_uses_tools(mock_strands_agent):
317318
318319 a2a_agent = A2AServer (mock_strands_agent , skills = None )
319320
320- # Should get skills from tools
321+ # Should get skills from tools (lazy loaded)
321322 skills = a2a_agent .agent_skills
322323 assert len (skills ) == 1
323324 assert skills [0 ].name == "test_tool"
@@ -334,6 +335,70 @@ def test_initialization_with_empty_skills_list(mock_strands_agent):
334335 assert len (skills ) == 0
335336
336337
338+ def test_lazy_loading_behavior (mock_strands_agent ):
339+ """Test that skills are only loaded from tools when accessed and no explicit skills are provided."""
340+ mock_tool_config = {"test_tool" : {"name" : "test_tool" , "description" : "A test tool" }}
341+ mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
342+
343+ # Create agent without explicit skills
344+ a2a_agent = A2AServer (mock_strands_agent )
345+
346+ # Verify that _agent_skills is None initially (not loaded yet)
347+ assert a2a_agent ._agent_skills is None
348+
349+ # Access agent_skills property - this should trigger lazy loading
350+ skills = a2a_agent .agent_skills
351+
352+ # Verify skills were loaded from tools
353+ assert len (skills ) == 1
354+ assert skills [0 ].name == "test_tool"
355+
356+ # Verify that _agent_skills is still None (lazy loading doesn't cache)
357+ assert a2a_agent ._agent_skills is None
358+
359+
360+ def test_explicit_skills_override_tools (mock_strands_agent ):
361+ """Test that explicitly provided skills override tool-based skills."""
362+ from a2a .types import AgentSkill
363+
364+ # Mock tool registry with tools
365+ mock_tool_config = {"test_tool" : {"name" : "test_tool" , "description" : "A test tool" }}
366+ mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
367+
368+ # Provide explicit skills
369+ explicit_skills = [AgentSkill (name = "explicit_skill" , id = "explicit_skill" , description = "An explicit skill" , tags = [])]
370+
371+ a2a_agent = A2AServer (mock_strands_agent , skills = explicit_skills )
372+
373+ # Should use explicit skills, not tools
374+ skills = a2a_agent .agent_skills
375+ assert len (skills ) == 1
376+ assert skills [0 ].name == "explicit_skill"
377+ assert skills [0 ].description == "An explicit skill"
378+
379+
380+ def test_skills_not_loaded_during_initialization (mock_strands_agent ):
381+ """Test that skills are not loaded from tools during initialization."""
382+ # Create a mock that would raise an exception if called
383+ mock_strands_agent .tool_registry .get_all_tools_config .side_effect = Exception ("Should not be called during init" )
384+
385+ # This should not raise an exception because tools are not accessed during initialization
386+ a2a_agent = A2AServer (mock_strands_agent )
387+
388+ # Verify that _agent_skills is None
389+ assert a2a_agent ._agent_skills is None
390+
391+ # Reset the mock to return proper data for when skills are actually accessed
392+ mock_tool_config = {"test_tool" : {"name" : "test_tool" , "description" : "A test tool" }}
393+ mock_strands_agent .tool_registry .get_all_tools_config .side_effect = None
394+ mock_strands_agent .tool_registry .get_all_tools_config .return_value = mock_tool_config
395+
396+ # Now accessing skills should work
397+ skills = a2a_agent .agent_skills
398+ assert len (skills ) == 1
399+ assert skills [0 ].name == "test_tool"
400+
401+
337402def test_public_agent_card_with_custom_skills (mock_strands_agent ):
338403 """Test that public_agent_card includes custom skills."""
339404 from a2a .types import AgentSkill
0 commit comments