Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 5 additions & 21 deletions sentry_sdk/integrations/litellm.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
from sentry_sdk.ai.utils import (
get_start_span_function,
set_data_normalized,
truncate_and_annotate_messages,
truncate_and_annotate_embedding_inputs,
)
from sentry_sdk.consts import SPANDATA
from sentry_sdk.integrations import DidNotEnable, Integration
Expand Down Expand Up @@ -83,36 +81,22 @@ def _input_callback(kwargs: "Dict[str, Any]") -> None:
# For embeddings, look for the 'input' parameter
embedding_input = kwargs.get("input")
if embedding_input:
scope = sentry_sdk.get_current_scope()
# Normalize to list format
input_list = (
embedding_input
if isinstance(embedding_input, list)
else [embedding_input]
)
messages_data = truncate_and_annotate_embedding_inputs(
input_list, span, scope
)
if messages_data is not None:
if input_list is not None:
set_data_normalized(
span,
SPANDATA.GEN_AI_EMBEDDINGS_INPUT,
messages_data,
unpack=False,
span, SPANDATA.GEN_AI_EMBEDDINGS_INPUT, input_list, unpack=False
)
else:
# For chat, look for the 'messages' parameter
messages = kwargs.get("messages", [])
if messages:
scope = sentry_sdk.get_current_scope()
messages_data = truncate_and_annotate_messages(messages, span, scope)
if messages_data is not None:
set_data_normalized(
span,
SPANDATA.GEN_AI_REQUEST_MESSAGES,
messages_data,
unpack=False,
)
set_data_normalized(
span, SPANDATA.GEN_AI_REQUEST_MESSAGES, messages, unpack=False
)

# Record other parameters
params = {
Expand Down
56 changes: 0 additions & 56 deletions tests/integrations/litellm/test_litellm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1382,59 +1382,3 @@ def test_integration_setup(sentry_init):
assert _input_callback in (litellm.input_callback or [])
assert _success_callback in (litellm.success_callback or [])
assert _failure_callback in (litellm.failure_callback or [])


def test_litellm_message_truncation(sentry_init, capture_items):
"""Test that large messages are truncated properly in LiteLLM integration."""
sentry_init(
integrations=[LiteLLMIntegration(include_prompts=True)],
traces_sample_rate=1.0,
send_default_pii=True,
)
items = capture_items("transaction", "span")

large_content = (
"This is a very long message that will exceed our size limits. " * 1000
)
messages = [
{"role": "user", "content": "small message 1"},
{"role": "assistant", "content": large_content},
{"role": "user", "content": large_content},
{"role": "assistant", "content": "small message 4"},
{"role": "user", "content": "small message 5"},
]
mock_response = MockCompletionResponse()

with start_transaction(name="litellm test"):
kwargs = {
"model": "gpt-3.5-turbo",
"messages": messages,
}

_input_callback(kwargs)
_success_callback(
kwargs,
mock_response,
datetime.now(),
datetime.now(),
)

spans = [item.payload for item in items if item.type == "span"]
chat_spans = [
span for span in spans if span["attributes"].get("sentry.op") == OP.GEN_AI_CHAT
]
assert len(chat_spans) > 0

chat_span = chat_spans[0]
assert SPANDATA.GEN_AI_REQUEST_MESSAGES in chat_span["attributes"]

messages_data = chat_span["attributes"][SPANDATA.GEN_AI_REQUEST_MESSAGES]
assert isinstance(messages_data, str)

parsed_messages = json.loads(messages_data)
assert isinstance(parsed_messages, list)
assert len(parsed_messages) == 1
assert "small message 5" in str(parsed_messages[0])

tx = next(item.payload for item in items if item.type == "transaction")
assert tx["_meta"]["spans"]["0"]["data"]["gen_ai.request.messages"][""]["len"] == 5
Loading