v2.10.0 (#697)
Co-authored-by: Clément Drouin <clement.drouin@mistral.ai> Co-authored-by: Corentin André <corentin.andre@mistral.ai> Co-authored-by: Guillaume LE GOFF <guillaume.lgf@gmail.com> Co-authored-by: Kim-Adeline Miguel <51720070+kimadeline@users.noreply.github.com> 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: Peter Evers <pevers90@gmail.com> Co-authored-by: Pierre Rossinès <pierre.rossines@mistral.ai> Co-authored-by: Quentin <quentin.torroba@mistral.ai> Co-authored-by: Vincent G <10739306+VinceOPS@users.noreply.github.com> Co-authored-by: MichisGitIsKing <MichisGitIsKing@users.noreply.github.com> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
626f905186
commit
228f3c65a9
158 changed files with 7235 additions and 916 deletions
|
|
@ -11,6 +11,7 @@ import httpx
|
|||
from vibe import __version__
|
||||
from vibe.core.config import ProviderConfig, VibeConfig
|
||||
from vibe.core.llm.format import ResolvedToolCall
|
||||
from vibe.core.logger import logger
|
||||
from vibe.core.telemetry.build_metadata import build_base_metadata
|
||||
from vibe.core.telemetry.types import (
|
||||
AgentEntrypoint,
|
||||
|
|
@ -30,6 +31,30 @@ _DEFAULT_TELEMETRY_BASE_URL = "https://api.mistral.ai"
|
|||
_DATALAKE_EVENTS_PATH = "/v1/datalake/events"
|
||||
|
||||
|
||||
def get_mistral_provider_and_api_key(
|
||||
config: VibeConfig,
|
||||
) -> tuple[ProviderConfig, str] | None:
|
||||
"""Resolve a Mistral provider and its API key, or None.
|
||||
|
||||
Prefers the active provider when it is a Mistral provider; otherwise
|
||||
falls back to the first configured Mistral provider. Returns a key
|
||||
only when a Mistral provider is found, to avoid leaking third-party
|
||||
credentials to Mistral-controlled endpoints (telemetry, A/B test
|
||||
evaluation, ...).
|
||||
"""
|
||||
try:
|
||||
provider = config.get_mistral_provider()
|
||||
except Exception:
|
||||
return None
|
||||
if provider is None:
|
||||
return None
|
||||
env_var = provider.api_key_env_var
|
||||
api_key = os.getenv(env_var) if env_var else None
|
||||
if api_key is None:
|
||||
return None
|
||||
return provider, api_key
|
||||
|
||||
|
||||
class TelemetryClient:
|
||||
def __init__(
|
||||
self,
|
||||
|
|
@ -38,11 +63,13 @@ class TelemetryClient:
|
|||
parent_session_id_getter: Callable[[], str | None] | None = None,
|
||||
entrypoint_metadata_getter: Callable[[], EntrypointMetadata | None]
|
||||
| None = None,
|
||||
experiments_getter: Callable[[], dict[str, str]] | None = None,
|
||||
) -> None:
|
||||
self._config_getter = config_getter
|
||||
self._session_id_getter = session_id_getter
|
||||
self._parent_session_id_getter = parent_session_id_getter
|
||||
self._entrypoint_metadata_getter = entrypoint_metadata_getter
|
||||
self._experiments_getter = experiments_getter
|
||||
self._client: httpx.AsyncClient | None = None
|
||||
self._pending_tasks: set[asyncio.Task[Any]] = set()
|
||||
self.last_correlation_id: str | None = None
|
||||
|
|
@ -52,33 +79,13 @@ class TelemetryClient:
|
|||
return urljoin(base.rstrip("/"), _DATALAKE_EVENTS_PATH)
|
||||
|
||||
def _get_mistral_api_key(self) -> str | None:
|
||||
"""Get the API key from the active provider if it's Mistral,
|
||||
otherwise the first Mistral provider.
|
||||
|
||||
Only returns an API key if the provider is a Mistral provider
|
||||
to avoid leaking third-party credentials to the telemetry endpoint.
|
||||
"""
|
||||
provider_and_api_key = self._get_mistral_provider_and_api_key()
|
||||
provider_and_api_key = get_mistral_provider_and_api_key(self._config_getter())
|
||||
if provider_and_api_key is None:
|
||||
return None
|
||||
_, api_key = provider_and_api_key
|
||||
return api_key
|
||||
|
||||
def _get_mistral_provider_and_api_key(self) -> tuple[ProviderConfig, str] | None:
|
||||
try:
|
||||
provider = self._config_getter().get_mistral_provider()
|
||||
except Exception:
|
||||
return None
|
||||
if provider is None:
|
||||
return None
|
||||
env_var = provider.api_key_env_var
|
||||
api_key = os.getenv(env_var) if env_var else None
|
||||
if api_key is None:
|
||||
return None
|
||||
return provider, api_key
|
||||
|
||||
def _is_enabled(self) -> bool:
|
||||
"""Check if telemetry is enabled in the current config."""
|
||||
try:
|
||||
return self._config_getter().enable_telemetry
|
||||
except Exception:
|
||||
|
|
@ -109,7 +116,10 @@ class TelemetryClient:
|
|||
return None
|
||||
return self._parent_session_id_getter()
|
||||
|
||||
def build_client_event_metadata(self) -> dict[str, str]:
|
||||
def build_client_event_metadata(self) -> dict[str, Any]:
|
||||
experiments = (
|
||||
self._experiments_getter() if self._experiments_getter is not None else None
|
||||
)
|
||||
return build_base_metadata(
|
||||
entrypoint_metadata=(
|
||||
self._entrypoint_metadata_getter()
|
||||
|
|
@ -118,6 +128,7 @@ class TelemetryClient:
|
|||
),
|
||||
session_id=self.session_id,
|
||||
parent_session_id=self.parent_session_id,
|
||||
experiments=experiments,
|
||||
)
|
||||
|
||||
def send_telemetry_event(
|
||||
|
|
@ -129,13 +140,19 @@ class TelemetryClient:
|
|||
) -> None:
|
||||
if not self._is_enabled():
|
||||
return
|
||||
provider_and_api_key = self._get_mistral_provider_and_api_key()
|
||||
provider_and_api_key = get_mistral_provider_and_api_key(self._config_getter())
|
||||
if provider_and_api_key is None:
|
||||
return
|
||||
provider, mistral_api_key = provider_and_api_key
|
||||
telemetry_url = self._get_telemetry_url(provider.api_base)
|
||||
user_agent = get_user_agent(provider.backend)
|
||||
properties = self.build_client_event_metadata() | properties
|
||||
logger.debug(
|
||||
"telemetry event=%s properties=%s correlation_id=%s",
|
||||
event_name,
|
||||
properties,
|
||||
correlation_id,
|
||||
)
|
||||
|
||||
payload: dict[str, Any] = {"event": event_name, "properties": properties}
|
||||
if correlation_id:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue