+28 -14
View File
@@ -11,6 +11,8 @@ ANTHROPIC_API_URL = "https://api.anthropic.com/v1/messages"
MODEL = "claude-3-7-sonnet-20250219" MODEL = "claude-3-7-sonnet-20250219"
BETA_FLAG = "computer-use-2025-01-24" BETA_FLAG = "computer-use-2025-01-24"
TOOL_VERSION = "20250124" TOOL_VERSION = "20250124"
pyautogui.PAUSE = 0.1
SCALING_FACTOR = 1.25
HEADERS = { HEADERS = {
"content-type": "application/json", "content-type": "application/json",
@@ -48,8 +50,9 @@ def execute_computer_tool(tool_input):
buffered = BytesIO() buffered = BytesIO()
screenshot.save(buffered, format="PNG") screenshot.save(buffered, format="PNG")
# Check size and resize if needed (5MB = 5242880 bytes) MAX_BINARY_SIZE = 5242880 * 3 // 4
if buffered.tell() > 4242880: img_data = None
if buffered.tell() > MAX_BINARY_SIZE:
# Reset buffer # Reset buffer
buffered.seek(0) buffered.seek(0)
screenshot = Image.open(buffered) screenshot = Image.open(buffered)
@@ -58,14 +61,19 @@ def execute_computer_tool(tool_input):
while True: while True:
buffered = BytesIO() buffered = BytesIO()
new_size = (int(screenshot.width * 0.8), int(screenshot.height * 0.8)) new_size = (int(screenshot.width * 0.8), int(screenshot.height * 0.8))
print('new size:', new_size)
screenshot = screenshot.resize(new_size, Image.Resampling.LANCZOS) screenshot = screenshot.resize(new_size, Image.Resampling.LANCZOS)
screenshot.save(buffered, format="PNG", optimize=True) screenshot.save(buffered, format="PNG", optimize=True)
if buffered.tell() <= 4242880: buffered.seek(0)
img_data = buffered.read()
if len(img_data) <= MAX_BINARY_SIZE:
break break
buffered.seek(0)
screenshot = Image.open(buffered)
else:
img_data = buffered.getvalue()
# Convert to base64 # Convert to base64
buffered.seek(0) img_base64 = base64.b64encode(img_data).decode('utf-8')
img_base64 = base64.b64encode(buffered.read()).decode('utf-8')
return { return {
"type": "image", "type": "image",
@@ -76,10 +84,10 @@ def execute_computer_tool(tool_input):
} }
} }
elif action == "click": elif action == "left_click":
# Get coordinates # Get coordinates
x = tool_input.get("coordinate_x") x = tool_input.get("coordinate")[0] * SCALING_FACTOR
y = tool_input.get("coordinate_y") y = tool_input.get("coordinate")[1] * SCALING_FACTOR
if x is None or y is None: if x is None or y is None:
return {"type": "text", "text": "Error: Missing coordinates for click action"} return {"type": "text", "text": "Error: Missing coordinates for click action"}
@@ -89,13 +97,13 @@ def execute_computer_tool(tool_input):
elif action == "double_click": elif action == "double_click":
# Get coordinates # Get coordinates
x = tool_input.get("coordinate_x") x = tool_input.get("coordinate")[0] * SCALING_FACTOR
y = tool_input.get("coordinate_y") y = tool_input.get("coordinate")[1] * SCALING_FACTOR
if x is None or y is None: if x is None or y is None:
return {"type": "text", "text": "Error: Missing coordinates for double click action"} return {"type": "text", "text": "Error: Missing coordinates for double click action"}
# Perform double click # Perform double click
pyautogui.doubleClick(x, y) pyautogui.doubleClick(x, y, interval=0.2)
return {"type": "text", "text": f"Double-clicked at coordinates ({x}, {y})"} return {"type": "text", "text": f"Double-clicked at coordinates ({x}, {y})"}
elif action == "type": elif action == "type":
@@ -231,8 +239,8 @@ def send_prompt(api_key, messages):
{ {
"type": f"computer_{TOOL_VERSION}", "type": f"computer_{TOOL_VERSION}",
"name": "computer", "name": "computer",
"display_width_px": 1024, "display_width_px": 2880,
"display_height_px": 768, "display_height_px": 1864,
"display_number": 1 "display_number": 1
}, },
{ {
@@ -315,6 +323,12 @@ def run():
# Execute the tool # Execute the tool
result_content = execute_tool(tool_name, tool_input) result_content = execute_tool(tool_name, tool_input)
print('[TOOL RESULT]')
for key in result_content:
if key == "source":
print(f"{key}: {len(result_content[key])} chars long")
else:
print(f"{key}: {result_content[key]}")
# Add to results # Add to results
tool_results.append({ tool_results.append({