chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:21:23 +08:00
commit b957a53def
5423 changed files with 863745 additions and 0 deletions
@@ -0,0 +1,99 @@
# Copyright (c) Microsoft. All rights reserved.
from unittest.mock import AsyncMock, MagicMock
from semantic_kernel.agents.strategies.termination.aggregator_termination_strategy import (
AggregateTerminationCondition,
AggregatorTerminationStrategy,
)
from semantic_kernel.agents.strategies.termination.termination_strategy import TerminationStrategy
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from tests.unit.agents.test_agent import MockAgent
async def test_aggregate_termination_condition_all_true():
agent = MockAgent(id="test-agent-id")
history = [MagicMock(spec=ChatMessageContent)]
# Mocking two strategies that return True
strategy1 = AsyncMock(spec=TerminationStrategy)
strategy1.should_terminate.return_value = True
strategy2 = AsyncMock(spec=TerminationStrategy)
strategy2.should_terminate.return_value = True
strategy = AggregatorTerminationStrategy(
strategies=[strategy1, strategy2], condition=AggregateTerminationCondition.ALL
)
result = await strategy.should_terminate_async(agent, history)
assert result is True
strategy1.should_terminate.assert_awaited_once()
strategy2.should_terminate.assert_awaited_once()
async def test_aggregate_termination_condition_all_false():
agent = MockAgent(id="test-agent-id")
history = [MagicMock(spec=ChatMessageContent)]
# Mocking two strategies, one returns True, the other False
strategy1 = AsyncMock(spec=TerminationStrategy)
strategy1.should_terminate.return_value = True
strategy2 = AsyncMock(spec=TerminationStrategy)
strategy2.should_terminate.return_value = False
strategy = AggregatorTerminationStrategy(
strategies=[strategy1, strategy2], condition=AggregateTerminationCondition.ALL
)
result = await strategy.should_terminate_async(agent, history)
assert result is False
strategy1.should_terminate.assert_awaited_once()
strategy2.should_terminate.assert_awaited_once()
async def test_aggregate_termination_condition_any_true():
agent = MockAgent(id="test-agent-id")
history = [MagicMock(spec=ChatMessageContent)]
# Mocking two strategies, one returns False, the other True
strategy1 = AsyncMock(spec=TerminationStrategy)
strategy1.should_terminate.return_value = False
strategy2 = AsyncMock(spec=TerminationStrategy)
strategy2.should_terminate.return_value = True
strategy = AggregatorTerminationStrategy(
strategies=[strategy1, strategy2], condition=AggregateTerminationCondition.ANY
)
result = await strategy.should_terminate_async(agent, history)
assert result is True
strategy1.should_terminate.assert_awaited_once()
strategy2.should_terminate.assert_awaited_once()
async def test_aggregate_termination_condition_any_false():
agent = MockAgent(id="test-agent-id")
history = [MagicMock(spec=ChatMessageContent)]
# Mocking two strategies that return False
strategy1 = AsyncMock(spec=TerminationStrategy)
strategy1.should_terminate.return_value = False
strategy2 = AsyncMock(spec=TerminationStrategy)
strategy2.should_terminate.return_value = False
strategy = AggregatorTerminationStrategy(
strategies=[strategy1, strategy2], condition=AggregateTerminationCondition.ANY
)
result = await strategy.should_terminate_async(agent, history)
assert result is False
strategy1.should_terminate.assert_awaited_once()
strategy2.should_terminate.assert_awaited_once()
@@ -0,0 +1,10 @@
# Copyright (c) Microsoft. All rights reserved.
from semantic_kernel.agents.strategies.termination.default_termination_strategy import DefaultTerminationStrategy
async def test_should_agent_terminate_():
strategy = DefaultTerminationStrategy(maximum_iterations=2)
result = await strategy.should_agent_terminate(None, [])
assert not result
@@ -0,0 +1,106 @@
# Copyright (c) Microsoft. All rights reserved.
from unittest.mock import AsyncMock, MagicMock
import pytest
from semantic_kernel.agents.strategies.selection.kernel_function_selection_strategy import (
KernelFunctionSelectionStrategy,
)
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from semantic_kernel.exceptions.agent_exceptions import AgentExecutionException
from semantic_kernel.functions.kernel_function import KernelFunction
from semantic_kernel.kernel import Kernel
from tests.unit.agents.test_agent import MockAgent
@pytest.fixture
def agents():
"""Fixture that provides a list of mock agents."""
return [MockAgent(id=f"agent-{i}", name=f"Agent_{i}") for i in range(3)]
async def test_kernel_function_selection_next_success(agents):
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.return_value = MagicMock(value="Agent_1")
mock_kernel = MagicMock(spec=Kernel)
strategy = KernelFunctionSelectionStrategy(
function=mock_function, kernel=mock_kernel, result_parser=lambda result: result.value
)
selected_agent = await strategy.next(agents, history)
assert selected_agent.name == "Agent_1"
mock_function.invoke.assert_awaited_once()
async def test_kernel_function_selection_next_agent_not_found(agents):
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.return_value = MagicMock(value="Nonexistent-Agent")
mock_kernel = MagicMock(spec=Kernel)
strategy = KernelFunctionSelectionStrategy(
function=mock_function, kernel=mock_kernel, result_parser=lambda result: result.value
)
with pytest.raises(AgentExecutionException) as excinfo:
await strategy.next(agents, history)
assert "Strategy unable to select next agent" in str(excinfo.value)
mock_function.invoke.assert_awaited_once()
async def test_kernel_function_selection_next_result_is_none(agents):
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.return_value = None
mock_kernel = MagicMock(spec=Kernel)
strategy = KernelFunctionSelectionStrategy(
function=mock_function, kernel=mock_kernel, result_parser=lambda result: result.value if result else None
)
with pytest.raises(AgentExecutionException) as excinfo:
await strategy.next(agents, history)
assert "Strategy unable to determine next agent" in str(excinfo.value)
mock_function.invoke.assert_awaited_once()
async def test_kernel_function_selection_next_exception_during_invoke(agents):
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.side_effect = Exception("Test exception")
mock_kernel = MagicMock(spec=Kernel)
strategy = KernelFunctionSelectionStrategy(
function=mock_function, kernel=mock_kernel, result_parser=lambda result: result.value
)
with pytest.raises(AgentExecutionException) as excinfo:
await strategy.next(agents, history)
assert "Strategy failed to execute function" in str(excinfo.value)
mock_function.invoke.assert_awaited_once()
async def test_kernel_function_selection_result_parser_is_async(agents):
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.return_value = MagicMock(value="Agent_2")
mock_kernel = MagicMock(spec=Kernel)
async def async_result_parser(result):
return result.value
strategy = KernelFunctionSelectionStrategy(
function=mock_function, kernel=mock_kernel, result_parser=async_result_parser
)
selected_agent = await strategy.next(agents, history)
assert selected_agent.name == "Agent_2"
mock_function.invoke.assert_awaited_once()
@@ -0,0 +1,114 @@
# Copyright (c) Microsoft. All rights reserved.
from unittest.mock import AsyncMock, MagicMock, patch
from semantic_kernel.agents.strategies import KernelFunctionTerminationStrategy
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from semantic_kernel.functions.kernel_arguments import KernelArguments
from semantic_kernel.functions.kernel_function import KernelFunction
from semantic_kernel.kernel import Kernel
from tests.unit.agents.test_agent import MockAgent
async def test_should_agent_terminate_with_result_true():
agent = MockAgent(id="test-agent-id")
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.return_value = MagicMock(value=True)
mock_kernel = MagicMock(spec=Kernel)
strategy = KernelFunctionTerminationStrategy(
agents=[agent], function=mock_function, kernel=mock_kernel, result_parser=lambda result: result.value
)
result = await strategy.should_agent_terminate(agent, history)
assert result is True
mock_function.invoke.assert_awaited_once()
async def test_should_agent_terminate_with_result_false():
agent = MockAgent(id="test-agent-id")
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.return_value = MagicMock(value=False)
mock_kernel = MagicMock(spec=Kernel)
strategy = KernelFunctionTerminationStrategy(
agents=[agent], function=mock_function, kernel=mock_kernel, result_parser=lambda result: result.value
)
result = await strategy.should_agent_terminate(agent, history)
assert result is False
mock_function.invoke.assert_awaited_once()
async def test_should_agent_terminate_with_none_result():
agent = MockAgent(id="test-agent-id")
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.return_value = None
mock_kernel = MagicMock(spec=Kernel)
strategy = KernelFunctionTerminationStrategy(
agents=[agent],
function=mock_function,
kernel=mock_kernel,
result_parser=lambda result: result.value if result else False,
)
result = await strategy.should_agent_terminate(agent, history)
assert result is False
mock_function.invoke.assert_awaited_once()
async def test_should_agent_terminate_custom_arguments():
agent = MockAgent(id="test-agent-id")
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.return_value = MagicMock(value=True)
mock_kernel = MagicMock(spec=Kernel)
custom_args = KernelArguments(execution_settings={"some_setting": MagicMock(model_dump=lambda: {"key": "value"})})
strategy = KernelFunctionTerminationStrategy(
agents=[agent],
function=mock_function,
kernel=mock_kernel,
arguments=custom_args,
result_parser=lambda result: result.value,
)
with patch.object(KernelArguments, "__init__", return_value=None) as mock_init:
result = await strategy.should_agent_terminate(agent, history)
mock_init.assert_called_once()
assert result is True
mock_function.invoke.assert_awaited_once()
async def test_should_agent_terminate_result_parser_awaitable():
agent = MockAgent(id="test-agent-id")
history = [MagicMock(spec=ChatMessageContent)]
mock_function = AsyncMock(spec=KernelFunction)
mock_function.invoke.return_value = MagicMock(value=True)
mock_kernel = MagicMock(spec=Kernel)
async def mock_result_parser(result):
return result.value
strategy = KernelFunctionTerminationStrategy(
agents=[agent], function=mock_function, kernel=mock_kernel, result_parser=mock_result_parser
)
result = await strategy.should_agent_terminate(agent, history)
assert result is True
mock_function.invoke.assert_awaited_once()
@@ -0,0 +1,108 @@
# Copyright (c) Microsoft. All rights reserved.
from unittest.mock import MagicMock
import pytest
from semantic_kernel.agents.agent import Agent
from semantic_kernel.agents.strategies.selection.sequential_selection_strategy import SequentialSelectionStrategy
from semantic_kernel.exceptions.agent_exceptions import AgentExecutionException
from tests.unit.agents.test_agent import MockAgent
@pytest.fixture
def agents():
"""Fixture that provides a list of mock agents."""
return [MockAgent(id=f"agent-{i}") for i in range(3)]
async def test_sequential_selection_next(agents):
strategy = SequentialSelectionStrategy()
# Test the sequence of selections
selected_agent_1 = await strategy.next(agents, [])
selected_agent_2 = await strategy.next(agents, [])
selected_agent_3 = await strategy.next(agents, [])
assert selected_agent_1.id == "agent-0"
assert selected_agent_2.id == "agent-1"
assert selected_agent_3.id == "agent-2"
async def test_sequential_selection_wraps_around(agents):
strategy = SequentialSelectionStrategy()
for _ in range(3):
await strategy.next(agents, [])
selected_agent = await strategy.next(agents, [])
assert selected_agent.id == "agent-0"
async def test_sequential_selection_reset(agents):
strategy = SequentialSelectionStrategy()
# Move the index to the middle of the list
await strategy.next(agents, [])
await strategy.next(agents, [])
strategy.reset()
selected_agent = await strategy.next(agents, [])
assert selected_agent.id == "agent-0"
async def test_sequential_selection_exceeds_length(agents):
strategy = SequentialSelectionStrategy()
strategy._index = len(agents)
selected_agent = await strategy.next(agents, [])
assert selected_agent.id == "agent-0"
assert strategy._index == 0
selected_agent = await strategy.next(agents, [])
assert selected_agent.id == "agent-1"
assert strategy._index == 1
async def test_sequential_selection_empty_agents():
strategy = SequentialSelectionStrategy()
with pytest.raises(AgentExecutionException) as excinfo:
await strategy.next([], [])
assert "Agent Failure - No agents present to select." in str(excinfo.value)
async def test_sequential_selection_avoid_selecting_same_agent_twice():
# Arrange
agent_0 = MagicMock(spec=Agent)
agent_0.id = "agent-0"
agent_0.name = "Agent0"
agent_0.plugins = []
agent_1 = MagicMock(spec=Agent)
agent_1.id = "agent-1"
agent_1.name = "Agent1"
agent_1.plugins = []
agents = [agent_0, agent_1]
strategy = SequentialSelectionStrategy()
# Simulate that we've already selected an agent once:
strategy.has_selected = True
# Set the initial agent to the first agent
strategy.initial_agent = agent_0
# Ensure the internal index is set to -1
strategy._index = -1
# Act
selected_agent = await strategy.next(agents, [])
# Assert
# According to the condition, we should skip selecting agent_0 again
assert selected_agent.id == "agent-1"
assert strategy._index == 1
@@ -0,0 +1,63 @@
# Copyright (c) Microsoft. All rights reserved.
from unittest.mock import MagicMock
import pytest
from semantic_kernel.agents import Agent
from semantic_kernel.agents.strategies.termination.termination_strategy import TerminationStrategy
from semantic_kernel.contents.chat_message_content import ChatMessageContent
from tests.unit.agents.test_agent import MockAgent
class TerminationStrategyTest(TerminationStrategy):
"""A test implementation of TerminationStrategy for testing purposes."""
async def should_agent_terminate(self, agent: "Agent", history: list[ChatMessageContent]) -> bool:
"""Simple test implementation that always returns True."""
return True
async def test_should_terminate_with_matching_agent():
agent = MockAgent(id="test-agent-id")
strategy = TerminationStrategyTest(agents=[agent])
# Assuming history is a list of ChatMessageContent; can be mocked or made minimal
history = [MagicMock(spec=ChatMessageContent)]
result = await strategy.should_terminate(agent, history)
assert result is True
async def test_should_terminate_with_non_matching_agent():
agent = MockAgent(id="test-agent-id")
non_matching_agent = MockAgent(id="non-matching-agent-id")
strategy = TerminationStrategyTest(agents=[non_matching_agent])
# Assuming history is a list of ChatMessageContent; can be mocked or made minimal
history = [MagicMock(spec=ChatMessageContent)]
result = await strategy.should_terminate(agent, history)
assert result is False
async def test_should_terminate_no_agents_in_strategy():
agent = MockAgent(id="test-agent-id")
strategy = TerminationStrategyTest()
# Assuming history is a list of ChatMessageContent; can be mocked or made minimal
history = [MagicMock(spec=ChatMessageContent)]
result = await strategy.should_terminate(agent, history)
assert result is True
async def test_should_agent_terminate_not_implemented():
agent = MockAgent(id="test-agent-id")
strategy = TerminationStrategy(agents=[agent])
# Assuming history is a list of ChatMessageContent; can be mocked or made minimal
history = [MagicMock(spec=ChatMessageContent)]
with pytest.raises(NotImplementedError):
await strategy.should_agent_terminate(agent, history)