diff --git a/src/google/adk/apps/_configs.py b/src/google/adk/apps/_configs.py index 87f3666ebdd..e5813155af1 100644 --- a/src/google/adk/apps/_configs.py +++ b/src/google/adk/apps/_configs.py @@ -58,14 +58,22 @@ class EventsCompactionConfig(BaseModel): summarizer: Optional[BaseEventsSummarizer] = None """The event summarizer to use for compaction.""" - compaction_interval: int + compaction_interval: int = Field(gt=0) """The number of *new* user-initiated invocations that, once - fully represented in the session's events, will trigger a compaction.""" + fully represented in the session's events, will trigger a compaction. - overlap_size: int + Must be greater than 0. A value of 0 (or negative) would make the + sliding-window trigger fire on *every* invocation, because the guard + ``len(new_invocation_ids) < compaction_interval`` can never hold. + """ + + overlap_size: int = Field(ge=0) """The number of preceding invocations to include from the end of the last compacted range. This creates an overlap between consecutive - compacted summaries, maintaining context.""" + compacted summaries, maintaining context. + + Must be greater than or equal to 0 (0 means no overlap). + """ token_threshold: Optional[int] = Field( default=None, diff --git a/tests/unittests/apps/test_compaction.py b/tests/unittests/apps/test_compaction.py index 2f53e1e937a..cf2dee231ab 100644 --- a/tests/unittests/apps/test_compaction.py +++ b/tests/unittests/apps/test_compaction.py @@ -487,6 +487,24 @@ def test_events_compaction_config_rejects_missing_modes(self): with pytest.raises(ValidationError): EventsCompactionConfig() + def test_events_compaction_config_rejects_non_positive_interval(self): + # compaction_interval must be > 0. A value of 0 (or negative) would make + # the sliding-window trigger fire on every invocation because the guard + # `len(new_invocation_ids) < compaction_interval` can never hold. + with pytest.raises(ValidationError): + EventsCompactionConfig(compaction_interval=0, overlap_size=0) + + with pytest.raises(ValidationError): + EventsCompactionConfig(compaction_interval=-1, overlap_size=0) + + def test_events_compaction_config_rejects_negative_overlap(self): + with pytest.raises(ValidationError): + EventsCompactionConfig(compaction_interval=2, overlap_size=-1) + + def test_events_compaction_config_allows_zero_overlap(self): + config = EventsCompactionConfig(compaction_interval=2, overlap_size=0) + self.assertEqual(config.overlap_size, 0) + def test_latest_prompt_token_count_fallback_applies_compaction(self): events = [ self._create_event(1.0, 'inv1', 'a' * 40),