mirror of
https://github.com/tiennm99/serena.git
synced 2026-09-04 08:19:48 +00:00
Fix parsing of tools with missing docstring descriptions
This commit is contained in:
+4
-1
@@ -61,7 +61,10 @@ def make_tool(
|
||||
|
||||
# Mount the tool description as a combination of the docstring description and
|
||||
# the return value description, if it exists.
|
||||
func_doc = f"{docstring.description.strip().strip('.')}."
|
||||
if docstring.description:
|
||||
func_doc = f"{docstring.description.strip().strip('.')}."
|
||||
else:
|
||||
func_doc = "No description available."
|
||||
if (docstring.returns) and (docstring_returns := docstring.returns.description):
|
||||
func_doc = f"{func_doc} Returns {docstring_returns.strip().strip('.')}."
|
||||
|
||||
|
||||
@@ -198,3 +198,65 @@ def test_make_tool_missing_apply() -> None:
|
||||
|
||||
with pytest.raises(AttributeError):
|
||||
make_tool(tool)
|
||||
|
||||
|
||||
def test_make_tool_missing_description() -> None:
|
||||
"""Test make_tool with a function that has no description in the docstring."""
|
||||
|
||||
class NoDescriptionTool(BaseMockTool):
|
||||
def apply(self, param: str) -> str:
|
||||
"""
|
||||
:param param: The parameter
|
||||
:return: A result
|
||||
"""
|
||||
return f"Result: {param}"
|
||||
|
||||
def apply_ex(self, *args, **kwargs) -> str:
|
||||
return self.apply(**kwargs)
|
||||
|
||||
tool = NoDescriptionTool()
|
||||
mcp_tool = make_tool(tool)
|
||||
|
||||
assert mcp_tool.name == "no_description"
|
||||
assert mcp_tool.description == "No description available. Returns A result."
|
||||
assert mcp_tool.parameters["properties"]["param"]["description"] == "The parameter."
|
||||
|
||||
|
||||
def test_make_tool_all_tools() -> None:
|
||||
"""Test that make_tool works for all tools in the codebase."""
|
||||
from serena.agent import iter_tool_classes, Tool
|
||||
|
||||
# Create a mock agent for tool initialization
|
||||
class MockAgent:
|
||||
def __init__(self):
|
||||
self.project_config = None
|
||||
self.serena_config = None
|
||||
|
||||
# Get all tool classes
|
||||
tool_classes = list(iter_tool_classes())
|
||||
|
||||
# Make sure we found some tools
|
||||
assert len(tool_classes) > 0
|
||||
|
||||
# Test each tool class
|
||||
for tool_class in tool_classes:
|
||||
try:
|
||||
# Skip abstract base classes that can't be instantiated
|
||||
if tool_class.__name__ == "Tool" or getattr(tool_class, "__abstractmethods__", set()):
|
||||
continue
|
||||
|
||||
# Create an instance of the tool
|
||||
tool_instance = tool_class(MockAgent())
|
||||
|
||||
# Try to create an MCP tool from it
|
||||
mcp_tool = make_tool(tool_instance)
|
||||
|
||||
# Basic validation
|
||||
assert isinstance(mcp_tool, MCPTool)
|
||||
assert mcp_tool.name == tool_class.get_name()
|
||||
|
||||
# The description should be a string (either from docstring or default)
|
||||
assert isinstance(mcp_tool.description, str)
|
||||
|
||||
except Exception as e:
|
||||
pytest.fail(f"Failed to create MCP tool for {tool_class.__name__}: {e}")
|
||||
|
||||
Reference in New Issue
Block a user