Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/cli/src/crewai_cli/crew_run_tui.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
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
Expand Down Expand Up @@ -571,6 +572,7 @@ def __init__(
self._want_deploy: bool = False
self._trace_url: str | None = None
self._consent_screen: TraceConsentScreen | None = None
self._telemetry: Telemetry | None = None

# ── Layout ──────────────────────────────────────────────

Expand Down Expand Up @@ -1042,10 +1044,21 @@ def action_deploy_crew(self) -> None:
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()
Comment thread
lorenzejay marked this conversation as resolved.
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:
Expand Down
33 changes: 33 additions & 0 deletions lib/cli/tests/test_crew_run_tui.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from datetime import datetime
import time
from types import SimpleNamespace
from unittest.mock import Mock

import pytest

Expand Down Expand Up @@ -126,6 +128,37 @@ def login(self) -> None:
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"
Expand Down
11 changes: 11 additions & 0 deletions lib/crewai-core/src/crewai_core/telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,17 @@ def _operation() -> None:

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:
Comment thread
joaomdmoura marked this conversation as resolved.
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."""

Expand Down
27 changes: 27 additions & 0 deletions lib/crewai-core/tests/test_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import os
from pathlib import Path
from unittest.mock import Mock

from crewai_core import (
constants,
Expand Down Expand Up @@ -128,3 +129,29 @@ def fail_if_called(provider: object) -> None:

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()
Loading