v2.6.0 (#524)
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:
parent
5103019b01
commit
eb580209d4
180 changed files with 11136 additions and 1030 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue