fix(compressor): apply bare-string guard to protect-tail boundary scan

The bare-string isinstance guard added in 80ae2621 covered _find_tail_cut_by_tokens
(line 1084) but missed the identical pattern in _calculate_protect_tail_boundary
(line 487, the protect-tail scan loop).  Both loops call .get("text", "") on every
list item in message["content"]; both crash with AttributeError when that list
contains a bare string.

Apply the same dict/str/fallback isinstance guard to the protect-tail path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
briandevans
2026-04-26 11:21:25 -07:00
committed by Teknium
parent 943465235e
commit bda2dbc29e

View File

@@ -484,7 +484,18 @@ class ContextCompressor(ContextEngine):
for i in range(len(result) - 1, -1, -1): for i in range(len(result) - 1, -1, -1):
msg = result[i] msg = result[i]
raw_content = msg.get("content") or "" raw_content = msg.get("content") or ""
content_len = sum(len(p.get("text", "")) for p in raw_content) if isinstance(raw_content, list) else len(raw_content) content_len = (
sum(
len(p.get("text", ""))
if isinstance(p, dict)
else len(p)
if isinstance(p, str)
else len(str(p))
for p in raw_content
)
if isinstance(raw_content, list)
else len(raw_content)
)
msg_tokens = content_len // _CHARS_PER_TOKEN + 10 msg_tokens = content_len // _CHARS_PER_TOKEN + 10
for tc in msg.get("tool_calls") or []: for tc in msg.get("tool_calls") or []:
if isinstance(tc, dict): if isinstance(tc, dict):