mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-03-22 05:37:20 +08:00
feat(MCP, microagent): MCP-support for Repo Microagent & add fetch as default tool (#8360)
Co-authored-by: openhands <openhands@all-hands.dev> Co-authored-by: Engel Nyst <enyst@users.noreply.github.com>
This commit is contained in:
@@ -1,12 +1,18 @@
|
||||
"""Tests for microagent loading in runtime."""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from conftest import (
|
||||
_close_test_runtime,
|
||||
_load_runtime,
|
||||
)
|
||||
|
||||
from openhands.core.config import MCPConfig
|
||||
from openhands.core.config.mcp_config import MCPStdioServerConfig
|
||||
from openhands.mcp.utils import add_mcp_tools_to_agent
|
||||
from openhands.microagent import KnowledgeMicroagent, RepoMicroagent
|
||||
|
||||
|
||||
@@ -165,3 +171,91 @@ Repository-specific test instructions.
|
||||
|
||||
finally:
|
||||
_close_test_runtime(runtime)
|
||||
|
||||
|
||||
def test_default_tools_microagent_exists():
|
||||
"""Test that the default-tools microagent exists in the global microagents directory."""
|
||||
# Get the path to the global microagents directory
|
||||
import openhands
|
||||
|
||||
project_root = os.path.dirname(openhands.__file__)
|
||||
parent_dir = os.path.dirname(project_root)
|
||||
microagents_dir = os.path.join(parent_dir, 'microagents')
|
||||
|
||||
# Check that the default-tools.md file exists
|
||||
default_tools_path = os.path.join(microagents_dir, 'default-tools.md')
|
||||
assert os.path.exists(default_tools_path), (
|
||||
f'default-tools.md not found at {default_tools_path}'
|
||||
)
|
||||
|
||||
# Read the file and check its content
|
||||
with open(default_tools_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Verify it's a repo microagent (always activated)
|
||||
assert 'type: repo' in content, 'default-tools.md should be a repo microagent'
|
||||
|
||||
# Verify it has the fetch tool configured
|
||||
assert 'name: "fetch"' in content, 'default-tools.md should have a fetch tool'
|
||||
assert 'command: "uvx"' in content, 'default-tools.md should use uvx command'
|
||||
assert 'args: ["mcp-server-fetch"]' in content, (
|
||||
'default-tools.md should use mcp-server-fetch'
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_add_mcp_tools_from_microagents():
|
||||
"""Test that add_mcp_tools_to_agent adds tools from microagents."""
|
||||
# Import ActionExecutionClient for mocking
|
||||
from openhands.runtime.impl.action_execution.action_execution_client import (
|
||||
ActionExecutionClient,
|
||||
)
|
||||
|
||||
# Create mock objects
|
||||
mock_agent = MagicMock()
|
||||
mock_runtime = MagicMock(spec=ActionExecutionClient)
|
||||
mock_memory = MagicMock()
|
||||
mock_mcp_config = MCPConfig()
|
||||
|
||||
# Configure the mock memory to return a microagent MCP config
|
||||
mock_stdio_server = MCPStdioServerConfig(
|
||||
name='test-tool', command='test-command', args=['test-arg1', 'test-arg2']
|
||||
)
|
||||
mock_microagent_mcp_config = MCPConfig(stdio_servers=[mock_stdio_server])
|
||||
mock_memory.get_microagent_mcp_tools.return_value = [mock_microagent_mcp_config]
|
||||
|
||||
# Configure the mock runtime
|
||||
mock_runtime.runtime_initialized = True
|
||||
mock_runtime.get_updated_mcp_config.return_value = mock_microagent_mcp_config
|
||||
|
||||
# Mock the fetch_mcp_tools_from_config function to return a mock tool
|
||||
mock_tool = {
|
||||
'type': 'function',
|
||||
'function': {
|
||||
'name': 'test-tool',
|
||||
'description': 'Test tool description',
|
||||
'parameters': {},
|
||||
},
|
||||
}
|
||||
|
||||
with patch(
|
||||
'openhands.mcp.utils.fetch_mcp_tools_from_config',
|
||||
new=AsyncMock(return_value=[mock_tool]),
|
||||
):
|
||||
# Call the function
|
||||
await add_mcp_tools_to_agent(
|
||||
mock_agent, mock_runtime, mock_memory, mock_mcp_config
|
||||
)
|
||||
|
||||
# Verify that the memory's get_microagent_mcp_tools was called
|
||||
mock_memory.get_microagent_mcp_tools.assert_called_once()
|
||||
|
||||
# Verify that the runtime's get_updated_mcp_config was called with the extra stdio servers
|
||||
mock_runtime.get_updated_mcp_config.assert_called_once()
|
||||
args, kwargs = mock_runtime.get_updated_mcp_config.call_args
|
||||
assert len(args) == 1
|
||||
assert len(args[0]) == 1
|
||||
assert args[0][0].name == 'test-tool'
|
||||
|
||||
# Verify that the agent's set_mcp_tools was called with the mock tool
|
||||
mock_agent.set_mcp_tools.assert_called_once_with([mock_tool])
|
||||
|
||||
Reference in New Issue
Block a user