Avoid full-string scans in token-budget truncation (#49712)

## Why

Token-budget truncation uses byte counts to estimate tokens, but previously scanned the entire string to count characters, including the discarded middle.

## What changed

Use UTF-8 boundary lookups to select the retained prefix and suffix for token-budget truncation. Skip character counting for a zero-token budget and defer it to paths that need character counts.

## Testing

Add regression coverage for multibyte characters crossing both retained boundaries, checking the truncated output and original token estimate.

GitOrigin-RevId: 37fee0c8d4ede8e74b491d3d641b0ea0e9003dd4
This commit is contained in:
jif
2026-09-30 19:14:56 +00:00
committed by copyberry
parent 596ae94fb0
commit 5e96aabd68
2 changed files with 23 additions and 3 deletions
@@ -109,6 +109,20 @@ fn truncate_middle_tokens_handles_utf8_content() {
assert_eq!(tokens, Some(16));
}
#[test]
fn truncate_middle_tokens_keeps_partial_characters_out_of_both_ends() {
for (input, expected) in [
("a😀b😀c", "a…2 tokens truncated…c"),
("é中😀é", "é…2 tokens truncated…é"),
("😀😀😀", "…2 tokens truncated…"),
] {
assert_eq!(
truncate_middle_with_token_budget(input, /*max_tokens*/ 1),
(expected.to_string(), Some(3)),
);
}
}
#[test]
fn truncate_middle_bytes_handles_utf8_content() {
let s = "😀😀😀😀😀😀😀😀😀😀\nsecond line with text\n";