fix: correct belief management

There was an issue in how we treated beliefs, specifically with multiple beliefs of the same name but different arguments. This is fixed with this commit.

Also implemented correct updating of the "responded" belief, when the user_said belief is updated (when we get a new user message, we state that we have not yet responded to that message)

ref: N25B-197
This commit is contained in:
2025-10-29 11:23:56 +01:00
parent dc811fd625
commit 3b7aeafe5e
3 changed files with 53 additions and 29 deletions

View File

@@ -4,7 +4,7 @@ from unittest.mock import AsyncMock, MagicMock, call
import pytest
from control_backend.agents.bdi.behaviours.belief_setter import BeliefSetter
from control_backend.agents.bdi.behaviours.belief_setter import BeliefSetterBehaviour
# Define a constant for the collector agent name to use in tests
COLLECTOR_AGENT_NAME = "belief_collector"
@@ -22,16 +22,14 @@ def mock_agent(mocker):
@pytest.fixture
def belief_setter(mock_agent, mocker):
"""Fixture to create an instance of BeliefSetter with a mocked agent."""
"""Fixture to create an instance of BeliefSetterBehaviour with a mocked agent."""
# Patch the settings to use a predictable agent name
mocker.patch(
"control_backend.agents.bdi.behaviours.belief_setter.settings.agent_settings.belief_collector_agent_name",
COLLECTOR_AGENT_NAME,
)
# Patch asyncio.sleep to prevent tests from actually waiting
mocker.patch("asyncio.sleep", return_value=None)
setter = BeliefSetter()
setter = BeliefSetterBehaviour()
setter.agent = mock_agent
# Mock the receive method, we will control its return value in each test
setter.receive = AsyncMock()
@@ -115,7 +113,7 @@ def test_process_belief_message_valid_json(belief_setter, mocker):
Test processing a valid belief message with correct thread and JSON body.
"""
# Arrange
beliefs_payload = {"is_hot": [["kitchen"]], "is_clean": [["kitchen"], ["bathroom"]]}
beliefs_payload = {"is_hot": ["kitchen"], "is_clean": ["kitchen", "bathroom"]}
msg = create_mock_message(
sender_node=COLLECTOR_AGENT_JID, body=json.dumps(beliefs_payload), thread="beliefs"
)
@@ -185,8 +183,8 @@ def test_set_beliefs_success(belief_setter, mock_agent, caplog):
"""
# Arrange
beliefs_to_set = {
"is_hot": [["kitchen"], ["living_room"]],
"door_is": [["front_door", "closed"]],
"is_hot": ["kitchen"],
"door_opened": ["front_door", "back_door"],
}
# Act
@@ -196,17 +194,25 @@ def test_set_beliefs_success(belief_setter, mock_agent, caplog):
# Assert
expected_calls = [
call("is_hot", "kitchen"),
call("is_hot", "living_room"),
call("door_is", "front_door", "closed"),
call("door_opened", "front_door", "back_door"),
]
mock_agent.bdi.set_belief.assert_has_calls(expected_calls, any_order=True)
assert mock_agent.bdi.set_belief.call_count == 3
assert mock_agent.bdi.set_belief.call_count == 2
# Check logs
assert "Set belief is_hot with arguments ['kitchen']" in caplog.text
assert "Set belief is_hot with arguments ['living_room']" in caplog.text
assert "Set belief door_is with arguments ['front_door', 'closed']" in caplog.text
assert "Set belief door_opened with arguments ['front_door', 'back_door']" in caplog.text
def test_responded_unset(belief_setter, mock_agent):
# Arrange
new_beliefs = {"user_said": ["message"]}
# Act
belief_setter._set_beliefs(new_beliefs)
# Assert
mock_agent.bdi.set_belief.assert_has_calls([call("user_said", "message")])
mock_agent.bdi.remove_belief.assert_has_calls([call("responded")])
def test_set_beliefs_bdi_not_initialized(belief_setter, mock_agent, caplog):
"""
@@ -214,7 +220,7 @@ def test_set_beliefs_bdi_not_initialized(belief_setter, mock_agent, caplog):
"""
# Arrange
mock_agent.bdi = None # Simulate BDI not being ready
beliefs_to_set = {"is_hot": [["kitchen"]]}
beliefs_to_set = {"is_hot": ["kitchen"]}
# Act
with caplog.at_level(logging.WARNING):