""" Tests for the bundled tool calls functionality in the CIAYN agent. """ import ast import pytest from unittest.mock import MagicMock, patch from ra_aid.agent_backends.ciayn_agent import CiaynAgent def test_detect_multiple_tool_calls_single(): """Test that a single tool call is correctly recognized as a single item.""" # Setup agent = CiaynAgent( model=MagicMock(), tools=[], ) code = 'ask_expert("What is the meaning of life?")' # Execute result = agent._detect_multiple_tool_calls(code) # Assert assert len(result) == 1 assert result[0] == code def test_detect_multiple_tool_calls_bundleable(): """Test that multiple bundleable tool calls are correctly split.""" # Setup agent = CiaynAgent( model=MagicMock(), tools=[], ) code = '''emit_expert_context("Important context") ask_expert("What does this mean?")''' # Execute result = agent._detect_multiple_tool_calls(code) # Assert assert len(result) == 2 assert "emit_expert_context" in result[0] assert "ask_expert" in result[1] def test_detect_multiple_tool_calls_non_bundleable(): """Test that multiple tool calls with non-bundleable tools are returned as-is.""" # Setup agent = CiaynAgent( model=MagicMock(), tools=[], ) # Include one non-bundleable tool code = '''emit_expert_context("Important context") list_directory("path/to/dir")''' # Execute result = agent._detect_multiple_tool_calls(code) # Assert # Should return the original code since list_directory is not bundleable assert len(result) == 1 assert "emit_expert_context" in result[0] assert "list_directory" in result[0] def test_detect_multiple_tool_calls_invalid_syntax(): """Test that invalid syntax does not break the detection.""" # Setup agent = CiaynAgent( model=MagicMock(), tools=[], ) code = 'emit_expert_context("Unclosed string' # Execute result = agent._detect_multiple_tool_calls(code) # Assert assert len(result) == 1 assert result[0] == code def test_execute_tool_bundled(): """Test executing a bundled tool call.""" # Setup mock tools mock_emit_expert_context = MagicMock() mock_emit_expert_context.__name__ = "emit_expert_context" mock_emit_expert_context.return_value = "Context emitted" mock_ask_expert = MagicMock() mock_ask_expert.__name__ = "ask_expert" mock_ask_expert.return_value = "Expert answer" # Create tool mocks with proper function references emit_tool = MagicMock() emit_tool.func = mock_emit_expert_context ask_tool = MagicMock() ask_tool.func = mock_ask_expert mock_tools = [emit_tool, ask_tool] # Mock get_function_info to avoid needing real function inspection with patch("ra_aid.tools.reflection.get_function_info", return_value="mock function info"): agent = CiaynAgent( model=MagicMock(), tools=mock_tools, ) code = '''emit_expert_context("Important context") ask_expert("What does this mean?")''' mock_message = MagicMock() mock_message.content = code # Mock validate_function_call_pattern to pass validation with patch("ra_aid.agent_backends.ciayn_agent.validate_function_call_pattern", return_value=False): # Execute result = agent._execute_tool(mock_message) # Assert: We now verify that the result contains both tool call results with tagging assert "