mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-16 17:55:26 -04:00
Stop conversations crashing during compaction on tool-call turns (#1777)
context_compactor.maybe_compact built its summary text with
msg.get('content', '')[:2000], which raised
TypeError: 'NoneType' object is not subscriptable on assistant turns
whose content is None (turns that carried only native tool_calls).
Once a conversation crossed the 85% compaction threshold — reached
after only a few turns on small-context local models plus the large
agent prompt — every subsequent message failed ("send more than three
messages and it stops working").
Flatten message content to text first via a _content_as_text helper
(str passthrough, multimodal list blocks joined, None -> "") and
tolerate a missing role. Adds tests/test_context_compactor.py covering
the helper and a >=4-message conversation that forces compaction with
a None-content tool-call turn (fails before this change, passes after).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
12696a05ae
commit
2625e97f11
@@ -15,6 +15,26 @@ from core.models import ChatMessage
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _content_as_text(content: Any) -> str:
|
||||
"""Flatten a message's content to plain text.
|
||||
|
||||
Handles the three shapes that flow through history: a plain string, a
|
||||
multimodal list of content blocks (vision/image attachments), and None
|
||||
(assistant turns that carried only native tool_calls persist content as
|
||||
None). Returns "" for anything without text so callers can safely slice
|
||||
the result.
|
||||
"""
|
||||
if isinstance(content, str):
|
||||
return content
|
||||
if isinstance(content, list):
|
||||
return " ".join(
|
||||
b.get("text", "") for b in content
|
||||
if isinstance(b, dict) and b.get("text")
|
||||
)
|
||||
return ""
|
||||
|
||||
|
||||
COMPACT_THRESHOLD = 0.85 # Trigger compaction at 85% of context window
|
||||
SUMMARY_MAX_TOKENS = 1024
|
||||
SMALL_CONTEXT_LIMIT = 8192 # Models with context <= this get aggressive trimming
|
||||
@@ -274,7 +294,7 @@ async def maybe_compact(
|
||||
|
||||
# Build the text to summarize
|
||||
convo_text = "\n".join(
|
||||
f"{msg['role'].upper()}: {msg.get('content', '')[:2000]}"
|
||||
f"{msg.get('role', 'user').upper()}: {_content_as_text(msg.get('content'))[:2000]}"
|
||||
for msg in older
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user