From 8180637345da889d6b6552e73569c730cdf6f164 Mon Sep 17 00:00:00 2001 From: Sergey Ryabov <944361+colriot@users.noreply.github.com> Date: Wed, 30 Oct 2024 23:45:36 +0000 Subject: [PATCH] community[patch]: Fix Playwright Tools bug with Pydantic schemas (#27050) - Add tests for Playwright tools schema serialization - Introduce base empty args Input class for BaseBrowserTool Test Plan: `poetry run pytest tests/unit_tests/tools/playwright/test_all.py` Fixes #26758 --------- Co-authored-by: Erick Friis Co-authored-by: Eugene Yurtsev --- libs/community/extended_testing_deps.txt | 1 + .../tools/playwright/current_page.py | 6 ++++- .../tools/playwright/extract_text.py | 6 ++++- .../tools/playwright/navigate_back.py | 6 ++++- .../unit_tests/tools/playwright/__init__.py | 0 .../unit_tests/tools/playwright/test_all.py | 26 +++++++++++++++++++ 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 libs/community/tests/unit_tests/tools/playwright/__init__.py create mode 100644 libs/community/tests/unit_tests/tools/playwright/test_all.py diff --git a/libs/community/extended_testing_deps.txt b/libs/community/extended_testing_deps.txt index 1214645947abf..5be87606873d4 100644 --- a/libs/community/extended_testing_deps.txt +++ b/libs/community/extended_testing_deps.txt @@ -58,6 +58,7 @@ oracledb>=2.2.0,<3 pandas>=2.0.1,<3 pdfminer-six>=20221105,<20240706 pgvector>=0.1.6,<0.2 +playwright>=1.48.0,<2 praw>=7.7.1,<8 premai>=0.3.25,<0.4 psychicapi>=0.8.0,<0.9 diff --git a/libs/community/langchain_community/tools/playwright/current_page.py b/libs/community/langchain_community/tools/playwright/current_page.py index 50033d7f37878..861b2eca53f85 100644 --- a/libs/community/langchain_community/tools/playwright/current_page.py +++ b/libs/community/langchain_community/tools/playwright/current_page.py @@ -15,12 +15,16 @@ ) +class CurrentWebPageToolInput(BaseModel): + """Explicit no-args input for CurrentWebPageTool.""" + + class CurrentWebPageTool(BaseBrowserTool): # type: ignore[override, override] """Tool for getting the URL of the current webpage.""" name: str = "current_webpage" description: str = "Returns the URL of the current page" - args_schema: Type[BaseModel] = BaseModel + args_schema: Type[BaseModel] = CurrentWebPageToolInput def _run( self, diff --git a/libs/community/langchain_community/tools/playwright/extract_text.py b/libs/community/langchain_community/tools/playwright/extract_text.py index dc77f1297f388..98774f73558cb 100644 --- a/libs/community/langchain_community/tools/playwright/extract_text.py +++ b/libs/community/langchain_community/tools/playwright/extract_text.py @@ -15,12 +15,16 @@ ) +class ExtractTextToolInput(BaseModel): + """Explicit no-args input for ExtractTextTool.""" + + class ExtractTextTool(BaseBrowserTool): # type: ignore[override, override] """Tool for extracting all the text on the current webpage.""" name: str = "extract_text" description: str = "Extract all the text on the current webpage" - args_schema: Type[BaseModel] = BaseModel + args_schema: Type[BaseModel] = ExtractTextToolInput @model_validator(mode="before") @classmethod diff --git a/libs/community/langchain_community/tools/playwright/navigate_back.py b/libs/community/langchain_community/tools/playwright/navigate_back.py index 688b135a23e7a..2a2eff3890653 100644 --- a/libs/community/langchain_community/tools/playwright/navigate_back.py +++ b/libs/community/langchain_community/tools/playwright/navigate_back.py @@ -15,12 +15,16 @@ ) +class NavigateBackToolInput(BaseModel): + """Explicit no-args input for NavigateBackTool.""" + + class NavigateBackTool(BaseBrowserTool): # type: ignore[override, override] """Navigate back to the previous page in the browser history.""" name: str = "previous_webpage" description: str = "Navigate back to the previous page in the browser history" - args_schema: Type[BaseModel] = BaseModel + args_schema: Type[BaseModel] = NavigateBackToolInput def _run(self, run_manager: Optional[CallbackManagerForToolRun] = None) -> str: """Use the tool.""" diff --git a/libs/community/tests/unit_tests/tools/playwright/__init__.py b/libs/community/tests/unit_tests/tools/playwright/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/libs/community/tests/unit_tests/tools/playwright/test_all.py b/libs/community/tests/unit_tests/tools/playwright/test_all.py new file mode 100644 index 0000000000000..8d0c9b98f5c04 --- /dev/null +++ b/libs/community/tests/unit_tests/tools/playwright/test_all.py @@ -0,0 +1,26 @@ +"""Test Playwright's Tools.""" + +from unittest.mock import Mock + +import pytest + +from langchain_community.agent_toolkits import PlayWrightBrowserToolkit + + +@pytest.mark.requires("playwright") +@pytest.mark.requires("bs4") +def test_playwright_tools_schemas() -> None: + """Test calling 'tool_call_schema' for every tool to check to init issues.""" + + from playwright.sync_api import Browser + + sync_browser = Mock(spec=Browser) + tools = PlayWrightBrowserToolkit.from_browser(sync_browser=sync_browser).get_tools() + + for tool in tools: + try: + tool.tool_call_schema + except Exception as e: + raise AssertionError( + f"Error for '{tool.name}' tool: {type(e).__name__}: {e}" + ) from e