test_weather_tool_parameters.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. """验证天气子助手能将多个命名参数传给 MCP 工具,不访问外部服务。"""
  2. import unittest
  3. from unittest.mock import Mock, patch
  4. from langchain_core.tools import Tool
  5. from a2a_server import weather_server
  6. class WeatherToolTests(unittest.IsolatedAsyncioTestCase):
  7. async def test_city_and_date_range_reach_mcp_as_named_parameters(self):
  8. parameters = {
  9. "city": "北京",
  10. "start_date": "2026-09-26",
  11. "end_date": "2026-09-28",
  12. }
  13. mcp_call = Mock(return_value="北京天气查询结果")
  14. # 复现 python-a2a 0.5.4 适配器返回的单输入 Tool。
  15. adapter_tool = Tool(
  16. name="query_weather",
  17. description="查询指定城市和日期范围的天气",
  18. func=mcp_call,
  19. metadata={"parameters": {
  20. "type": "object",
  21. "properties": {key: {"type": "string"} for key in parameters},
  22. "required": list(parameters),
  23. }},
  24. )
  25. class ToolCallingExecutor:
  26. def __init__(self, *, agent, tools, verbose):
  27. self.tool = tools[0]
  28. async def ainvoke(self, inputs):
  29. # 模拟模型的结构化工具调用,使用真实 LangChain 参数分发逻辑。
  30. return {"output": await self.tool.ainvoke(parameters)}
  31. with (
  32. patch.object(weather_server, "to_langchain_tool", return_value=[adapter_tool]),
  33. patch.object(weather_server, "create_tool_calling_agent"),
  34. patch.object(weather_server, "AgentExecutor", ToolCallingExecutor),
  35. ):
  36. result = await weather_server.query_weather("北京未来三天天气")
  37. self.assertEqual(result, {"status": "success", "message": "北京天气查询结果"})
  38. mcp_call.assert_called_once_with(**parameters)
  39. if __name__ == "__main__":
  40. unittest.main()