-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtool_provider.py
More file actions
88 lines (68 loc) · 2.72 KB
/
Copy pathtool_provider.py
File metadata and controls
88 lines (68 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from langchain_anthropic import ChatAnthropic
from typing import Any
import json
llm = ChatAnthropic(model="claude-haiku-4-5-20251001")
class ToolServer:
"""Simulated MCP Tool Server."""
def list_tools(self) -> list[dict]:
return [
{
"name": "calculate",
"description": "Evaluate a math expression",
"args": {"expression": "string — e.g. '2 + 3 * 4'"},
},
{
"name": "get_weather",
"description": "Get current weather for a city",
"args": {"city": "string — e.g. 'Paris'"},
},
]
def call_tool(self, name: str, args: dict[str, Any]) -> str:
if name == "calculate":
try:
result = eval(args["expression"], {"__builtins__": {}})
return f"Result: {result}"
except Exception as e:
return f"Error: {e}"
elif name == "get_weather":
city = args.get("city", "Unknown")
mock_weather = {
"Paris": "Sunny, 22°C",
"Tokyo": "Cloudy, 18°C",
"New York": "Rainy, 15°C",
}
return mock_weather.get(city, f"Weather data unavailable for {city}")
return f"Unknown tool: {name}"
def agent_reason_and_call(server: ToolServer, question: str) -> tuple:
tools = server.list_tools()
tools_description = json.dumps(tools, indent=2)
plan_prompt = f"""You have access to these tools:
{tools_description}
Question: {question}
Reply with a JSON object only: {{"tool": "<name>", "args": {{...}}}}"""
plan_response = llm.invoke(plan_prompt)
raw = plan_response.content.strip()
# Extract JSON from response
start, end = raw.find("{"), raw.rfind("}") + 1
tool_call = json.loads(raw[start:end])
tool_result = server.call_tool(tool_call["tool"], tool_call["args"])
answer_prompt = f"""Question: {question}
Tool used: {tool_call['tool']} with args {tool_call['args']}
Tool result: {tool_result}
Provide a concise final answer."""
answer = llm.invoke(answer_prompt)
return answer.content, tool_call, tool_result
def main():
server = ToolServer()
question = "What is the weather like in Tokyo right now?"
print("=== Tool Provider Pattern ===")
print(f"Question: {question}\n")
print("Available tools:")
for t in server.list_tools():
print(f" - {t['name']}: {t['description']}")
answer, tool_call, tool_result = agent_reason_and_call(server, question)
print(f"\nAgent chose tool: {tool_call['tool']} with args {tool_call['args']}")
print(f"Tool result: {tool_result}")
print(f"\nFinal Answer: {answer}")
if __name__ == "__main__":
main()