@phase2 @acms @context_strategies @sliding_window Feature: SlidingWindowStrategy with configurable window size As a CleverAgents developer I want a SlidingWindowStrategy that implements the ContextStrategy protocol So that long-running agent sessions can limit token usage by keeping only the most recent messages # =========================================================================== # Protocol conformance # =========================================================================== @sliding_window_protocol Scenario: SlidingWindowStrategy satisfies the ContextStrategy protocol Given a SlidingWindowStrategy with window_size 10 and window_mode "messages" Then the sw strategy should satisfy the ContextStrategy protocol And the sw strategy name should be "sliding_window" And the sw strategy should have a capabilities object @sliding_window_protocol Scenario: SlidingWindowStrategy explain returns a description Given a SlidingWindowStrategy with window_size 5 and window_mode "messages" Then the sw strategy explain should contain "sliding" # =========================================================================== # Messages mode — basic truncation # =========================================================================== @sliding_window_messages Scenario: Messages mode keeps only the most recent N messages Given a SlidingWindowStrategy with window_size 2 and window_mode "messages" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://app/a.py | message 1 | 0.5 | 10 | 3 | user | | project://app/b.py | message 2 | 0.6 | 10 | 3 | user | | project://app/c.py | message 3 | 0.7 | 10 | 3 | user | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 2 fragments should be returned by sliding window strategy And the sliding window result should contain uko_node "project://app/b.py" And the sliding window result should contain uko_node "project://app/c.py" And the sliding window result should not contain uko_node "project://app/a.py" @sliding_window_messages Scenario: Messages mode with exact boundary keeps all messages Given a SlidingWindowStrategy with window_size 3 and window_mode "messages" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://app/a.py | message 1 | 0.5 | 10 | 3 | user | | project://app/b.py | message 2 | 0.6 | 10 | 3 | user | | project://app/c.py | message 3 | 0.7 | 10 | 3 | user | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 3 fragments should be returned by sliding window strategy @sliding_window_messages Scenario: Messages mode with fewer messages than window size returns all Given a SlidingWindowStrategy with window_size 10 and window_mode "messages" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://app/a.py | message 1 | 0.5 | 10 | 3 | user | | project://app/b.py | message 2 | 0.6 | 10 | 3 | user | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 2 fragments should be returned by sliding window strategy @sliding_window_messages Scenario: Messages mode with empty context returns empty Given a SlidingWindowStrategy with window_size 5 and window_mode "messages" And an empty sliding window fragment list And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 0 fragments should be returned by sliding window strategy # =========================================================================== # Tokens mode — basic truncation # =========================================================================== @sliding_window_tokens Scenario: Tokens mode keeps most recent messages within token limit Given a SlidingWindowStrategy with window_size 25 and window_mode "tokens" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://app/a.py | message 1 | 0.5 | 10 | 3 | user | | project://app/b.py | message 2 | 0.6 | 10 | 3 | user | | project://app/c.py | message 3 | 0.7 | 10 | 3 | user | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 2 fragments should be returned by sliding window strategy And the sliding window result should contain uko_node "project://app/b.py" And the sliding window result should contain uko_node "project://app/c.py" And the sliding window result should not contain uko_node "project://app/a.py" @sliding_window_tokens Scenario: Tokens mode with exact boundary keeps all messages Given a SlidingWindowStrategy with window_size 30 and window_mode "tokens" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://app/a.py | message 1 | 0.5 | 10 | 3 | user | | project://app/b.py | message 2 | 0.6 | 10 | 3 | user | | project://app/c.py | message 3 | 0.7 | 10 | 3 | user | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 3 fragments should be returned by sliding window strategy @sliding_window_tokens Scenario: Tokens mode with empty context returns empty Given a SlidingWindowStrategy with window_size 100 and window_mode "tokens" And an empty sliding window fragment list And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 0 fragments should be returned by sliding window strategy @sliding_window_tokens Scenario: Tokens mode with single large message that fits returns it Given a SlidingWindowStrategy with window_size 50 and window_mode "tokens" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://app/a.py | message 1 | 0.5 | 40 | 3 | user | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 1 fragments should be returned by sliding window strategy # =========================================================================== # System prompt preservation # =========================================================================== @sliding_window_system_prompt Scenario: System prompt is always preserved outside the sliding window in messages mode Given a SlidingWindowStrategy with window_size 2 and window_mode "messages" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://system/prompt | system context | 0.9 | 20 | 5 | system | | project://app/a.py | message 1 | 0.5 | 10 | 3 | user | | project://app/b.py | message 2 | 0.6 | 10 | 3 | user | | project://app/c.py | message 3 | 0.7 | 10 | 3 | user | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 3 fragments should be returned by sliding window strategy And the sliding window result should contain uko_node "project://system/prompt" And the sliding window result should contain uko_node "project://app/b.py" And the sliding window result should contain uko_node "project://app/c.py" And the sliding window result should not contain uko_node "project://app/a.py" @sliding_window_system_prompt Scenario: System prompt is always preserved outside the sliding window in tokens mode Given a SlidingWindowStrategy with window_size 25 and window_mode "tokens" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://system/prompt | system context | 0.9 | 20 | 5 | system | | project://app/a.py | message 1 | 0.5 | 10 | 3 | user | | project://app/b.py | message 2 | 0.6 | 10 | 3 | user | | project://app/c.py | message 3 | 0.7 | 10 | 3 | user | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 3 fragments should be returned by sliding window strategy And the sliding window result should contain uko_node "project://system/prompt" And the sliding window result should contain uko_node "project://app/b.py" And the sliding window result should contain uko_node "project://app/c.py" And the sliding window result should not contain uko_node "project://app/a.py" @sliding_window_system_prompt Scenario: Multiple system prompts are all preserved Given a SlidingWindowStrategy with window_size 1 and window_mode "messages" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://system/prompt1 | system context 1 | 0.9 | 20 | 5 | system | | project://system/prompt2 | system context 2 | 0.8 | 20 | 5 | system | | project://app/a.py | message 1 | 0.5 | 10 | 3 | user | | project://app/b.py | message 2 | 0.6 | 10 | 3 | user | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 3 fragments should be returned by sliding window strategy And the sliding window result should contain uko_node "project://system/prompt1" And the sliding window result should contain uko_node "project://system/prompt2" And the sliding window result should contain uko_node "project://app/b.py" And the sliding window result should not contain uko_node "project://app/a.py" @sliding_window_system_prompt Scenario: Context with only system prompts returns all of them Given a SlidingWindowStrategy with window_size 1 and window_mode "messages" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://system/prompt1 | system context 1 | 0.9 | 20 | 5 | system | | project://system/prompt2 | system context 2 | 0.8 | 20 | 5 | system | And a sliding window budget with max_tokens 1000 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 2 fragments should be returned by sliding window strategy # =========================================================================== # Budget enforcement # =========================================================================== @sliding_window_budget Scenario: Strategy respects token budget after sliding window truncation Given a SlidingWindowStrategy with window_size 10 and window_mode "messages" And the following sliding window fragments: | uko_node | content | score | tokens | depth | role | | project://app/a.py | message 1 | 0.5 | 100 | 3 | user | | project://app/b.py | message 2 | 0.6 | 100 | 3 | user | | project://app/c.py | message 3 | 0.7 | 100 | 3 | user | And a sliding window budget with max_tokens 250 and reserved_tokens 0 When I apply the SlidingWindowStrategy Then 2 fragments should be returned by sliding window strategy # =========================================================================== # can_handle # =========================================================================== @sliding_window_can_handle Scenario: can_handle returns a positive confidence Given a SlidingWindowStrategy with window_size 10 and window_mode "messages" When I check can_handle on SlidingWindowStrategy Then the sliding window confidence should be greater than 0.0 # =========================================================================== # Plugin registry registration # =========================================================================== @sliding_window_registry Scenario: SlidingWindowStrategy is registered under key "sliding_window" in the pipeline Given an ACMS pipeline for sliding window tests Then the sw pipeline should have strategy "sliding_window" @sliding_window_registry Scenario: SlidingWindowStrategy can be registered manually with the pipeline Given an ACMS pipeline for sliding window tests When I register a custom SlidingWindowStrategy with the pipeline Then the sw pipeline should have strategy "custom_sliding_window" # =========================================================================== # Configuration validation # =========================================================================== @sliding_window_config Scenario: window_size must be positive When I attempt to create a SlidingWindowStrategy with window_size 0 Then a ValueError should be raised for sliding window @sliding_window_config Scenario: window_mode must be messages or tokens When I attempt to create a SlidingWindowStrategy with window_mode "invalid" Then a ValueError should be raised for sliding window @sliding_window_config Scenario: window_mode messages is valid When I create a SlidingWindowStrategy with window_size 5 and window_mode "messages" Then no error should be raised for sliding window @sliding_window_config Scenario: window_mode tokens is valid When I create a SlidingWindowStrategy with window_size 100 and window_mode "tokens" Then no error should be raised for sliding window