Co-authored-by: Antoine <33425718+anth2o@users.noreply.github.com>
Co-authored-by: Bastien <bastien.baret@gmail.com>
Co-authored-by: Clément Sirieix <clement.sirieix@mistral.ai>
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: Michel Thomazo <51709227+michelTho@users.noreply.github.com>
Co-authored-by: Nelson PROIA <144663685+Nelson-PROIA@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: Robin Gullo <robin.gullo@mistral.ai>
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Clément Drouin 2026-04-28 17:44:07 +02:00 committed by GitHub
parent a83c81ecf5
commit 632ea8c032
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
253 changed files with 13965 additions and 2525 deletions

View file

@ -1,27 +1,39 @@
from __future__ import annotations
import sys
from typing import Any
from rich import print as rprint
from textual.app import App
from vibe.core.paths import GLOBAL_ENV_FILE
from vibe.core.telemetry.types import EntrypointMetadata
from vibe.setup.onboarding.screens import ApiKeyScreen, WelcomeScreen
class OnboardingApp(App[str | None]):
CSS_PATH = "onboarding.tcss"
def __init__(
self, entrypoint_metadata: EntrypointMetadata | None = None, **kwargs: Any
) -> None:
super().__init__(**kwargs)
self._entrypoint_metadata = entrypoint_metadata
def on_mount(self) -> None:
self.theme = "textual-ansi"
self.install_screen(WelcomeScreen(), "welcome")
self.install_screen(ApiKeyScreen(), "api_key")
self.install_screen(
ApiKeyScreen(entrypoint_metadata=self._entrypoint_metadata), "api_key"
)
self.push_screen("welcome")
def run_onboarding(app: App | None = None) -> None:
result = (app or OnboardingApp()).run()
def run_onboarding(
app: App | None = None, *, entrypoint_metadata: EntrypointMetadata | None = None
) -> None:
result = (app or OnboardingApp(entrypoint_metadata=entrypoint_metadata)).run()
match result:
case None:
rprint("\n[yellow]Setup cancelled. See you next time![/]")

View file

@ -188,7 +188,7 @@ class OnboardingContext:
@classmethod
def from_config(cls, config: VibeConfig) -> OnboardingContext:
return cls(provider=config.get_provider_for_model(config.get_active_model()))
return cls(provider=config.get_active_provider())
@classmethod
def load(cls, **overrides: Any) -> OnboardingContext:

View file

@ -16,6 +16,7 @@ from vibe.cli.textual_ui.widgets.no_markup_static import NoMarkupStatic
from vibe.core.config import DEFAULT_PROVIDERS, ProviderConfig, VibeConfig
from vibe.core.paths import GLOBAL_ENV_FILE
from vibe.core.telemetry.send import TelemetryClient
from vibe.core.telemetry.types import EntrypointMetadata
from vibe.core.types import Backend
from vibe.setup.onboarding.base import OnboardingScreen
from vibe.setup.onboarding.context import OnboardingContext
@ -33,7 +34,12 @@ def _save_api_key_to_env_file(env_key: str, api_key: str) -> None:
set_key(GLOBAL_ENV_FILE.path, env_key, api_key)
def persist_api_key(provider: ProviderConfig, api_key: str) -> str:
def persist_api_key(
provider: ProviderConfig,
api_key: str,
*,
entrypoint_metadata: EntrypointMetadata | None = None,
) -> str:
env_key = provider.api_key_env_var
if not env_key:
return "env_var_error:<empty>"
@ -47,7 +53,10 @@ def persist_api_key(provider: ProviderConfig, api_key: str) -> str:
return f"save_error:{err}"
if provider.backend == Backend.MISTRAL:
try:
telemetry = TelemetryClient(config_getter=VibeConfig)
telemetry = TelemetryClient(
config_getter=VibeConfig,
entrypoint_metadata_getter=lambda: entrypoint_metadata,
)
telemetry.send_onboarding_api_key_added()
except Exception:
pass
@ -77,9 +86,15 @@ class ApiKeyScreen(OnboardingScreen):
NEXT_SCREEN = None
def __init__(self, provider: ProviderConfig | None = None) -> None:
def __init__(
self,
provider: ProviderConfig | None = None,
*,
entrypoint_metadata: EntrypointMetadata | None = None,
) -> None:
super().__init__()
self.provider = _resolve_onboarding_provider(provider)
self._entrypoint_metadata = entrypoint_metadata
def _compose_provider_link(self, provider_name: str) -> ComposeResult:
if self.provider.name not in PROVIDER_HELP:
@ -159,7 +174,11 @@ class ApiKeyScreen(OnboardingScreen):
self._save_and_finish(event.value)
def _save_and_finish(self, api_key: str) -> None:
self.app.exit(persist_api_key(self.provider, api_key))
self.app.exit(
persist_api_key(
self.provider, api_key, entrypoint_metadata=self._entrypoint_metadata
)
)
def on_mouse_up(self, event: MouseUp) -> None:
copy_selection_to_clipboard(self.app)