fix(agent): copy conversation_history to avoid mutating caller's list

This commit is contained in:
Farukest 2026-03-01 03:06:13 +03:00
parent 7b23dbfe68
commit e87859e82c
No known key found for this signature in database
GPG key ID: 73E2756B3FFF5241
2 changed files with 35 additions and 2 deletions

View file

@ -1842,8 +1842,8 @@ class AIAgent:
self._turns_since_memory = 0
self._iters_since_skill = 0
# Initialize conversation
messages = conversation_history or []
# Initialize conversation (copy to avoid mutating the caller's list)
messages = list(conversation_history) if conversation_history else []
# Hydrate todo store from conversation history (gateway creates a fresh
# AIAgent per message, so the in-memory store is empty -- we need to

View file

@ -758,3 +758,36 @@ class TestRunConversation:
)
result = agent.run_conversation("search something")
mock_compress.assert_called_once()
# ---------------------------------------------------------------------------
# Conversation history mutation
# ---------------------------------------------------------------------------
class TestConversationHistoryNotMutated:
"""run_conversation must not mutate the caller's conversation_history list."""
def test_caller_list_unchanged_after_run(self, agent):
"""Passing conversation_history should not modify the original list."""
history = [
{"role": "user", "content": "previous question"},
{"role": "assistant", "content": "previous answer"},
]
original_len = len(history)
resp = _mock_response(content="new answer", finish_reason="stop")
agent.client.chat.completions.create.return_value = resp
with (
patch.object(agent, "_persist_session"),
patch.object(agent, "_save_trajectory"),
patch.object(agent, "_cleanup_task_resources"),
):
result = agent.run_conversation("new question", conversation_history=history)
# Caller's list must be untouched
assert len(history) == original_len, (
f"conversation_history was mutated: expected {original_len} items, got {len(history)}"
)
# Result should have more messages than the original history
assert len(result["messages"]) > original_len