v2.15.0 (#773)
Co-authored-by: Kim-Adeline Miguel <51720070+kimadeline@users.noreply.github.com> Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai> Co-authored-by: Maxime Dolores <maxime.dolores@ext.mistral.ai> Co-authored-by: Nelson PROIA <144663685+Nelson-PROIA@users.noreply.github.com> Co-authored-by: Paul VEZIA <166131032+le-codeur-rapide@users.noreply.github.com> Co-authored-by: Pierre Rossinès <pierre.rossines@mistral.ai> Co-authored-by: Quentin <quentin.torroba@mistral.ai> Co-authored-by: Val <102326092+vdeva@users.noreply.github.com> 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
702d0f412e
commit
cafb6d4147
247 changed files with 12401 additions and 3029 deletions
|
|
@ -1,9 +1,11 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
from pydantic import BaseModel
|
||||
import pytest
|
||||
|
||||
from tests.conftest import build_test_vibe_config
|
||||
|
|
@ -14,7 +16,7 @@ from vibe.core.telemetry.build_metadata import (
|
|||
build_base_metadata,
|
||||
build_request_metadata,
|
||||
)
|
||||
from vibe.core.telemetry.send import TelemetryClient
|
||||
from vibe.core.telemetry.send import TelemetryClient, _extract_file_extension
|
||||
from vibe.core.telemetry.types import (
|
||||
AttachmentKind,
|
||||
EntrypointMetadata,
|
||||
|
|
@ -25,18 +27,35 @@ from vibe.core.types import Backend
|
|||
from vibe.core.utils import get_user_agent
|
||||
|
||||
_original_send_telemetry_event = TelemetryClient.send_telemetry_event
|
||||
from vibe.core.tools.builtins.edit import Edit, EditArgs
|
||||
from vibe.core.tools.builtins.read import Read, ReadArgs
|
||||
from vibe.core.tools.builtins.write_file import WriteFile, WriteFileArgs
|
||||
|
||||
|
||||
def _make_resolved_tool_call(
|
||||
tool_name: str, args_dict: dict[str, Any]
|
||||
) -> ResolvedToolCall:
|
||||
if tool_name == "write_file":
|
||||
validated = WriteFileArgs(path="foo.txt", content="x")
|
||||
cls: type[BaseTool] = WriteFile
|
||||
else:
|
||||
validated = FakeToolArgs()
|
||||
cls = FakeTool
|
||||
validated: BaseModel
|
||||
cls: type[BaseTool]
|
||||
match tool_name:
|
||||
case "write_file":
|
||||
validated = WriteFileArgs(
|
||||
path=args_dict.get("path", "foo.txt"), content="x"
|
||||
)
|
||||
cls = WriteFile
|
||||
case "edit":
|
||||
validated = EditArgs(
|
||||
file_path=args_dict.get("file_path", "foo.txt"),
|
||||
old_string="a",
|
||||
new_string="b",
|
||||
)
|
||||
cls = Edit
|
||||
case "read":
|
||||
validated = ReadArgs(file_path=args_dict.get("file_path", "foo.txt"))
|
||||
cls = Read
|
||||
case _:
|
||||
validated = FakeToolArgs()
|
||||
cls = FakeTool
|
||||
return ResolvedToolCall(
|
||||
tool_name=tool_name, tool_class=cls, validated_args=validated, call_id="call_1"
|
||||
)
|
||||
|
|
@ -50,6 +69,37 @@ def _run_telemetry_tasks() -> None:
|
|||
loop.close()
|
||||
|
||||
|
||||
class TestExtractFileExtension:
|
||||
@pytest.mark.parametrize(
|
||||
("path", "expected"),
|
||||
[
|
||||
("/tmp/foo.py", ".py"),
|
||||
("foo.TSX", ".tsx"),
|
||||
("/tmp/Makefile", None),
|
||||
("/tmp/.bashrc", None),
|
||||
("archive.tar.gz", ".gz"),
|
||||
("", None),
|
||||
],
|
||||
)
|
||||
def test_string_inputs(self, path: str, expected: str | None) -> None:
|
||||
assert _extract_file_extension(path) == expected
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("path", "expected"),
|
||||
[
|
||||
(Path("/tmp/foo.py"), ".py"),
|
||||
(Path("foo.TSX"), ".tsx"),
|
||||
(Path("/tmp/Makefile"), None),
|
||||
],
|
||||
)
|
||||
def test_path_inputs(self, path: Path, expected: str | None) -> None:
|
||||
assert _extract_file_extension(path) == expected
|
||||
|
||||
@pytest.mark.parametrize("path", [None, 42, ["foo.py"], {"path": "foo.py"}])
|
||||
def test_non_path_like_inputs_return_none(self, path: object) -> None:
|
||||
assert _extract_file_extension(path) is None
|
||||
|
||||
|
||||
class TestTelemetryClient:
|
||||
def test_send_telemetry_event_swallows_config_getter_value_error(self) -> None:
|
||||
def _raise_config_error() -> Any:
|
||||
|
|
@ -151,6 +201,7 @@ class TestTelemetryClient:
|
|||
assert properties["model"] == "mistral-large"
|
||||
assert properties["nb_files_created"] == 0
|
||||
assert properties["nb_files_modified"] == 0
|
||||
assert properties["file_extension"] is None
|
||||
assert properties["message_id"] is None
|
||||
|
||||
def test_send_tool_call_finished_with_message_id(
|
||||
|
|
@ -176,7 +227,7 @@ class TestTelemetryClient:
|
|||
) -> None:
|
||||
config = build_test_vibe_config(enable_telemetry=True)
|
||||
client = TelemetryClient(config_getter=lambda: config)
|
||||
tool_call = _make_resolved_tool_call("write_file", {})
|
||||
tool_call = _make_resolved_tool_call("write_file", {"path": "/tmp/foo.PY"})
|
||||
|
||||
client.send_tool_call_finished(
|
||||
tool_call=tool_call,
|
||||
|
|
@ -189,6 +240,86 @@ class TestTelemetryClient:
|
|||
|
||||
assert telemetry_events[0]["properties"]["nb_files_created"] == 1
|
||||
assert telemetry_events[0]["properties"]["nb_files_modified"] == 0
|
||||
assert telemetry_events[0]["properties"]["file_extension"] == ".py"
|
||||
|
||||
def test_send_tool_call_finished_file_extension_edit(
|
||||
self, telemetry_events: list[dict[str, Any]]
|
||||
) -> None:
|
||||
config = build_test_vibe_config(enable_telemetry=True)
|
||||
client = TelemetryClient(config_getter=lambda: config)
|
||||
tool_call = _make_resolved_tool_call(
|
||||
"edit", {"file_path": "/tmp/component.tsx"}
|
||||
)
|
||||
|
||||
client.send_tool_call_finished(
|
||||
tool_call=tool_call,
|
||||
status="success",
|
||||
decision=None,
|
||||
agent_profile_name="default",
|
||||
model="mistral-large",
|
||||
result={},
|
||||
)
|
||||
|
||||
assert telemetry_events[0]["properties"]["nb_files_modified"] == 1
|
||||
assert telemetry_events[0]["properties"]["nb_files_created"] == 0
|
||||
assert telemetry_events[0]["properties"]["file_extension"] == ".tsx"
|
||||
|
||||
def test_send_tool_call_finished_file_extension_read(
|
||||
self, telemetry_events: list[dict[str, Any]]
|
||||
) -> None:
|
||||
config = build_test_vibe_config(enable_telemetry=True)
|
||||
client = TelemetryClient(config_getter=lambda: config)
|
||||
tool_call = _make_resolved_tool_call("read", {"file_path": "/tmp/lib.rs"})
|
||||
|
||||
client.send_tool_call_finished(
|
||||
tool_call=tool_call,
|
||||
status="success",
|
||||
decision=None,
|
||||
agent_profile_name="default",
|
||||
model="mistral-large",
|
||||
result={},
|
||||
)
|
||||
|
||||
assert telemetry_events[0]["properties"]["nb_files_created"] == 0
|
||||
assert telemetry_events[0]["properties"]["nb_files_modified"] == 0
|
||||
assert telemetry_events[0]["properties"]["file_extension"] == ".rs"
|
||||
|
||||
def test_send_tool_call_finished_file_extension_none_when_no_suffix(
|
||||
self, telemetry_events: list[dict[str, Any]]
|
||||
) -> None:
|
||||
config = build_test_vibe_config(enable_telemetry=True)
|
||||
client = TelemetryClient(config_getter=lambda: config)
|
||||
tool_call = _make_resolved_tool_call("write_file", {"path": "/tmp/Makefile"})
|
||||
|
||||
client.send_tool_call_finished(
|
||||
tool_call=tool_call,
|
||||
status="success",
|
||||
decision=None,
|
||||
agent_profile_name="default",
|
||||
model="mistral-large",
|
||||
result={},
|
||||
)
|
||||
|
||||
assert telemetry_events[0]["properties"]["file_extension"] is None
|
||||
|
||||
def test_send_tool_call_finished_file_extension_none_on_failure(
|
||||
self, telemetry_events: list[dict[str, Any]]
|
||||
) -> None:
|
||||
config = build_test_vibe_config(enable_telemetry=True)
|
||||
client = TelemetryClient(config_getter=lambda: config)
|
||||
tool_call = _make_resolved_tool_call("write_file", {"path": "/tmp/foo.py"})
|
||||
|
||||
client.send_tool_call_finished(
|
||||
tool_call=tool_call,
|
||||
status="failure",
|
||||
decision=None,
|
||||
agent_profile_name="default",
|
||||
model="mistral-large",
|
||||
result={},
|
||||
)
|
||||
|
||||
assert telemetry_events[0]["properties"]["nb_files_created"] == 0
|
||||
assert telemetry_events[0]["properties"]["file_extension"] is None
|
||||
|
||||
def test_send_tool_call_finished_decision_none(
|
||||
self, telemetry_events: list[dict[str, Any]]
|
||||
|
|
@ -378,6 +509,40 @@ class TestTelemetryClient:
|
|||
"nb_session_messages": 4,
|
||||
}
|
||||
|
||||
def test_send_remote_resume_requested_payload(
|
||||
self, telemetry_events: list[dict[str, Any]]
|
||||
) -> None:
|
||||
config = build_test_vibe_config(enable_telemetry=True)
|
||||
client = TelemetryClient(config_getter=lambda: config)
|
||||
client.send_remote_resume_requested(session_id="remote-123")
|
||||
assert len(telemetry_events) == 1
|
||||
assert telemetry_events[0]["event_name"] == "vibe.remote_resume_requested"
|
||||
assert telemetry_events[0]["properties"] == {"session_id": "remote-123"}
|
||||
|
||||
def test_send_teleport_failed_payload_includes_error_details(
|
||||
self, telemetry_events: list[dict[str, Any]]
|
||||
) -> None:
|
||||
config = build_test_vibe_config(enable_telemetry=True)
|
||||
client = TelemetryClient(config_getter=lambda: config)
|
||||
|
||||
client.send_teleport_failed(
|
||||
stage="workflow_start",
|
||||
error_class="ServiceTeleportError",
|
||||
push_required=False,
|
||||
nb_session_messages=4,
|
||||
error_details={"failure_kind": "http_error", "http_status_code": 502},
|
||||
)
|
||||
|
||||
assert telemetry_events[0]["event_name"] == "vibe.teleport_failed"
|
||||
assert telemetry_events[0]["properties"] == {
|
||||
"stage": "workflow_start",
|
||||
"error_class": "ServiceTeleportError",
|
||||
"push_required": False,
|
||||
"nb_session_messages": 4,
|
||||
"failure_kind": "http_error",
|
||||
"http_status_code": 502,
|
||||
}
|
||||
|
||||
def test_send_new_session_payload(
|
||||
self, telemetry_events: list[dict[str, Any]]
|
||||
) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue