Skip to content

Commit 36fcaf9

Browse files
committed
fix(litellm): fix gen_ai.request.messages to be as expected
1 parent 3d3ce5b commit 36fcaf9

File tree

1 file changed

+64
-1
lines changed

1 file changed

+64
-1
lines changed

sentry_sdk/integrations/litellm.py

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from sentry_sdk.utils import event_from_exception
1515

1616
if TYPE_CHECKING:
17-
from typing import Any, Dict
17+
from typing import Any, Dict, List
1818
from datetime import datetime
1919

2020
try:
@@ -35,6 +35,68 @@ def _get_metadata_dict(kwargs: "Dict[str, Any]") -> "Dict[str, Any]":
3535
return metadata
3636

3737

38+
def _convert_message_parts(messages: "List[Dict[str, Any]]") -> "List[Dict[str, Any]]":
39+
"""
40+
Convert the message parts from OpenAI format to the `gen_ai.request.messages` format.
41+
e.g:
42+
{
43+
"role": "user",
44+
"content": [
45+
{
46+
"text": "How many ponies do you see in the image?",
47+
"type": "text"
48+
},
49+
{
50+
"type": "image_url",
51+
"image_url": {
52+
"url": "data:image/jpeg;base64,...",
53+
"detail": "high"
54+
}
55+
}
56+
]
57+
}
58+
becomes:
59+
{
60+
"role": "user",
61+
"content": [
62+
{
63+
"text": "How many ponies do you see in the image?",
64+
"type": "text"
65+
},
66+
{
67+
"type": "blob",
68+
"modality": "image",
69+
"mime_type": "image/jpeg",
70+
"content": "data:image/jpeg;base64,..."
71+
}
72+
]
73+
}
74+
"""
75+
76+
def _map_item(item: "Dict[str, Any]") -> "Dict[str, Any]":
77+
if item.get("type") == "image_url":
78+
image_url = item.get("image_url") or {}
79+
if image_url.get("url", "").startswith("data:"):
80+
return {
81+
"type": "blob",
82+
"modality": "image",
83+
"mime_type": item["image_url"]["url"].split(";base64,")[0],
84+
"content": item["image_url"]["url"].split(";base64,")[1],
85+
}
86+
else:
87+
return {
88+
"type": "uri",
89+
"uri": item["image_url"]["url"],
90+
}
91+
return item
92+
93+
for message in messages:
94+
content = message.get("content")
95+
if isinstance(content, list):
96+
message["content"] = [_map_item(item) for item in content]
97+
return messages
98+
99+
38100
def _input_callback(kwargs: "Dict[str, Any]") -> None:
39101
"""Handle the start of a request."""
40102
integration = sentry_sdk.get_client().get_integration(LiteLLMIntegration)
@@ -101,6 +163,7 @@ def _input_callback(kwargs: "Dict[str, Any]") -> None:
101163
messages = kwargs.get("messages", [])
102164
if messages:
103165
scope = sentry_sdk.get_current_scope()
166+
messages = _convert_message_parts(messages)
104167
messages_data = truncate_and_annotate_messages(messages, span, scope)
105168
if messages_data is not None:
106169
set_data_normalized(

0 commit comments

Comments
 (0)