diff --git a/lib/crewai-tools/src/crewai_tools/rag/data_types.py b/lib/crewai-tools/src/crewai_tools/rag/data_types.py index 27ee48abb..0fcf07e12 100644 --- a/lib/crewai-tools/src/crewai_tools/rag/data_types.py +++ b/lib/crewai-tools/src/crewai_tools/rag/data_types.py @@ -135,7 +135,8 @@ class DataTypes: if "docs" in url.netloc or ("docs" in url.path and url.scheme != "file"): return DataType.DOCS_SITE - if "github.com" in url.netloc: + hostname = (url.hostname or "").lower() + if hostname == "github.com" or hostname.endswith(".github.com"): return DataType.GITHUB return DataType.WEBSITE diff --git a/lib/crewai-tools/tests/rag/test_data_types.py b/lib/crewai-tools/tests/rag/test_data_types.py new file mode 100644 index 000000000..1812e1ea4 --- /dev/null +++ b/lib/crewai-tools/tests/rag/test_data_types.py @@ -0,0 +1,32 @@ +"""Tests for DataType content classification.""" + +from crewai_tools.rag.data_types import DataType + + +class TestDataTypeFromContentGitHub: + """GitHub URL detection must use hostname matching, not substrings.""" + + def test_github_com_url(self) -> None: + assert ( + DataType.from_content("https://github.com/crewai/crewai") + == DataType.GITHUB + ) + + def test_github_subdomain_url(self) -> None: + assert ( + DataType.from_content("https://gist.github.com/user/abc") + == DataType.GITHUB + ) + + def test_spoofed_github_hostname_is_website(self) -> None: + # Substring checks like `"github.com" in netloc` would misclassify this. + assert ( + DataType.from_content("https://github.com.evil.example/crewai") + == DataType.WEBSITE + ) + + def test_github_in_path_is_not_github(self) -> None: + assert ( + DataType.from_content("https://example.com/github.com/repo") + == DataType.WEBSITE + ) diff --git a/lib/crewai-tools/tests/tools/stagehand_tool_test.py b/lib/crewai-tools/tests/tools/stagehand_tool_test.py index 508b1357e..eefe1340e 100644 --- a/lib/crewai-tools/tests/tools/stagehand_tool_test.py +++ b/lib/crewai-tools/tests/tools/stagehand_tool_test.py @@ -163,8 +163,14 @@ def test_navigate_command(mock_run, stagehand_tool): command_type="navigate", ) - # Assertions - assert "https://example.com" in result + # Assertions — compare the full mocked result (avoid URL substring checks) + assert result == "Successfully navigated to https://example.com" + mock_run.assert_called_once_with( + stagehand_tool, + instruction="Go to example.com", + url="https://example.com", + command_type="navigate", + ) @patch(