mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-07 02:02:35 +00:00
refactor(core): extract crewai-core for shared utilities and standalone CLI
- New lib/crewai-core/ package: version, paths, constants, lock_store, user_data,
printer, telemetry. Pure leaf — depends only on appdirs/portalocker/rich/otel.
- crewai now depends on crewai-core; old crewai.utilities.{version,paths,printer,
lock_store} and the user-data block of events/listeners/tracing/utils.py become
one-shot DeprecationWarning shims that re-export from crewai_core.
- crewai-cli drops its hard dep on crewai and depends only on crewai-core. CLI
imports for telemetry/version/printer/constants now point at crewai_core.
- tools/main.py lazy-imports project_utils + get_user_id; the publish/login
subcommands print a friendly "requires crewai" error if it's missing.
- crewai-cli is now genuinely standalone: 'crewai --help', 'version', 'login',
'config', 'traces', 'create', 'template' all work without crewai installed.
- 351 CLI tests + 9 crewai-core smoke tests + crewai's full mypy (471 files) clean.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
from crewai.utilities.printer import PRINTER
|
||||
from crewai_core.printer import PRINTER
|
||||
|
||||
from crewai_cli.utils import copy_template
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
from crewai.telemetry.telemetry import Telemetry
|
||||
from crewai_core.telemetry import Telemetry
|
||||
import httpx
|
||||
from rich.console import Console
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from pathlib import Path
|
||||
import shutil
|
||||
|
||||
import click
|
||||
from crewai.telemetry import Telemetry
|
||||
from crewai_core.telemetry import Telemetry
|
||||
|
||||
|
||||
def create_flow(name: str) -> None:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import subprocess
|
||||
|
||||
import click
|
||||
from crewai.utilities.constants import CREWAI_TRAINED_AGENTS_FILE_ENV
|
||||
from crewai_core.constants import CREWAI_TRAINED_AGENTS_FILE_ENV
|
||||
|
||||
from crewai_cli.utils import build_env_with_all_tool_credentials
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import subprocess
|
||||
|
||||
import click
|
||||
from crewai.utilities.constants import CREWAI_TRAINED_AGENTS_FILE_ENV
|
||||
from crewai_core.constants import CREWAI_TRAINED_AGENTS_FILE_ENV
|
||||
|
||||
from crewai_cli.utils import build_env_with_all_tool_credentials
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from enum import Enum
|
||||
import subprocess
|
||||
|
||||
import click
|
||||
from crewai.utilities.constants import CREWAI_TRAINED_AGENTS_FILE_ENV
|
||||
from crewai_core.constants import CREWAI_TRAINED_AGENTS_FILE_ENV
|
||||
from packaging import version
|
||||
|
||||
from crewai_cli.utils import build_env_with_all_tool_credentials, read_toml
|
||||
|
||||
@@ -8,11 +8,6 @@ import tempfile
|
||||
from typing import Any
|
||||
|
||||
import click
|
||||
from crewai.events.listeners.tracing.utils import get_user_id
|
||||
from crewai.utilities.project_utils import (
|
||||
extract_available_exports,
|
||||
extract_tools_metadata,
|
||||
)
|
||||
from rich.console import Console
|
||||
|
||||
from crewai_cli import git
|
||||
@@ -33,6 +28,32 @@ from crewai_cli.utils import (
|
||||
console = Console()
|
||||
|
||||
|
||||
_REQUIRES_CREWAI_MSG = (
|
||||
"[red]This subcommand requires the full crewai package.\n"
|
||||
"Install it with: pip install crewai[/red]"
|
||||
)
|
||||
|
||||
|
||||
def _require_project_utils() -> Any:
|
||||
try:
|
||||
from crewai.utilities import project_utils
|
||||
|
||||
return project_utils
|
||||
except ImportError:
|
||||
console.print(_REQUIRES_CREWAI_MSG)
|
||||
raise SystemExit(1) from None
|
||||
|
||||
|
||||
def _require_get_user_id() -> Any:
|
||||
try:
|
||||
from crewai.events.listeners.tracing.utils import get_user_id
|
||||
|
||||
return get_user_id
|
||||
except ImportError:
|
||||
console.print(_REQUIRES_CREWAI_MSG)
|
||||
raise SystemExit(1) from None
|
||||
|
||||
|
||||
class ToolCommand(BaseCommand, PlusAPIMixin):
|
||||
"""
|
||||
A class to handle tool repository related operations for CrewAI projects.
|
||||
@@ -99,7 +120,8 @@ class ToolCommand(BaseCommand, PlusAPIMixin):
|
||||
encoded_tarball = None
|
||||
|
||||
console.print("[bold blue]Discovering tools from your project...[/bold blue]")
|
||||
available_exports = extract_available_exports()
|
||||
project_utils = _require_project_utils()
|
||||
available_exports = project_utils.extract_available_exports()
|
||||
|
||||
if available_exports:
|
||||
console.print(
|
||||
@@ -108,7 +130,7 @@ class ToolCommand(BaseCommand, PlusAPIMixin):
|
||||
|
||||
console.print("[bold blue]Extracting tool metadata...[/bold blue]")
|
||||
try:
|
||||
tools_metadata = extract_tools_metadata()
|
||||
tools_metadata = project_utils.extract_tools_metadata()
|
||||
except Exception as e:
|
||||
console.print(
|
||||
f"[yellow]Warning: Could not extract tool metadata: {e}[/yellow]\n"
|
||||
@@ -202,6 +224,7 @@ class ToolCommand(BaseCommand, PlusAPIMixin):
|
||||
console.print(f"Successfully installed {handle}", style="bold green")
|
||||
|
||||
def login(self) -> None:
|
||||
get_user_id = _require_get_user_id()
|
||||
login_response = self.plus_api_client.login_to_tool_repository(
|
||||
user_identifier=get_user_id()
|
||||
)
|
||||
|
||||
@@ -1,71 +1,22 @@
|
||||
"""Standalone user-data helpers for the CLI package.
|
||||
|
||||
These mirror the functions in ``crewai.events.listeners.tracing.utils`` but
|
||||
depend only on the standard library + *appdirs* so that crewai-cli can work
|
||||
without importing the full crewai framework.
|
||||
"""
|
||||
"""User-data helpers — re-exported from ``crewai_core.user_data``."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any, cast
|
||||
|
||||
import appdirs
|
||||
from crewai_core.paths import db_storage_path as _db_storage_path
|
||||
from crewai_core.user_data import (
|
||||
_load_user_data as _load_user_data,
|
||||
_save_user_data as _save_user_data,
|
||||
has_user_declined_tracing as has_user_declined_tracing,
|
||||
is_tracing_enabled as is_tracing_enabled,
|
||||
update_user_data as update_user_data,
|
||||
)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _get_project_directory_name() -> str:
|
||||
return os.environ.get("CREWAI_STORAGE_DIR", Path.cwd().name)
|
||||
|
||||
|
||||
def _db_storage_path() -> str:
|
||||
app_name = _get_project_directory_name()
|
||||
app_author = "CrewAI"
|
||||
data_dir = Path(appdirs.user_data_dir(app_name, app_author))
|
||||
data_dir.mkdir(parents=True, exist_ok=True)
|
||||
return str(data_dir)
|
||||
|
||||
|
||||
def _user_data_file() -> Path:
|
||||
base = Path(_db_storage_path())
|
||||
base.mkdir(parents=True, exist_ok=True)
|
||||
return base / ".crewai_user.json"
|
||||
|
||||
|
||||
def _load_user_data() -> dict[str, Any]:
|
||||
p = _user_data_file()
|
||||
if p.exists():
|
||||
try:
|
||||
return cast(dict[str, Any], json.loads(p.read_text()))
|
||||
except (json.JSONDecodeError, OSError, PermissionError) as e:
|
||||
logger.warning("Failed to load user data: %s", e)
|
||||
return {}
|
||||
|
||||
|
||||
def _save_user_data(data: dict[str, Any]) -> None:
|
||||
try:
|
||||
p = _user_data_file()
|
||||
p.write_text(json.dumps(data, indent=2))
|
||||
except (OSError, PermissionError) as e:
|
||||
logger.warning("Failed to save user data: %s", e)
|
||||
|
||||
|
||||
def is_tracing_enabled() -> bool:
|
||||
"""Check if tracing is enabled.
|
||||
|
||||
Mirrors ``crewai.events.listeners.tracing.utils.is_tracing_enabled``:
|
||||
consent only *blocks* tracing; activation requires
|
||||
``CREWAI_TRACING_ENABLED=true``.
|
||||
"""
|
||||
data = _load_user_data()
|
||||
if (
|
||||
data.get("first_execution_done", False)
|
||||
and data.get("trace_consent", False) is False
|
||||
):
|
||||
return False
|
||||
return os.getenv("CREWAI_TRACING_ENABLED", "false").lower() == "true"
|
||||
__all__ = [
|
||||
"_db_storage_path",
|
||||
"_load_user_data",
|
||||
"_save_user_data",
|
||||
"has_user_declined_tracing",
|
||||
"is_tracing_enabled",
|
||||
"update_user_data",
|
||||
]
|
||||
|
||||
@@ -10,7 +10,7 @@ from urllib import request
|
||||
from urllib.error import URLError
|
||||
|
||||
import appdirs
|
||||
from crewai.utilities.version import get_crewai_version as get_crewai_version
|
||||
from crewai_core.version import get_crewai_version as get_crewai_version
|
||||
from packaging.version import InvalidVersion, Version, parse
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user