Skip to content

Commit c625e12

Browse files
revert test_ai_monitoring tests
1 parent 23868e5 commit c625e12

1 file changed

Lines changed: 134 additions & 46 deletions

File tree

tests/test_ai_monitoring.py

Lines changed: 134 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
)
1212
from sentry_sdk.ai.monitoring import ai_track
1313
from sentry_sdk.ai.utils import (
14+
MAX_GEN_AI_MESSAGE_BYTES,
1415
MAX_SINGLE_MESSAGE_CONTENT_CHARS,
1516
set_data_normalized,
1617
truncate_and_annotate_messages,
18+
truncate_messages_by_size,
19+
_find_truncation_index,
1720
parse_data_uri,
1821
redact_blob_message_parts,
1922
get_modality_from_mime_type,
@@ -219,8 +222,105 @@ def large_messages():
219222
]
220223

221224

225+
class TestTruncateMessagesBySize:
226+
def test_no_truncation_needed(self, sample_messages):
227+
"""Test that messages under the limit are not truncated"""
228+
result, truncation_index = truncate_messages_by_size(
229+
sample_messages, max_bytes=MAX_GEN_AI_MESSAGE_BYTES
230+
)
231+
assert len(result) == len(sample_messages)
232+
assert result == sample_messages
233+
assert truncation_index == 0
234+
235+
def test_truncation_removes_oldest_first(self, large_messages):
236+
"""Test that oldest messages are removed first during truncation"""
237+
small_limit = 3000
238+
result, truncation_index = truncate_messages_by_size(
239+
large_messages, max_bytes=small_limit
240+
)
241+
assert len(result) < len(large_messages)
242+
243+
assert result[-1] == large_messages[-1]
244+
assert truncation_index == len(large_messages) - len(result)
245+
246+
def test_empty_messages_list(self):
247+
"""Test handling of empty messages list"""
248+
result, truncation_index = truncate_messages_by_size(
249+
[], max_bytes=MAX_GEN_AI_MESSAGE_BYTES // 500
250+
)
251+
assert result == []
252+
assert truncation_index == 0
253+
254+
def test_find_truncation_index(
255+
self,
256+
):
257+
"""Test that the truncation index is found correctly"""
258+
# when represented in JSON, these are each 7 bytes long
259+
messages = ["A" * 5, "B" * 5, "C" * 5, "D" * 5, "E" * 5]
260+
truncation_index = _find_truncation_index(messages, 20)
261+
assert truncation_index == 3
262+
assert messages[truncation_index:] == ["D" * 5, "E" * 5]
263+
264+
messages = ["A" * 5, "B" * 5, "C" * 5, "D" * 5, "E" * 5]
265+
truncation_index = _find_truncation_index(messages, 40)
266+
assert truncation_index == 0
267+
assert messages[truncation_index:] == [
268+
"A" * 5,
269+
"B" * 5,
270+
"C" * 5,
271+
"D" * 5,
272+
"E" * 5,
273+
]
274+
275+
def test_progressive_truncation(self, large_messages):
276+
"""Test that truncation works progressively with different limits"""
277+
limits = [
278+
MAX_GEN_AI_MESSAGE_BYTES // 5,
279+
MAX_GEN_AI_MESSAGE_BYTES // 10,
280+
MAX_GEN_AI_MESSAGE_BYTES // 25,
281+
MAX_GEN_AI_MESSAGE_BYTES // 100,
282+
MAX_GEN_AI_MESSAGE_BYTES // 500,
283+
]
284+
prev_count = len(large_messages)
285+
286+
for limit in limits:
287+
result = truncate_messages_by_size(large_messages, max_bytes=limit)
288+
current_count = len(result)
289+
290+
assert current_count <= prev_count
291+
assert current_count >= 1
292+
prev_count = current_count
293+
294+
def test_single_message_truncation(self):
295+
large_content = "This is a very long message. " * 10_000
296+
297+
messages = [
298+
{"role": "system", "content": "You are a helpful assistant."},
299+
{"role": "user", "content": large_content},
300+
]
301+
302+
result, truncation_index = truncate_messages_by_size(
303+
messages, max_single_message_chars=MAX_SINGLE_MESSAGE_CONTENT_CHARS
304+
)
305+
306+
assert len(result) == 1
307+
assert (
308+
len(result[0]["content"].rstrip("...")) <= MAX_SINGLE_MESSAGE_CONTENT_CHARS
309+
)
310+
311+
# If the last message is too large, the system message is not present
312+
system_msgs = [m for m in result if m.get("role") == "system"]
313+
assert len(system_msgs) == 0
314+
315+
# Confirm the user message is truncated with '...'
316+
user_msgs = [m for m in result if m.get("role") == "user"]
317+
assert len(user_msgs) == 1
318+
assert user_msgs[0]["content"].endswith("...")
319+
assert len(user_msgs[0]["content"]) < len(large_content)
320+
321+
222322
class TestTruncateAndAnnotateMessages:
223-
def test_truncation_sets_metadata_on_scope(self, large_messages):
323+
def test_no_truncation_returns_list(self, sample_messages):
224324
class MockSpan:
225325
def __init__(self):
226326
self.span_id = "test_span_id"
@@ -233,20 +333,17 @@ class MockScope:
233333
def __init__(self):
234334
self._gen_ai_original_message_count = {}
235335

236-
small_limit = 3000
237336
span = MockSpan()
238337
scope = MockScope()
239-
original_count = len(large_messages)
240-
result = truncate_and_annotate_messages(
241-
large_messages, span, scope, max_single_message_chars=small_limit
242-
)
338+
result = truncate_and_annotate_messages(sample_messages, span, scope)
243339

244340
assert isinstance(result, list)
245341
assert not isinstance(result, AnnotatedValue)
246-
assert len(result) < len(large_messages)
247-
assert scope._gen_ai_original_message_count[span.span_id] == original_count
342+
assert len(result) == len(sample_messages)
343+
assert result == sample_messages
344+
assert span.span_id not in scope._gen_ai_original_message_count
248345

249-
def test_scope_tracks_original_message_count(self, large_messages):
346+
def test_truncation_sets_metadata_on_scope(self, large_messages):
250347
class MockSpan:
251348
def __init__(self):
252349
self.span_id = "test_span_id"
@@ -260,18 +357,19 @@ def __init__(self):
260357
self._gen_ai_original_message_count = {}
261358

262359
small_limit = 3000
263-
original_count = len(large_messages)
264360
span = MockSpan()
265361
scope = MockScope()
266-
362+
original_count = len(large_messages)
267363
result = truncate_and_annotate_messages(
268-
large_messages, span, scope, max_single_message_chars=small_limit
364+
large_messages, span, scope, max_bytes=small_limit
269365
)
270366

367+
assert isinstance(result, list)
368+
assert not isinstance(result, AnnotatedValue)
369+
assert len(result) < len(large_messages)
271370
assert scope._gen_ai_original_message_count[span.span_id] == original_count
272-
assert len(result) == 1
273371

274-
def test_empty_messages_returns_none(self):
372+
def test_scope_tracks_original_message_count(self, large_messages):
275373
class MockSpan:
276374
def __init__(self):
277375
self.span_id = "test_span_id"
@@ -284,15 +382,19 @@ class MockScope:
284382
def __init__(self):
285383
self._gen_ai_original_message_count = {}
286384

385+
small_limit = 3000
386+
original_count = len(large_messages)
287387
span = MockSpan()
288388
scope = MockScope()
289-
result = truncate_and_annotate_messages([], span, scope)
290-
assert result is None
291389

292-
result = truncate_and_annotate_messages(None, span, scope)
293-
assert result is None
390+
result = truncate_and_annotate_messages(
391+
large_messages, span, scope, max_bytes=small_limit
392+
)
393+
394+
assert scope._gen_ai_original_message_count[span.span_id] == original_count
395+
assert len(result) == 1
294396

295-
def test_single_message_truncation(self, large_messages):
397+
def test_empty_messages_returns_none(self):
296398
class MockSpan:
297399
def __init__(self):
298400
self.span_id = "test_span_id"
@@ -305,33 +407,13 @@ class MockScope:
305407
def __init__(self):
306408
self._gen_ai_original_message_count = {}
307409

308-
large_content = "This is a very long message. " * 10_000
309-
310-
messages = [
311-
{"role": "system", "content": "You are a helpful assistant."},
312-
{"role": "user", "content": large_content},
313-
]
314-
315410
span = MockSpan()
316411
scope = MockScope()
317-
result = truncate_and_annotate_messages(
318-
messages,
319-
span,
320-
scope,
321-
max_single_message_chars=MAX_SINGLE_MESSAGE_CONTENT_CHARS,
322-
)
323-
assert result is not None
324-
325-
assert len(result) == 1
326-
assert (
327-
len(result[0]["content"].rstrip("...")) <= MAX_SINGLE_MESSAGE_CONTENT_CHARS
328-
)
412+
result = truncate_and_annotate_messages([], span, scope)
413+
assert result is None
329414

330-
# Confirm the user message is truncated with '...'
331-
user_msgs = [m for m in result if m.get("role") == "user"]
332-
assert len(user_msgs) == 1
333-
assert user_msgs[0]["content"].endswith("...")
334-
assert len(user_msgs[0]["content"]) < len(large_content)
415+
result = truncate_and_annotate_messages(None, span, scope)
416+
assert result is None
335417

336418
def test_truncated_messages_newest_first(self, large_messages):
337419
class MockSpan:
@@ -350,7 +432,7 @@ def __init__(self):
350432
span = MockSpan()
351433
scope = MockScope()
352434
result = truncate_and_annotate_messages(
353-
large_messages, span, scope, max_single_message_chars=small_limit
435+
large_messages, span, scope, max_bytes=small_limit
354436
)
355437

356438
assert isinstance(result, list)
@@ -418,12 +500,15 @@ class MockScope:
418500
def __init__(self):
419501
self._gen_ai_original_message_count = {}
420502

503+
small_limit = 3000
421504
span = MockSpan()
422505
scope = MockScope()
423506
original_count = len(large_messages)
424507

425508
# Simulate what integrations do
426-
truncated_messages = truncate_and_annotate_messages(large_messages, span, scope)
509+
truncated_messages = truncate_and_annotate_messages(
510+
large_messages, span, scope, max_bytes=small_limit
511+
)
427512
span.set_data(SPANDATA.GEN_AI_REQUEST_MESSAGES, truncated_messages)
428513

429514
# Verify metadata was set on scope
@@ -472,11 +557,14 @@ class MockScope:
472557
def __init__(self):
473558
self._gen_ai_original_message_count = {}
474559

560+
small_limit = 3000
475561
span = MockSpan()
476562
scope = MockScope()
477563
original_message_count = len(large_messages)
478564

479-
truncated_messages = truncate_and_annotate_messages(large_messages, span, scope)
565+
truncated_messages = truncate_and_annotate_messages(
566+
large_messages, span, scope, max_bytes=small_limit
567+
)
480568

481569
assert len(truncated_messages) < original_message_count
482570

0 commit comments

Comments
 (0)