v2.9.5 (#676)
Co-authored-by: Clément Drouin <clement.drouin@mistral.ai> Co-authored-by: Kim-Adeline Miguel <51720070+kimadeline@users.noreply.github.com> Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai> Co-authored-by: allansimon-mistral <allan.simon@ext.mistral.ai> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
4972dd5694
commit
b23f49e5f4
74 changed files with 2342 additions and 240 deletions
|
|
@ -133,3 +133,13 @@ class TestCommandRegistry:
|
|||
assert result is not None
|
||||
_, cmd, _ = result
|
||||
assert cmd.handler == "_show_data_retention"
|
||||
|
||||
def test_loop_command_registration(self) -> None:
|
||||
registry = CommandRegistry()
|
||||
assert registry.get_command_name("/loop") == "loop"
|
||||
result = registry.parse_command("/loop 30s ping")
|
||||
assert result is not None
|
||||
cmd_name, cmd, cmd_args = result
|
||||
assert cmd_name == "loop"
|
||||
assert cmd.handler == "_loop_command"
|
||||
assert cmd_args == "30s ping"
|
||||
|
|
|
|||
28
tests/cli/test_compact_message.py
Normal file
28
tests/cli/test_compact_message.py
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from vibe.cli.textual_ui.widgets.compact import CompactMessage
|
||||
from vibe.core.session.session_id import shorten_session_id
|
||||
|
||||
|
||||
class TestCompactMessage:
|
||||
def test_get_content_includes_session_ids_after_compaction(self) -> None:
|
||||
message = CompactMessage()
|
||||
message.post_message = MagicMock()
|
||||
|
||||
message.set_complete(
|
||||
old_tokens=177_017,
|
||||
new_tokens=23_263,
|
||||
old_session_id="11111111-1111-1111-1111-111111111111",
|
||||
new_session_id="22222222-2222-2222-2222-222222222222",
|
||||
)
|
||||
|
||||
assert message.get_content() == (
|
||||
"Compaction complete: 177,017 → 23,263 tokens (-87.%)\n"
|
||||
"session: "
|
||||
f"{shorten_session_id('11111111-1111-1111-1111-111111111111')} "
|
||||
"(before compaction) → "
|
||||
f"{shorten_session_id('22222222-2222-2222-2222-222222222222')} "
|
||||
"(after compaction)"
|
||||
)
|
||||
55
tests/cli/test_initial_agent_name.py
Normal file
55
tests/cli/test_initial_agent_name.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
from vibe.cli.cli import get_initial_agent_name
|
||||
from vibe.core.agents.models import BuiltinAgentName
|
||||
from vibe.core.config import VibeConfig
|
||||
|
||||
|
||||
def _make_args(*, agent: str | None, prompt: str | None) -> argparse.Namespace:
|
||||
return argparse.Namespace(agent=agent, prompt=prompt)
|
||||
|
||||
|
||||
def test_uses_args_agent_when_provided() -> None:
|
||||
config = VibeConfig.model_construct(default_agent=BuiltinAgentName.PLAN)
|
||||
args = _make_args(agent="accept-edits", prompt=None)
|
||||
|
||||
assert get_initial_agent_name(args, config) == "accept-edits"
|
||||
|
||||
|
||||
def test_falls_back_to_config_default_agent_when_args_agent_is_none() -> None:
|
||||
config = VibeConfig.model_construct(default_agent=BuiltinAgentName.PLAN)
|
||||
args = _make_args(agent=None, prompt=None)
|
||||
|
||||
assert get_initial_agent_name(args, config) == BuiltinAgentName.PLAN
|
||||
|
||||
|
||||
def test_defaults_to_default_when_unset_in_config_and_args() -> None:
|
||||
config = VibeConfig.model_construct()
|
||||
args = _make_args(agent=None, prompt=None)
|
||||
|
||||
assert get_initial_agent_name(args, config) == BuiltinAgentName.DEFAULT
|
||||
|
||||
|
||||
def test_programmatic_mode_promotes_default_to_auto_approve() -> None:
|
||||
config = VibeConfig.model_construct(default_agent=BuiltinAgentName.DEFAULT)
|
||||
args = _make_args(agent=None, prompt="hello")
|
||||
|
||||
assert get_initial_agent_name(args, config) == BuiltinAgentName.AUTO_APPROVE
|
||||
|
||||
|
||||
def test_programmatic_mode_ignores_config_default_agent_when_args_agent_is_none() -> (
|
||||
None
|
||||
):
|
||||
config = VibeConfig.model_construct(default_agent=BuiltinAgentName.PLAN)
|
||||
args = _make_args(agent=None, prompt="hello")
|
||||
|
||||
assert get_initial_agent_name(args, config) == BuiltinAgentName.AUTO_APPROVE
|
||||
|
||||
|
||||
def test_programmatic_mode_keeps_explicit_agent_arg() -> None:
|
||||
config = VibeConfig.model_construct(default_agent=BuiltinAgentName.DEFAULT)
|
||||
args = _make_args(agent="accept-edits", prompt="hello")
|
||||
|
||||
assert get_initial_agent_name(args, config) == "accept-edits"
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
|
@ -10,7 +11,7 @@ from tests.conftest import build_test_vibe_app, build_test_vibe_config
|
|||
from vibe.cli.plan_offer.ports.whoami_gateway import WhoAmIPlanType, WhoAmIResponse
|
||||
from vibe.cli.textual_ui.widgets.chat_input import ChatInputContainer
|
||||
from vibe.core.config import ModelConfig, ProviderConfig, VibeConfig
|
||||
from vibe.core.types import Backend
|
||||
from vibe.core.types import Backend, LLMMessage, Role
|
||||
|
||||
|
||||
def _chat_plan_gateway(*, prompt_switching_to_pro_plan: bool) -> FakeWhoAmIGateway:
|
||||
|
|
@ -36,6 +37,16 @@ async def _wait_until(pause, predicate, timeout: float = 2.0) -> None:
|
|||
raise AssertionError("Condition was not met within the timeout")
|
||||
|
||||
|
||||
def _teleport_failed_events(
|
||||
telemetry_events: list[dict[str, Any]],
|
||||
) -> list[dict[str, Any]]:
|
||||
return [
|
||||
event
|
||||
for event in telemetry_events
|
||||
if event["event_name"] == "vibe.teleport_failed"
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_teleport_command_visible_for_paid_chat_users() -> None:
|
||||
app = build_test_vibe_app(
|
||||
|
|
@ -56,6 +67,81 @@ async def test_teleport_command_visible_for_paid_chat_users() -> None:
|
|||
assert "&" in input_widget.mode_characters
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_teleport_command_without_history_sends_early_failure_telemetry(
|
||||
telemetry_events: list[dict[str, Any]],
|
||||
) -> None:
|
||||
app = build_test_vibe_app(
|
||||
config=_vibe_code_enabled_config(),
|
||||
plan_offer_gateway=_chat_plan_gateway(prompt_switching_to_pro_plan=False),
|
||||
)
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
await _wait_until(
|
||||
pilot.pause,
|
||||
lambda: app.commands.get_command_name("/teleport") == "teleport",
|
||||
)
|
||||
|
||||
await app.on_chat_input_container_submitted(
|
||||
ChatInputContainer.Submitted("/teleport")
|
||||
)
|
||||
|
||||
assert _teleport_failed_events(telemetry_events) == [
|
||||
{
|
||||
"event_name": "vibe.teleport_failed",
|
||||
"properties": {
|
||||
"stage": "no_history",
|
||||
"error_class": "TeleportNoHistoryError",
|
||||
"push_required": False,
|
||||
"github_auth_required": False,
|
||||
"nb_session_messages": 0,
|
||||
"session_id": app.agent_loop.session_id,
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_teleport_command_in_remote_session_sends_early_failure_telemetry(
|
||||
telemetry_events: list[dict[str, Any]],
|
||||
) -> None:
|
||||
app = build_test_vibe_app(
|
||||
config=_vibe_code_enabled_config(),
|
||||
plan_offer_gateway=_chat_plan_gateway(prompt_switching_to_pro_plan=False),
|
||||
)
|
||||
app.agent_loop.messages.append(LLMMessage(role=Role.user, content="hello"))
|
||||
app.agent_loop.messages.append(LLMMessage(role=Role.assistant, content="hi"))
|
||||
|
||||
async with app.run_test() as pilot:
|
||||
await _wait_until(
|
||||
pilot.pause,
|
||||
lambda: app.commands.get_command_name("/teleport") == "teleport",
|
||||
)
|
||||
|
||||
await app._remote_manager.attach(session_id="remote-session", config=app.config)
|
||||
await app.on_chat_input_container_submitted(
|
||||
ChatInputContainer.Submitted("/teleport")
|
||||
)
|
||||
await _wait_until(
|
||||
pilot.pause, lambda: len(_teleport_failed_events(telemetry_events)) == 1
|
||||
)
|
||||
await app._remote_manager.detach()
|
||||
|
||||
assert _teleport_failed_events(telemetry_events) == [
|
||||
{
|
||||
"event_name": "vibe.teleport_failed",
|
||||
"properties": {
|
||||
"stage": "remote_session",
|
||||
"error_class": "TeleportRemoteSessionError",
|
||||
"push_required": False,
|
||||
"github_auth_required": False,
|
||||
"nb_session_messages": 2,
|
||||
"session_id": app.agent_loop.session_id,
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_teleport_command_hidden_when_current_key_is_not_eligible() -> None:
|
||||
app = build_test_vibe_app(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue