1010"""
1111
1212import time
13- import asyncio
1413import logging
14+ import pytest
1515from typing import List
1616from praisonaiagents import Agent , tool
1717from praisonaiagents .tools .call_executor import create_tool_call_executor , ToolCall
@@ -88,11 +88,11 @@ def mock_execute_tool(name: str, args: dict, tool_call_id: str = None) -> str:
8888 print (f"Results: { len (par_results )} tools executed" )
8989
9090 # Verify results are identical and in correct order
91- assert len (seq_results ) == len (par_results )
91+ assert len (seq_results ) == len (par_results ), "Result counts should match"
9292 for i , (seq_result , par_result ) in enumerate (zip (seq_results , par_results )):
93- assert seq_result .function_name == par_result .function_name
94- assert seq_result .arguments == par_result .arguments
95- assert seq_result .tool_call_id == par_result .tool_call_id
93+ assert seq_result .function_name == par_result .function_name , f"Function names should match at index { i } "
94+ assert seq_result .arguments == par_result .arguments , f"Arguments should match at index { i } "
95+ assert seq_result .tool_call_id == par_result .tool_call_id , f"Tool call IDs should match at index { i } "
9696 print (f" Result { i + 1 } : { seq_result .function_name } -> { seq_result .result } " )
9797
9898 # Verify latency improvement
@@ -104,10 +104,16 @@ def mock_execute_tool(name: str, args: dict, tool_call_id: str = None) -> str:
104104 assert speedup >= 1.5 , f"Expected speedup >= 1.5x, got { speedup :.2f} x"
105105 print ("✅ ToolCallExecutor protocol test passed!\n " )
106106
107+ @pytest .mark .live
107108def test_agent_parallel_tools ():
108109 """Real agentic test with LLM end-to-end."""
109110 print ("=== Real Agentic Test: Parallel Tool Execution ===" )
110111
112+ # Skip if no OpenAI API key
113+ import os
114+ if not os .getenv ('OPENAI_API_KEY' ) and not os .getenv ('PRAISONAI_LIVE_TESTS' ):
115+ pytest .skip ("OpenAI API key not available for live test" )
116+
111117 # Create agents with different settings
112118 sequential_agent = Agent (
113119 name = "sequential_agent" ,
@@ -138,61 +144,59 @@ def test_agent_parallel_tools():
138144 # Test sequential agent (baseline)
139145 print ("\n --- Sequential Agent ---" )
140146 sequential_start = time .time ()
141- try :
142- sequential_result = sequential_agent .start (prompt )
143- sequential_time = time .time () - sequential_start
144- print (f"Sequential agent completed in: { sequential_time :.2f} s" )
145- print (f"Result length: { len (sequential_result )} chars" )
146- print (f"Result preview: { sequential_result [:200 ]} ..." )
147- except Exception as e :
148- print (f"Sequential agent error: { e } " )
149- sequential_time = float ('inf' )
150- sequential_result = None
147+ sequential_result = sequential_agent .start (prompt )
148+ sequential_time = time .time () - sequential_start
149+ print (f"Sequential agent completed in: { sequential_time :.2f} s" )
150+ print (f"Result length: { len (sequential_result )} chars" )
151+ print (f"Result preview: { sequential_result [:200 ]} ..." )
151152
152153 # Test parallel agent
153154 print ("\n --- Parallel Agent ---" )
154155 parallel_start = time .time ()
155- try :
156- parallel_result = parallel_agent .start (prompt )
157- parallel_time = time .time () - parallel_start
158- print (f"Parallel agent completed in: { parallel_time :.2f} s" )
159- print (f"Result length: { len (parallel_result )} chars" )
160- print (f"Result preview: { parallel_result [:200 ]} ..." )
161- except Exception as e :
162- print (f"Parallel agent error: { e } " )
163- parallel_time = float ('inf' )
164- parallel_result = None
165-
166- # Compare performance
167- if sequential_time < float ('inf' ) and parallel_time < float ('inf' ):
168- speedup = sequential_time / parallel_time if parallel_time > 0 else 1
169- print (f"\n === Performance Comparison ===" )
170- print (f"Sequential time: { sequential_time :.2f} s" )
171- print (f"Parallel time: { parallel_time :.2f} s" )
172- print (f"Speedup: { speedup :.2f} x" )
173-
174- # Both agents should produce similar results
175- if sequential_result and parallel_result :
176- print (f"Both agents completed successfully" )
177- print (f"Sequential result contains tools: { 'fetch_user_data' in sequential_result } " )
178- print (f"Parallel result contains tools: { 'fetch_user_data' in parallel_result } " )
156+ parallel_result = parallel_agent .start (prompt )
157+ parallel_time = time .time () - parallel_start
158+ print (f"Parallel agent completed in: { parallel_time :.2f} s" )
159+ print (f"Result length: { len (parallel_result )} chars" )
160+ print (f"Result preview: { parallel_result [:200 ]} ..." )
161+
162+ speedup = sequential_time / parallel_time if parallel_time > 0 else float ("inf" )
163+ print (f"\n === Performance Comparison ===" )
164+ print (f"Sequential time: { sequential_time :.2f} s" )
165+ print (f"Parallel time: { parallel_time :.2f} s" )
166+ print (f"Speedup: { speedup :.2f} x" )
167+
168+ # Assertions for test validation
169+ assert isinstance (sequential_result , str ) and sequential_result .strip (), (
170+ "Sequential agent should return a non-empty string result."
171+ )
172+ assert isinstance (parallel_result , str ) and parallel_result .strip (), (
173+ "Parallel agent should return a non-empty string result."
174+ )
175+
176+ # Both results should contain evidence of tool execution
177+ assert 'user123' in sequential_result .lower () or 'john doe' in sequential_result .lower (), (
178+ "Sequential result should contain user data"
179+ )
180+ assert 'user123' in parallel_result .lower () or 'john doe' in parallel_result .lower (), (
181+ "Parallel result should contain user data"
182+ )
179183
180184 print ("✅ Real agentic test completed!\n " )
181185
182- def main () :
183- """Run all tests."""
186+ if __name__ == "__main__" :
187+ """Run tests directly ."""
184188 print ("Testing Gap 2: Parallel Tool Execution" )
185189 print ("=====================================" )
186190
187191 # Test 1: Direct executor protocol testing
188192 test_executor_protocols ()
189193
190- # Test 2: Real agentic test (per AGENTS.md requirement)
191- test_agent_parallel_tools ()
194+ # Test 2: Real agentic test (per AGENTS.md requirement)
195+ try :
196+ test_agent_parallel_tools ()
197+ except Exception as e :
198+ print (f"Live test skipped or failed: { e } " )
192199
193- print ("All tests completed successfully ! 🎉" )
200+ print ("Tests completed! 🎉" )
194201 print ("\n Gap 2 implementation allows agents to execute batched LLM tool calls in parallel," )
195202 print ("reducing latency for I/O-bound workflows while maintaining backward compatibility." )
196-
197- if __name__ == "__main__" :
198- main ()
0 commit comments