mirror of
https://github.com/All-Hands-AI/OpenHands.git
synced 2026-04-29 03:00:45 -04:00
Compare commits
6 Commits
uv-migrati
...
openhands/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6b4c27460 | ||
|
|
9991323709 | ||
|
|
c9fa53b026 | ||
|
|
8859c07084 | ||
|
|
5818e79576 | ||
|
|
fbe99983e8 |
112
tests/unit/test_anthropic_api_error.py
Normal file
112
tests/unit/test_anthropic_api_error.py
Normal file
@@ -0,0 +1,112 @@
|
||||
import base64
|
||||
import os
|
||||
from io import BytesIO
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
from litellm.exceptions import BadRequestError
|
||||
from PIL import Image
|
||||
|
||||
from openhands.runtime.browser.base64 import image_to_png_base64_url
|
||||
|
||||
|
||||
def create_test_image():
|
||||
"""Create a simple test image."""
|
||||
# Create a simple 10x10 RGB image
|
||||
img_array = np.zeros((10, 10, 3), dtype=np.uint8)
|
||||
img_array[:, :, 0] = 255 # Red channel
|
||||
return Image.fromarray(img_array)
|
||||
|
||||
|
||||
def test_anthropic_api_png_format_error():
|
||||
"""Test that demonstrates the error when sending a PNG image to Anthropic API."""
|
||||
import litellm
|
||||
|
||||
# Skip this test if no Anthropic API key is available
|
||||
api_key = os.environ.get('ANTHROPIC_API_KEY')
|
||||
if not api_key:
|
||||
pytest.skip('No Anthropic API key available')
|
||||
|
||||
# Create a test image and convert it to PNG base64
|
||||
test_image = create_test_image()
|
||||
png_base64 = image_to_png_base64_url(test_image, add_data_prefix=True)
|
||||
|
||||
# Verify the image URL format is PNG
|
||||
assert png_base64.startswith('data:image/png;base64,'), (
|
||||
f'Expected PNG format, got: {png_base64[:30]}...'
|
||||
)
|
||||
|
||||
# Create a message with the PNG image
|
||||
messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
'content': [
|
||||
{'type': 'text', 'text': "What's in this image?"},
|
||||
{'type': 'image_url', 'image_url': {'url': png_base64}},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
# Try to call the Anthropic API directly with the PNG image
|
||||
# This should raise a BadRequestError about image URL format
|
||||
with pytest.raises(BadRequestError) as excinfo:
|
||||
litellm.completion(
|
||||
model='anthropic/claude-3-opus-20240229', messages=messages, api_key=api_key
|
||||
)
|
||||
|
||||
# Verify the error message contains information about image format
|
||||
error_message = str(excinfo.value)
|
||||
assert 'Image url not in expected format' in error_message, (
|
||||
f'Unexpected error message: {error_message}'
|
||||
)
|
||||
|
||||
|
||||
def test_anthropic_api_jpeg_format():
|
||||
"""Test that demonstrates that JPEG format works with Anthropic API."""
|
||||
import litellm
|
||||
|
||||
# Skip this test if no Anthropic API key is available
|
||||
api_key = os.environ.get('ANTHROPIC_API_KEY')
|
||||
if not api_key:
|
||||
pytest.skip('No Anthropic API key available')
|
||||
|
||||
# Create a test image and convert it to JPEG base64
|
||||
test_image = create_test_image()
|
||||
|
||||
# Save as JPEG to BytesIO
|
||||
buffer = BytesIO()
|
||||
test_image.save(buffer, format='JPEG')
|
||||
buffer.seek(0)
|
||||
|
||||
# Convert to base64
|
||||
jpeg_base64_data = base64.b64encode(buffer.read()).decode('utf-8')
|
||||
jpeg_base64 = f'data:image/jpeg;base64,{jpeg_base64_data}'
|
||||
|
||||
# Verify the image URL format is JPEG
|
||||
assert jpeg_base64.startswith('data:image/jpeg;base64,'), (
|
||||
f'Expected JPEG format, got: {jpeg_base64[:30]}...'
|
||||
)
|
||||
|
||||
# Create a message with the JPEG image
|
||||
messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
'content': [
|
||||
{'type': 'text', 'text': "What's in this image?"},
|
||||
{'type': 'image_url', 'image_url': {'url': jpeg_base64}},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
# Try to call the Anthropic API with the JPEG image
|
||||
# This should work without errors
|
||||
response = litellm.completion(
|
||||
model='anthropic/claude-3-opus-20240229',
|
||||
messages=messages,
|
||||
api_key=api_key,
|
||||
max_tokens=100, # Limit response size for faster test
|
||||
)
|
||||
|
||||
# Verify we got a response
|
||||
assert response is not None
|
||||
assert response.choices[0].message.content is not None
|
||||
178
tests/unit/test_anthropic_browser_integration.py
Normal file
178
tests/unit/test_anthropic_browser_integration.py
Normal file
@@ -0,0 +1,178 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import httpx
|
||||
import numpy as np
|
||||
import pytest
|
||||
from PIL import Image
|
||||
|
||||
from openhands.core.message import ImageContent, Message, TextContent
|
||||
from openhands.events.observation.browse import BrowserOutputObservation
|
||||
from openhands.runtime.browser.base64 import image_to_png_base64_url
|
||||
|
||||
|
||||
def create_test_image():
|
||||
"""Create a simple test image."""
|
||||
# Create a simple 10x10 RGB image
|
||||
img_array = np.zeros((10, 10, 3), dtype=np.uint8)
|
||||
img_array[:, :, 0] = 255 # Red channel
|
||||
return Image.fromarray(img_array)
|
||||
|
||||
|
||||
@patch('httpx.post')
|
||||
def test_anthropic_browser_integration_error(mock_httpx_post):
|
||||
"""Test that demonstrates the integration issue between browser screenshots and Anthropic models.
|
||||
|
||||
This test is designed to fail to show the issue.
|
||||
"""
|
||||
|
||||
# Configure the mock to raise the BadRequestError when called with specific parameters
|
||||
def mock_httpx_post_side_effect(*args, **kwargs):
|
||||
# Check if this is a call to the Anthropic API
|
||||
if args and 'api.anthropic.com' in args[0]:
|
||||
# Get the JSON data being sent to the API
|
||||
json_data = kwargs.get('json', {})
|
||||
messages = json_data.get('messages', [])
|
||||
|
||||
# Check if there's an image URL in the messages
|
||||
for message in messages:
|
||||
content = message.get('content', [])
|
||||
if isinstance(content, list):
|
||||
for item in content:
|
||||
if isinstance(item, dict) and item.get('type') == 'image':
|
||||
image_url = item.get('source', {}).get('data', '')
|
||||
|
||||
# Check if the image URL format is what Anthropic expects
|
||||
if image_url.startswith('data:image/png;base64,'):
|
||||
# This is the actual error that would occur in the real scenario
|
||||
error_response = httpx.Response(
|
||||
status_code=400,
|
||||
json={
|
||||
'error': {
|
||||
'message': "Image url not in expected format. Example Expected input - \"image_url\": \"data:image/jpeg;base64,{base64_image}\". Supported formats - ['image/jpeg', 'image/png', 'image/gif', 'image/webp']."
|
||||
}
|
||||
},
|
||||
request=httpx.Request('POST', args[0]),
|
||||
)
|
||||
raise httpx.HTTPStatusError(
|
||||
'400 Bad Request',
|
||||
request=httpx.Request('POST', args[0]),
|
||||
response=error_response,
|
||||
)
|
||||
|
||||
# If no image URL is found or the format is correct, return a mock response
|
||||
mock_response = MagicMock()
|
||||
mock_response.status_code = 200
|
||||
mock_response.json.return_value = {
|
||||
'content': [{'text': 'This is a mock response'}]
|
||||
}
|
||||
return mock_response
|
||||
|
||||
mock_httpx_post.side_effect = mock_httpx_post_side_effect
|
||||
|
||||
# Create a test image and convert it to base64
|
||||
test_image = create_test_image()
|
||||
screenshot = image_to_png_base64_url(test_image, add_data_prefix=True)
|
||||
|
||||
# Create a BrowserOutputObservation with the screenshot
|
||||
observation = BrowserOutputObservation(
|
||||
content='Test content',
|
||||
url='https://example.com',
|
||||
screenshot=screenshot,
|
||||
trigger_by_action='browse_interactive',
|
||||
)
|
||||
|
||||
# Simulate the process of creating a message from the browser observation
|
||||
text_content = TextContent(type='text', text=observation.get_agent_obs_text())
|
||||
image_content = ImageContent(type='image_url', image_urls=[observation.screenshot])
|
||||
|
||||
# Create a message with both text and image content
|
||||
Message(role='user', content=[text_content, image_content], vision_enabled=True)
|
||||
|
||||
# Format the message for the LLM (simplified version of what happens in the real code)
|
||||
formatted_messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
'content': [
|
||||
{'type': 'text', 'text': observation.get_agent_obs_text()},
|
||||
{'type': 'image_url', 'image_url': {'url': observation.screenshot}},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
# Import litellm to use it directly with our mocked httpx.post
|
||||
import os
|
||||
|
||||
import litellm
|
||||
|
||||
# Get the Anthropic API key from environment variables
|
||||
api_key = os.environ.get('ANTHROPIC_API_KEY')
|
||||
|
||||
# Try to send the message to the LLM using litellm
|
||||
# This should raise an error, but we'll catch it to examine it
|
||||
try:
|
||||
# Call litellm directly with the Anthropic model
|
||||
litellm.completion(
|
||||
model='anthropic/claude-3-opus-20240229',
|
||||
messages=formatted_messages,
|
||||
api_key=api_key,
|
||||
)
|
||||
# If we get here, the test should fail because no error was raised
|
||||
pytest.fail('Expected HTTPStatusError was not raised')
|
||||
except httpx.HTTPStatusError as e:
|
||||
# Verify the error message
|
||||
assert 'Image url not in expected format' in str(
|
||||
e.response.json()['error']['message']
|
||||
)
|
||||
assert 'Supported formats' in str(e.response.json()['error']['message'])
|
||||
|
||||
# This assertion will fail to demonstrate the issue
|
||||
assert observation.screenshot.startswith('data:image/jpeg;base64,'), (
|
||||
f"Image URL format is incorrect. Expected 'data:image/jpeg;base64,' but got {observation.screenshot[:30]}..."
|
||||
)
|
||||
|
||||
# The test fails because the image URL format is not what Anthropic expects
|
||||
# The current implementation uses 'data:image/png;base64,' but Anthropic expects 'data:image/jpeg;base64,'
|
||||
# This is the root cause of the issue
|
||||
|
||||
|
||||
def test_anthropic_direct_api_call():
|
||||
"""Test that directly calls the Anthropic API to reproduce the error.
|
||||
|
||||
This test is marked as xfail because it's expected to fail, demonstrating the issue.
|
||||
"""
|
||||
import os
|
||||
|
||||
import litellm
|
||||
|
||||
# Skip this test if no Anthropic API key is available
|
||||
api_key = os.environ.get('ANTHROPIC_API_KEY')
|
||||
if not api_key:
|
||||
pytest.skip('No Anthropic API key available')
|
||||
|
||||
# Create a test image and convert it to base64
|
||||
test_image = create_test_image()
|
||||
screenshot = image_to_png_base64_url(test_image, add_data_prefix=True)
|
||||
|
||||
# Create a message with the screenshot
|
||||
formatted_messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
'content': [
|
||||
{'type': 'text', 'text': "What's in this image?"},
|
||||
{'type': 'image_url', 'image_url': {'url': screenshot}},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
# This test is expected to fail with a BadRequestError
|
||||
# Mark it as xfail to indicate this is the expected behavior
|
||||
pytest.xfail(
|
||||
'This test is expected to fail with a BadRequestError about image URL format'
|
||||
)
|
||||
|
||||
# Try to call the Anthropic API directly
|
||||
litellm.completion(
|
||||
model='anthropic/claude-3-opus-20240229',
|
||||
messages=formatted_messages,
|
||||
api_key=api_key,
|
||||
)
|
||||
156
tests/unit/test_anthropic_browser_simulation.py
Normal file
156
tests/unit/test_anthropic_browser_simulation.py
Normal file
@@ -0,0 +1,156 @@
|
||||
import os
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import litellm
|
||||
import numpy as np
|
||||
import pytest
|
||||
from PIL import Image
|
||||
|
||||
from openhands.events.observation.browse import BrowserOutputObservation
|
||||
from openhands.runtime.browser.base64 import image_to_png_base64_url
|
||||
|
||||
|
||||
def create_test_image():
|
||||
"""Create a simple test image."""
|
||||
# Create a simple 10x10 RGB image
|
||||
img_array = np.zeros((10, 10, 3), dtype=np.uint8)
|
||||
img_array[:, :, 0] = 255 # Red channel
|
||||
return Image.fromarray(img_array)
|
||||
|
||||
|
||||
def test_browser_env_screenshot_format():
|
||||
"""Test the format of screenshots generated by the browser environment."""
|
||||
# Create a test image
|
||||
test_image = create_test_image()
|
||||
|
||||
# Convert to PNG base64 URL (this is what happens in the browser environment)
|
||||
screenshot = image_to_png_base64_url(test_image, add_data_prefix=True)
|
||||
|
||||
# Verify the format
|
||||
assert screenshot.startswith('data:image/png;base64,'), (
|
||||
f"Expected 'data:image/png;base64,' but got {screenshot[:30]}..."
|
||||
)
|
||||
|
||||
# Create a BrowserOutputObservation with the screenshot
|
||||
observation = BrowserOutputObservation(
|
||||
content='Test content',
|
||||
url='https://example.com',
|
||||
screenshot=screenshot,
|
||||
trigger_by_action='browse_interactive',
|
||||
)
|
||||
|
||||
# Verify the screenshot in the observation
|
||||
assert observation.screenshot == screenshot, (
|
||||
"Screenshot in observation doesn't match original screenshot"
|
||||
)
|
||||
|
||||
# This assertion would fail if we expected JPEG format
|
||||
assert not observation.screenshot.startswith('data:image/jpeg;base64,'), (
|
||||
'Screenshot should not be in JPEG format'
|
||||
)
|
||||
|
||||
|
||||
def test_anthropic_with_browser_observation():
|
||||
"""Test sending a browser observation to Anthropic API."""
|
||||
import litellm
|
||||
|
||||
# Skip this test if no Anthropic API key is available
|
||||
api_key = os.environ.get('ANTHROPIC_API_KEY')
|
||||
if not api_key:
|
||||
pytest.skip('No Anthropic API key available')
|
||||
|
||||
# Create a test image
|
||||
test_image = create_test_image()
|
||||
screenshot = image_to_png_base64_url(test_image, add_data_prefix=True)
|
||||
|
||||
# Create a BrowserOutputObservation with the screenshot
|
||||
observation = BrowserOutputObservation(
|
||||
content='Test content',
|
||||
url='https://example.com',
|
||||
screenshot=screenshot,
|
||||
trigger_by_action='browse_interactive',
|
||||
)
|
||||
|
||||
# Create a message with the observation
|
||||
formatted_messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
'content': [
|
||||
{'type': 'text', 'text': observation.get_agent_obs_text()},
|
||||
{'type': 'image_url', 'image_url': {'url': observation.screenshot}},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
# Try to call the Anthropic API
|
||||
response = litellm.completion(
|
||||
model='anthropic/claude-3-opus-20240229',
|
||||
messages=formatted_messages,
|
||||
api_key=api_key,
|
||||
max_tokens=100, # Limit response size for faster test
|
||||
)
|
||||
|
||||
# Verify we got a response
|
||||
assert response is not None
|
||||
assert response.choices[0].message.content is not None
|
||||
|
||||
# Print the response for debugging
|
||||
print(f'Response from Anthropic: {response.choices[0].message.content}')
|
||||
|
||||
|
||||
@patch('litellm.completion')
|
||||
def test_browser_env_with_anthropic(mock_completion):
|
||||
"""Test the browser environment with Anthropic."""
|
||||
# Configure the mock to simulate the real behavior
|
||||
mock_response = MagicMock()
|
||||
mock_response.choices = [MagicMock()]
|
||||
mock_response.choices[0].message = MagicMock()
|
||||
mock_response.choices[0].message.content = 'This is a test response'
|
||||
mock_completion.return_value = mock_response
|
||||
|
||||
# Create a test image
|
||||
test_image = create_test_image()
|
||||
|
||||
# Directly convert the image to PNG base64 URL (simulating what happens in browser_env.py)
|
||||
screenshot = image_to_png_base64_url(test_image, add_data_prefix=True)
|
||||
|
||||
# Verify the screenshot format
|
||||
assert screenshot.startswith('data:image/png;base64,'), (
|
||||
f"Expected 'data:image/png;base64,' but got {screenshot[:30]}..."
|
||||
)
|
||||
|
||||
# Create a BrowserOutputObservation with the screenshot
|
||||
observation = BrowserOutputObservation(
|
||||
content='Test content',
|
||||
url='https://example.com',
|
||||
screenshot=screenshot,
|
||||
trigger_by_action='browse_interactive',
|
||||
)
|
||||
|
||||
# Create a message with the observation
|
||||
formatted_messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
'content': [
|
||||
{'type': 'text', 'text': observation.get_agent_obs_text()},
|
||||
{'type': 'image_url', 'image_url': {'url': observation.screenshot}},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
# Try to call the Anthropic API through litellm
|
||||
response = litellm.completion(
|
||||
model='anthropic/claude-3-opus-20240229',
|
||||
messages=formatted_messages,
|
||||
api_key='fake_api_key', # Using mock, so API key doesn't matter
|
||||
)
|
||||
|
||||
# Verify the mock was called with the correct arguments
|
||||
mock_completion.assert_called_once()
|
||||
call_args = mock_completion.call_args[1]
|
||||
assert call_args['model'] == 'anthropic/claude-3-opus-20240229'
|
||||
assert call_args['messages'] == formatted_messages
|
||||
|
||||
# Verify we got a response
|
||||
assert response is not None
|
||||
assert response.choices[0].message.content == 'This is a test response'
|
||||
69
tests/unit/test_anthropic_direct_api_call.py
Normal file
69
tests/unit/test_anthropic_direct_api_call.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
from litellm.exceptions import BadRequestError
|
||||
from PIL import Image
|
||||
|
||||
from openhands.runtime.browser.base64 import image_to_png_base64_url
|
||||
|
||||
|
||||
def create_test_image():
|
||||
"""Create a simple test image."""
|
||||
# Create a simple 10x10 RGB image
|
||||
img_array = np.zeros((10, 10, 3), dtype=np.uint8)
|
||||
img_array[:, :, 0] = 255 # Red channel
|
||||
return Image.fromarray(img_array)
|
||||
|
||||
|
||||
def test_anthropic_direct_api_call():
|
||||
"""Test that directly calls the Anthropic API to reproduce the error.
|
||||
|
||||
This test is designed to fail to demonstrate the issue.
|
||||
"""
|
||||
import litellm
|
||||
|
||||
# Skip this test if no Anthropic API key is available
|
||||
api_key = os.environ.get('ANTHROPIC_API_KEY')
|
||||
if not api_key:
|
||||
pytest.skip('No Anthropic API key available')
|
||||
|
||||
# Create a test image and convert it to base64
|
||||
test_image = create_test_image()
|
||||
screenshot = image_to_png_base64_url(test_image, add_data_prefix=True)
|
||||
|
||||
# Verify the image URL format
|
||||
assert screenshot.startswith('data:image/png;base64,'), (
|
||||
f"Expected 'data:image/png;base64,' but got {screenshot[:30]}..."
|
||||
)
|
||||
|
||||
# Create a message with the screenshot
|
||||
formatted_messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
'content': [
|
||||
{'type': 'text', 'text': "What's in this image?"},
|
||||
{'type': 'image_url', 'image_url': {'url': screenshot}},
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
# Try to call the Anthropic API directly
|
||||
try:
|
||||
litellm.completion(
|
||||
model='anthropic/claude-3-opus-20240229',
|
||||
messages=formatted_messages,
|
||||
api_key=api_key,
|
||||
)
|
||||
# If we get here, the test should fail because no error was raised
|
||||
raise AssertionError('Expected BadRequestError was not raised')
|
||||
except BadRequestError as e:
|
||||
# Verify the error message
|
||||
assert 'Image url not in expected format' in str(e), (
|
||||
f'Unexpected error message: {str(e)}'
|
||||
)
|
||||
|
||||
# This assertion will fail to demonstrate the issue
|
||||
assert screenshot.startswith('data:image/jpeg;base64,'), (
|
||||
f"Image URL format is incorrect. Expected 'data:image/jpeg;base64,' but got {screenshot[:30]}..."
|
||||
)
|
||||
108
tests/unit/test_anthropic_image_format.py
Normal file
108
tests/unit/test_anthropic_image_format.py
Normal file
@@ -0,0 +1,108 @@
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
from PIL import Image
|
||||
|
||||
from openhands.core.message import ImageContent, Message, TextContent
|
||||
from openhands.runtime.browser.base64 import image_to_png_base64_url
|
||||
|
||||
|
||||
def create_test_image():
|
||||
"""Create a simple test image."""
|
||||
# Create a simple 10x10 RGB image
|
||||
img_array = np.zeros((10, 10, 3), dtype=np.uint8)
|
||||
img_array[:, :, 0] = 255 # Red channel
|
||||
return Image.fromarray(img_array)
|
||||
|
||||
|
||||
def test_anthropic_image_format_issue(caplog):
|
||||
"""Test that demonstrates the issue with image format for Anthropic."""
|
||||
# Skip if no API key
|
||||
anthropic_api_key = os.environ.get('ANTHROPIC_API_KEY')
|
||||
if not anthropic_api_key:
|
||||
pytest.skip('ANTHROPIC_API_KEY not set')
|
||||
|
||||
# Create a test image
|
||||
test_image = create_test_image()
|
||||
|
||||
# Convert to PNG base64 URL (this is what happens in the browser environment)
|
||||
screenshot = image_to_png_base64_url(test_image, add_data_prefix=True)
|
||||
|
||||
# Verify the format
|
||||
assert screenshot.startswith('data:image/png;base64,'), (
|
||||
f"Expected 'data:image/png;base64,' but got {screenshot[:30]}..."
|
||||
)
|
||||
|
||||
# Create a message with the screenshot
|
||||
message = Message(
|
||||
role='user',
|
||||
content=[
|
||||
TextContent(text="What's in this image?"),
|
||||
ImageContent(image_urls=[screenshot]),
|
||||
],
|
||||
vision_enabled=True,
|
||||
)
|
||||
|
||||
# Serialize the message for litellm
|
||||
serialized_message = message.serialize_model()
|
||||
|
||||
# Verify the serialized message
|
||||
assert serialized_message['role'] == 'user'
|
||||
assert isinstance(serialized_message['content'], list)
|
||||
assert len(serialized_message['content']) == 2
|
||||
assert serialized_message['content'][0]['type'] == 'text'
|
||||
assert serialized_message['content'][1]['type'] == 'image_url'
|
||||
assert 'url' in serialized_message['content'][1]['image_url']
|
||||
assert serialized_message['content'][1]['image_url']['url'] == screenshot
|
||||
|
||||
# Try to call the Anthropic API through litellm
|
||||
# This actually succeeds with PNG format, which is surprising
|
||||
import litellm
|
||||
|
||||
try:
|
||||
print('\n\nTesting with PNG format:')
|
||||
response = litellm.completion(
|
||||
model='anthropic/claude-3-opus-20240229',
|
||||
messages=[serialized_message],
|
||||
api_key=anthropic_api_key,
|
||||
)
|
||||
print(f'Response: {response}')
|
||||
print('PNG format works with Anthropic API directly!')
|
||||
|
||||
# Let's also try with a JPEG format to compare
|
||||
import base64
|
||||
import io
|
||||
|
||||
# Convert the test image to JPEG
|
||||
buffered = io.BytesIO()
|
||||
test_image.save(buffered, format='JPEG')
|
||||
jpeg_base64 = base64.b64encode(buffered.getvalue()).decode()
|
||||
jpeg_url = f'data:image/jpeg;base64,{jpeg_base64}'
|
||||
|
||||
# Create a message with the JPEG screenshot
|
||||
jpeg_message = Message(
|
||||
role='user',
|
||||
content=[
|
||||
TextContent(text="What's in this JPEG image?"),
|
||||
ImageContent(image_urls=[jpeg_url]),
|
||||
],
|
||||
vision_enabled=True,
|
||||
)
|
||||
|
||||
# Serialize the message for litellm
|
||||
jpeg_serialized_message = jpeg_message.serialize_model()
|
||||
|
||||
# Try with JPEG format
|
||||
print('\n\nTesting with JPEG format:')
|
||||
jpeg_response = litellm.completion(
|
||||
model='anthropic/claude-3-opus-20240229',
|
||||
messages=[jpeg_serialized_message],
|
||||
api_key=anthropic_api_key,
|
||||
)
|
||||
print(f'JPEG Response: {jpeg_response}')
|
||||
print('JPEG format also works with Anthropic API directly!')
|
||||
|
||||
except Exception as e:
|
||||
print(f'Error: {str(e)}')
|
||||
raise
|
||||
Reference in New Issue
Block a user