Skip to content

Commit ec42cfa

Browse files
GWealecopybara-github
authored andcommitted
feat: make EventsCompactionConfig sliding-window fields optional
EventsCompactionConfig required compaction_interval and overlap_size, so a token-threshold-only compaction config could not be constructed even though the runtime already tolerates a missing sliding-window trigger. Make both sliding-window fields Optional and validate them as a both-or-neither pair, mirroring the token-threshold pair, and require at least one trigger overall. This also tightens validation with positivity bounds enforced whenever a value is provided (compaction_interval > 0, overlap_size >= 0). Minor behavior change: compaction_interval <= 0 and negative overlap_size, previously accepted, now raise ValidationError. Close #6398 Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 950899288
1 parent 551372b commit ec42cfa

2 files changed

Lines changed: 35 additions & 6 deletions

File tree

src/google/adk/apps/_configs.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ class EventsCompactionConfig(BaseModel):
5858
summarizer: Optional[BaseEventsSummarizer] = None
5959
"""The event summarizer to use for compaction."""
6060

61-
compaction_interval: int
61+
compaction_interval: Optional[int] = Field(default=None, gt=0)
6262
"""The number of *new* user-initiated invocations that, once
6363
fully represented in the session's events, will trigger a compaction."""
6464

65-
overlap_size: int
65+
overlap_size: Optional[int] = Field(default=None, ge=0)
6666
"""The number of preceding invocations to include from the
6767
end of the last compacted range. This creates an overlap between consecutive
6868
compacted summaries, maintaining context."""
@@ -85,11 +85,22 @@ class EventsCompactionConfig(BaseModel):
8585
"""
8686

8787
@model_validator(mode="after")
88-
def _validate_token_params(self) -> EventsCompactionConfig:
88+
def _validate_trigger_params(self) -> EventsCompactionConfig:
8989
token_threshold_set = self.token_threshold is not None
9090
retention_size_set = self.event_retention_size is not None
9191
if token_threshold_set != retention_size_set:
9292
raise ValueError(
9393
"token_threshold and event_retention_size must be set together."
9494
)
95+
compaction_interval_set = self.compaction_interval is not None
96+
overlap_size_set = self.overlap_size is not None
97+
if compaction_interval_set != overlap_size_set:
98+
raise ValueError(
99+
"compaction_interval and overlap_size must be set together."
100+
)
101+
if not (token_threshold_set or compaction_interval_set):
102+
raise ValueError(
103+
"At least one compaction trigger must be configured: the"
104+
" token-threshold pair or the sliding-window pair."
105+
)
95106
return self

tests/unittests/apps/test_compaction.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,20 +473,38 @@ def test_events_compaction_config_rejects_partial_token_fields(
473473
def test_events_compaction_config_rejects_partial_sliding_fields(
474474
self,
475475
):
476-
with pytest.raises(ValidationError):
476+
with pytest.raises(ValidationError, match='must be set together'):
477477
EventsCompactionConfig(
478478
compaction_interval=2,
479479
)
480480

481-
with pytest.raises(ValidationError):
481+
with pytest.raises(ValidationError, match='must be set together'):
482482
EventsCompactionConfig(
483483
overlap_size=0,
484484
)
485485

486486
def test_events_compaction_config_rejects_missing_modes(self):
487-
with pytest.raises(ValidationError):
487+
with pytest.raises(
488+
ValidationError, match='At least one compaction trigger'
489+
):
488490
EventsCompactionConfig()
489491

492+
def test_events_compaction_config_accepts_token_only_without_sliding_window(
493+
self,
494+
):
495+
config = EventsCompactionConfig(
496+
token_threshold=160_000,
497+
event_retention_size=50,
498+
)
499+
self.assertIsNone(config.compaction_interval)
500+
self.assertIsNone(config.overlap_size)
501+
self.assertEqual(config.token_threshold, 160_000)
502+
self.assertEqual(config.event_retention_size, 50)
503+
504+
def test_events_compaction_config_rejects_zero_compaction_interval(self):
505+
with pytest.raises(ValidationError):
506+
EventsCompactionConfig(compaction_interval=0, overlap_size=1)
507+
490508
def test_latest_prompt_token_count_fallback_applies_compaction(self):
491509
events = [
492510
self._create_event(1.0, 'inv1', 'a' * 40),

0 commit comments

Comments
 (0)