Co-authored-by: Clément Drouin <clement.drouin@mistral.ai>
Co-authored-by: Clément Sirieix <clement.sirieix@mistral.ai>
Co-authored-by: Gauthier Guinet <43207538+Gguinet@users.noreply.github.com>
Co-authored-by: Kim-Adeline Miguel <kimadeline.miguel@mistral.ai>
Co-authored-by: Michel Thomazo <51709227+michelTho@users.noreply.github.com>
Co-authored-by: Quentin <torroba.q@gmail.com>
Co-authored-by: Simon <80467011+sorgfresser@users.noreply.github.com>
Co-authored-by: Simon Van de Kerckhove <simon.vandekerckhove@mistral.ai>
Co-authored-by: Vincent G <10739306+VinceOPS@users.noreply.github.com>
Co-authored-by: angelapopopo <angele.lenglemetz@mistral.ai>
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Mathias Gesbert 2026-03-23 18:45:21 +01:00 committed by GitHub
parent 5103019b01
commit eb580209d4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
180 changed files with 11136 additions and 1030 deletions

View file

@ -10,11 +10,17 @@ from mcp.types import (
)
import pytest
from tests.conftest import build_test_agent_loop, build_test_vibe_config
from tests.conftest import (
build_test_agent_loop,
build_test_vibe_config,
make_test_models,
)
from tests.mock.utils import mock_llm_chunk
from tests.stubs.fake_backend import FakeBackend
from vibe.core.config import Backend, ModelConfig, ProviderConfig, VibeConfig
from vibe.core.types import EntrypointMetadata
from vibe.core.agents.models import BuiltinAgentName
from vibe.core.config import ModelConfig, ProviderConfig, VibeConfig
from vibe.core.tools.base import BaseToolConfig, ToolPermission
from vibe.core.types import Backend, EntrypointMetadata, FunctionCall, ToolCall
def _two_model_vibe_config(active_model: str) -> VibeConfig:
@ -119,7 +125,12 @@ async def test_passes_session_id_to_backend(vibe_config: VibeConfig):
[_ async for _ in agent.act("Hello")]
assert len(backend.requests_metadata) > 0
assert backend.requests_metadata[0] == {"session_id": agent.session_id}
meta = backend.requests_metadata[0]
assert meta is not None
assert meta["session_id"] == agent.session_id
assert "message_id" in meta
assert meta["is_user_prompt"] == "true"
assert meta["call_type"] == "main_call"
@pytest.mark.asyncio
@ -141,13 +152,16 @@ async def test_passes_entrypoint_metadata_to_backend(vibe_config: VibeConfig):
[_ async for _ in agent.act("Hello")]
assert len(backend.requests_metadata) > 0
assert backend.requests_metadata[0] == {
"agent_entrypoint": "acp",
"agent_version": "2.0.0",
"client_name": "vibe_ide",
"client_version": "0.5.0",
"session_id": agent.session_id,
}
meta = backend.requests_metadata[0]
assert meta is not None
assert meta["agent_entrypoint"] == "acp"
assert meta["agent_version"] == "2.0.0"
assert meta["client_name"] == "vibe_ide"
assert meta["client_version"] == "0.5.0"
assert meta["session_id"] == agent.session_id
assert "message_id" in meta
assert meta["is_user_prompt"] == "true"
assert meta["call_type"] == "main_call"
@pytest.mark.asyncio
@ -197,3 +211,108 @@ async def test_mcp_sampling_handler_uses_updated_config_when_agent_config_change
result2 = await handler(context, params)
assert isinstance(result2, CreateMessageResult)
assert result2.model == "devstral-small-latest"
def _generic_provider_vibe_config() -> VibeConfig:
"""VibeConfig with generic backend so no metadata header is sent."""
providers = [
ProviderConfig(
name="mistral",
api_base="https://api.mistral.ai/v1",
api_key_env_var="MISTRAL_API_KEY",
backend=Backend.GENERIC,
)
]
return build_test_vibe_config(providers=providers)
@pytest.mark.asyncio
async def test_mistral_metadata_header_is_user_prompt_per_turn() -> None:
"""First LLM call in a turn has is_user_prompt=True; second call (after tools) has is_user_prompt=False."""
tool_call = ToolCall(
id="call_1",
index=0,
function=FunctionCall(name="todo", arguments='{"action": "read"}'),
)
backend = FakeBackend([
[mock_llm_chunk(content="Checking todos.", tool_calls=[tool_call])],
[mock_llm_chunk(content="Here are your todos.")],
])
config = build_test_vibe_config(
providers=[
ProviderConfig(
name="mistral",
api_base="https://api.mistral.ai/v1",
api_key_env_var="MISTRAL_API_KEY",
backend=Backend.MISTRAL,
)
],
enabled_tools=["todo"],
tools={"todo": BaseToolConfig(permission=ToolPermission.ALWAYS)},
)
agent = build_test_agent_loop(
config=config, backend=backend, agent_name=BuiltinAgentName.AUTO_APPROVE
)
[_ async for _ in agent.act("What's on my todo list?")]
assert len(backend.requests_metadata) == 2
first_metadata = backend.requests_metadata[0]
second_metadata = backend.requests_metadata[1]
assert first_metadata is not None and "is_user_prompt" in first_metadata
assert second_metadata is not None and "is_user_prompt" in second_metadata
assert first_metadata["is_user_prompt"] == "true"
assert second_metadata["is_user_prompt"] == "false"
assert first_metadata["call_type"] == "main_call"
assert second_metadata["call_type"] == "secondary_call"
@pytest.mark.asyncio
async def test_auto_compact_internal_chat_has_is_user_prompt_false_then_user_turn_true() -> (
None
):
"""Compact's internal _chat() sends is_user_prompt=False; the following user turn sends is_user_prompt=True."""
backend = FakeBackend([
[mock_llm_chunk(content="<summary>")],
[mock_llm_chunk(content="<final>")],
])
config = build_test_vibe_config(
models=make_test_models(auto_compact_threshold=1),
providers=[
ProviderConfig(
name="mistral",
api_base="https://api.mistral.ai/v1",
api_key_env_var="MISTRAL_API_KEY",
backend=Backend.MISTRAL,
)
],
)
agent = build_test_agent_loop(config=config, backend=backend)
agent.stats.context_tokens = 2
[_ async for _ in agent.act("Hello")]
assert len(backend.requests_metadata) == 2
compact_metadata = backend.requests_metadata[0]
user_turn_metadata = backend.requests_metadata[1]
assert compact_metadata is not None and "is_user_prompt" in compact_metadata
assert user_turn_metadata is not None and "is_user_prompt" in user_turn_metadata
assert compact_metadata["is_user_prompt"] == "false"
assert user_turn_metadata["is_user_prompt"] == "true"
assert compact_metadata["call_type"] == "secondary_call"
assert user_turn_metadata["call_type"] == "main_call"
@pytest.mark.asyncio
async def test_generic_provider_has_no_metadata_header() -> None:
"""Non-Mistral provider does not send the metadata header."""
backend = FakeBackend([mock_llm_chunk(content="Response")])
config = _generic_provider_vibe_config()
agent = build_test_agent_loop(config=config, backend=backend)
[_ async for _ in agent.act("Hello")]
assert len(backend.requests_extra_headers) == 1
headers = backend.requests_extra_headers[0]
assert headers is not None
assert "metadata" not in headers