1import anthropic
2import json
3from typing import Any
4
5client = anthropic.Anthropic()
6
7def get_weather(location: str, unit: str = "celsius") -> dict:
8 """Simulated weather API."""
9 return {"location": location, "temperature": 22, "unit": unit, "condition": "Sunny"}
10
11def calculate(expression: str) -> float:
12 """Safe math evaluator."""
13 allowed = set("0123456789+-*/(). ")
14 if any(c not in allowed for c in expression):
15 raise ValueError("Invalid expression")
16 return eval(expression)
17
18TOOLS = [
19 {
20 "name": "get_weather",
21 "description": "Get current weather for a location",
22 "input_schema": {
23 "type": "object",
24 "properties": {
25 "location": {"type": "string", "description": "City name"},
26 "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
27 },
28 "required": ["location"],
29 },
30 },
31 {
32 "name": "calculate",
33 "description": "Evaluate a mathematical expression",
34 "input_schema": {
35 "type": "object",
36 "properties": {"expression": {"type": "string"}},
37 "required": ["expression"],
38 },
39 },
40]
41
42def run_with_tools(query: str) -> str:
43 messages = [{"role": "user", "content": query}]
44 response = client.messages.create(model="claude-3-5-sonnet-20241022", max_tokens=1024, tools=TOOLS, messages=messages)
45 while response.stop_reason == "tool_use":
46 tool_results = []
47 for block in response.content:
48 if block.type == "tool_use":
49 fn = {"get_weather": get_weather, "calculate": calculate}[block.name]
50 result = fn(**block.input)
51 tool_results.append({"type": "tool_result", "tool_use_id": block.id, "content": json.dumps(result)})
52 messages.append({"role": "assistant", "content": response.content})
53 messages.append({"role": "user", "content": tool_results})
54 response = client.messages.create(model="claude-3-5-sonnet-20241022", max_tokens=1024, tools=TOOLS, messages=messages)
55 return next(b.text for b in response.content if hasattr(b, "text"))