fix(spend_logs): stop the tightest truncation limit storing the whole prompt

`_sanitize_request_body_for_spend_logs_payload` keeps 35% of a long string from
the front and 65% from the end, writing the tail as `value[-end_chars:]`. That
slice is the entire string when `end_chars` is 0, and both shares floor to 0
once `MAX_STRING_LENGTH_PROMPT_IN_DB` is 1 or less, so the tightest limits an
operator can set are the ones that store the most: a 5000 character prompt came
out at 5246 characters, the full text behind a marker announcing that 5000
characters had been skipped, and went to the database the limit exists to keep
it out of. A negative limit stored all but the first character.

Index the tail from the front so a zero-length tail is empty. Nothing else
moves: for every limit from 2 to 399 the output is byte identical to before.
This commit is contained in:
Vineeth Sai 2026-08-28 17:35:48 -07:00
parent cbdaa3b153
commit 87cfeb4666
2 changed files with 23 additions and 2 deletions

View file

@ -769,12 +769,17 @@ def _sanitize_request_body_for_spend_logs_payload(
# Calculate how many characters are being skipped
skipped_chars: Final = len(value) - total_keep
# Build the truncated string: beginning + truncation marker + end
# Build the truncated string: beginning + truncation marker + end.
# The tail is indexed from the front rather than written as
# `value[-end_chars:]`, which is the whole string when end_chars is 0.
# Both shares floor to 0 at MAX_STRING_LENGTH_PROMPT_IN_DB of 1 or less,
# so the tightest limits stored the entire prompt plus the marker saying
# it had been skipped, larger than the value the limit exists to bound.
truncated_value: Final = (
f"{value[:start_chars]}"
f"... ({LITELLM_TRUNCATED_PAYLOAD_FIELD} skipped {skipped_chars} chars. "
f"{LITELLM_TRUNCATION_DB_SAFEGUARD_NOTE}) ..."
f"{value[-end_chars:]}"
f"{value[len(value) - end_chars :]}"
)
return truncated_value
return value

View file

@ -300,6 +300,22 @@ def test_sanitize_request_body_for_spend_logs_payload_long_string():
assert sanitized["normal_text"] == "short text"
@pytest.mark.parametrize("limit", [0, 1, -1])
def test_sanitize_request_body_never_stores_more_than_it_was_given(monkeypatch, limit):
"""The truncation is a database-size safeguard, so the tightest limits must be
the ones that store least. Both shares floor to zero at a limit of 1 or less,
and `value[-0:]` is the whole string, so the entire prompt was written out
behind a marker saying it had been skipped."""
monkeypatch.setenv("MAX_STRING_LENGTH_PROMPT_IN_DB", str(limit))
long_string: Final = "a" * 5000
sanitized = _sanitize_request_body_for_spend_logs_payload({"text": long_string})
assert long_string not in sanitized["text"]
assert len(sanitized["text"]) < len(long_string)
assert LITELLM_TRUNCATED_PAYLOAD_FIELD in sanitized["text"]
def test_sanitize_request_body_for_spend_logs_payload_nested_dict():
from litellm.constants import MAX_STRING_LENGTH_PROMPT_IN_DB