From 48fa7dcc9bc82d59d4841c9125fa0fa6ba9d83f0 Mon Sep 17 00:00:00 2001 From: Greyson Lalonde Date: Tue, 5 May 2026 04:35:26 +0800 Subject: [PATCH] fix(cli): restore parity with main --- lib/cli/src/crewai_cli/cli.py | 22 +++++++++---------- lib/cli/src/crewai_cli/command.py | 13 +++++++++-- lib/cli/src/crewai_cli/create_flow.py | 4 ++++ lib/cli/src/crewai_cli/deploy/main.py | 6 ++++- lib/cli/src/crewai_cli/organization/main.py | 2 +- lib/cli/src/crewai_cli/plus_api.py | 6 +++-- .../src/crewai_cli/remote_template/main.py | 2 ++ lib/cli/src/crewai_cli/tools/main.py | 2 +- lib/cli/src/crewai_cli/triggers/main.py | 2 +- 9 files changed, 40 insertions(+), 19 deletions(-) diff --git a/lib/cli/src/crewai_cli/cli.py b/lib/cli/src/crewai_cli/cli.py index 02ce62d9a..c8010e7c6 100644 --- a/lib/cli/src/crewai_cli/cli.py +++ b/lib/cli/src/crewai_cli/cli.py @@ -737,7 +737,7 @@ def env_view() -> None: table.add_row( "CREWAI_TRACING_ENABLED", "[dim]Not set[/dim]", - "[dim]---[/dim]", + "[dim]—[/dim]", ) # Check other related env vars @@ -756,7 +756,7 @@ def env_view() -> None: # Check if .env file exists table.add_row( ".env file", - "Found" if env_file_exists else "Not found", + "✅ Found" if env_file_exists else "❌ Not found", str(env_file.resolve()) if env_file_exists else "N/A", ) @@ -772,11 +772,11 @@ def env_view() -> None: # Show helpful message if env_file_exists: console.print( - "\n[dim]Tip: To enable tracing via .env, add: CREWAI_TRACING_ENABLED=true[/dim]" + "\n[dim]💡 Tip: To enable tracing via .env, add: CREWAI_TRACING_ENABLED=true[/dim]" ) else: console.print( - "\n[dim]Tip: Create a .env file in your project root and add: CREWAI_TRACING_ENABLED=true[/dim]" + "\n[dim]💡 Tip: Create a .env file in your project root and add: CREWAI_TRACING_ENABLED=true[/dim]" ) console.print() @@ -801,7 +801,7 @@ def traces_enable() -> None: _save_user_data(user_data) panel = Panel( - "Trace collection has been enabled!\n\n" + "✅ Trace collection has been enabled!\n\n" "Your crew/flow executions will now send traces to CrewAI+.\n" "Use 'crewai traces disable' to turn off trace collection.", title="Traces Enabled", @@ -826,7 +826,7 @@ def traces_disable() -> None: _save_user_data(user_data) panel = Panel( - "Trace collection has been disabled!\n\n" + "❌ Trace collection has been disabled!\n\n" "Your crew/flow executions will no longer send traces.\n" "Use 'crewai traces enable' to turn trace collection back on.", title="Traces Disabled", @@ -858,19 +858,19 @@ def traces_status() -> None: # Check user consent trace_consent = user_data.get("trace_consent") if trace_consent is True: - consent_status = "Enabled (user consented)" + consent_status = "✅ Enabled (user consented)" elif trace_consent is False: - consent_status = "Disabled (user declined)" + consent_status = "❌ Disabled (user declined)" else: - consent_status = "Not set (first-time user)" + consent_status = "⚪ Not set (first-time user)" table.add_row("User Consent", consent_status) # Check overall status if is_tracing_enabled(): - overall_status = "ENABLED" + overall_status = "✅ ENABLED" border_style = "green" else: - overall_status = "DISABLED" + overall_status = "❌ DISABLED" border_style = "red" table.add_row("Overall Status", overall_status) diff --git a/lib/cli/src/crewai_cli/command.py b/lib/cli/src/crewai_cli/command.py index 77913f627..c33f1578a 100644 --- a/lib/cli/src/crewai_cli/command.py +++ b/lib/cli/src/crewai_cli/command.py @@ -2,6 +2,7 @@ from __future__ import annotations import json +from crewai.telemetry.telemetry import Telemetry import httpx from rich.console import Console @@ -14,14 +15,17 @@ console = Console() class BaseCommand: def __init__(self) -> None: - pass + self._telemetry = Telemetry() + self._telemetry.set_tracer() class PlusAPIMixin: - def __init__(self) -> None: + def __init__(self, telemetry: Telemetry) -> None: try: + telemetry.set_tracer() self.plus_api_client = PlusAPI(api_key=get_auth_token()) except Exception: + telemetry.deploy_signup_error_span() console.print( "Please sign up/login to CrewAI+ before using the CLI.", style="bold red", @@ -30,6 +34,11 @@ class PlusAPIMixin: raise SystemExit from None def _validate_response(self, response: httpx.Response) -> None: + """Handle and display error messages from API responses. + + Args: + response: The response from the Plus API. + """ try: json_response = response.json() except (json.JSONDecodeError, ValueError): diff --git a/lib/cli/src/crewai_cli/create_flow.py b/lib/cli/src/crewai_cli/create_flow.py index 3ed784945..1352cb5ee 100644 --- a/lib/cli/src/crewai_cli/create_flow.py +++ b/lib/cli/src/crewai_cli/create_flow.py @@ -2,6 +2,7 @@ from pathlib import Path import shutil import click +from crewai.telemetry import Telemetry def create_flow(name: str) -> None: @@ -11,6 +12,9 @@ def create_flow(name: str) -> None: click.secho(f"Creating flow {folder_name}...", fg="green", bold=True) + telemetry = Telemetry() + telemetry.flow_creation_span(class_name) + project_root = Path(folder_name) if project_root.exists(): click.secho(f"Error: Folder {folder_name} already exists.", fg="red") diff --git a/lib/cli/src/crewai_cli/deploy/main.py b/lib/cli/src/crewai_cli/deploy/main.py index fd78e2431..7a61e42dc 100644 --- a/lib/cli/src/crewai_cli/deploy/main.py +++ b/lib/cli/src/crewai_cli/deploy/main.py @@ -45,7 +45,7 @@ class DeployCommand(BaseCommand, PlusAPIMixin): """ BaseCommand.__init__(self) - PlusAPIMixin.__init__(self) + PlusAPIMixin.__init__(self, telemetry=self._telemetry) self.project_name = get_project_name(require=True) self._validate_project_structure() @@ -129,6 +129,7 @@ class DeployCommand(BaseCommand, PlusAPIMixin): """ if not _run_predeploy_validation(skip_validate): return + self._telemetry.start_deployment_span(uuid) console.print("Starting deployment...", style="bold blue") if uuid: response = self.plus_api_client.deploy_by_uuid(uuid) @@ -151,6 +152,7 @@ class DeployCommand(BaseCommand, PlusAPIMixin): """ if not _run_predeploy_validation(skip_validate): return + self._telemetry.create_crew_deployment_span() console.print("Creating deployment...", style="bold blue") env_vars = fetch_and_json_env_file() @@ -300,6 +302,7 @@ class DeployCommand(BaseCommand, PlusAPIMixin): uuid (Optional[str]): The UUID of the crew to get logs for. log_type (str): The type of logs to retrieve (default: "deployment"). """ + self._telemetry.get_crew_logs_span(uuid, log_type) console.print(f"Fetching {log_type} logs...", style="bold blue") if uuid: @@ -320,6 +323,7 @@ class DeployCommand(BaseCommand, PlusAPIMixin): Args: uuid (Optional[str]): The UUID of the crew to remove. """ + self._telemetry.remove_crew_span(uuid) console.print("Removing deployment...", style="bold blue") if uuid: diff --git a/lib/cli/src/crewai_cli/organization/main.py b/lib/cli/src/crewai_cli/organization/main.py index e7053623b..b8ba86f92 100644 --- a/lib/cli/src/crewai_cli/organization/main.py +++ b/lib/cli/src/crewai_cli/organization/main.py @@ -12,7 +12,7 @@ console = Console() class OrganizationCommand(BaseCommand, PlusAPIMixin): def __init__(self) -> None: BaseCommand.__init__(self) - PlusAPIMixin.__init__(self) + PlusAPIMixin.__init__(self, telemetry=self._telemetry) def list(self) -> None: try: diff --git a/lib/cli/src/crewai_cli/plus_api.py b/lib/cli/src/crewai_cli/plus_api.py index 43ac71c63..c655138e5 100644 --- a/lib/cli/src/crewai_cli/plus_api.py +++ b/lib/cli/src/crewai_cli/plus_api.py @@ -22,10 +22,9 @@ class PlusAPI: EPHEMERAL_TRACING_RESOURCE = "/crewai_plus/api/v1/tracing/ephemeral" INTEGRATIONS_RESOURCE = "/crewai_plus/api/v1/integrations" - def __init__(self, api_key: str) -> None: + def __init__(self, api_key: str | None = None) -> None: self.api_key = api_key self.headers = { - "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", "User-Agent": f"CrewAI-CLI/{get_crewai_version()}", "X-Crewai-Version": get_crewai_version(), @@ -34,6 +33,9 @@ class PlusAPI: if settings.org_uuid: self.headers["X-Crewai-Organization-Id"] = settings.org_uuid + if api_key: + self.headers["Authorization"] = f"Bearer {api_key}" + self.base_url = ( os.getenv("CREWAI_PLUS_URL") or str(settings.enterprise_base_url) diff --git a/lib/cli/src/crewai_cli/remote_template/main.py b/lib/cli/src/crewai_cli/remote_template/main.py index b2b7527f3..a7db81191 100644 --- a/lib/cli/src/crewai_cli/remote_template/main.py +++ b/lib/cli/src/crewai_cli/remote_template/main.py @@ -131,6 +131,8 @@ class TemplateCommand(BaseCommand): zip_bytes = self._download_zip(repo_name) self._extract_zip(zip_bytes, dest) + self._telemetry.template_installed_span(repo_name.removeprefix(TEMPLATE_PREFIX)) + console.print( f"\n [green]\u2713[/green] Installed template [bold white]{folder_name}[/bold white]" f" [dim](source: github.com/{GITHUB_ORG}/{repo_name})[/dim]\n" diff --git a/lib/cli/src/crewai_cli/tools/main.py b/lib/cli/src/crewai_cli/tools/main.py index bfbc3ffd9..d1935d6ca 100644 --- a/lib/cli/src/crewai_cli/tools/main.py +++ b/lib/cli/src/crewai_cli/tools/main.py @@ -40,7 +40,7 @@ class ToolCommand(BaseCommand, PlusAPIMixin): def __init__(self) -> None: BaseCommand.__init__(self) - PlusAPIMixin.__init__(self) + PlusAPIMixin.__init__(self, telemetry=self._telemetry) def create(self, handle: str) -> None: self._ensure_not_in_project() diff --git a/lib/cli/src/crewai_cli/triggers/main.py b/lib/cli/src/crewai_cli/triggers/main.py index dc55d6839..2c081d722 100644 --- a/lib/cli/src/crewai_cli/triggers/main.py +++ b/lib/cli/src/crewai_cli/triggers/main.py @@ -18,7 +18,7 @@ class TriggersCommand(BaseCommand, PlusAPIMixin): def __init__(self) -> None: BaseCommand.__init__(self) - PlusAPIMixin.__init__(self) + PlusAPIMixin.__init__(self, telemetry=self._telemetry) def list_triggers(self) -> None: """List all available triggers from integrations."""