diff --git a/examples/logging/anthropic_messages_image.py b/examples/logging/anthropic_messages_image.py new file mode 100644 index 00000000..e5e599cb --- /dev/null +++ b/examples/logging/anthropic_messages_image.py @@ -0,0 +1,37 @@ +import base64 + +import anthropic +import httpx + +from log10.load import log10 + + +log10(anthropic) + +client = anthropic.Anthropic() + +image1_url = "https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg" +image1_media_type = "image/jpeg" +image1_data = base64.b64encode(httpx.get(image1_url).content).decode("utf-8") + +message = client.messages.create( + model="claude-3-haiku-20240307", + max_tokens=1024, + messages=[ + { + "role": "user", + "content": [ + { + "type": "image", + "source": { + "type": "base64", + "media_type": image1_media_type, + "data": image1_data, + }, + }, + {"type": "text", "text": "Describe this image."}, + ], + } + ], +) +print(message) diff --git a/examples/logging/openai_chat_image.py b/examples/logging/openai_chat_image.py new file mode 100644 index 00000000..ec859b86 --- /dev/null +++ b/examples/logging/openai_chat_image.py @@ -0,0 +1,38 @@ +import base64 + +import httpx +import openai + +from log10.load import log10 + + +log10(openai) + +client = openai.OpenAI() + + +image1_url = "https://upload.wikimedia.org/wikipedia/commons/a/a7/Camponotus_flavomarginatus_ant.jpg" +image1_media_type = "image/jpeg" +image1_data = base64.b64encode(httpx.get(image1_url).content).decode("utf-8") + + +response = client.chat.completions.create( + model="gpt-4-vision-preview", + messages=[ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "What are in these image?", + }, + { + "type": "image_url", + "image_url": {"url": f"data:{image1_media_type};base64,{image1_data}"}, + }, + ], + } + ], + max_tokens=300, +) +print(response.choices[0]) diff --git a/log10/load.py b/log10/load.py index 2156b6c9..6c10c15d 100644 --- a/log10/load.py +++ b/log10/load.py @@ -198,6 +198,7 @@ def log_url(res, completionID): async def log_async(completion_url, func, **kwargs): global last_completion_response + kwargs = kwargs.copy() res = None try: res = post_request(completion_url) @@ -217,6 +218,19 @@ async def log_async(completion_url, func, **kwargs): if "anthropic" in func.__module__: if "system" in kwargs: kwargs["messages"].insert(0, {"role": "system", "content": kwargs["system"]}) + if "messages" in kwargs: + for m in kwargs["messages"]: + new_content = [] + for c in m.get("content", []): + if c.get("type") == "image": + image_type = c.get("source", {}).get("media_type", "") + image_data = c.get("source", {}).get("data", "") + new_content.append( + {"type": "image_url", "image_url": f"data:{image_type};base64,{image_data}"} + ) + else: + new_content.append(c) + m["content"] = new_content log_row = { # do we want to also store args?