Co-authored-by: Kim-Adeline Miguel <51720070+kimadeline@users.noreply.github.com> Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai> Co-authored-by: Maxime Dolores <maxime.dolores@ext.mistral.ai> Co-authored-by: Nelson PROIA <144663685+Nelson-PROIA@users.noreply.github.com> Co-authored-by: Paul VEZIA <166131032+le-codeur-rapide@users.noreply.github.com> Co-authored-by: Pierre Rossinès <pierre.rossines@mistral.ai> Co-authored-by: Quentin <quentin.torroba@mistral.ai> Co-authored-by: Val <102326092+vdeva@users.noreply.github.com> Co-authored-by: Vincent G <10739306+VinceOPS@users.noreply.github.com> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
191 lines
7.6 KiB
Python
191 lines
7.6 KiB
Python
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from tests.conftest import build_test_vibe_config
|
|
from vibe.core.agents.manager import AgentManager
|
|
from vibe.core.agents.models import BUILTIN_AGENTS, EXPLORE, AgentSafety, AgentType
|
|
|
|
|
|
class TestAgentProfile:
|
|
def test_explore_agent_is_subagent(self) -> None:
|
|
"""Test that EXPLORE agent has SUBAGENT type."""
|
|
assert EXPLORE.agent_type == AgentType.SUBAGENT
|
|
|
|
def test_explore_agent_has_safe_safety(self) -> None:
|
|
"""Test that EXPLORE agent has SAFE safety level."""
|
|
assert EXPLORE.safety == AgentSafety.SAFE
|
|
|
|
def test_explore_agent_has_enabled_tools(self) -> None:
|
|
"""Test that EXPLORE agent has expected enabled tools."""
|
|
enabled_tools = EXPLORE.overrides.get("enabled_tools", [])
|
|
assert "grep" in enabled_tools
|
|
assert "read" in enabled_tools
|
|
|
|
def test_builtin_agents_contains_explore(self) -> None:
|
|
"""Test that BUILTIN_AGENTS includes explore."""
|
|
assert "explore" in BUILTIN_AGENTS
|
|
assert BUILTIN_AGENTS["explore"] is EXPLORE
|
|
|
|
|
|
class TestAgentManager:
|
|
@pytest.fixture
|
|
def manager(self) -> AgentManager:
|
|
config = build_test_vibe_config(
|
|
include_project_context=False, include_prompt_detail=False
|
|
)
|
|
return AgentManager(lambda: config)
|
|
|
|
def test_get_subagents_returns_only_subagents(self, manager: AgentManager) -> None:
|
|
"""Test that only SUBAGENT type agents are returned."""
|
|
subagents = manager.get_subagents()
|
|
|
|
for agent in subagents:
|
|
assert agent.agent_type == AgentType.SUBAGENT
|
|
|
|
def test_get_subagents_includes_explore(self, manager: AgentManager) -> None:
|
|
"""Test that EXPLORE is included in subagents."""
|
|
subagents = manager.get_subagents()
|
|
names = [a.name for a in subagents]
|
|
|
|
assert "explore" in names
|
|
|
|
def test_get_subagents_excludes_agents(self, manager: AgentManager) -> None:
|
|
"""Test that AGENT type agents are not returned."""
|
|
subagents = manager.get_subagents()
|
|
names = [a.name for a in subagents]
|
|
|
|
# These are AGENT type
|
|
assert "default" not in names
|
|
assert "plan" not in names
|
|
assert "auto-approve" not in names
|
|
|
|
def test_get_builtin_agent(self, manager: AgentManager) -> None:
|
|
"""Test getting a builtin agent by name."""
|
|
agent = manager.get_agent("explore")
|
|
|
|
assert agent is EXPLORE
|
|
assert agent.agent_type == AgentType.SUBAGENT
|
|
|
|
def test_get_nonexistent_agent_raises(self, manager: AgentManager) -> None:
|
|
"""Test that getting a nonexistent agent raises ValueError."""
|
|
with pytest.raises(ValueError, match="not found"):
|
|
manager.get_agent("nonexistent-agent")
|
|
|
|
def test_get_default_agent(self, manager: AgentManager) -> None:
|
|
"""Test getting the default agent."""
|
|
agent = manager.get_agent("default")
|
|
|
|
assert agent.name == "default"
|
|
assert agent.agent_type == AgentType.AGENT
|
|
|
|
def test_initial_agent_rejects_subagent(self) -> None:
|
|
"""Test that creating AgentManager with a subagent as initial_agent raises."""
|
|
config = build_test_vibe_config(
|
|
include_project_context=False, include_prompt_detail=False
|
|
)
|
|
with pytest.raises(ValueError, match="cannot be used as the primary agent"):
|
|
AgentManager(lambda: config, initial_agent="explore")
|
|
|
|
def test_initial_agent_accepts_subagent_when_allowed(self) -> None:
|
|
"""Test that allow_subagent=True permits subagent as initial_agent."""
|
|
config = build_test_vibe_config(
|
|
include_project_context=False, include_prompt_detail=False
|
|
)
|
|
manager = AgentManager(
|
|
lambda: config, initial_agent="explore", allow_subagent=True
|
|
)
|
|
assert manager.active_profile.name == "explore"
|
|
|
|
def test_initial_agent_accepts_agent_type(self) -> None:
|
|
"""Test that creating AgentManager with an agent-type agent works."""
|
|
config = build_test_vibe_config(
|
|
include_project_context=False, include_prompt_detail=False
|
|
)
|
|
manager = AgentManager(lambda: config, initial_agent="plan")
|
|
assert manager.active_profile.name == "plan"
|
|
|
|
def test_initial_agent_raises_when_agent_is_disabled(self) -> None:
|
|
config = build_test_vibe_config(
|
|
include_project_context=False,
|
|
include_prompt_detail=False,
|
|
disabled_agents=["plan"],
|
|
)
|
|
with pytest.raises(ValueError, match="disabled_agents") as exc_info:
|
|
AgentManager(lambda: config, initial_agent="plan")
|
|
message = str(exc_info.value)
|
|
assert "default_agent" not in message
|
|
assert message.startswith("Agent 'plan'")
|
|
|
|
def test_explicit_agent_excluded_by_enabled_agents_does_not_blame_default(
|
|
self,
|
|
) -> None:
|
|
config = build_test_vibe_config(
|
|
include_project_context=False,
|
|
include_prompt_detail=False,
|
|
enabled_agents=["default"],
|
|
)
|
|
with pytest.raises(ValueError, match="enabled_agents") as exc_info:
|
|
AgentManager(lambda: config, initial_agent="plan")
|
|
message = str(exc_info.value)
|
|
assert "default_agent" not in message
|
|
assert message.startswith("Agent 'plan'")
|
|
|
|
def test_initial_agent_raises_when_agent_does_not_exist(self) -> None:
|
|
config = build_test_vibe_config(
|
|
include_project_context=False, include_prompt_detail=False
|
|
)
|
|
with pytest.raises(ValueError, match="not found"):
|
|
AgentManager(lambda: config, initial_agent="nonexistent-agent")
|
|
|
|
def test_default_agent_excluded_by_enabled_agents_raises_config_contradiction(
|
|
self,
|
|
) -> None:
|
|
config = build_test_vibe_config(
|
|
include_project_context=False,
|
|
include_prompt_detail=False,
|
|
enabled_agents=["plan"],
|
|
)
|
|
with pytest.raises(ValueError, match="enabled_agents") as exc_info:
|
|
AgentManager(lambda: config)
|
|
message = str(exc_info.value)
|
|
assert "default" in message
|
|
assert "default_agent" in message
|
|
|
|
def test_default_agent_excluded_by_disabled_agents_raises_config_contradiction(
|
|
self,
|
|
) -> None:
|
|
config = build_test_vibe_config(
|
|
include_project_context=False,
|
|
include_prompt_detail=False,
|
|
disabled_agents=["default"],
|
|
)
|
|
with pytest.raises(ValueError, match="disabled_agents") as exc_info:
|
|
AgentManager(lambda: config)
|
|
assert "default_agent" in str(exc_info.value)
|
|
|
|
def test_disabled_agents_ignored_entirely_when_enabled_agents_set(
|
|
self, caplog: pytest.LogCaptureFixture
|
|
) -> None:
|
|
config = build_test_vibe_config(
|
|
include_project_context=False,
|
|
include_prompt_detail=False,
|
|
enabled_agents=["plan"],
|
|
disabled_agents=["plan"],
|
|
)
|
|
with caplog.at_level("WARNING"):
|
|
manager = AgentManager(lambda: config, initial_agent="plan")
|
|
assert manager.active_profile.name == "plan"
|
|
assert caplog.text == ""
|
|
|
|
def test_install_required_agent_reports_install_not_disabled_agents(self) -> None:
|
|
# 'lean' is install_required and enabled but not installed: the message
|
|
# must point to installation, not blame disabled_agents.
|
|
config = build_test_vibe_config(
|
|
include_project_context=False,
|
|
include_prompt_detail=False,
|
|
enabled_agents=["lean"],
|
|
)
|
|
with pytest.raises(ValueError, match="requires installation") as exc_info:
|
|
AgentManager(lambda: config, initial_agent="lean")
|
|
assert "disabled_agents" not in str(exc_info.value)
|