Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion astrbot/core/agent/context/truncator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ def _split_system_rest(
Returns:
tuple: (system_messages, non_system_messages)
"""
first_non_system = 0
# Default to the end so an all-system list lands entirely in the system
# half; otherwise the loop never breaks and the split would be reversed.
first_non_system = len(messages)
for i, msg in enumerate(messages):
if msg.role != "system":
first_non_system = i
Expand Down
23 changes: 23 additions & 0 deletions tests/agent/test_truncator.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,29 @@ def test_all_system_messages(self):
if len(result) > 0:
assert all(msg.role == "system" for msg in result)

def test_split_system_rest_with_only_system_messages(self):
"""All-system input must land entirely in the system half, not the rest."""
truncator = ContextTruncator()
messages = [
self.create_message("system", "System 1"),
self.create_message("system", "System 2"),
]

system_messages, non_system_messages = truncator._split_system_rest(messages)

assert len(system_messages) == 2
assert non_system_messages == []

def test_halving_keeps_all_system_messages(self):
"""Halving must never drop system messages, even with no turns present."""
truncator = ContextTruncator()
messages = [self.create_message("system", f"System {i}") for i in range(4)]

result = truncator.truncate_by_halving(messages)

assert len(result) == 4
assert all(msg.role == "system" for msg in result)

# ==================== #6196: 长 tool chain 只有一条 user 消息 ====================

def _build_tool_chain(self, tool_rounds: int = 20) -> list[Message]:
Expand Down
Loading