|
|
| import asyncio |
| import json |
| import os |
|
|
| |
| import pathlib |
| import sys |
| import traceback |
| from unittest.mock import AsyncMock, MagicMock, patch |
|
|
| backend_path = pathlib.Path(__file__).resolve().parent.parent.parent |
| sys.path.append(str(backend_path)) |
| sys.path.append(os.getcwd()) |
|
|
| |
| sys.modules['anthropic'] = MagicMock() |
| sys.modules['google.generativeai'] = MagicMock() |
| sys.modules['zhipuai'] = MagicMock() |
| sys.modules['instructor'] = MagicMock() |
|
|
| from enhanced_ai_workflow_endpoints import AgentStep, FinalAnswer, RealAIWorkflowService, ToolCall |
|
|
|
|
| async def main(): |
| log_file = "chaos_broken_tool.txt" |
| try: |
| with open(log_file, "w") as f: |
| f.write(">>> [CHAOS] Starting TEST 3: The Broken Tool Loop\n") |
| f.write(" [GOAL] Verify system handles repeated tool failures without infinite loop\n") |
|
|
| |
| async def broken_tool(self, tool_call): |
| with open(log_file, "a") as f: |
| f.write(f" [CHAOS] Executing Tool: {tool_call.tool_name} -> SIMULATING FAILURE\n") |
| return "Error: Connection Reset" |
|
|
| |
| with patch('enhanced_ai_workflow_endpoints.ReActAgent._execute_tool', new=broken_tool): |
| |
| mock_client = MagicMock() |
| mock_client.chat.completions.create = AsyncMock() |
| |
| |
| |
| |
| step_1 = AgentStep(action=ToolCall(tool_name="search_web", parameters={"q": "python"}, reasoning="Attempt 1")) |
| |
| step_2 = AgentStep(action=ToolCall(tool_name="search_web", parameters={"q": "python"}, reasoning="Attempt 2")) |
| |
| step_3 = AgentStep(action=ToolCall(tool_name="search_web", parameters={"q": "python"}, reasoning="Attempt 3")) |
| |
| step_4 = AgentStep(action=FinalAnswer(answer="I cannot search right now.", reasoning="Too many failures.")) |
| |
| mock_client.chat.completions.create.side_effect = [step_1, step_2, step_3, step_4] |
| |
| service = RealAIWorkflowService() |
| service.get_client = MagicMock(return_value=mock_client) |
| service.check_api_key = MagicMock(return_value=True) |
|
|
| |
| result = await service.process_with_nlu("Search python", provider="deepseek") |
| |
| with open(log_file, "a") as f: |
| f.write(f" [RESULT] Agent Final Answer: {result.get('answer')}\n") |
| if result.get('answer') == "I cannot search right now.": |
| f.write("[PASS] Circuit Breaker worked (Agent gave up naturally or Loop Limit hit).\n") |
| else: |
| f.write(f"[FAIL] Unexpected result: {result}\n") |
|
|
| except Exception as e: |
| with open(log_file, "a") as f: |
| f.write(f"[FAIL] Exception: {e}\n") |
| traceback.print_exc(file=f) |
|
|
| if __name__ == "__main__": |
| asyncio.run(main()) |
|
|