mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-07-01 13:18:10 +00:00
feat(cli): track TUI button telemetry
This commit is contained in:
@@ -10,6 +10,7 @@ import threading
|
||||
import time
|
||||
from typing import Any, ClassVar, cast
|
||||
|
||||
from crewai_core.telemetry import Telemetry
|
||||
from rich.text import Text
|
||||
from textual import work
|
||||
from textual.app import App, ComposeResult
|
||||
@@ -571,6 +572,7 @@ FooterKey .footer-key--key {
|
||||
self._want_deploy: bool = False
|
||||
self._trace_url: str | None = None
|
||||
self._consent_screen: TraceConsentScreen | None = None
|
||||
self._telemetry: Telemetry | None = None
|
||||
|
||||
# ── Layout ──────────────────────────────────────────────
|
||||
|
||||
@@ -1042,10 +1044,21 @@ FooterKey .footer-key--key {
|
||||
self._unsubscribe()
|
||||
self.exit(self._crew_result)
|
||||
|
||||
def _record_tui_button_click(self, button_name: str) -> None:
|
||||
try:
|
||||
if self._telemetry is None:
|
||||
self._telemetry = Telemetry()
|
||||
self._telemetry.set_tracer()
|
||||
self._telemetry.tui_button_clicked_span(button_name)
|
||||
except Exception: # noqa: S110
|
||||
pass
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
if event.button.id in ("btn-traces", "btn-traces-done"):
|
||||
self._record_tui_button_click("view_traces")
|
||||
self.action_view_traces()
|
||||
elif event.button.id == "btn-deploy":
|
||||
self._record_tui_button_click("deploy")
|
||||
self.action_deploy_crew()
|
||||
|
||||
def _scroll_to_result(self) -> None:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
from datetime import datetime
|
||||
import time
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -126,6 +128,37 @@ def test_chain_deploy_does_not_login_for_deploy_exit(monkeypatch, capsys) -> Non
|
||||
assert "Deploy failed with exit code 42" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_view_traces_button_click_records_telemetry(monkeypatch) -> None:
|
||||
app = CrewRunApp()
|
||||
app._status = "completed"
|
||||
app._trace_url = "https://app.crewai.com/traces/test"
|
||||
app._telemetry = Mock()
|
||||
opened_urls: list[str] = []
|
||||
|
||||
monkeypatch.setattr("webbrowser.open", lambda url: opened_urls.append(url))
|
||||
|
||||
app.on_button_pressed(SimpleNamespace(button=SimpleNamespace(id="btn-traces")))
|
||||
|
||||
app._telemetry.tui_button_clicked_span.assert_called_once_with("view_traces")
|
||||
assert opened_urls == ["https://app.crewai.com/traces/test"]
|
||||
|
||||
|
||||
def test_deploy_button_click_records_telemetry() -> None:
|
||||
app = CrewRunApp()
|
||||
app._status = "completed"
|
||||
app._crew_result = object()
|
||||
app._telemetry = Mock()
|
||||
app._unsubscribe = lambda: None # type: ignore[method-assign]
|
||||
exits: list[object] = []
|
||||
app.exit = lambda result: exits.append(result) # type: ignore[method-assign]
|
||||
|
||||
app.on_button_pressed(SimpleNamespace(button=SimpleNamespace(id="btn-deploy")))
|
||||
|
||||
app._telemetry.tui_button_clicked_span.assert_called_once_with("deploy")
|
||||
assert app._want_deploy is True
|
||||
assert exits == [app._crew_result]
|
||||
|
||||
|
||||
def test_conversation_turn_done_records_assistant_message() -> None:
|
||||
class RawResult:
|
||||
raw = "hello from the flow"
|
||||
|
||||
@@ -249,6 +249,17 @@ class Telemetry:
|
||||
|
||||
self._safe_telemetry_procedure(_operation)
|
||||
|
||||
def tui_button_clicked_span(self, button_name: str) -> None:
|
||||
"""Records when a user clicks a button in the CLI TUI."""
|
||||
|
||||
def _operation() -> None:
|
||||
tracer = trace.get_tracer("crewai.telemetry")
|
||||
span = tracer.start_span("TUI Button Clicked")
|
||||
self._add_attribute(span, "button_name", button_name)
|
||||
close_span(span)
|
||||
|
||||
self._safe_telemetry_procedure(_operation)
|
||||
|
||||
def flow_creation_span(self, flow_name: str) -> None:
|
||||
"""Records the creation of a new flow."""
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from unittest.mock import Mock
|
||||
|
||||
from crewai_core import (
|
||||
constants,
|
||||
@@ -128,3 +129,29 @@ def test_core_telemetry_skips_duplicate_tracer_provider(
|
||||
|
||||
assert called is False
|
||||
assert telemetry.trace_set is True
|
||||
|
||||
|
||||
def test_core_telemetry_records_tui_button_click(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
from crewai_core.telemetry import Telemetry
|
||||
|
||||
Telemetry._instance = None
|
||||
monkeypatch.delenv("OTEL_SDK_DISABLED", raising=False)
|
||||
monkeypatch.delenv("CREWAI_DISABLE_TELEMETRY", raising=False)
|
||||
monkeypatch.delenv("CREWAI_DISABLE_TRACKING", raising=False)
|
||||
|
||||
tracer = Mock()
|
||||
span = Mock()
|
||||
tracer.start_span.return_value = span
|
||||
monkeypatch.setattr(
|
||||
"crewai_core.telemetry.trace.get_tracer",
|
||||
lambda _name: tracer,
|
||||
)
|
||||
|
||||
telemetry = Telemetry()
|
||||
telemetry.tui_button_clicked_span("view_traces")
|
||||
|
||||
tracer.start_span.assert_called_once_with("TUI Button Clicked")
|
||||
span.set_attribute.assert_called_once_with("button_name", "view_traces")
|
||||
span.end.assert_called_once()
|
||||
|
||||
Reference in New Issue
Block a user