diff --git a/pytests/test_maisaka_timing_gate.py b/pytests/test_maisaka_timing_gate.py index a2f79b8a..ec7eaf98 100644 --- a/pytests/test_maisaka_timing_gate.py +++ b/pytests/test_maisaka_timing_gate.py @@ -238,3 +238,47 @@ def test_finish_tool_removes_empty_assistant_history_message() -> None: ) assert runtime._chat_history == [] + + +def test_timing_gate_head_trim_keeps_short_history() -> None: + messages = [ + AssistantMessage(content="第一条消息", timestamp=datetime.now()), + AssistantMessage(content="第二条消息", timestamp=datetime.now()), + ] + + trimmed_messages = MaisakaHeartFlowChatting._drop_head_context_messages( + messages, + drop_context_count=3, + ) + + assert trimmed_messages == messages + + +def test_timing_gate_head_trim_keeps_history_within_config_limit() -> None: + messages = [ + AssistantMessage(content=f"消息 {index}", timestamp=datetime.now()) + for index in range(10) + ] + + trimmed_messages = MaisakaHeartFlowChatting._drop_head_context_messages( + messages, + drop_context_count=7, + trim_threshold_context_count=10, + ) + + assert trimmed_messages == messages + + +def test_timing_gate_head_trim_applies_after_config_limit_exceeded() -> None: + messages = [ + AssistantMessage(content=f"消息 {index}", timestamp=datetime.now()) + for index in range(11) + ] + + trimmed_messages = MaisakaHeartFlowChatting._drop_head_context_messages( + messages, + drop_context_count=7, + trim_threshold_context_count=10, + ) + + assert trimmed_messages == messages[7:] diff --git a/src/maisaka/runtime.py b/src/maisaka/runtime.py index 77eed427..e3ccf739 100644 --- a/src/maisaka/runtime.py +++ b/src/maisaka/runtime.py @@ -614,6 +614,7 @@ class MaisakaHeartFlowChatting: sub_agent_history = self._drop_head_context_messages( selected_history, drop_head_context_count, + trim_threshold_context_count=context_message_limit, ) if extra_messages: sub_agent_history.extend(list(extra_messages)) @@ -637,12 +638,21 @@ class MaisakaHeartFlowChatting: def _drop_head_context_messages( chat_history: Sequence[LLMContextMessage], drop_context_count: int, + *, + trim_threshold_context_count: int | None = None, ) -> list[LLMContextMessage]: """从已选上下文头部丢弃指定数量的普通上下文消息。""" if drop_context_count <= 0: return list(chat_history) + context_message_count = sum(1 for message in chat_history if message.count_in_context) + if trim_threshold_context_count is not None and context_message_count <= trim_threshold_context_count: + return list(chat_history) + + if context_message_count <= drop_context_count: + return list(chat_history) + first_kept_index = 0 dropped_context_count = 0 while (