Files
EvoScientist/tests/test_compact_middleware.py
T
m4 c2743251e9 Initial commit of EvoScientist framework
Self-evolving AI scientist framework built on LangGraph/LangChain with
CLI/TUI core, FastAPI gateway, and Next.js frontend.

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
2026-07-13 08:07:45 +08:00

182 lines
6.0 KiB
Python

"""Tests for proactive summarization configuration via settings.yaml.
``deepagents.middleware.summarization.compute_summarization_defaults`` is
patched at module load time to read ``compact_trigger_fraction`` and
``compact_enabled`` from settings.yaml. These tests verify that patch.
"""
from unittest.mock import MagicMock, patch
from deepagents.middleware import summarization as _deep_summarization
from EvoScientist.middleware.compact import compute_compact_trigger
# ---------------------------------------------------------------------------
# compute_compact_trigger tests
# ---------------------------------------------------------------------------
def test_compute_trigger_with_profile():
model = MagicMock()
model.profile = {"max_input_tokens": 200_000}
assert compute_compact_trigger(model, fraction=0.5) == ("fraction", 0.5)
def test_compute_trigger_with_custom_fraction():
model = MagicMock()
model.profile = {"max_input_tokens": 200_000}
assert compute_compact_trigger(model, fraction=0.3) == ("fraction", 0.3)
def test_compute_trigger_without_profile():
model = MagicMock()
model.profile = None
assert compute_compact_trigger(model, fraction=0.5) == ("tokens", 100_000)
def test_compute_trigger_custom_fallback():
model = MagicMock()
model.profile = None
result = compute_compact_trigger(model, fraction=0.5, fallback=("tokens", 50_000))
assert result == ("tokens", 50_000)
# ---------------------------------------------------------------------------
# Patch integration tests
# ---------------------------------------------------------------------------
def test_patch_applied_on_import():
"""The compact module should replace compute_summarization_defaults."""
from EvoScientist.middleware import compact
assert (
_deep_summarization.compute_summarization_defaults
is compact._configured_summarization_defaults
)
@patch("EvoScientist.config.load_config")
def test_patch_uses_config_fraction(mock_load_config):
cfg = MagicMock()
cfg.compact_enabled = True
cfg.compact_trigger_fraction = 0.4
cfg.compact_keep_messages = 5
mock_load_config.return_value = cfg
from EvoScientist.middleware.compact import _configured_summarization_defaults
model = MagicMock()
model.profile = {"max_input_tokens": 200_000}
result = _configured_summarization_defaults(model)
assert result["trigger"] == [("messages", 20), ("fraction", 0.4)]
assert result["keep"] == ("messages", 5)
@patch("EvoScientist.config.load_config")
def test_patch_disabled_sets_trigger_to_1(mock_load_config):
cfg = MagicMock()
cfg.compact_enabled = False
cfg.compact_trigger_fraction = 0.5
mock_load_config.return_value = cfg
from EvoScientist.middleware.compact import _configured_summarization_defaults
model = MagicMock()
model.profile = {"max_input_tokens": 200_000}
result = _configured_summarization_defaults(model)
assert result["trigger"] == ("fraction", 1.0)
@patch("EvoScientist.config.load_config")
def test_patch_disabled_no_profile_uses_tokens(mock_load_config):
cfg = MagicMock()
cfg.compact_enabled = False
cfg.compact_trigger_fraction = 0.5
mock_load_config.return_value = cfg
from EvoScientist.middleware.compact import _configured_summarization_defaults
model = MagicMock()
model.profile = None
result = _configured_summarization_defaults(model)
assert result["trigger"] == ("tokens", 9_999_999)
@patch("EvoScientist.config.load_config")
def test_patch_no_profile_keeps_token_trigger(mock_load_config):
"""Models without profile should keep deepagents' token-based trigger."""
cfg = MagicMock()
cfg.compact_enabled = True
cfg.compact_trigger_fraction = 0.4
mock_load_config.return_value = cfg
from EvoScientist.middleware.compact import _configured_summarization_defaults
model = MagicMock()
model.profile = None
result = _configured_summarization_defaults(model)
# Should NOT be overridden to fraction since model has no profile
assert result["trigger"][0] == "tokens"
assert result["trigger"] == ("tokens", 170_000) # deepagents default
@patch("EvoScientist.config.load_config")
def test_patch_fallback_on_bad_fraction(mock_load_config):
cfg = MagicMock()
cfg.compact_enabled = True
cfg.compact_trigger_fraction = 2.5 # invalid (> 1)
mock_load_config.return_value = cfg
from EvoScientist.middleware.compact import _configured_summarization_defaults
model = MagicMock()
model.profile = {"max_input_tokens": 200_000}
result = _configured_summarization_defaults(model)
assert result["trigger"] == [("messages", 20), ("fraction", 0.5)]
@patch("EvoScientist.config.load_config")
def test_patch_uses_current_conversation_mode_for_message_trigger(mock_load_config):
cfg = MagicMock()
cfg.compact_enabled = True
cfg.compact_trigger_fraction = 0.4
mock_load_config.return_value = cfg
from EvoScientist.conversation_modes import (
reset_current_conversation_mode,
set_current_conversation_mode,
)
from EvoScientist.middleware.compact import _configured_summarization_defaults
model = MagicMock()
model.profile = {"max_input_tokens": 200_000}
token = set_current_conversation_mode("low")
try:
result = _configured_summarization_defaults(model)
finally:
reset_current_conversation_mode(token)
assert result["trigger"] == [("messages", 8), ("fraction", 0.4)]
assert result["keep"] == ("messages", 3)
@patch("EvoScientist.config.load_config")
def test_patch_fallback_on_config_error(mock_load_config):
mock_load_config.side_effect = RuntimeError("config corrupt")
from EvoScientist.middleware.compact import _configured_summarization_defaults
model = MagicMock()
model.profile = {"max_input_tokens": 200_000}
result = _configured_summarization_defaults(model)
# Should fall back to deepagents built-in defaults
assert result["trigger"] == ("fraction", 0.85)