diff --git a/src/crewai/cli/tools/main.py b/src/crewai/cli/tools/main.py index 2cb4821c3..fad69467d 100644 --- a/src/crewai/cli/tools/main.py +++ b/src/crewai/cli/tools/main.py @@ -3,6 +3,7 @@ import os import subprocess import tempfile from pathlib import Path +from typing import Any import click from rich.console import Console @@ -178,7 +179,8 @@ class ToolCommand(BaseCommand, PlusAPIMixin): "Successfully authenticated to the tool repository.", style="bold green" ) - def _add_package(self, tool_details): + def _add_package(self, tool_details: dict[str, Any]): + is_from_pypi = tool_details.get("source", None) == "pypi" tool_handle = tool_details["handle"] repository_handle = tool_details["repository"]["handle"] repository_url = tool_details["repository"]["url"] @@ -187,10 +189,13 @@ class ToolCommand(BaseCommand, PlusAPIMixin): add_package_command = [ "uv", "add", - "--index", - index, - tool_handle, ] + + if is_from_pypi: + add_package_command.append(tool_handle) + else: + add_package_command.extend(["--index", index, tool_handle]) + add_package_result = subprocess.run( add_package_command, capture_output=False, diff --git a/tests/cli/tools/test_main.py b/tests/cli/tools/test_main.py index f9fe871f3..e3bd1fe9b 100644 --- a/tests/cli/tools/test_main.py +++ b/tests/cli/tools/test_main.py @@ -85,6 +85,36 @@ def test_install_success(mock_get, mock_subprocess_run, capsys, tool_command): env=unittest.mock.ANY, ) +@patch("crewai.cli.tools.main.subprocess.run") +@patch("crewai.cli.plus_api.PlusAPI.get_tool") +def test_install_success_from_pypi(mock_get, mock_subprocess_run, capsys, tool_command): + mock_get_response = MagicMock() + mock_get_response.status_code = 200 + mock_get_response.json.return_value = { + "handle": "sample-tool", + "repository": {"handle": "sample-repo", "url": "https://example.com/repo"}, + "source": "pypi", + } + mock_get.return_value = mock_get_response + mock_subprocess_run.return_value = MagicMock(stderr=None) + + tool_command.install("sample-tool") + output = capsys.readouterr().out + assert "Successfully installed sample-tool" in output + + mock_get.assert_has_calls([mock.call("sample-tool"), mock.call().json()]) + mock_subprocess_run.assert_any_call( + [ + "uv", + "add", + "sample-tool", + ], + capture_output=False, + text=True, + check=True, + env=unittest.mock.ANY, + ) + @patch("crewai.cli.plus_api.PlusAPI.get_tool") def test_install_tool_not_found(mock_get, capsys, tool_command):