|
from openai import OpenAI |
|
import json |
|
from typing import List, Dict |
|
import time |
|
import os |
|
|
|
# Initialize OpenRouter client |
|
client = OpenAI( |
|
base_url="https://openrouter.ai/api/v1", |
|
api_key=os.environ.get("OPENROUTER_API_KEY"), |
|
default_headers={ |
|
"HTTP-Referer": "http://localhost:3000", # Required for OpenRouter |
|
"X-Title": "Tool Use Test" # Optional, but good practice |
|
} |
|
) |
|
|
|
def find_tools(search_term: str) -> List[Dict]: |
|
"""Mock tool search function that returns available tools""" |
|
tools = [ |
|
{"id": "calc_basic", "name": "Calculator", "description": "Basic calculator for arithmetic operations, evals python statements"}, |
|
{"id": "weather_api", "name": "Weather API", "description": "Get weather information"}, |
|
{"id": "time_conv", "name": "Time Converter", "description": "Convert between time zones"} |
|
] |
|
return tools |
|
|
|
def select_tool(tool_id: str) -> Dict: |
|
"""Mock tool selection that returns the tool configuration""" |
|
if tool_id == "calc_basic": |
|
return { |
|
"id": "calc_basic", |
|
"name": "Calculator", |
|
"description": "Basic calculator for arithmetic operations", |
|
"function": lambda x: eval(x) |
|
} |
|
return {"error": "Tool not found"} |
|
|
|
def calculator(expression: str) -> float: |
|
"""Simple calculator using eval""" |
|
try: |
|
return eval(expression) |
|
except Exception as e: |
|
return f"Error: {str(e)}" |
|
|
|
def pretty_print_message(message: dict): |
|
"""Pretty print a message with proper formatting""" |
|
role = message.get("role", "unknown") |
|
content = message.get("content", "") |
|
|
|
print(f"\n=== {role.upper()} ===") |
|
print(content) |
|
|
|
if tool_calls := message.get("tool_calls"): |
|
print("\n--- Tool Calls ---") |
|
for tool_call in tool_calls: |
|
print(f"Tool: {tool_call['function']['name']}") |
|
print(f"Arguments: {tool_call['function']['arguments']}") |
|
|
|
def main(): |
|
messages = [ |
|
{"role": "user", "content": "What's the eight root of 4819387574"} |
|
] |
|
|
|
# Base tools that are always available |
|
base_tools = [ |
|
{ |
|
"type": "function", |
|
"function": { |
|
"name": "find_tools", |
|
"description": "Search for available tools", |
|
"parameters": { |
|
"type": "object", |
|
"properties": { |
|
"search_term": { |
|
"type": "string", |
|
"description": "Term to search for tools" |
|
} |
|
}, |
|
"required": ["search_term"] |
|
} |
|
} |
|
}, |
|
{ |
|
"type": "function", |
|
"function": { |
|
"name": "select_tool", |
|
"description": "Select and activate a tool for use", |
|
"parameters": { |
|
"type": "object", |
|
"properties": { |
|
"tool_id": { |
|
"type": "string", |
|
"description": "ID of the tool to select" |
|
} |
|
}, |
|
"required": ["tool_id"] |
|
} |
|
} |
|
} |
|
] |
|
|
|
calculator_tool = { |
|
"type": "function", |
|
"function": { |
|
"name": "calculator", |
|
"description": "Perform basic arithmetic calculations", |
|
"parameters": { |
|
"type": "object", |
|
"properties": { |
|
"expression": { |
|
"type": "string", |
|
"description": "Mathematical expression to evaluate" |
|
} |
|
}, |
|
"required": ["expression"] |
|
} |
|
} |
|
} |
|
|
|
# Start with just the base tools |
|
available_tools = base_tools.copy() |
|
print("Starting conversation...\n") |
|
|
|
while True: |
|
response = client.chat.completions.create( |
|
model="anthropic/claude-3.5-sonnet", |
|
messages=messages, |
|
tools=available_tools, |
|
tool_choice="auto" |
|
) |
|
|
|
message = response.choices[0].message |
|
messages.append(message) |
|
pretty_print_message(message.model_dump()) |
|
|
|
if not message.tool_calls: |
|
break |
|
|
|
for tool_call in message.tool_calls: |
|
function_name = tool_call.function.name |
|
function_args = json.loads(tool_call.function.arguments) |
|
|
|
result = None |
|
if function_name == "find_tools": |
|
result = find_tools(function_args["search_term"]) |
|
elif function_name == "select_tool": |
|
result = select_tool(function_args["tool_id"]) |
|
# Add calculator tool if it was selected |
|
if function_args["tool_id"] == "calc_basic" and calculator_tool not in available_tools: |
|
available_tools.append(calculator_tool) |
|
elif function_name == "calculator": |
|
result = calculator(function_args["expression"]) |
|
|
|
messages.append({ |
|
"role": "tool", |
|
"tool_call_id": tool_call.id, |
|
"name": function_name, |
|
"content": str(result) |
|
}) |
|
|
|
if __name__ == "__main__": |
|
main() |