diff --git a/lib/cli/src/crewai_cli/run_crew.py b/lib/cli/src/crewai_cli/run_crew.py index cbc14ff86..05d6878f5 100644 --- a/lib/cli/src/crewai_cli/run_crew.py +++ b/lib/cli/src/crewai_cli/run_crew.py @@ -10,7 +10,6 @@ import sys from typing import TYPE_CHECKING, Any import click -from crewai.project.json_loader import find_crew_json_file from crewai_core.constants import CREWAI_TRAINED_AGENTS_FILE_ENV from packaging import version @@ -38,6 +37,15 @@ class CrewType(Enum): _INPUT_PLACEHOLDER_RE = re.compile(r"(? Any: + from crewai.project.json_loader import find_crew_json_file as _find_crew_json_file + + return _find_crew_json_file + + +def _is_missing_crewai_package(exc: ModuleNotFoundError) -> bool: + return bool(exc.name and exc.name.startswith("crewai")) + + +def _full_crewai_install_error() -> click.ClickException: + return click.ClickException(_FULL_CREWAI_INSTALL_MESSAGE) + + +def find_crew_json_file() -> Path | None: + try: + return _import_find_crew_json_file()() + except ModuleNotFoundError as exc: + if _is_missing_crewai_package(exc): + raise _full_crewai_install_error() from exc + raise + + def _has_json_crew() -> bool: """Check if this is a JSON-defined crew project. diff --git a/lib/cli/tests/test_run_crew.py b/lib/cli/tests/test_run_crew.py index 88d31fa1e..d56118187 100644 --- a/lib/cli/tests/test_run_crew.py +++ b/lib/cli/tests/test_run_crew.py @@ -5,12 +5,33 @@ from pathlib import Path import subprocess import sys +import click import pytest from crewai_core.constants import CREWAI_TRAINED_AGENTS_FILE_ENV import crewai_cli.run_crew as run_crew_module +def test_missing_crewai_package_shows_full_install_hint(monkeypatch): + def missing_crewai_package(): + raise ModuleNotFoundError("No module named 'crewai'", name="crewai") + + monkeypatch.setattr( + run_crew_module, "_import_find_crew_json_file", missing_crewai_package + ) + + with pytest.raises(click.ClickException) as exc_info: + run_crew_module.find_crew_json_file() + + message = exc_info.value.message + assert "CrewAI CLI is installed without the `crewai` package" in message + assert ( + "uv tool install --force --prerelease=allow 'crewai[tools]==1.14.8a'" + in message + ) + assert "quotes are required in zsh" in message + + def test_run_crew_forwards_trained_agents_file_to_json_crews(monkeypatch): """crewai run -f must reach JSON crews, not only classic subprocess crews.""" monkeypatch.setattr(run_crew_module, "_has_json_crew", lambda: True)