Files
cleveragents-core/features/conversation_state_management.feature
HAL9000 fcf1306817 fix(langgraph): resolve conversation state management review issues
Fixed all issues identified in PR review:

1. Fixed self.history property/attribute conflict in ConversationStateManager:
   - Renamed internal snapshot list from self.history to self._snapshots
   - The @property history now correctly returns conversation messages
   - Added public snapshots property for time-travel snapshot access
   - Updated existing tests to use manager.snapshots instead of manager.history

2. Removed unused variable full_history and dead code self._node_executors
   noqa comment from graph.py execute() method

3. Fixed ambiguous NON-BREAKING HYPHEN in state.py docstring

4. Restored removed public methods to ConversationStateManager:
   - clear_history(), load_checkpoint(), get_latest_checkpoint()
   - time_travel(), replace_state()
   - Added state property for backward compatibility

5. Fixed reset() to properly restore metadata from initial_state

6. Added BDD feature file and step definitions for conversation state
   management covering all 6 changed files

ISSUES CLOSED: #1
2026-06-18 09:49:41 -04:00

83 lines
4.1 KiB
Gherkin

Feature: Conversation state management
The ConversationStateManager separates persistent conversation history from
ephemeral execution state. Conversation history survives across runs while
execution state (current_node, execution_count, error) resets each time.
Scenario: Conversation history persists across execution resets
Given a ConversationStateManager with no initial state
When I append messages "hello" and "world" to the conversation history
And I reset the execution state
Then the conversation history should still contain 2 messages
And the execution count should be 0 after reset
Scenario: reset_execution_state clears only execution fields
Given a ConversationStateManager with no initial state
When I update the state with current_node "agent_a" and execution_count 5
And I append a message "keep me" to the conversation history
And I reset the execution state
Then the conversation history should contain the message "keep me"
And the current_node should be None after reset
Scenario: get_full_history returns all persistent messages
Given a ConversationStateManager with no initial state
When I append messages "first" and "second" and "third" to the conversation history
Then get_full_history should return 3 messages
Scenario: history property returns persistent conversation messages
Given a ConversationStateManager with no initial state
When I append a message "persistent" to the conversation history
Then the history property should contain the message "persistent"
Scenario: update_state with messages key appends to conversation history
Given a ConversationStateManager with no initial state
When I call update_state with messages containing "new message"
Then the conversation history should contain the message "new message"
Scenario: GraphState.to_graph_state returns conversation_history and execution_state keys
Given a GraphState with messages and metadata
When I call to_graph_state on the GraphState
Then the result should contain a conversation_history key
And the result should contain an execution_state key with current_node
Scenario: ExecutionState model holds execution-level fields
Given an ExecutionState with current_node "node_x" and execution_count 3
Then the ExecutionState current_node should be "node_x"
And the ExecutionState execution_count should be 3
Scenario: StateManager backward-compat alias works as ConversationStateManager
Given a StateManager created via the backward-compat alias
When I append a message "compat" to the conversation history via StateManager
Then the StateManager history property should contain the message "compat"
Scenario: append_messages evicts oldest entries when MAX_HISTORY_SIZE is exceeded
Given a ConversationStateManager with no initial state
When I append 55 messages to the conversation history
Then the conversation history should contain at most 50 messages
And the most recent messages should be retained
Scenario: Full reset clears both conversation history and execution state
Given a ConversationStateManager with no initial state
When I append a message "before reset" to the conversation history
And I update the state with current_node "some_node" and execution_count 5
And I perform a full reset
Then the conversation history should be empty after full reset
And the execution count should be 0 after full reset
Scenario: Bridge default update mode is APPEND
Given a RxPyLangGraphBridge instance
Then the default update mode should be APPEND
Scenario: Session full_history property returns all messages
Given a Session with two messages appended
Then the full_history property should return 2 messages
Scenario: Session get_messages with no limit returns full thread
Given a Session with three messages appended
When I call get_messages with no limit
Then all 3 messages should be returned
Scenario: Session append_message preserves full history
Given a Session with one existing message
When I append a second message to the session
Then the session should have 2 messages in total