v2.11.0 (#717)
Co-authored-by: Clément Drouin <clement.drouin@mistral.ai> Co-authored-by: Clément Sirieix <clement.sirieix@mistral.ai> Co-authored-by: Guillaume LE GOFF <guillaume.lgf@gmail.com> Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai> Co-authored-by: Michel Thomazo <51709227+michelTho@users.noreply.github.com> Co-authored-by: Pierre Rossinès <pierre.rossines@mistral.ai> Co-authored-by: Vincent G <10739306+VinceOPS@users.noreply.github.com> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
f71bfd3b8c
commit
adb1ca74ce
202 changed files with 5828 additions and 1968 deletions
|
|
@ -6,16 +6,17 @@ from vibe.cli.textual_ui.widgets.banner.banner import Banner, BannerState, _plur
|
|||
from vibe.core.config import VibeConfig
|
||||
from vibe.core.config._settings import ModelConfig, ThinkingLevel
|
||||
from vibe.core.skills.manager import SkillManager
|
||||
from vibe.core.tools.mcp.registry import MCPRegistry
|
||||
|
||||
|
||||
def _make_mock_config(
|
||||
active_model: str = "test-model", thinking: ThinkingLevel = "off"
|
||||
active_model: str = "test-model",
|
||||
thinking: ThinkingLevel = "off",
|
||||
mcp_servers: list | None = None,
|
||||
) -> Mock:
|
||||
config = Mock(spec=VibeConfig)
|
||||
config.active_model = active_model
|
||||
config.models = [active_model]
|
||||
config.mcp_servers = []
|
||||
config.mcp_servers = mcp_servers or []
|
||||
config.connectors = []
|
||||
config.disable_welcome_banner_animation = False
|
||||
config.get_active_model.return_value = ModelConfig(
|
||||
|
|
@ -40,48 +41,38 @@ class TestBannerInitialState:
|
|||
skill_manager = Mock(spec=SkillManager)
|
||||
skill_manager.custom_skills_count = 0
|
||||
|
||||
mcp_registry = Mock(spec=MCPRegistry)
|
||||
mcp_registry.count_loaded.return_value = 0
|
||||
|
||||
banner = Banner(
|
||||
config=_make_mock_config(),
|
||||
skill_manager=skill_manager,
|
||||
mcp_registry=mcp_registry,
|
||||
connectors_count=5,
|
||||
connectors_enabled=5,
|
||||
connectors_total=5,
|
||||
)
|
||||
|
||||
assert banner._initial_state.active_model == "test-model[off]"
|
||||
assert banner._initial_state.models_count == 1
|
||||
assert banner._initial_state.mcp_servers_count == 0
|
||||
assert banner._initial_state.connectors_count == 5
|
||||
assert (
|
||||
banner._initial_state.mcp_servers_enabled == 0
|
||||
) # No MCP servers configured
|
||||
assert banner._initial_state.mcp_servers_total == 0
|
||||
assert banner._initial_state.connectors_enabled == 5
|
||||
assert banner._initial_state.connectors_total == 5
|
||||
assert banner._initial_state.skills_count == 0
|
||||
|
||||
def test_banner_initial_state_with_no_connectors(self) -> None:
|
||||
skill_manager = Mock(spec=SkillManager)
|
||||
skill_manager.custom_skills_count = 0
|
||||
|
||||
mcp_registry = Mock(spec=MCPRegistry)
|
||||
mcp_registry.count_loaded.return_value = 0
|
||||
banner = Banner(config=_make_mock_config(), skill_manager=skill_manager)
|
||||
|
||||
banner = Banner(
|
||||
config=_make_mock_config(),
|
||||
skill_manager=skill_manager,
|
||||
mcp_registry=mcp_registry,
|
||||
)
|
||||
|
||||
assert banner._initial_state.connectors_count == 0
|
||||
assert banner._initial_state.connectors_enabled == 0
|
||||
assert banner._initial_state.connectors_total == 0
|
||||
|
||||
def test_banner_shows_thinking_level(self) -> None:
|
||||
skill_manager = Mock(spec=SkillManager)
|
||||
skill_manager.custom_skills_count = 0
|
||||
|
||||
mcp_registry = Mock(spec=MCPRegistry)
|
||||
mcp_registry.count_loaded.return_value = 0
|
||||
|
||||
banner = Banner(
|
||||
config=_make_mock_config(thinking="max"),
|
||||
skill_manager=skill_manager,
|
||||
mcp_registry=mcp_registry,
|
||||
config=_make_mock_config(thinking="max"), skill_manager=skill_manager
|
||||
)
|
||||
|
||||
assert banner._initial_state.active_model == "test-model[max]"
|
||||
|
|
@ -90,49 +81,150 @@ class TestBannerInitialState:
|
|||
skill_manager = Mock(spec=SkillManager)
|
||||
skill_manager.custom_skills_count = 0
|
||||
|
||||
mcp_registry = Mock(spec=MCPRegistry)
|
||||
mcp_registry.count_loaded.return_value = 0
|
||||
banner = Banner(config=_make_mock_config(), skill_manager=skill_manager)
|
||||
|
||||
banner = Banner(
|
||||
config=_make_mock_config(),
|
||||
skill_manager=skill_manager,
|
||||
mcp_registry=mcp_registry,
|
||||
)
|
||||
|
||||
# Now test _format_meta_counts by setting state
|
||||
# Now test _format_meta_counts by setting state with x/y format
|
||||
banner.state = BannerState(
|
||||
models_count=2, mcp_servers_count=1, connectors_count=3, skills_count=5
|
||||
models_count=2,
|
||||
mcp_servers_enabled=1,
|
||||
mcp_servers_total=2,
|
||||
connectors_enabled=3,
|
||||
connectors_total=3,
|
||||
skills_count=5,
|
||||
)
|
||||
result = banner._format_meta_counts()
|
||||
assert "2 models" in result
|
||||
assert "3 connectors" in result
|
||||
assert "1 MCP server" in result
|
||||
assert "3 connectors" in result # When enabled == total, just show count
|
||||
assert "1/2 MCP servers" in result
|
||||
assert "5 skills" in result
|
||||
|
||||
# Test without connectors
|
||||
banner.state = BannerState(
|
||||
models_count=2, mcp_servers_count=1, connectors_count=0, skills_count=5
|
||||
models_count=2,
|
||||
mcp_servers_enabled=1,
|
||||
mcp_servers_total=2,
|
||||
connectors_enabled=0,
|
||||
connectors_total=0,
|
||||
skills_count=5,
|
||||
)
|
||||
result = banner._format_meta_counts()
|
||||
assert "2 models" in result
|
||||
assert "connectors" not in result # Should not appear when 0
|
||||
assert "1 MCP server" in result
|
||||
assert "1/2 MCP servers" in result
|
||||
assert "5 skills" in result
|
||||
|
||||
|
||||
class TestBannerMCPServersCount:
|
||||
"""Test that banner correctly counts MCP servers regardless of tool discovery."""
|
||||
|
||||
def test_banner_counts_enabled_mcp_servers(self) -> None:
|
||||
"""Test that banner counts all enabled MCP servers, not just those with tools."""
|
||||
from vibe.core.config import MCPServer
|
||||
|
||||
# Create mock MCP servers - even if they have no tools, they should be counted
|
||||
mock_server1 = Mock(spec=MCPServer)
|
||||
mock_server1.name = "server1"
|
||||
mock_server1.disabled = False
|
||||
|
||||
mock_server2 = Mock(spec=MCPServer)
|
||||
mock_server2.name = "server2"
|
||||
mock_server2.disabled = False
|
||||
|
||||
# Create a disabled server that should NOT be counted
|
||||
mock_server3 = Mock(spec=MCPServer)
|
||||
mock_server3.name = "server3"
|
||||
mock_server3.disabled = True
|
||||
|
||||
skill_manager = Mock(spec=SkillManager)
|
||||
skill_manager.custom_skills_count = 0
|
||||
|
||||
# Note: we don't need to mock count_loaded anymore since it's not used
|
||||
|
||||
banner = Banner(
|
||||
config=_make_mock_config(
|
||||
mcp_servers=[mock_server1, mock_server2, mock_server3]
|
||||
),
|
||||
skill_manager=skill_manager,
|
||||
)
|
||||
|
||||
# Should count only enabled servers (server1 and server2, not server3)
|
||||
assert banner._initial_state.mcp_servers_enabled == 2
|
||||
assert banner._initial_state.mcp_servers_total == 3
|
||||
|
||||
def test_banner_shows_zero_mcp_servers(self) -> None:
|
||||
"""Test that banner correctly shows 0 when no MCP servers are configured."""
|
||||
skill_manager = Mock(spec=SkillManager)
|
||||
skill_manager.custom_skills_count = 0
|
||||
|
||||
banner = Banner(
|
||||
config=_make_mock_config(mcp_servers=[]), skill_manager=skill_manager
|
||||
)
|
||||
|
||||
assert banner._initial_state.mcp_servers_enabled == 0
|
||||
assert banner._initial_state.mcp_servers_total == 0
|
||||
|
||||
def test_banner_shows_disabled_count_in_xy_format(self) -> None:
|
||||
"""Test that banner shows x/y format with disabled servers."""
|
||||
from vibe.core.config import MCPServer
|
||||
|
||||
skill_manager = Mock(spec=SkillManager)
|
||||
skill_manager.custom_skills_count = 0
|
||||
|
||||
banner = Banner(
|
||||
config=_make_mock_config(
|
||||
mcp_servers=[
|
||||
Mock(spec=MCPServer, name="s1", disabled=False),
|
||||
Mock(spec=MCPServer, name="s2", disabled=False),
|
||||
Mock(spec=MCPServer, name="s3", disabled=True),
|
||||
]
|
||||
),
|
||||
skill_manager=skill_manager,
|
||||
)
|
||||
|
||||
assert banner._initial_state.mcp_servers_enabled == 2
|
||||
assert banner._initial_state.mcp_servers_total == 3
|
||||
# Test the formatted output using the initial state
|
||||
banner.state = banner._initial_state
|
||||
result = banner._format_meta_counts()
|
||||
assert "2/3 MCP servers" in result
|
||||
|
||||
def test_banner_shows_simple_count_when_all_enabled(self) -> None:
|
||||
"""Test that banner shows simple count when all MCP servers are enabled."""
|
||||
from vibe.core.config import MCPServer
|
||||
|
||||
skill_manager = Mock(spec=SkillManager)
|
||||
skill_manager.custom_skills_count = 0
|
||||
|
||||
banner = Banner(
|
||||
config=_make_mock_config(
|
||||
mcp_servers=[
|
||||
Mock(spec=MCPServer, name="s1", disabled=False),
|
||||
Mock(spec=MCPServer, name="s2", disabled=False),
|
||||
]
|
||||
),
|
||||
skill_manager=skill_manager,
|
||||
)
|
||||
|
||||
assert banner._initial_state.mcp_servers_enabled == 2
|
||||
assert banner._initial_state.mcp_servers_total == 2
|
||||
banner.state = banner._initial_state
|
||||
result = banner._format_meta_counts()
|
||||
# When all are enabled, show simple count not x/y
|
||||
assert "2 MCP servers" in result
|
||||
assert "/" not in result # No slash when all enabled
|
||||
|
||||
|
||||
class TestBannerConnectorsCount:
|
||||
def test_connectors_count_passed_through(self) -> None:
|
||||
skill_manager = Mock(spec=SkillManager)
|
||||
skill_manager.custom_skills_count = 0
|
||||
|
||||
mcp_registry = Mock(spec=MCPRegistry)
|
||||
mcp_registry.count_loaded.return_value = 0
|
||||
|
||||
banner = Banner(
|
||||
config=_make_mock_config(),
|
||||
skill_manager=skill_manager,
|
||||
mcp_registry=mcp_registry,
|
||||
connectors_count=5,
|
||||
connectors_enabled=3,
|
||||
connectors_total=5,
|
||||
)
|
||||
|
||||
assert banner._initial_state.connectors_count == 5
|
||||
assert banner._initial_state.connectors_enabled == 3
|
||||
assert banner._initial_state.connectors_total == 5
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue