Skip to content

Commit e562bc1

Browse files
committed
Apply ruff formatting
1 parent ffdd3ff commit e562bc1

2 files changed

Lines changed: 140 additions & 1 deletion

File tree

python/semantic_kernel/agents/orchestration/group_chat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def __init__(
289289
"""
290290
self._manager = manager
291291
self._internal_topic_type = internal_topic_type
292-
self._chat_history = chat_history or ChatHistory()
292+
self._chat_history = chat_history if chat_history is not None else ChatHistory()
293293
self._participant_descriptions = participant_descriptions
294294
self._result_callback = result_callback
295295

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Copyright (c) Microsoft. All rights reserved.
2+
3+
import sys
4+
5+
from semantic_kernel.agents.orchestration.group_chat import (
6+
GroupChatOrchestration,
7+
RoundRobinGroupChatManager,
8+
)
9+
from semantic_kernel.agents.runtime.in_process.in_process_runtime import InProcessRuntime
10+
from semantic_kernel.contents.chat_history import ChatHistory
11+
from semantic_kernel.contents.history_reducer.chat_history_truncation_reducer import ChatHistoryTruncationReducer
12+
from tests.unit.agents.orchestration.conftest import MockAgent
13+
14+
if sys.version_info >= (3, 12):
15+
pass # pragma: no cover
16+
else:
17+
pass # pragma: no cover
18+
19+
20+
# region Tests with ChatHistoryTruncationReducer
21+
22+
23+
async def test_group_chat_with_chat_history_parameter():
24+
"""Test GroupChatOrchestration accepts chat_history parameter."""
25+
agent = MockAgent(name="TestAgent", description="Test agent")
26+
chat_history = ChatHistory()
27+
28+
# Should not raise an error
29+
orchestration = GroupChatOrchestration(
30+
members=[agent], manager=RoundRobinGroupChatManager(), chat_history=chat_history
31+
)
32+
33+
assert orchestration._chat_history is chat_history
34+
35+
36+
async def test_group_chat_with_truncation_reducer():
37+
"""Test GroupChatOrchestration with ChatHistoryTruncationReducer."""
38+
agent = MockAgent(name="TestAgent", description="Test agent")
39+
40+
# Create truncation reducer that keeps only 2 messages
41+
reducer = ChatHistoryTruncationReducer(target_count=2, threshold_count=0, auto_reduce=True)
42+
43+
runtime = InProcessRuntime()
44+
runtime.start()
45+
46+
try:
47+
orchestration = GroupChatOrchestration(
48+
members=[agent], manager=RoundRobinGroupChatManager(max_rounds=3), chat_history=reducer
49+
)
50+
51+
orchestration_result = await orchestration.invoke(task="Test message", runtime=runtime)
52+
await orchestration_result.get(timeout=1.0)
53+
54+
# Verify the reducer was used and has messages
55+
assert len(reducer.messages) > 0, "Reducer should have received messages"
56+
57+
# Verify truncation is working - should not exceed target_count + threshold_count + buffer
58+
# (The exact count may vary due to "transfer" messages and timing)
59+
assert len(reducer.messages) <= 5, "Reducer should limit message count"
60+
61+
finally:
62+
await runtime.stop_when_idle()
63+
64+
65+
async def test_group_chat_fallback_to_regular_chat_history():
66+
"""Test that GroupChat falls back to add_message for regular ChatHistory."""
67+
agent = MockAgent(name="TestAgent", description="Test agent")
68+
69+
# Use regular ChatHistory (no add_message_async method)
70+
regular_history = ChatHistory()
71+
72+
runtime = InProcessRuntime()
73+
runtime.start()
74+
75+
try:
76+
# Should work without errors
77+
orchestration = GroupChatOrchestration(
78+
members=[agent], manager=RoundRobinGroupChatManager(max_rounds=1), chat_history=regular_history
79+
)
80+
81+
orchestration_result = await orchestration.invoke(task="Test message", runtime=runtime)
82+
await orchestration_result.get(timeout=1.0)
83+
84+
# Verify messages were added to history
85+
assert len(regular_history.messages) > 0, "Messages should be added to regular ChatHistory"
86+
87+
finally:
88+
await runtime.stop_when_idle()
89+
90+
91+
async def test_group_chat_no_chat_history_parameter():
92+
"""Test GroupChatOrchestration works when no chat_history provided."""
93+
agent = MockAgent(name="TestAgent", description="Test agent")
94+
95+
orchestration = GroupChatOrchestration(members=[agent], manager=RoundRobinGroupChatManager())
96+
97+
# Should not set chat_history in constructor when None provided
98+
assert orchestration._chat_history is None
99+
100+
101+
async def test_empty_reducer_not_replaced_by_default_history():
102+
"""Test that empty ChatHistoryReducer instances are not replaced by default ChatHistory.
103+
104+
This is a regression test for the bug where empty reducers evaluated to False
105+
and were replaced by ChatHistory() due to the 'chat_history or ChatHistory()' pattern.
106+
"""
107+
agent = MockAgent(name="TestAgent", description="Test agent")
108+
109+
# Create empty reducer (should evaluate to False in boolean context but still be used)
110+
empty_reducer = ChatHistoryTruncationReducer(target_count=5, threshold_count=0, auto_reduce=True)
111+
112+
# Verify it's empty and evaluates to False initially
113+
assert len(empty_reducer.messages) == 0
114+
assert bool(empty_reducer) is False
115+
116+
runtime = InProcessRuntime()
117+
runtime.start()
118+
119+
try:
120+
orchestration = GroupChatOrchestration(
121+
members=[agent], manager=RoundRobinGroupChatManager(max_rounds=1), chat_history=empty_reducer
122+
)
123+
124+
orchestration_result = await orchestration.invoke(task="Test message", runtime=runtime)
125+
await orchestration_result.get(timeout=1.0)
126+
127+
# Verify messages were added to our reducer (not a default ChatHistory)
128+
assert len(empty_reducer.messages) > 0, "Messages should be added to the reducer instance"
129+
130+
# Verify we can access reducer-specific functionality (proves it's our reducer)
131+
assert hasattr(empty_reducer, "auto_reduce"), "Should still be our reducer instance"
132+
assert empty_reducer.auto_reduce is True, "Should have reducer-specific properties"
133+
assert empty_reducer.target_count == 5, "Should have our original target_count"
134+
135+
finally:
136+
await runtime.stop_when_idle()
137+
138+
139+
# endregion Tests with ChatHistoryTruncationReducer

0 commit comments

Comments
 (0)