Skip to content
Open
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
3 changes: 3 additions & 0 deletions sentry_sdk/ai/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import sentry_sdk
from sentry_sdk.utils import logger
from sentry_sdk.consts import SPANDATA

MAX_GEN_AI_MESSAGE_BYTES = 20_000 # 20KB
# Maximum characters when only a single message is left after bytes truncation
Expand Down Expand Up @@ -698,6 +699,8 @@ def truncate_and_annotate_messages(
if len(messages) > 1:
scope._gen_ai_original_message_count[span.span_id] = len(messages)

span.set_data(SPANDATA.META_GEN_AI_ORIGINAL_INPUT_MESSAGES_LENGTH, len(messages))

return [truncated_message]


Expand Down
8 changes: 8 additions & 0 deletions sentry_sdk/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,14 @@ class SPANDATA:
Example: "a1b2c3d4e5f6"
"""

META_GEN_AI_ORIGINAL_INPUT_MESSAGES_LENGTH = (
"sentry.sdk_meta.gen_ai.input.messages.original_length"
)
"""
The original number of input non-system instruction messages, before SDK trimming.
Example: 4
"""


class SPANSTATUS:
"""
Expand Down
2 changes: 2 additions & 0 deletions tests/integrations/anthropic/test_anthropic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,7 @@ def test_anthropic_message_truncation(sentry_init, capture_events):
assert len(parsed_messages) == 1
assert "small message 5" in str(parsed_messages[0])

assert chat_span["data"][SPANDATA.META_GEN_AI_ORIGINAL_INPUT_MESSAGES_LENGTH] == 5
assert tx["_meta"]["spans"]["0"]["data"]["gen_ai.request.messages"][""]["len"] == 5


Expand Down Expand Up @@ -1061,6 +1062,7 @@ async def test_anthropic_message_truncation_async(sentry_init, capture_events):
assert len(parsed_messages) == 1
assert "small message 5" in str(parsed_messages[0])

assert chat_span["data"][SPANDATA.META_GEN_AI_ORIGINAL_INPUT_MESSAGES_LENGTH] == 5
assert tx["_meta"]["spans"]["0"]["data"]["gen_ai.request.messages"][""]["len"] == 5


Expand Down
1 change: 1 addition & 0 deletions tests/integrations/google_genai/test_google_genai.py
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,7 @@ def test_google_genai_message_truncation(
assert parsed_messages[0]["role"] == "user"
assert small_content in parsed_messages[0]["content"]

assert invoke_span["data"][SPANDATA.META_GEN_AI_ORIGINAL_INPUT_MESSAGES_LENGTH] == 2
assert (
event["_meta"]["spans"]["0"]["data"]["gen_ai.request.messages"][""]["len"] == 2
)
Expand Down
2 changes: 2 additions & 0 deletions tests/integrations/langchain/test_langchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,8 @@ def test_langchain_message_truncation(sentry_init, capture_events):
assert isinstance(parsed_messages, list)
assert len(parsed_messages) == 1
assert "small message 5" in str(parsed_messages[0])

assert llm_span["data"][SPANDATA.META_GEN_AI_ORIGINAL_INPUT_MESSAGES_LENGTH] == 5
assert tx["_meta"]["spans"]["0"]["data"]["gen_ai.request.messages"][""]["len"] == 5


Expand Down
2 changes: 2 additions & 0 deletions tests/integrations/langgraph/test_langgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -1384,4 +1384,6 @@ def original_invoke(self, *args, **kwargs):
assert isinstance(parsed_messages, list)
assert len(parsed_messages) == 1
assert "small message 5" in str(parsed_messages[0])

assert invoke_span["data"][SPANDATA.META_GEN_AI_ORIGINAL_INPUT_MESSAGES_LENGTH] == 5
assert tx["_meta"]["spans"]["0"]["data"]["gen_ai.request.messages"][""]["len"] == 5
2 changes: 2 additions & 0 deletions tests/integrations/litellm/test_litellm.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,8 @@ def test_litellm_message_truncation(sentry_init, capture_events):
assert isinstance(parsed_messages, list)
assert len(parsed_messages) == 1
assert "small message 5" in str(parsed_messages[0])

assert chat_span["data"][SPANDATA.META_GEN_AI_ORIGINAL_INPUT_MESSAGES_LENGTH] == 5
assert tx["_meta"]["spans"]["0"]["data"]["gen_ai.request.messages"][""]["len"] == 5


Expand Down
3 changes: 3 additions & 0 deletions tests/integrations/openai/test_openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,7 @@ def test_ai_client_span_responses_api(
"gen_ai.usage.total_tokens": 30,
"gen_ai.request.model": "gpt-4o",
"gen_ai.response.text": "the model response",
"sentry.sdk_meta.gen_ai.input.messages.original_length": 1,
"thread.id": mock.ANY,
"thread.name": mock.ANY,
}
Expand Down Expand Up @@ -1910,6 +1911,7 @@ async def test_ai_client_span_responses_async_api(
"gen_ai.usage.output_tokens.reasoning": 8,
"gen_ai.usage.total_tokens": 30,
"gen_ai.response.text": "the model response",
"sentry.sdk_meta.gen_ai.input.messages.original_length": 1,
"thread.id": mock.ANY,
"thread.name": mock.ANY,
}
Expand Down Expand Up @@ -2177,6 +2179,7 @@ async def test_ai_client_span_streaming_responses_async_api(
"gen_ai.usage.total_tokens": 30,
"gen_ai.request.model": "gpt-4o",
"gen_ai.response.text": "the model response",
"sentry.sdk_meta.gen_ai.input.messages.original_length": 1,
"thread.id": mock.ANY,
"thread.name": mock.ANY,
}
Expand Down
Loading