v2.3.0 (#429)
Co-authored-by: Carlo <carloantonio.patti@mistral.ai> Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai> Co-authored-by: Clement Sirieix <clem.sirieix@gmail.com> Co-authored-by: Michel Thomazo <michel.thomazo@mistral.ai> Co-authored-by: Clément Drouin <clement.drouin@mistral.ai> Co-authored-by: Vincent Guilloux <vincent.guilloux@mistral.ai> Co-authored-by: Thomas Kenbeek <thomas.kenbeek@mistral.ai> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
a560a47ce8
commit
5d2e01a6d7
139 changed files with 7152 additions and 1457 deletions
|
|
@ -1,11 +1,54 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from mcp.types import (
|
||||
CreateMessageRequestParams,
|
||||
CreateMessageResult,
|
||||
SamplingMessage,
|
||||
TextContent,
|
||||
)
|
||||
import pytest
|
||||
|
||||
from tests.conftest import build_test_agent_loop
|
||||
from tests.conftest import build_test_agent_loop, build_test_vibe_config
|
||||
from tests.mock.utils import mock_llm_chunk
|
||||
from tests.stubs.fake_backend import FakeBackend
|
||||
from vibe.core.config import VibeConfig
|
||||
from vibe.core.config import Backend, ModelConfig, ProviderConfig, VibeConfig
|
||||
from vibe.core.types import EntrypointMetadata
|
||||
|
||||
|
||||
def _two_model_vibe_config(active_model: str) -> VibeConfig:
|
||||
"""VibeConfig with two models so we can switch active_model."""
|
||||
models = [
|
||||
ModelConfig(
|
||||
name="mistral-vibe-cli-latest", provider="mistral", alias="devstral-latest"
|
||||
),
|
||||
ModelConfig(
|
||||
name="devstral-small-latest", provider="mistral", alias="devstral-small"
|
||||
),
|
||||
]
|
||||
providers = [
|
||||
ProviderConfig(
|
||||
name="mistral",
|
||||
api_base="https://api.mistral.ai/v1",
|
||||
api_key_env_var="MISTRAL_API_KEY",
|
||||
backend=Backend.MISTRAL,
|
||||
)
|
||||
]
|
||||
return build_test_vibe_config(
|
||||
active_model=active_model, models=models, providers=providers
|
||||
)
|
||||
|
||||
|
||||
def _make_sampling_params() -> CreateMessageRequestParams:
|
||||
return CreateMessageRequestParams(
|
||||
messages=[
|
||||
SamplingMessage(role="user", content=TextContent(type="text", text="Hi"))
|
||||
],
|
||||
systemPrompt=None,
|
||||
temperature=None,
|
||||
maxTokens=100,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
|
@ -66,3 +109,79 @@ async def test_updates_tokens_stats_based_on_backend_response_streaming(
|
|||
[_ async for _ in agent.act("Hello")]
|
||||
|
||||
assert agent.stats.context_tokens == 275
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_passes_entrypoint_metadata_to_backend(vibe_config: VibeConfig):
|
||||
metadata = EntrypointMetadata(
|
||||
agent_entrypoint="acp",
|
||||
agent_version="2.0.0",
|
||||
client_name="vibe_ide",
|
||||
client_version="0.5.0",
|
||||
)
|
||||
backend = FakeBackend([mock_llm_chunk(content="Response")])
|
||||
agent = build_test_agent_loop(
|
||||
config=vibe_config,
|
||||
backend=backend,
|
||||
enable_streaming=True,
|
||||
entrypoint_metadata=metadata,
|
||||
)
|
||||
|
||||
[_ 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",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mcp_sampling_handler_uses_updated_backend_when_agent_backend_changes():
|
||||
"""AgentLoop's MCP sampling handler uses current backend when backend is reassigned."""
|
||||
backend1 = FakeBackend([mock_llm_chunk(content="from-backend-1")])
|
||||
backend2 = FakeBackend([mock_llm_chunk(content="from-backend-2")])
|
||||
config = _two_model_vibe_config("devstral-latest")
|
||||
agent = build_test_agent_loop(config=config, backend=backend1)
|
||||
handler = agent._sampling_handler
|
||||
params = _make_sampling_params()
|
||||
context = MagicMock()
|
||||
|
||||
result1 = await handler(context, params)
|
||||
assert isinstance(result1, CreateMessageResult)
|
||||
assert result1.content.type == "text"
|
||||
assert result1.content.text == "from-backend-1"
|
||||
assert len(backend1.requests_messages) == 1
|
||||
assert len(backend2.requests_messages) == 0
|
||||
|
||||
agent.backend = backend2
|
||||
result2 = await handler(context, params)
|
||||
assert isinstance(result2, CreateMessageResult)
|
||||
assert result2.content.type == "text"
|
||||
assert result2.content.text == "from-backend-2"
|
||||
assert len(backend1.requests_messages) == 1
|
||||
assert len(backend2.requests_messages) == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_mcp_sampling_handler_uses_updated_config_when_agent_config_changes():
|
||||
chunk = mock_llm_chunk(content="ok")
|
||||
backend = FakeBackend([chunk])
|
||||
config1 = _two_model_vibe_config("devstral-latest")
|
||||
config2 = _two_model_vibe_config("devstral-small")
|
||||
agent = build_test_agent_loop(config=config1, backend=backend)
|
||||
handler = agent._sampling_handler
|
||||
params = _make_sampling_params()
|
||||
context = MagicMock()
|
||||
|
||||
result1 = await handler(context, params)
|
||||
assert isinstance(result1, CreateMessageResult)
|
||||
assert result1.model == "mistral-vibe-cli-latest"
|
||||
|
||||
agent._base_config = config2
|
||||
agent.agent_manager.invalidate_config()
|
||||
result2 = await handler(context, params)
|
||||
assert isinstance(result2, CreateMessageResult)
|
||||
assert result2.model == "devstral-small-latest"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue