Skip to content

Commit ee3629c

Browse files
authored
fix(ai): truncate messages for google genai (#4992)
1 parent 2944936 commit ee3629c

File tree

2 files changed

+64
-6
lines changed

2 files changed

+64
-6
lines changed

sentry_sdk/integrations/google_genai/utils.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
)
1616

1717
import sentry_sdk
18-
from sentry_sdk.ai.utils import set_data_normalized
18+
from sentry_sdk.ai.utils import (
19+
set_data_normalized,
20+
truncate_and_annotate_messages,
21+
normalize_message_roles,
22+
)
1923
from sentry_sdk.consts import OP, SPANDATA
2024
from sentry_sdk.scope import should_send_default_pii
2125
from sentry_sdk.utils import (
@@ -462,12 +466,18 @@ def set_span_data_for_request(span, integration, model, contents, kwargs):
462466
messages.append({"role": "user", "content": contents_text})
463467

464468
if messages:
465-
set_data_normalized(
466-
span,
467-
SPANDATA.GEN_AI_REQUEST_MESSAGES,
468-
messages,
469-
unpack=False,
469+
normalized_messages = normalize_message_roles(messages)
470+
scope = sentry_sdk.get_current_scope()
471+
messages_data = truncate_and_annotate_messages(
472+
normalized_messages, span, scope
470473
)
474+
if messages_data is not None:
475+
set_data_normalized(
476+
span,
477+
SPANDATA.GEN_AI_REQUEST_MESSAGES,
478+
messages_data,
479+
unpack=False,
480+
)
471481

472482
# Extract parameters directly from config (not nested under generation_config)
473483
for param, span_key in [

tests/integrations/google_genai/test_google_genai.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,3 +905,51 @@ def test_tool_calls_extraction(sentry_init, capture_events, mock_genai_client):
905905
assert tool_calls[1]["type"] == "function_call"
906906
# Arguments are serialized as JSON strings
907907
assert json.loads(tool_calls[1]["arguments"]) == {"timezone": "PST"}
908+
909+
910+
def test_google_genai_message_truncation(
911+
sentry_init, capture_events, mock_genai_client
912+
):
913+
"""Test that large messages are truncated properly in Google GenAI integration."""
914+
sentry_init(
915+
integrations=[GoogleGenAIIntegration(include_prompts=True)],
916+
traces_sample_rate=1.0,
917+
send_default_pii=True,
918+
)
919+
events = capture_events()
920+
921+
large_content = (
922+
"This is a very long message that will exceed our size limits. " * 1000
923+
)
924+
small_content = "This is a small user message"
925+
926+
mock_http_response = create_mock_http_response(EXAMPLE_API_RESPONSE_JSON)
927+
928+
with mock.patch.object(
929+
mock_genai_client._api_client, "request", return_value=mock_http_response
930+
):
931+
with start_transaction(name="google_genai"):
932+
mock_genai_client.models.generate_content(
933+
model="gemini-1.5-flash",
934+
contents=small_content,
935+
config=create_test_config(
936+
system_instruction=large_content,
937+
),
938+
)
939+
940+
(event,) = events
941+
invoke_span = event["spans"][0]
942+
assert SPANDATA.GEN_AI_REQUEST_MESSAGES in invoke_span["data"]
943+
944+
messages_data = invoke_span["data"][SPANDATA.GEN_AI_REQUEST_MESSAGES]
945+
assert isinstance(messages_data, str)
946+
947+
parsed_messages = json.loads(messages_data)
948+
assert isinstance(parsed_messages, list)
949+
assert len(parsed_messages) == 1
950+
assert parsed_messages[0]["role"] == "user"
951+
assert small_content in parsed_messages[0]["content"]
952+
953+
assert (
954+
event["_meta"]["spans"]["0"]["data"]["gen_ai.request.messages"][""]["len"] == 2
955+
)

0 commit comments

Comments
 (0)